void CalcHeaders() { _dosHeader = (IMAGE_DOS_HEADER *)_address; _ntHeaders32 = (IMAGE_NT_HEADERS32 *)(_address + _dosHeader->e_lfanew); _ntHeaders64 = (IMAGE_NT_HEADERS64 *)(_address + _dosHeader->e_lfanew); _isPE64 = _ntHeaders32->OptionalHeader.Magic == (ushort)OptionalHeaderMagic.PE32Plus; _fileHeader = _isPE64 ? &_ntHeaders64->FileHeader : &_ntHeaders32->FileHeader; _header32 = &_ntHeaders32->OptionalHeader; _header64 = &_ntHeaders64->OptionalHeader; _sections = new IMAGE_SECTION_HEADER[_fileHeader->NumberOfSections]; var offset = _isPE64 ? sizeof(IMAGE_NT_HEADERS64) : sizeof(IMAGE_NT_HEADERS32); fixed(void *sections = _sections) { Buffer.MemoryCopy((byte *)_ntHeaders32 + offset, sections, _sections.Length * sizeof(IMAGE_SECTION_HEADER), _sections.Length * sizeof(IMAGE_SECTION_HEADER)); } FileHeader = new FileHeader(_fileHeader); if (IsPE64) { OptionalHeader = new OptionalHeader(_header64); } else { OptionalHeader = new OptionalHeader(_header32); } _workBuffer = Marshal.AllocCoTaskMem(1 << 12); }
static unsafe USysCall64() { UNICODE_STRING szNtdll = new UNICODE_STRING("ntdll"); UIntPtr ptrNtdll = UIntPtr.Zero; long ntstatus = LdrGetDllHandle(IntPtr.Zero, IntPtr.Zero, ref szNtdll, ref ptrNtdll); if (ntstatus != 0) { Debugger.Break(); } byte * lpNtdll = (byte *)ptrNtdll; IMAGE_DOS_HEADER * piDH = (IMAGE_DOS_HEADER *)lpNtdll; IMAGE_OPTIONAL_HEADER64 *piOH = (IMAGE_OPTIONAL_HEADER64 *)(lpNtdll + piDH->e_lfanew + 0x18); IMAGE_EXPORT_DIRECTORY * exportDir = (IMAGE_EXPORT_DIRECTORY *)(lpNtdll + piOH->ExportTable.VirtualAddress); uint * names = (uint *)(lpNtdll + exportDir->AddressOfNames); uint * functions = (uint *)(lpNtdll + exportDir->AddressOfFunctions); ushort *ordinals = (ushort *)(lpNtdll + exportDir->AddressOfNameOrdinals); var listOfNames = new List <string>(); var dictOfZwFunctions = new Dictionary <string, ulong>(); for (int i = 0; i < exportDir->NumberOfNames; i++) { var name = Marshal.PtrToStringAnsi(new IntPtr(lpNtdll + names[i])); if (!name.StartsWith("Zw")) { continue; } var fnAddr = new UIntPtr(lpNtdll + functions[ordinals[i]]); dictOfZwFunctions.Add(name, fnAddr.ToUInt64()); } var sortedByAddr = dictOfZwFunctions .OrderBy(x => x.Value) .ToDictionary(x => "Nt" + x.Key.Substring(2, x.Key.Length - 2), x => x.Value); var sysCallLookup = new Dictionary <string, uint>(); uint sysNo = 0; foreach (var entry in sortedByAddr) { sysCallLookup.Add(entry.Key, sysNo); sysNo++; } SysCallTable = sysCallLookup; }
//[FieldOffset(112)] public IMAGE_DATA_DIRECTORY DataDirectory0; //[FieldOffset(120)] public IMAGE_DATA_DIRECTORY DataDirectory1; //[FieldOffset(128)] public IMAGE_DATA_DIRECTORY DataDirectory2; //[FieldOffset(136)] public IMAGE_DATA_DIRECTORY DataDirectory3; //[FieldOffset(144)] public IMAGE_DATA_DIRECTORY DataDirectory4; //[FieldOffset(152)] public IMAGE_DATA_DIRECTORY DataDirectory5; //[FieldOffset(160)] public IMAGE_DATA_DIRECTORY DataDirectory6; //[FieldOffset(168)] public IMAGE_DATA_DIRECTORY DataDirectory7; //[FieldOffset(176)] public IMAGE_DATA_DIRECTORY DataDirectory8; //[FieldOffset(184)] public IMAGE_DATA_DIRECTORY DataDirectory9; //[FieldOffset(192)] public IMAGE_DATA_DIRECTORY DataDirectory10; //[FieldOffset(200)] public IMAGE_DATA_DIRECTORY DataDirectory11; //[FieldOffset(208)] public IMAGE_DATA_DIRECTORY DataDirectory12; //[FieldOffset(216)] public IMAGE_DATA_DIRECTORY DataDirectory13; //[FieldOffset(224)] public IMAGE_DATA_DIRECTORY DataDirectory14; //[FieldOffset(232)] public IMAGE_DATA_DIRECTORY DataDirectory15; public static unsafe IMAGE_DATA_DIRECTORY *GetDataDirectory(IMAGE_OPTIONAL_HEADER64 *header, int zeroBasedIndex) { return((&header->ExportTable) + zeroBasedIndex); }
/// <summary> /// Locates version resource in a PE image /// </summary> /// <param name="FileData">Pointer to raw or mapped exe or dll</param> /// <param name="ResourceSize">Returns size of found resource</param> /// <returns>Pointer to located version resource or null if none found</returns> public unsafe static VS_VERSIONINFO *GetRawFileVersionResource(void *FileData, out int ResourceSize) { ResourceSize = 0; var dos_header = (IMAGE_DOS_HEADER *)FileData; var header = (IMAGE_NT_HEADERS *)((byte *)FileData + dos_header->e_lfanew); if (header == null || header->Signature != 0x4550 || header->FileHeader.SizeOfOptionalHeader == 0) { SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND); return(null); } IMAGE_DATA_DIRECTORY *resource_header; if (header->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)) { IMAGE_OPTIONAL_HEADER32 *optional_header = (IMAGE_OPTIONAL_HEADER32 *)&header->OptionalHeader; var data_directory = (IMAGE_DATA_DIRECTORY *)&optional_header->DataDirectory[0]; resource_header = data_directory + 2; } else if (header->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER64)) { IMAGE_OPTIONAL_HEADER64 *optional_header = (IMAGE_OPTIONAL_HEADER64 *)&header->OptionalHeader; var data_directory = (IMAGE_DATA_DIRECTORY *)&optional_header->DataDirectory[0]; resource_header = data_directory + 2; } else { SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND); return(null); } var section_table = (IMAGE_SECTION_HEADER *)((BYTE *)&header->OptionalHeader + header->FileHeader.SizeOfOptionalHeader); IMAGE_SECTION_HEADER *section_header = null; for (int i = 0; i < header->FileHeader.NumberOfSections; i++) { if (section_table[i].Name != _rsrc_id) { continue; } section_header = section_table + i; break; } if (section_header == null) { SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); return(null); } var raw = (BYTE *)FileData + section_header->PointerToRawData; var resource_section = (IMAGE_RESOURCE_DIRECTORY *)(raw + (resource_header->VirtualAddress - section_header->VirtualAddress)); var resource_dir_entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resource_section + 1); for (int i = 0; i < resource_section->NumberOfNamedEntries + resource_section->NumberOfIdEntries; i++) { if (!resource_dir_entry[i].NameIsString && resource_dir_entry[i].Id == RT_VERSION && resource_dir_entry[i].DataIsDirectory) { var found_entry = resource_dir_entry + i; var found_dir = (IMAGE_RESOURCE_DIRECTORY *)((BYTE *)resource_section + found_entry->OffsetToDirectory); if ((found_dir->NumberOfIdEntries + found_dir->NumberOfNamedEntries) == 0) { continue; } var found_dir_entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(found_dir + 1); for (int j = 0; j < found_dir->NumberOfNamedEntries + found_dir->NumberOfIdEntries; j++) { if (!found_dir_entry[j].DataIsDirectory) { continue; } var found_subdir = (IMAGE_RESOURCE_DIRECTORY *)((BYTE *)resource_section + found_dir_entry->OffsetToDirectory); if ((found_subdir->NumberOfIdEntries + found_subdir->NumberOfNamedEntries) == 0) { continue; } var found_subdir_entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(found_subdir + 1); if (found_subdir_entry->DataIsDirectory) { continue; } var found_data_entry = (IMAGE_RESOURCE_DATA_ENTRY *)((BYTE *)resource_section + found_subdir_entry->OffsetToData); var resptr = (VS_VERSIONINFO *)(raw + (found_data_entry->OffsetToData - section_header->VirtualAddress)); if (resptr->wType != 0 || !StringComparer.Ordinal.Equals(new string(resptr->szKey, 0, 15), "VS_VERSION_INFO") || resptr->FixedFileInfo.Signature != FixedFileVerInfo.FixedFileVerSignature) { SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); return(null); } ResourceSize = (int)found_data_entry->Size; return(resptr); } } } SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND); return(null); }
public static unsafe IMAGE_DATA_DIRECTORY* GetDataDirectory(IMAGE_OPTIONAL_HEADER64* header, int zeroBasedIndex) { return &header->DataDirectory0 + zeroBasedIndex; }
internal OptionalHeader(IMAGE_OPTIONAL_HEADER64 *header) { _header64 = header; }