/// <summary> /// Parses the given buffer for the header of a PEFile. If it can be parsed correctly, /// a new PEHeader object is constructed from the buffer and returned. Otherwise, null /// is returned. /// </summary> internal static PEHeader FromBuffer(PEBuffer buffer, bool virt) { byte * ptr = buffer.Fetch(0, 0x300); IMAGE_DOS_HEADER *tmpDos = (IMAGE_DOS_HEADER *)ptr; int needed = tmpDos->e_lfanew + sizeof(IMAGE_NT_HEADERS); if (buffer.Length < needed) { ptr = buffer.Fetch(0, needed); if (buffer.Length < needed) { return(null); } tmpDos = (IMAGE_DOS_HEADER *)ptr; } IMAGE_NT_HEADERS *tmpNt = (IMAGE_NT_HEADERS *)((byte *)tmpDos + tmpDos->e_lfanew); needed += tmpNt->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_SECTION_HEADER) * tmpNt->FileHeader.NumberOfSections; if (buffer.Length < needed) { ptr = buffer.Fetch(0, needed); if (buffer.Length < needed) { return(null); } } return(new PEHeader(buffer, virt)); }
public static void Main() { if (!Native.GetModuleHandleEx(ModuleHandleFlags.UnchangedRefCount, "Inkjet.dll", out ThisModule)) { ThisModule = IntPtr.Zero; } IntPtr ExeHandle; List <string> ExportNames = new List <string>(); if (Native.GetModuleHandleEx(ModuleHandleFlags.UnchangedRefCount, null, out ExeHandle)) { IMAGE_DOS_HEADER * DosHeader = (IMAGE_DOS_HEADER *)ExeHandle; IMAGE_NT_HEADERS * Header = (IMAGE_NT_HEADERS *)(ExeHandle + (int)DosHeader->LFaNew); IMAGE_EXPORT_DIRECTORY *Exports = (IMAGE_EXPORT_DIRECTORY *)(ExeHandle + Header->OptionalHeader.ExportTable.VirtualAddress); IntPtr Names = ExeHandle + Exports->AddressOfNames; for (int i = 0; i < Exports->NumberOfNames; i++) { string Name = Marshal.PtrToStringAnsi(ExeHandle + ((int *)Names)[i]); if (Name.Trim().Length == 0) { continue; } ExportNames.Add(Name); } } File.WriteAllText("E:\\Projects\\Hackery\\bin\\HAAX.txt", string.Join("\n", ExportNames)); Process Cur = Process.GetCurrentProcess(); MessageBox.Show("Magic!", string.Format("{0} ({1})", Cur.ProcessName, Cur.Id)); }
private static unsafe void WriteNTHeader(byte[] buffer, uint pos, IMAGE_NT_HEADERS header) { fixed(byte *p = buffer) { IMAGE_NT_HEADERS *ptr = (IMAGE_NT_HEADERS *)(p + pos); *ptr = header; } }
/// <summary> /// 重定位表的处理 /// </summary> /// <param name="pPEHeader"></param> private unsafe void ReLocation(IMAGE_NT_HEADERS *pPEHeader) { #if _WIN64 Int64 iDelta = (Int64)((Int64)this.mModuleHandle - (Int64)pPEHeader->OptionalHeader.ImageBase); #else Int32 iDelta = (Int32)this.mModuleHandle - (Int32)pPEHeader->OptionalHeader.ImageBase; #endif if (iDelta == 0) { return; } #if _WIN64 IMAGE_BASE_RELOCATION *pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_BASERELOC).VirtualAddress)); while (pRelocation->VirtualAddress > 0 && pRelocation->SizeOfBlock > 0) { UInt16 *pLocData = (UInt16 *)((IntPtr)pRelocation + sizeof(IMAGE_BASE_RELOCATION)); var iNumberOfReloc = (pRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2; for (Int32 i = 0; i < iNumberOfReloc; i++) { if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_HIGHLOW) { UInt32 *lpPoint = (UInt32 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF))); * lpPoint += (UInt32)iDelta; } else if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_DIR64) { UInt64 *lpPoint = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF))); * lpPoint += (UInt64)iDelta; } } pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)((Int64)((IntPtr)pRelocation) + (Int64)pRelocation->SizeOfBlock)); } #else IMAGE_BASE_RELOCATION *pRelocation = (IMAGE_BASE_RELOCATION *)(this.mModuleHandle + (Int32)pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_BASERELOC).VirtualAddress); while (pRelocation->VirtualAddress > 0 && pRelocation->SizeOfBlock > 0) { UInt16 *pLocData = (UInt16 *)((IntPtr)pRelocation + sizeof(IMAGE_BASE_RELOCATION)); var iNumberOfReloc = (pRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2; for (Int32 i = 0; i < iNumberOfReloc; i++) { if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_HIGHLOW) { UInt32 *lpPoint = (UInt32 *)(this.mModuleHandle + (Int32)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF)); * lpPoint += (UInt32)iDelta; } } pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)pRelocation + (Int32)pRelocation->SizeOfBlock); } #endif }
private static bool GetLibraryInfo(IntPtr handle, out DynLibInfo lib) { lib = new DynLibInfo(); if (handle == IntPtr.Zero) { return(false); } MEMORY_BASIC_INFORMATION info; if (VirtualQuery(handle, out info, Marshal.SizeOf <MEMORY_BASIC_INFORMATION>()) == 0) { return(false); } //uintptr_t baseAddr = reinterpret_cast<uintptr_t>(info.AllocationBase); IMAGE_DOS_HEADER * dos = (IMAGE_DOS_HEADER *)info.AllocationBase; IMAGE_NT_HEADERS * pe = (IMAGE_NT_HEADERS *)(info.AllocationBase + dos->e_lfanew); IMAGE_FILE_HEADER * file = &pe->FileHeader; IMAGE_OPTIONAL_HEADER *opt = &pe->OptionalHeader; if (dos->e_magic != IMAGE_DOS_SIGNATURE) { return(false); } if (pe->Signature != IMAGE_NT_SIGNATURE) { return(false); } if (opt->Magic != MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC) { return(false); } if (file->Machine != 0x014c)// Intel 386. { return(false); } if ((file->Characteristics & 0x2000) == 0)// File is a DLL. { return(false); } lib.memorySize = opt->SizeOfImage; lib.baseAddress = info.AllocationBase; return(true); }
private static unsafe IMAGE_NT_HEADERS ReadNTHeader(byte[] buffer, uint pos) { IMAGE_NT_HEADERS dosHeader = new IMAGE_NT_HEADERS(); fixed(byte *p = buffer) { IMAGE_NT_HEADERS *ptr = (IMAGE_NT_HEADERS *)(p + pos); dosHeader = *ptr; } return(dosHeader); }
/// <summary> /// 拷贝区段数据到内存 /// </summary> /// <param name="pUnmanagedBuffer"></param> /// <param name="pPEHeader"></param> /// <param name="pSectionHeader"></param> private unsafe void CopyDllDatas(IntPtr pUnmanagedBuffer, IMAGE_NT_HEADERS *pPEHeader, IMAGE_SECTION_HEADER *pSectionHeader) { Win32API.CopyMemory(this.mModuleHandle, pUnmanagedBuffer, pPEHeader->OptionalHeader.SizeOfHeaders); // 复制(DOS头+DOS STUB) + PE头 + SECTION TABLE // 复制每一个SECTION for (Int32 i = 0; i < pPEHeader->FileHeader.NumberOfSections; i++) { if (pSectionHeader[i].VirtualAddress > 0 && pSectionHeader[i].SizeOfRawData > 0) { var lpSection = this.mModuleHandle + (Int32)pSectionHeader[i].VirtualAddress; Win32API.CopyMemory(lpSection, pUnmanagedBuffer + (Int32)pSectionHeader[i].PointerToRawData, pSectionHeader[i].SizeOfRawData); } } }
/// <summary> /// 计算要申请的内存空间大小 /// </summary> /// <param name="pPEHeader"></param> /// <param name="pSectionHeader"></param> /// <returns></returns> private unsafe UInt32 CalcTotalImageSize(IMAGE_NT_HEADERS *pPEHeader, IMAGE_SECTION_HEADER *pSectionHeader) { var iAlign = pPEHeader->OptionalHeader.SectionAlignment; var iSize = this.GetAlignedSize(pPEHeader->OptionalHeader.SizeOfHeaders, iAlign); for (Int32 i = 0; i < pPEHeader->FileHeader.NumberOfSections; i++) { var iCodeSize = pSectionHeader[i].VirtualSize; // 该区块表对应的区块加载到内存后的大小,这是区块的数据在没有进行SectionAlignment对齐处理前的实际大小 var iLoadSize = pSectionHeader[i].SizeOfRawData; // 该区块在文件中所占的大小,该字段是已经被FileAlignment对齐处理过的长度。 var iMaxSize = iLoadSize > iCodeSize ? iLoadSize : iCodeSize; var iSectionSize = this.GetAlignedSize((pSectionHeader[i].VirtualAddress + iMaxSize), iAlign); if (iSize < iSectionSize) { iSize = iSectionSize; } } return(iSize); }
public ExportResolver(ProcessModule module) { lib = (IMAGE_DOS_HEADER *)module.BaseAddress; if (lib->e_magic != IMAGE_DOS_SIGNATURE) { throw new Exception("Invalid IMAGE_DOS_HEADER signature"); } header = (IMAGE_NT_HEADERS *)((byte *)lib + lib->e_lfanew); if (header->Signature != IMAGE_NT_SIGNATURE) { throw new Exception("Invalid IMAGE_NT_HEADERS signature"); } if (header->OptionalHeader.NumberOfRvaAndSizes == 0) { throw new Exception("Invalid NumberOfRvaAndSizes"); } exports = (IMAGE_EXPORT_DIRECTORY *)((byte *)lib + header->OptionalHeader.ExportTable.VirtualAddress); }
static void CopySections(byte *data, IMAGE_NT_HEADERS *old_headers, MEMORYMODULE *module) { uint i, size; IntPtr codeBase1 = module->codeBase; #if AMD64 long codeBaseAddr = (long)codeBase1.ToInt64(); #else uint codeBaseAddr = (uint)codeBase1.ToInt64(); #endif IntPtr dest; IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(module->headers); for (i = 0; i < module->headers->FileHeader.NumberOfSections; i++, section++) { if (section->SizeOfRawData == 0) { // section doesn't contain data in the dll itself, but may define // uninitialized data size = old_headers->OptionalHeader.SectionAlignment; if (size > 0) { dest = VirtualAlloc(new IntPtr(codeBaseAddr + section->VirtualAddress), size, AllocationType.COMMIT, MemoryProtection.READWRITE);// MEM_COMMIT, PAGE_READWRITE); //section->PhysicalAddress = dest; memset(dest, 0, new UIntPtr(size)); section->VirtualSize = (uint)(dest.ToInt64() - codeBase1.ToInt64()); } // section is empty continue; } // commit memory block and copy data from dll dest = VirtualAlloc(new IntPtr(codeBaseAddr + section->VirtualAddress), section->SizeOfRawData, AllocationType.COMMIT, MemoryProtection.READWRITE); memcpy((byte *)dest.ToPointer(), (byte *)(data + section->PointerToRawData), new UIntPtr(section->SizeOfRawData)); section->VirtualSize = (uint)(dest.ToInt64() - codeBase1.ToInt64()); } }
/// <summary> /// Loads a unmanged (native) DLL in the memory. /// </summary> /// <param name="data">Dll as a byte array</param> public MemoryModule(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } _headers = null; _codeBase = null; _pageSize = 0; _modules = new List <HCoustomMudule>(); _initialized = false; _exeEntry = null; _dllEntry = null; Disposed = false; _isRelocated = false; MemoryLoadLibrary(data); }
public static Symbol[] GetExports(IntPtr Handle) { List <Symbol> Exports = new List <Symbol>(); IMAGE_DOS_HEADER * DOS = (IMAGE_DOS_HEADER *)Handle; IMAGE_NT_HEADERS * NT = (IMAGE_NT_HEADERS *)((byte *)DOS + DOS->LFaNew); IMAGE_OPTIONAL_HEADER * Optional = &NT->OptionalHeader; IMAGE_EXPORT_DIRECTORY *ExportsDir = (IMAGE_EXPORT_DIRECTORY *)((byte *)Handle + Optional->ExportTable.VirtualAddress); uint *AddrOfNames = (uint *)((byte *)Handle + ExportsDir->AddressOfNames); uint *AddrOfFuncs = (uint *)((byte *)Handle + ExportsDir->AddressOfNames); for (int j = 0; j < ExportsDir->NumberOfNames; j++) { string Name = Marshal.PtrToStringAnsi((IntPtr)((uint)Handle + AddrOfNames[j])); long Func = AddrOfFuncs[j]; Exports.Add(new Symbol(Name, (ulong)Func, 0)); } return(Exports.ToArray()); }
/// <summary> /// 加载dLL /// </summary> /// <param name="pUnmanagedBuffer"></param> /// <param name="iBufferLength"></param> /// <returns></returns> private unsafe Boolean LoadDLLFromMemory(IntPtr pUnmanagedBuffer, Int32 iBufferLength) { try { if (iBufferLength < sizeof(IMAGE_DOS_HEADER)) { throw new Exception("Data is too short"); } IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)pUnmanagedBuffer; if (pDosHeader->e_magic != 0x5A4D) { throw new Exception("DOS file format error"); } if (iBufferLength < pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)) { throw new Exception("Data is short"); } IMAGE_NT_HEADERS *pPEHeader = (IMAGE_NT_HEADERS *)(pUnmanagedBuffer + pDosHeader->e_lfanew); if (pPEHeader->Signature != Win32API.IMAGE_NT_SIGNATURE) { throw new Exception("windows file Signature error"); } if ((pPEHeader->FileHeader.Characteristics & Win32API.IMAGE_FILE_DLL) != Win32API.IMAGE_FILE_DLL) { throw new Exception("Dll Not dynamic library"); } IMAGE_SECTION_HEADER *pSectionHeader = (IMAGE_SECTION_HEADER *)(pUnmanagedBuffer + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)); for (Int32 i = 0; i < pPEHeader->FileHeader.NumberOfSections; i++) { if (pSectionHeader[i].PointerToRawData + pSectionHeader[i].SizeOfRawData > iBufferLength) { throw new Exception("Section data error"); } } //计算空间 this.mModuleSize = this.CalcTotalImageSize(pPEHeader, pSectionHeader); if (this.mModuleSize == 0 || this.mModuleSize > iBufferLength * 10) { throw new Exception("unknown error"); } #if _WIN64 this.mModuleHandle = Win32API.VirtualAlloc((IntPtr)((Int64)pPEHeader->OptionalHeader.ImageBase), this.mModuleSize, Win32API.MEM_COMMIT | Win32API.MEM_RESERVE, Win32API.PAGE_EXECUTE_READWRITE); #else this.mModuleHandle = Win32API.VirtualAlloc((IntPtr)((Int32)pPEHeader->OptionalHeader.ImageBase), this.mModuleSize, Win32API.MEM_COMMIT | Win32API.MEM_RESERVE, Win32API.PAGE_EXECUTE_READWRITE); #endif if (this.mModuleHandle == IntPtr.Zero) { Int32 iLastError = Marshal.GetLastWin32Error(); this.mModuleHandle = Win32API.VirtualAlloc(IntPtr.Zero, this.mModuleSize, Win32API.MEM_COMMIT | Win32API.MEM_RESERVE, Win32API.PAGE_EXECUTE_READWRITE); } if (this.mModuleHandle == IntPtr.Zero) { throw new Exception("run out of memory?"); } this.CopyDllDatas(pUnmanagedBuffer, pPEHeader, pSectionHeader); pDosHeader = (IMAGE_DOS_HEADER *)this.mModuleHandle; pPEHeader = (IMAGE_NT_HEADERS *)(this.mModuleHandle + pDosHeader->e_lfanew); pSectionHeader = (IMAGE_SECTION_HEADER *)(this.mModuleHandle + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)); if (pDosHeader->e_magic != 0x5A4D) { throw new Exception("DOS file format error"); } if (iBufferLength < pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)) { throw new Exception("DOS file header data error"); } if (pPEHeader->Signature != Win32API.IMAGE_NT_SIGNATURE) { throw new Exception("windows file Signature error"); } if ((pPEHeader->FileHeader.Characteristics & Win32API.IMAGE_FILE_DLL) != Win32API.IMAGE_FILE_DLL) { throw new Exception("Dll Not dynamic library"); } for (Int32 i = 0; i < pPEHeader->FileHeader.NumberOfSections; i++) { if (pSectionHeader[i].PointerToRawData + pSectionHeader[i].SizeOfRawData > iBufferLength) { throw new Exception("Section data error"); } } //重定位 var baseRelocDirEntry = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_BASERELOC); if (baseRelocDirEntry.VirtualAddress > 0 && baseRelocDirEntry.Size > 0) { this.ReLocation(pPEHeader); } this.FillImportTable(pPEHeader); #if _WIN64 this.mDllMain = (DllMainHandle)Marshal.GetDelegateForFunctionPointer((IntPtr)((Int64)this.mModuleHandle + (Int64)pPEHeader->OptionalHeader.AddressOfEntryPoint), typeof(DllMainHandle)); #else this.mDllMain = (DllMainHandle)Marshal.GetDelegateForFunctionPointer(this.mModuleHandle + (Int32)pPEHeader->OptionalHeader.AddressOfEntryPoint, typeof(DllMainHandle)); #endif return(this.mDllMain.Invoke(this.mModuleHandle, Win32API.DLL_PROCESS_ATTACH, IntPtr.Zero)); } catch (Exception ex) { throw (ex); } }
private void MemoryLoadLibrary(byte[] data) { IMAGE_DOS_HEADER * dosHeader; IMAGE_NT_HEADERS * oldHeader; IMAGE_SECTION_HEADER *section; SYSTEM_INFO systemInfo; void * dllEntryPtr; void * exeEntryPtr; byte * headers, dataPtr, code; SizeT optionalSectionSize; SizeT lastSectionEnd = 0; SizeT alignedImageSize; PtrDiffT locationDelta; _dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); if (!_dataHandle.IsAllocated) { throw new NativeDllLoadException("Can't allocate memory."); } dataPtr = (byte *)_dataHandle.AddrOfPinnedObject(); dosHeader = (IMAGE_DOS_HEADER *)dataPtr; if (dosHeader->e_magic != Win.IMAGE_DOS_SIGNATURE) { throw new BadImageFormatException("Not a valid executable file."); } oldHeader = (IMAGE_NT_HEADERS *)(dataPtr + dosHeader->e_lfanew); if (oldHeader->Signature != Win.IMAGE_NT_SIGNATURE) { throw new BadImageFormatException("Not a valid PE file."); } if (oldHeader->FileHeader.Machine != GetMachineType()) { throw new BadImageFormatException("Machine type doesn't fit. (i386 vs. AMD64)"); } if ((oldHeader->OptionalHeader.SectionAlignment & 1) > 0) { throw new BadImageFormatException("Wrong section alignment"); } section = Win.IMAGE_FIRST_SECTION(oldHeader); optionalSectionSize = oldHeader->OptionalHeader.SectionAlignment; for (int i = 0; i < oldHeader->FileHeader.NumberOfSections; i++, section++) { SizeT endOfSection; if (section->SizeOfRawData == 0) // Section without data in the DLL { endOfSection = section->VirtualAddress + optionalSectionSize; } else { endOfSection = section->VirtualAddress + section->SizeOfRawData; } if (endOfSection > lastSectionEnd) { lastSectionEnd = endOfSection; } } Win.GetNativeSystemInfo(&systemInfo); alignedImageSize = AlignValueUp(oldHeader->OptionalHeader.SizeOfImage, systemInfo.dwPageSize); if (alignedImageSize != AlignValueUp(lastSectionEnd, systemInfo.dwPageSize)) { throw new BadImageFormatException("Wrong section alignment."); } code = (byte *)Win.VirtualAlloc( (void *)(oldHeader->OptionalHeader.ImageBase), oldHeader->OptionalHeader.SizeOfImage, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE); if (code == null) { code = (byte *)Win.VirtualAlloc( null, oldHeader->OptionalHeader.SizeOfImage, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE); } if (code == null) { throw new NativeDllLoadException("Out of Memory"); } #if WIN64 while ((((ulong)code) >> 32) < (((ulong)(code + alignedImageSize)) >> 32)) { _blockedMemory.Add((IntPtr)code); code = (byte *)Win.VirtualAlloc( null, alignedImageSize, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE); if (code == null) { throw new NativeDllLoadException("Out of Memory"); } } #endif _pageSize = systemInfo.dwPageSize; _codeBase = code; IsDll = (oldHeader->FileHeader.Characteristics & Win.IMAGE_FILE_DLL) != 0; headers = (byte *)Win.VirtualAlloc( code, oldHeader->OptionalHeader.SizeOfHeaders, AllocationType.COMMIT, MemoryProtection.READWRITE); if (headers == null) { throw new NativeDllLoadException("Out of Memory"); } Marshal.Copy(data, 0, (IntPtr)headers, (int)(dosHeader->e_lfanew + oldHeader->OptionalHeader.SizeOfHeaders)); _headers = (IMAGE_NT_HEADERS *)&(headers)[dosHeader->e_lfanew]; _headers->OptionalHeader.ImageBase = (UIntPtrT)code; CopySections(data, oldHeader); locationDelta = (PtrDiffT)(_headers->OptionalHeader.ImageBase - oldHeader->OptionalHeader.ImageBase); if (locationDelta != 0) { _isRelocated = PerformBaseRelocation(locationDelta); } else { _isRelocated = true; } BuildImportTable(); FinalizeSections(); ExecuteTLS(); if (_headers->OptionalHeader.AddressOfEntryPoint == 0) { throw new NativeDllLoadException("DLL has no entry point"); } if (IsDll) { dllEntryPtr = code + _headers->OptionalHeader.AddressOfEntryPoint; _dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)dllEntryPtr, typeof(DllEntryDelegate)); if (_dllEntry != null && _dllEntry(code, DllReason.DLL_PROCESS_ATTACH, null)) { _initialized = true; } else { _initialized = false; throw new NativeDllLoadException("Can't attach DLL to process."); } } else { exeEntryPtr = code + _headers->OptionalHeader.AddressOfEntryPoint; _exeEntry = Marshal.GetDelegateForFunctionPointer <ExeEntryDelegate>((IntPtr)exeEntryPtr); } }
/// <summary> /// Equivalent to the IMAGE_FIRST_SECTION macro /// </summary> /// <param name="ntheader">Pointer to to ntheader</param> /// <returns>Pointer to the first section</returns> public static IMAGE_SECTION_HEADER *IMAGE_FIRST_SECTION(IMAGE_NT_HEADERS *ntheader) { return((IMAGE_SECTION_HEADER *)((UIntPtrT)ntheader + (UIntPtrT)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS), "OptionalHeader") + ntheader->FileHeader.SizeOfOptionalHeader)); }
void CopySections(byte[] data, IMAGE_NT_HEADERS *oldHeader) { if (data == null) { throw new ArgumentNullException("data"); } if (oldHeader->Signature != Win.IMAGE_NT_SIGNATURE) { throw new BadImageFormatException("Invalid PE-Header"); } uint size; byte *dest; IMAGE_SECTION_HEADER *section = Win.IMAGE_FIRST_SECTION(_headers); for (int i = 0; i < _headers->FileHeader.NumberOfSections; i++, section++) { if (section->SizeOfRawData == 0) { // section doesn't contain data in the dll itself, but may define // uninitialized data size = oldHeader->OptionalHeader.SectionAlignment; if (size > 0) { dest = (byte *)Win.VirtualAlloc( _codeBase + section->VirtualAddress, size, AllocationType.COMMIT, MemoryProtection.READWRITE); if (dest == null) { throw new NativeDllLoadException("Unable to allocate memory."); } dest = _codeBase + section->VirtualAddress; section->PhysicalAddress = (uint)dest & 0xffffffff; Win.MemSet(dest, 0, (void *)size); } continue; } dest = (byte *)Win.VirtualAlloc( _codeBase + section->VirtualAddress, section->SizeOfRawData, AllocationType.COMMIT, MemoryProtection.READWRITE); if (dest == null) { throw new NativeDllLoadException("Out of memory."); } dest = _codeBase + section->VirtualAddress; Marshal.Copy(data, (int)section->PointerToRawData, (IntPtr)dest, (int)section->SizeOfRawData); section->PhysicalAddress = (uint)dest & 0xffffffff; } }
static IMAGE_SECTION_HEADER *IMAGE_FIRST_SECTION(IMAGE_NT_HEADERS *img) { return((IMAGE_SECTION_HEADER *)((ulong)img + 0x18 + img->FileHeader.SizeOfOptionalHeader)); }
/// <summary> /// 获取API函数地址 /// </summary> /// <param name="sProcName"></param> /// <returns></returns> private unsafe IntPtr GetProcAddress(String sProcName) { if (this.mModuleHandle == IntPtr.Zero) { return(IntPtr.Zero); } if (String.IsNullOrEmpty(sProcName)) { return(IntPtr.Zero); } IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)this.mModuleHandle; IMAGE_NT_HEADERS *pPEHeader = (IMAGE_NT_HEADERS *)(this.mModuleHandle + pDosHeader->e_lfanew); var exportDirectoryEntry = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_EXPORT); var iOffsetStart = exportDirectoryEntry.VirtualAddress; var iSize = exportDirectoryEntry.Size; if (iOffsetStart == 0 || iSize == 0) { return(IntPtr.Zero); } #if _WIN64 IMAGE_EXPORT_DIRECTORY *pExportDirectory = (IMAGE_EXPORT_DIRECTORY *)((IntPtr)((Int64)this.mModuleHandle + (Int64)iOffsetStart)); UInt32 *pAddressOfFunctions = (UInt32 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pExportDirectory->AddressOfFunctions)); UInt16 *pAddressOfNameOrdinals = (UInt16 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pExportDirectory->AddressOfNameOrdinals)); UInt32 *pAddressOfNames = (UInt32 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pExportDirectory->AddressOfNames)); #else IMAGE_EXPORT_DIRECTORY *pExportDirectory = (IMAGE_EXPORT_DIRECTORY *)(this.mModuleHandle + (Int32)iOffsetStart); UInt32 *pAddressOfFunctions = (UInt32 *)(this.mModuleHandle + (Int32)pExportDirectory->AddressOfFunctions); UInt16 *pAddressOfNameOrdinals = (UInt16 *)(this.mModuleHandle + (Int32)pExportDirectory->AddressOfNameOrdinals); UInt32 *pAddressOfNames = (UInt32 *)(this.mModuleHandle + (Int32)pExportDirectory->AddressOfNames); #endif UInt16 iOrdinal = 0; if (UInt16.TryParse(sProcName, out iOrdinal)) { if (iOrdinal >= pExportDirectory->Base) { iOrdinal = (UInt16)(iOrdinal - pExportDirectory->Base); if (iOrdinal >= 0 && iOrdinal < pExportDirectory->NumberOfFunctions) { var iFunctionOffset = pAddressOfFunctions[iOrdinal]; if (iFunctionOffset > iOffsetStart && iFunctionOffset < (iOffsetStart + iSize)) // maybe Export Forwarding { return(IntPtr.Zero); } else { #if _WIN64 return((IntPtr)((Int64)this.mModuleHandle + iFunctionOffset)); #else return((IntPtr)((Int32)this.mModuleHandle + iFunctionOffset)); #endif } } } } else { for (Int32 i = 0; i < pExportDirectory->NumberOfNames; i++) { #if _WIN64 var sFuncName = Marshal.PtrToStringAnsi((IntPtr)((Int64)this.mModuleHandle + (Int64)pAddressOfNames[i])); #else var sFuncName = Marshal.PtrToStringAnsi(this.mModuleHandle + (Int32)pAddressOfNames[i]); #endif if (sProcName.Equals(sFuncName)) { iOrdinal = pAddressOfNameOrdinals[i]; if (iOrdinal >= 0 && iOrdinal < pExportDirectory->NumberOfFunctions) { var iFunctionOffset = pAddressOfFunctions[iOrdinal]; if (iFunctionOffset > iOffsetStart && iFunctionOffset < (iOffsetStart + iSize)) // maybe Export Forwarding { return(IntPtr.Zero); } else { #if _WIN64 return((IntPtr)((Int64)this.mModuleHandle + iFunctionOffset)); #else return((IntPtr)((Int32)this.mModuleHandle + iFunctionOffset)); #endif } } } } } return(IntPtr.Zero); }
/// <summary> /// 填充导入表 /// </summary> /// <param name="pPEHeader"></param> private unsafe void FillImportTable(IMAGE_NT_HEADERS *pPEHeader) { #if _WIN64 var iOffset = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).VirtualAddress; if (iOffset == 0) { return; } if (pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).Size == 0) { return; } IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)((IntPtr)((Int64)this.mModuleHandle + (Int64)iOffset)); while (pImportDescriptor->Name != 0) { UInt64 *pRealIAT = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pImportDescriptor->FirstThunk)); UInt64 *pOriginalIAT = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (pImportDescriptor->OriginalFirstThunk == 0 ? (Int64)pImportDescriptor->FirstThunk : (Int64)pImportDescriptor->OriginalFirstThunk))); var sDllName = Marshal.PtrToStringAnsi((IntPtr)((Int64)this.mModuleHandle + (Int64)pImportDescriptor->Name)); var hDll = Win32API.GetModuleHandle(sDllName); if (hDll == IntPtr.Zero) { hDll = Win32API.LoadLibrary(sDllName); } if (hDll == IntPtr.Zero) { throw new Exception(String.Format("load library({0}) fail", sDllName)); } while (*pOriginalIAT != 0) { IntPtr lpFunction = IntPtr.Zero; if ((*pOriginalIAT & Win32API.IMAGE_ORDINAL_FLAG) == Win32API.IMAGE_ORDINAL_FLAG) // 最高位是1 { var iFuncID = *pOriginalIAT & 0x0000FFFF; lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int32)iFuncID)); } else { //var sFuncName = Marshal.PtrToStringAnsi((IntPtr)((Int64)this.mModuleHandle + (Int64)(*pOriginalIAT) + 2)); lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int64)this.mModuleHandle + (Int64)(*pOriginalIAT) + 2)); } if (lpFunction != IntPtr.Zero) { *pRealIAT = (UInt64)lpFunction; } pRealIAT++; pOriginalIAT++; } pImportDescriptor++; } #else var iOffset = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).VirtualAddress; if (iOffset == 0) { return; } if (pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).Size == 0) { return; } IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)(this.mModuleHandle + (Int32)iOffset); while (pImportDescriptor->Name != 0) { UInt32 *pRealIAT = (UInt32 *)(this.mModuleHandle + (Int32)pImportDescriptor->FirstThunk); UInt32 *pOriginalIAT = (UInt32 *)(this.mModuleHandle + (pImportDescriptor->OriginalFirstThunk == 0 ? (Int32)pImportDescriptor->FirstThunk : (Int32)pImportDescriptor->OriginalFirstThunk)); var sDllName = Marshal.PtrToStringAnsi(this.mModuleHandle + (Int32)pImportDescriptor->Name); var hDll = Win32API.GetModuleHandle(sDllName); if (hDll == IntPtr.Zero) { hDll = Win32API.LoadLibrary(sDllName); } if (hDll == IntPtr.Zero) { throw new Exception(String.Format("load library({0}) fail", sDllName)); } while (*pOriginalIAT != 0) { IntPtr lpFunction = IntPtr.Zero; if ((*pOriginalIAT & Win32API.IMAGE_ORDINAL_FLAG) == Win32API.IMAGE_ORDINAL_FLAG) // 最高位是1 { var iFuncID = *pOriginalIAT & 0x0000FFFF; lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int32)iFuncID)); } else { //var sFuncName = Marshal.PtrToStringAnsi(this.mModuleHandle + (Int32)(*pOriginalIAT) + 2); lpFunction = Win32API.GetProcAddress(hDll, this.mModuleHandle + (Int32)(*pOriginalIAT) + 2); } if (lpFunction != IntPtr.Zero) { *pRealIAT = (UInt32)lpFunction; } pRealIAT++; pOriginalIAT++; } pImportDescriptor++; } #endif }