internal unsafe Boolean LoadLibrary(Byte[] data) { //fnDllEntry dllEntry; IMAGE_DOS_HEADER dosHeader = PointerHelpers.ToStruct <IMAGE_DOS_HEADER>(data); IMAGE_NT_HEADERS oldHeader = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(data, (UInt32)dosHeader.e_lfanew); IntPtr code = (IntPtr)(Win32Imports.VirtualAlloc(oldHeader.OptionalHeader.ImageBase, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE)); if (code == IntPtr.Zero) { code = (IntPtr)(Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE)); } _module = new MEMORYMODULE { codeBase = code, numModules = 0, modules = new IntPtr(0), initialized = 0 }; Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE); IntPtr headers = (IntPtr)(Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfHeaders, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE)); Marshal.Copy(data, 0, headers, (Int32)(dosHeader.e_lfanew + oldHeader.OptionalHeader.SizeOfHeaders)); _module.headers = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(headers, (UInt32)dosHeader.e_lfanew); _module.headers.OptionalHeader.ImageBase = (UInt32)code; this.CopySections(data, oldHeader, headers, dosHeader); UInt32 locationDelta = (UInt32)(code.ToInt32() - oldHeader.OptionalHeader.ImageBase); if (locationDelta != 0) { this.PerformBaseRelocation(locationDelta); } this.BuildImportTable(); this.FinalizeSections(headers, dosHeader, oldHeader); Boolean success = false; try { fnDllEntry dllEntry = (fnDllEntry)Marshal.GetDelegateForFunctionPointer( new IntPtr(_module.codeBase.ToInt32() + (Int32)_module.headers.OptionalHeader.AddressOfEntryPoint), typeof(fnDllEntry)); success = dllEntry(code.ToInt32(), 1, (void *)0); } catch (Exception exc) { System.Diagnostics.Trace.WriteLine(exc.Message); return(false); } return(success); }
/// <summary> /// Loads a native assembly into memory from bytes. /// </summary> /// <param name="data">The assembly data to inject.</param> public unsafe bool LoadAssembly(byte[] data) { var dosHeader = PointerHelpers.ToStruct <IMAGE_DOS_HEADER>(data); var oldHeader = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(data, (uint)dosHeader.e_lfanew); var code = (IntPtr)(Win32Imports.VirtualAlloc(oldHeader.OptionalHeader.ImageBase, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE)); if (code.ToInt32() == 0) { code = (IntPtr)(Win32Imports.VirtualAlloc((uint)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE)); } module = new MEMORYMODULE { codeBase = code, numModules = 0, modules = new IntPtr(0), initialized = 0 }; Win32Imports.VirtualAlloc((uint)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE); var headers = (IntPtr)(Win32Imports.VirtualAlloc((uint)code, oldHeader.OptionalHeader.SizeOfHeaders, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE)); Marshal.Copy(data, 0, headers, (int)(dosHeader.e_lfanew + oldHeader.OptionalHeader.SizeOfHeaders)); module.headers = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(headers, (uint)dosHeader.e_lfanew); module.headers.OptionalHeader.ImageBase = (uint)code; CopySections(data, oldHeader, headers, dosHeader); var locationDelta = (uint)(code - (int)oldHeader.OptionalHeader.ImageBase); if (locationDelta != 0) { PerformBaseRelocation(locationDelta); } BuildImportTable(); FinalizeSections(headers, dosHeader, oldHeader); bool success = false; try { fnDllEntry dllEntry = (fnDllEntry) Marshal.GetDelegateForFunctionPointer( new IntPtr(module.codeBase.ToInt32() + (int)module.headers.OptionalHeader.AddressOfEntryPoint), typeof(fnDllEntry)); success = dllEntry(code.ToInt32(), 1, (void *)0); } catch (Exception ex) { throw ex; } return(success); }