/// <summary> /// Helper for getting the base address of a module loaded by the current process. This base /// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for /// manual export parsing. This function parses the _PEB_LDR_DATA structure. /// </summary> /// <author>Ruben Boonen (@FuzzySec)</author> /// <param name="DLLName">The name of the DLL (e.g. "ntdll.dll").</param> /// <returns>IntPtr base address of the loaded module or IntPtr.Zero if the module is not found.</returns> public static IntPtr GetPebLdrModuleEntry(string DLLName) { // Get _PEB pointer Execute.Native.PROCESS_BASIC_INFORMATION pbi = Native.NtQueryInformationProcessBasicInformation((IntPtr)(-1)); // Set function variables bool Is32Bit = false; UInt32 LdrDataOffset = 0; UInt32 InLoadOrderModuleListOffset = 0; if (IntPtr.Size == 4) { Is32Bit = true; LdrDataOffset = 0xc; InLoadOrderModuleListOffset = 0xC; } else { LdrDataOffset = 0x18; InLoadOrderModuleListOffset = 0x10; } // Get module InLoadOrderModuleList -> _LIST_ENTRY IntPtr PEB_LDR_DATA = Marshal.ReadIntPtr((IntPtr)((UInt64)pbi.PebBaseAddress + LdrDataOffset)); IntPtr pInLoadOrderModuleList = (IntPtr)((UInt64)PEB_LDR_DATA + InLoadOrderModuleListOffset); Execute.Native.LIST_ENTRY le = (Execute.Native.LIST_ENTRY)Marshal.PtrToStructure(pInLoadOrderModuleList, typeof(Execute.Native.LIST_ENTRY)); // Loop entries IntPtr flink = le.Flink; IntPtr hModule = IntPtr.Zero; PE.LDR_DATA_TABLE_ENTRY dte = (PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(PE.LDR_DATA_TABLE_ENTRY)); while (dte.InLoadOrderLinks.Flink != le.Blink) { // Match module name if (Marshal.PtrToStringUni(dte.FullDllName.Buffer).EndsWith(DLLName, StringComparison.OrdinalIgnoreCase)) { hModule = dte.DllBase; } // Move Ptr flink = dte.InLoadOrderLinks.Flink; dte = (PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(PE.LDR_DATA_TABLE_ENTRY)); } return(hModule); }
public static IntPtr GetPebLdrModuleEntry(string DLLName) { SPEx.Native.PROCESS_BASIC_INFORMATION pbi = Native.NtQueryInformationProcessBasicInformation((IntPtr)(-1)); Boolean Is32Bit = false; UInt32 LdrDataOffset = 0; UInt32 InLoadOrderModuleListOffset = 0; if (IntPtr.Size == 4) { Is32Bit = true; LdrDataOffset = 0xc; InLoadOrderModuleListOffset = 0xC; } else { LdrDataOffset = 0x18; InLoadOrderModuleListOffset = 0x10; } IntPtr PEB_LDR_DATA = Marshal.ReadIntPtr((IntPtr)((UInt64)pbi.PebBaseAddress + LdrDataOffset)); IntPtr pInLoadOrderModuleList = (IntPtr)((UInt64)PEB_LDR_DATA + InLoadOrderModuleListOffset); SPEx.Native.LIST_ENTRY le = (SPEx.Native.LIST_ENTRY)Marshal.PtrToStructure(pInLoadOrderModuleList, typeof(SPEx.Native.LIST_ENTRY)); IntPtr flink = le.Flink; IntPtr hModule = IntPtr.Zero; while (true) { PE.LDR_DATA_TABLE_ENTRY dte = (PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(PE.LDR_DATA_TABLE_ENTRY)); if (dte.InLoadOrderLinks.Flink == le.Blink) { break; } if ((Marshal.PtrToStringUni(dte.FullDllName.Buffer)).ToLower().EndsWith(DLLName.ToLower())) { hModule = dte.DllBase; } flink = dte.InLoadOrderLinks.Flink; } return(hModule); }