private void BuildImportTable32(MEMORYMODULE32 module32) { int moduleCount = 0; IntPtr codeBase = module32.codeBase; IMAGE_DATA_DIRECTORY directory = module32.headers.OptionalHeader.ImportTable; if (directory.Size > 0) { //Log.Console("ImportTable.Size: "+ directory.Size); uint* nameRef, funcRef; IMAGE_IMPORT_DESCRIPTOR importDesc = codeBase.ToStruct<IMAGE_IMPORT_DESCRIPTOR>(directory.VirtualAddress); while (importDesc.Name > 0) { string moduleName = Marshal.PtrToStringAnsi(codeBase.Add(importDesc.Name)); //Log.Console("Import Module: " + moduleName); IntPtr handle = Native.LoadLibrary(moduleName); if (handle == IntPtr.Zero) break; if (importDesc.CharacteristicsOrOriginalFirstThunk > 0) { nameRef = (uint*)codeBase.Add(importDesc.CharacteristicsOrOriginalFirstThunk); funcRef = (uint*)codeBase.Add(importDesc.FirstThunk); } else { nameRef = (uint*)codeBase.Add(importDesc.FirstThunk); funcRef = (uint*)codeBase.Add(importDesc.FirstThunk); } for (; *nameRef > 0; nameRef++, funcRef++) { //Log.Console("Import: " + nameRef->ToString("X16") + ", 0x" + funcRef->ToString("x16")); if ((*nameRef & 0x8000000000000000) != 0) { *funcRef = (uint)Native.GetProcAddress(handle, new IntPtr(*nameRef & 0xffff)); } else { string functionName = Marshal.PtrToStringAnsi(codeBase.Add((*nameRef) + 2)); *funcRef = (uint)Native.GetProcAddress(handle, functionName); //Log.Console("Import Function: " + functionName + " -> 0x" + funcRef->ToString("x16")); } //Log.Console("Import nameRef: 0x" + nameRef->ToString("X16")); //Log.Console("Import funcRef: 0x" + funcRef->ToString("X16")); if (*funcRef == 0) { break; } } moduleCount++; importDesc = codeBase.ToStruct<IMAGE_IMPORT_DESCRIPTOR>(directory.VirtualAddress + (uint)(Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR)) * moduleCount)); } } }
public MemoryModule(byte[] bytes) { IntPtr address = IntPtr.Zero; IntPtr dllEntryPoint = IntPtr.Zero; ProtectionFlags[0] = new int[2][]; ProtectionFlags[1] = new int[2][]; ProtectionFlags[0][0] = new int[2]; ProtectionFlags[0][1] = new int[2]; ProtectionFlags[1][0] = new int[2]; ProtectionFlags[1][1] = new int[2]; ProtectionFlags[0][0][0] = 0x01; ProtectionFlags[0][0][1] = 0x08; ProtectionFlags[0][1][0] = 0x02; ProtectionFlags[0][1][1] = 0x04; ProtectionFlags[1][0][0] = 0x10; ProtectionFlags[1][0][1] = 0x80; ProtectionFlags[1][1][0] = 0x20; ProtectionFlags[1][1][1] = 0x40; IMAGE_DOS_HEADER dosHeader = bytes.ToStruct<IMAGE_DOS_HEADER>(); IMAGE_NT_HEADERS32 ntHeader = bytes.ToStruct<IMAGE_NT_HEADERS32>((uint)dosHeader.e_lfanew); Is64Bit = (ntHeader.OptionalHeader.Magic == 0x020B || ntHeader.FileHeader.Machine == 0x8664); #region [ Load x64 Machine Dynamic Link Library ] if (Is64Bit) { IMAGE_NT_HEADERS64 header64 = bytes.ToStruct<IMAGE_NT_HEADERS64>((uint)dosHeader.e_lfanew); address = Native.VirtualAlloc((IntPtr)header64.OptionalHeader.ImageBase, header64.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (address == IntPtr.Zero) address = Native.VirtualAlloc(address, header64.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (address != IntPtr.Zero) { //Log.Console("Memory Address: 0x" + address.ToString("X16")); IntPtr headers = Native.VirtualAlloc(address, header64.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE); Marshal.Copy(bytes, 0, headers, (int)(dosHeader.e_lfanew + header64.OptionalHeader.SizeOfHeaders)); CopySections64(bytes, address, header64, headers, dosHeader); int moduleCount = GetModuleCount(address, header64.OptionalHeader.ImportTable); module64 = new MEMORYMODULE64 { codeBase = address, numModules = moduleCount, modules = Marshal.AllocHGlobal(moduleCount * sizeof(int)), initialized = 0 }; module64.headers = headers.ToStruct<IMAGE_NT_HEADERS64>((uint)dosHeader.e_lfanew); module64.headers.OptionalHeader.ImageBase = (ulong)address; ulong locationDelta = (ulong)address - header64.OptionalHeader.ImageBase; if (locationDelta != 0) PerformBaseRelocation64(locationDelta); BuildImportTable64(module64); FinalizeSections64(address, headers, dosHeader, header64); dllEntryPoint = address.Add(header64.OptionalHeader.AddressOfEntryPoint); } } #endregion #region [ Load x86 Machine Dynamic Link Library ] else { IMAGE_NT_HEADERS32 header32 = bytes.ToStruct<IMAGE_NT_HEADERS32>((uint)dosHeader.e_lfanew); address = Native.VirtualAlloc((IntPtr)header32.OptionalHeader.ImageBase, header32.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (address == IntPtr.Zero) address = Native.VirtualAlloc(address, header32.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (address != IntPtr.Zero) { //Log.Console("Memory Address: 0x" + address.ToString("X16")); IntPtr headers = Native.VirtualAlloc(address, header32.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE); Marshal.Copy(bytes, 0, headers, (int)(dosHeader.e_lfanew + header32.OptionalHeader.SizeOfHeaders)); CopySections32(bytes, address, header32, headers, dosHeader); int moduleCount = GetModuleCount(address, header32.OptionalHeader.ImportTable); module32 = new MEMORYMODULE32 { codeBase = address, numModules = 0, modules = new IntPtr(0), initialized = 0 }; module32.headers = headers.ToStruct<IMAGE_NT_HEADERS32>((uint)dosHeader.e_lfanew); module32.headers.OptionalHeader.ImageBase = (uint)address; ulong locationDelta = (ulong)address - header32.OptionalHeader.ImageBase; if (locationDelta != 0) PerformBaseRelocation32(locationDelta); BuildImportTable32(module32); FinalizeSections32(address, headers, dosHeader, header32); dllEntryPoint = address.Add(header32.OptionalHeader.AddressOfEntryPoint); } } #endregion //Log.Console("DllEntryPoint: 0x" + dllEntryPoint.ToString("X16")); DllEntry dllEntry = (DllEntry)Marshal.GetDelegateForFunctionPointer(dllEntryPoint, typeof(DllEntry)); dllEntry(address, 1, IntPtr.Zero); }