public PeUtility([NotNull] Stream srcStream) { curFileStream = srcStream ?? throw new ArgumentNullException(nameof(srcStream)); var reader = new BinaryReader(curFileStream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset srcStream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); var ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); this.fileHeaderOffset = srcStream.Position; if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (var headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } }
private void Init(Stream stream) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } }
internal FileHeader(PortableExecutableImage image, IMAGE_FILE_HEADER fileHeader, ulong headerOffset, ulong imageBase) { _image = image; _header = fileHeader; Location = new Location(image, headerOffset, headerOffset.ToUInt32(), imageBase + headerOffset, Size.ToUInt32(), Size.ToUInt32()); }
private void Load(Stream stream) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader, null); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader, null); // Read optional header magic to determin 32-bit vs 64-bit var optMagic = reader.ReadUInt16(); _is32bit = (optMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC); var lookahead = new byte[] { (byte)(optMagic >> 8), (byte)(optMagic & 0xff) }; if (_is32bit) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader, lookahead); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader, lookahead); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader, null); } }
public PELoader(byte[] fileBytes) { // Read in the DLL or EXE and get the timestamp using (MemoryStream stream = new MemoryStream(fileBytes, 0, fileBytes.Length)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } RawBytes = fileBytes; } }
/// <summary> /// Reading from unmanaged memory pointer address. /// </summary> /// <param name="memPtr"></param> /// <param name="index"></param> private void Load(IntPtr memPtr, long index) { var startIndex = index; dosHeader = FromMemoryPtr <IMAGE_DOS_HEADER>(memPtr, ref index); index = startIndex + dosHeader.e_lfanew + 4; fileHeader = FromMemoryPtr <IMAGE_FILE_HEADER>(memPtr, ref index); // See the optiona header magic to determine 32-bit vs 64-bit var optMagic = Marshal.ReadInt16(new IntPtr(memPtr.ToInt64() + index)); _is32bit = (optMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC); if (_is32bit) { optionalHeader32 = FromMemoryPtr <IMAGE_OPTIONAL_HEADER32>(memPtr, ref index); } else { optionalHeader64 = FromMemoryPtr <IMAGE_OPTIONAL_HEADER64>(memPtr, ref index); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromMemoryPtr <IMAGE_SECTION_HEADER>(memPtr, ref index); } }
public PeHeaderReader(string filePath) { // Read in the DLL or EXE and get the timestamp using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } } }
private static IMAGE_SECTION_HEADER GetSection(IntPtr hProcess, IntPtr baseAddress, string section) { IMAGE_DOS_HEADER image_dos_header = ReadUnmanagedStructure <IMAGE_DOS_HEADER>(hProcess, baseAddress); IntPtr lpAddr = new IntPtr(baseAddress.ToInt64() + (image_dos_header.e_lfanew + 4)); IMAGE_FILE_HEADER image_file_header = ReadUnmanagedStructure <IMAGE_FILE_HEADER>(hProcess, lpAddr); lpAddr = new IntPtr(lpAddr.ToInt64() + (Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) + image_file_header.SizeOfOptionalHeader)); for (int i = 0; i < image_file_header.NumberOfSections; i++) { IMAGE_SECTION_HEADER image_section_header = ReadUnmanagedStructure <IMAGE_SECTION_HEADER>(hProcess, lpAddr); lpAddr = new IntPtr(lpAddr.ToInt64() + Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER))); for (int j = 0; j < 8; j++) { if (section.Length == j) { return(image_section_header); } if (section[j] != image_section_header.Name[j]) { break; } } } return(new IMAGE_SECTION_HEADER()); }
/// <summary> /// return the machine type /// </summary> /// <returns></returns> public string GetMachineType(PeHeaderReader reader) { IMAGE_FILE_HEADER fileHeader = reader.FileHeader; UInt16 machine = fileHeader.Machine; //string hexValue = machine.ToString("X"); switch (machine) { case 332: return("Intel 386"); break; case 512: return("Intel 64"); break; case 34404: return("AMD 64"); break; default: return("Machine type Unknown"); break; } }
public PeFile32(IMAGE_DOS_HEADER dosHeader, IMAGE_FILE_HEADER peHeader, IMAGE_OPTIONAL_HEADER32 optionalHeader, IMAGE_EXPORT_DIRECTORY exportDirectory, Dictionary <string, IntPtr> exports) { this.DosHeader = dosHeader; this.PeHeader = peHeader; this.OptionalHeader = optionalHeader; this.ExportDirectory = exportDirectory; Exports = exports; }
/// <summary> /// Create a new IMAGE_NT_HEADERS object. /// </summary> /// <param name="buff">A PE file as a byte array.</param> /// <param name="offset">Raw offset of the NT header.</param> public IMAGE_NT_HEADERS(byte[] buff, uint offset) : base(buff, offset) { FileHeader = new IMAGE_FILE_HEADER(buff, offset + 0x4); var is32Bit = FileHeader.Machine == 0x14c; OptionalHeader = new IMAGE_OPTIONAL_HEADER(buff, offset + 0x18, !is32Bit); }
public void ImageFileHeaderConstructorWorks_Test() { var fileHeader = new IMAGE_FILE_HEADER(RawStructures.RawFileHeader, 2); Assert.Equal((ushort)0x1100, fileHeader.Machine); Assert.Equal((ushort)0x3322, fileHeader.NumberOfSections); Assert.Equal((uint)0x77665544, fileHeader.TimeDateStamp); Assert.Equal(0xbbaa9988, fileHeader.PointerToSymbolTable); Assert.Equal(0xffeeddcc, fileHeader.NumberOfSymbols); Assert.Equal((ushort)0x2211, fileHeader.SizeOfOptionalHeader); Assert.Equal((ushort)0x4433, fileHeader.Characteristics); }
public static PE64FileHeader FromNativeStruct(IMAGE_FILE_HEADER nativeStruct) { return(new PE64FileHeader { Machine = nativeStruct.Machine, NumberOfSections = nativeStruct.NumberOfSections, TimeDateStamp = nativeStruct.TimeDateStamp, PointerToSymbolTable = nativeStruct.PointerToSymbolTable, NumberOfSymbols = nativeStruct.NumberOfSymbols, SizeOfOptionalHeader = nativeStruct.SizeOfOptionalHeader, Characteristics = nativeStruct.Characteristics }); }
public static IMAGE_FILE_HEADER Deserialize(MultiPartFile file) { IMAGE_FILE_HEADER ifh = new IMAGE_FILE_HEADER(); ifh.Machine = file.ReadUInt16(); ifh.NumberOfSections = file.ReadUInt16(); ifh.TimeDateStamp = file.ReadUInt32(); ifh.PointerToSymbolTable = file.ReadUInt32(); ifh.NumberOfSymbols = file.ReadUInt32(); ifh.SizeOfOptionalHeader = file.ReadUInt16(); ifh.Characteristics = file.ReadUInt16(); return(ifh); }
public PEReader(string filePath) { using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } }
public bool IsPE(string fileName) { using (var stream = new FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { var reader = new BinaryReader(stream); var peHeader = reader.ReadBytes(2); // PE Header is less than the minimum if (peHeader.Length < 2) { return(false); } // Check the first two bytes to rule out anything not DLL, EXE, SYS etc if (peHeader[0] != (byte)'M' && peHeader[1] != (byte)'Z') { return(false); } reader.BaseStream.Seek(0, SeekOrigin.Begin); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); var ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (var headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } return(true); } }
public PeFileHeaderReader(string path) { Path = path; using (var stream = new FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { var reader = new BinaryReader(stream); var dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); reader.BaseStream.Position = stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin) + 4; _fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); } }
static void HideHollowedProcess(IntPtr hProcess, HostProcessInfo hpi) { if (IntPtr.Size == 4) { Console.WriteLine("[=] Hide allow process not available on x86 yet, use --disable-header-patch to supress this warning"); return; } //Pull out the current image headers IMAGE_DOS_HEADER dosHeader = ReadType <IMAGE_DOS_HEADER>(hProcess, hpi.newLoadAddress); IMAGE_FILE_HEADER fileHeader = ReadType <IMAGE_FILE_HEADER>(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + dosHeader.e_lfanew)); IMAGE_OPTIONAL_HEADER64 optionalHeader = ReadType <IMAGE_OPTIONAL_HEADER64>(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + dosHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)))); //Clear some key areas used to spot PE files in memory ClearMemory(hProcess, hpi.newLoadAddress, 3); ClearMemory(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + 0x40), (int)dosHeader.e_lfanew - 0x40); ClearMemory(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + (int)dosHeader.e_lfanew), Marshal.SizeOf(typeof(IMAGE_FILE_HEADER))); //Clear out section names and characteristics used to identify implanted PE files for (int section = 0; section < fileHeader.NumberOfSections; section++) { IntPtr sectionOffset = new IntPtr(hpi.newLoadAddress.ToInt64() + (int)dosHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) + fileHeader.SizeOfOptionalHeader + (Marshal.SizeOf(typeof(Execute.PE.IMAGE_SECTION_HEADER)) * section)); Execute.PE.IMAGE_SECTION_HEADER ish = ReadType <Execute.PE.IMAGE_SECTION_HEADER>(hProcess, sectionOffset); ish.Name = new char[8]; ish.Characteristics = 0; WriteType <Execute.PE.IMAGE_SECTION_HEADER>(hProcess, sectionOffset, ish); } //Replace base address in PEB with the original WritePointer(hProcess, new IntPtr(hpi.peb.ToInt64() + 0x10), hpi.previousLoadAddress); //Finally replace main module load address and entrypoint with original host process IntPtr pebLdrDataPtr = ReadPointer(hProcess, new IntPtr(hpi.peb.ToInt64() + 0x18)); PEB_LDR_DATA pebLdrData = ReadType <PEB_LDR_DATA>(hProcess, pebLdrDataPtr); LDR_DATA_TABLE_ENTRY mainModule = ReadType <LDR_DATA_TABLE_ENTRY>(hProcess, pebLdrData.InLoadOrderModuleListPtr.Flink); mainModule.DllBase = hpi.previousLoadAddress; mainModule.EntryPoint = hpi.previousEntryPoint; WriteType(hProcess, pebLdrData.InLoadOrderModuleListPtr.Flink, mainModule); }
public PELoader(string filePath) { // Read in the DLL or EXE and get the timestamp try { using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); } } catch (Exception e) { Console.WriteLine("[!] {0}", e.Message); Environment.Exit(0); } }
/// <summary> /// find the header information /// </summary> /// <returns></returns> private void GetHeader(List <HeaderObject> Headers, PeHeaderReader reader) { IMAGE_FILE_HEADER fileHeader = reader.FileHeader; UInt16 machine = fileHeader.Machine; UInt16 numberOfSections = fileHeader.NumberOfSections; UInt32 timeDateStamp = fileHeader.TimeDateStamp; UInt32 pointerToSymbolTable = fileHeader.PointerToSymbolTable; UInt32 numberOfSymbols = fileHeader.NumberOfSymbols; UInt16 sizeOfOptionalHeader = fileHeader.SizeOfOptionalHeader; UInt16 characteristics = fileHeader.Characteristics; string MachineType = GetMachineType(reader); string character = GetCharacterInformation(characteristics); Headers.Add(new HeaderObject("Machine", MachineType)); Headers.Add(new HeaderObject("Number of sections", numberOfSections.ToString())); Headers.Add(new HeaderObject("Timestamp", timeDateStamp.ToString())); Headers.Add(new HeaderObject("Pointer to symbol table", pointerToSymbolTable.ToString())); Headers.Add(new HeaderObject("Number of symbols", numberOfSymbols.ToString())); Headers.Add(new HeaderObject("Size of optional header", sizeOfOptionalHeader.ToString())); Headers.Add(new HeaderObject("Characteristics", character)); return; }
public PeHeaderReader(string filePath) { // Read in the DLL or EXE and get the timestamp using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); uint ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } } }
/// <summary> /// find the section information for a given file /// </summary> /// <returns></returns> private void GetSections(List <SectionObject> Sections, PeHeaderReader reader) { PeHeaderReader.IMAGE_SECTION_HEADER[] sections = reader.ImageSectionHeaders; IMAGE_FILE_HEADER fileheader = reader.FileHeader; UInt32 numberofSection = fileheader.NumberOfSections; foreach (PeHeaderReader.IMAGE_SECTION_HEADER section in sections) { char[] name = section.Name; UInt32 virtualAddress = section.VirtualAddress; UInt32 pointerToRawData = section.PointerToRawData; UInt32 virtualSize = section.VirtualSize; UInt32 sizeOFrawData = section.SizeOfRawData; UInt32 pointerToRelocations = section.PointerToRelocations; UInt32 pointerToLineNumber = section.PointerToLinenumbers; UInt16 numberOfRelocations = section.NumberOfRelocations; UInt16 NumberOfLineNumbers = section.NumberOfLinenumbers; PeHeaderReader.DataSectionFlags dataSectionFlags = section.Characteristics; string nameOfSection = section.Section; Sections.Add(new SectionObject(nameOfSection, virtualAddress, virtualSize, pointerToRawData, sizeOFrawData)); } return; }
public PESupport(string LibraryName) { Debug.Assert(LibraryName != null); this.LibraryName = LibraryName; hLibrary = IntPtr.Zero; IntPtr original_hLibrary = LoadLibraryEx(this.LibraryName, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES); // access violations occur with LOAD_LIBRARY_AS_DATAFILE, but don't with DONT_RESOLVE_DLL_REFERENCES for some reason hLibrary = new IntPtr(original_hLibrary.ToInt32() - original_hLibrary.ToInt32() % 4); // adjust things to a DWORD boundary int error = Marshal.GetLastWin32Error(); if (hLibrary == null && error != 0) { throw new System.ApplicationException("Got error " + error + " when loading library " + LibraryName); } // do some sanity checking dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(hLibrary, typeof(IMAGE_DOS_HEADER)); if (!dosHeader.isValid) { throw new System.ApplicationException("Library does not appear to be a valid DOS file!"); } ntHeader = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure(hLibrary + dosHeader.e_lfanew, typeof(IMAGE_NT_HEADERS32)); if (!ntHeader.isValid) { throw new System.ApplicationException("Library NT Header does not appear valid!"); } fileHeader = ntHeader.FileHeader; if (fileHeader.Machine != (UInt16)(MachineType.I386)) { throw new System.ApplicationException("Library appears to be compiled for x64 while this program only supports x86 libraries."); } optionalHeader = ntHeader.OptionalHeader; exports = new Dictionary<int, List<string>>(); // if we don't have an export directory, move on if (optionalHeader.ExportTable.VirtualAddress == 0 || optionalHeader.ExportTable.Size == 0) { FreeLibrary(original_hLibrary); return; } // initialise the export header exportHeader = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(hLibrary + (int)optionalHeader.ExportTable.VirtualAddress, typeof(IMAGE_EXPORT_DIRECTORY)); for (int i = 0; i < exportHeader.NumberOfNames; i++) { // grab the pointer to the next entry in the string table. In C, this would be a char* IntPtr namePtr = (IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfNames) + (4 * i), typeof(IntPtr)); // dereference the previous char* string name; try { name = Marshal.PtrToStringAnsi(hLibrary + namePtr.ToInt32()); } catch (Exception ex) { name = ""; Console.WriteLine(ex.StackTrace); } // grab the address for this function int address = ((IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfFunctions) + 4 * i, typeof(IntPtr))).ToInt32(); address += (int)optionalHeader.ImageBase; if (exports.ContainsKey(address)) { exports[address].Add(name); } else { exports[address] = new List<string>(); exports[address].Add(name); } } FreeLibrary(original_hLibrary); }
public PESupport(string LibraryName) { Debug.Assert(LibraryName != null); this.LibraryName = LibraryName; hLibrary = IntPtr.Zero; IntPtr original_hLibrary = LoadLibraryEx(this.LibraryName, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES); // access violations occur with LOAD_LIBRARY_AS_DATAFILE, but don't with DONT_RESOLVE_DLL_REFERENCES for some reason hLibrary = new IntPtr(original_hLibrary.ToInt32() - original_hLibrary.ToInt32() % 4); // adjust things to a DWORD boundary int error = Marshal.GetLastWin32Error(); if (hLibrary == null && error != 0) { throw new System.ApplicationException("Got error " + error + " when loading library " + LibraryName); } // do some sanity checking dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(hLibrary, typeof(IMAGE_DOS_HEADER)); if (!dosHeader.isValid) { throw new System.ApplicationException("Library does not appear to be a valid DOS file!"); } ntHeader = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure(hLibrary + dosHeader.e_lfanew, typeof(IMAGE_NT_HEADERS32)); if (!ntHeader.isValid) { throw new System.ApplicationException("Library NT Header does not appear valid!"); } fileHeader = ntHeader.FileHeader; if (fileHeader.Machine != (UInt16)(MachineType.I386)) { throw new System.ApplicationException("Library appears to be compiled for x64 while this program only supports x86 libraries."); } optionalHeader = ntHeader.OptionalHeader; exports = new Dictionary <int, List <string> >(); // if we don't have an export directory, move on if (optionalHeader.ExportTable.VirtualAddress == 0 || optionalHeader.ExportTable.Size == 0) { FreeLibrary(original_hLibrary); return; } // initialise the export header exportHeader = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(hLibrary + (int)optionalHeader.ExportTable.VirtualAddress, typeof(IMAGE_EXPORT_DIRECTORY)); for (int i = 0; i < exportHeader.NumberOfNames; i++) { // grab the pointer to the next entry in the string table. In C, this would be a char* IntPtr namePtr = (IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfNames) + (4 * i), typeof(IntPtr)); // dereference the previous char* string name; try { name = Marshal.PtrToStringAnsi(hLibrary + namePtr.ToInt32()); } catch (Exception ex) { name = ""; Console.WriteLine(ex.StackTrace); } // grab the address for this function int address = ((IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfFunctions) + 4 * i, typeof(IntPtr))).ToInt32(); address += (int)optionalHeader.ImageBase; if (exports.ContainsKey(address)) { exports[address].Add(name); } else { exports[address] = new List <string>(); exports[address].Add(name); } } FreeLibrary(original_hLibrary); }
public static bool Is32BitHeader(IMAGE_FILE_HEADER fileHeader) { UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100; return((IMAGE_FILE_32BIT_MACHINE & fileHeader.Characteristics) == IMAGE_FILE_32BIT_MACHINE); }
public PeHeaderReader(string filePath) { using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } uint offDebug = 0; uint cbDebug = 0; long cbFromHeader = 0; int loopexit = 0; if (this.Is32BitHeader) { cbDebug = optionalHeader32.Debug.Size; } else { cbDebug = optionalHeader64.Debug.Size; } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); if ((imageSectionHeaders[headerNo].PointerToRawData != 0) && (imageSectionHeaders[headerNo].SizeOfRawData != 0) && (cbFromHeader < (long) (imageSectionHeaders[headerNo].PointerToRawData + imageSectionHeaders[headerNo].SizeOfRawData))) { cbFromHeader = (long) (imageSectionHeaders[headerNo].PointerToRawData + imageSectionHeaders[headerNo].SizeOfRawData); } if (cbDebug != 0) { if (this.Is32BitHeader) { if (imageSectionHeaders[headerNo].VirtualAddress <= optionalHeader32.Debug.VirtualAddress && ((imageSectionHeaders[headerNo].VirtualAddress + imageSectionHeaders[headerNo].SizeOfRawData) > optionalHeader32.Debug.VirtualAddress)) { offDebug = optionalHeader32.Debug.VirtualAddress - imageSectionHeaders[headerNo].VirtualAddress + imageSectionHeaders[headerNo].PointerToRawData; } } else { if (imageSectionHeaders[headerNo].VirtualAddress <= optionalHeader64.Debug.VirtualAddress && ((imageSectionHeaders[headerNo].VirtualAddress + imageSectionHeaders[headerNo].SizeOfRawData) > optionalHeader64.Debug.VirtualAddress)) { offDebug = optionalHeader64.Debug.VirtualAddress - imageSectionHeaders[headerNo].VirtualAddress + imageSectionHeaders[headerNo].PointerToRawData; } } } } stream.Seek(offDebug, SeekOrigin.Begin); while (cbDebug >= Marshal.SizeOf(typeof(IMAGE_DEBUG_DIRECTORY))) { if (loopexit == 0) { imageDebugDirectory = FromBinaryReader <IMAGE_DEBUG_DIRECTORY>(reader); long seekPosition = stream.Position; if (imageDebugDirectory.Type == 0x2) { stream.Seek(imageDebugDirectory.PointerToRawData, SeekOrigin.Begin); DebugInfo = FromBinaryReader <IMAGE_DEBUG_DIRECTORY_RAW>(reader); loopexit = 1; //Downloading logic for .NET native images if (new string(DebugInfo.name).Contains(".ni.")) { stream.Seek(seekPosition, SeekOrigin.Begin); loopexit = 0; } } if ((imageDebugDirectory.PointerToRawData != 0) && (imageDebugDirectory.SizeOfData != 0) && (cbFromHeader < (long) (imageDebugDirectory.PointerToRawData + imageDebugDirectory.SizeOfData))) { cbFromHeader = (long) (imageDebugDirectory.PointerToRawData + imageDebugDirectory.SizeOfData); } } cbDebug -= (uint)Marshal.SizeOf(typeof(IMAGE_DEBUG_DIRECTORY)); } if (loopexit != 0) { _pdbName = new string(DebugInfo.name); _pdbName = _pdbName.Remove(_pdbName.IndexOf("\0")); _pdbage = DebugInfo.age.ToString("X"); _debugGUID = DebugInfo.guid; } } }
private unsafe void PopulateHeaderStructs(FileStream fin) { byte[] Data = new byte[4096]; int iRead = fin.Read(Data, 0, 4096); fin.Flush(); fin.Close(); fixed(byte *p_Data = Data) { IMAGE_DOS_HEADER * idh = (IMAGE_DOS_HEADER *)p_Data; IMAGE_NT_HEADERS32 *inhs = (IMAGE_NT_HEADERS32 *)(idh->nt_head_ptr + p_Data); ModuleMachineType = (MachineType)inhs->FileHeader.Machine; if (ModuleMachineType == MachineType.I386) { IMAGE_NT_HEADERS32 *inhs32 = (IMAGE_NT_HEADERS32 *)(idh->nt_head_ptr + p_Data); ImageFileHeader = inhs32->FileHeader; ModuleMachineType = (MachineType)inhs32->FileHeader.Machine; ImageOptionalHeader32 = inhs32->OptionalHeader; ModuleImageBase = (IntPtr)inhs32->OptionalHeader.ImageBase; ImageNTHeaders32 = new IMAGE_NT_HEADERS32 { Signature = inhs32->Signature, FileHeader = inhs32->FileHeader, OptionalHeader = inhs32->OptionalHeader }; byte[] bytes = new byte[256]; var ret = ErcCore.ReadProcessMemory(ModuleProcess.Handle, (IntPtr)((uint)ModuleBase + ImageOptionalHeader32.LoadConfigTable.VirtualAddress), bytes, 256, out int BytesRead); if (BitConverter.ToUInt32(bytes, 58) > 0 || BitConverter.ToUInt32(bytes, 62) > 0) { ModuleSafeSEH = true; } } else if (ModuleMachineType == MachineType.x64) { IMAGE_NT_HEADERS64 *inhs64 = (IMAGE_NT_HEADERS64 *)(idh->nt_head_ptr + p_Data); ImageFileHeader = inhs64->FileHeader; ImageOptionalHeader64 = inhs64->OptionalHeader; ModuleImageBase = (IntPtr)inhs64->OptionalHeader.ImageBase; ImageNTHeaders64 = new IMAGE_NT_HEADERS64 { Signature = inhs64->Signature, FileHeader = inhs64->FileHeader, OptionalHeader = inhs64->OptionalHeader }; byte[] bytes = new byte[256]; var ret = ErcCore.ReadProcessMemory(ModuleProcess.Handle, (IntPtr)((long)ModuleBase + (long)ImageOptionalHeader64.LoadConfigTable.VirtualAddress), bytes, 256, out int BytesRead); if (BitConverter.ToUInt64(bytes, 88) > 0 || BitConverter.ToUInt64(bytes, 96) > 0) { ModuleSafeSEH = true; } } else { ModuleFailed = true; } } }
/// <summary> /// Parses the specified data. /// </summary> /// <param name="data">The PE image data.</param> private void ParseData(byte[] data) { using (DwarfMemoryReader reader = new DwarfMemoryReader(data)) { dosHeader = reader.ReadStructure <IMAGE_DOS_HEADER>(); if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE) { throw new ArgumentException($"Invalid IMAGE_DOS_HEADER magic constant. Expected: 0x{IMAGE_DOS_SIGNATURE:X}, Got: 0x{dosHeader.e_magic:X}"); } reader.Position = (int)dosHeader.e_lfanew; ntHeaders32 = reader.ReadStructure <IMAGE_NT_HEADERS32>(); if (ntHeaders32.Signature != IMAGE_NT_SIGNATURE) { throw new ArgumentException($"Invalid optional header signature. Expected: 0x{IMAGE_NT_SIGNATURE:X}, Got: 0x{ntHeaders32.Signature:X}"); } if (ntHeaders32.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 || ntHeaders32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) { reader.Position = (int)dosHeader.e_lfanew; ntHeaders64 = reader.ReadStructure <IMAGE_NT_HEADERS64>(); Is64bit = true; fileHeader = ntHeaders64.FileHeader; reader.Position += ntHeaders64.FileHeader.SizeOfOptionalHeader - Marshal.SizeOf <IMAGE_OPTIONAL_HEADER64>(); CodeSegmentOffset = ntHeaders64.OptionalHeader.ImageBase; } else { Is64bit = false; fileHeader = ntHeaders32.FileHeader; reader.Position += ntHeaders32.FileHeader.SizeOfOptionalHeader - Marshal.SizeOf <IMAGE_OPTIONAL_HEADER32>(); CodeSegmentOffset = ntHeaders32.OptionalHeader.ImageBase; } // Load image section headers uint stringTablePosition = fileHeader.PointerToSymbolTable + fileHeader.NumberOfSymbols * IMAGE_SIZEOF_SYMBOL; imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int section = 0; section < imageSectionHeaders.Length; section++) { IMAGE_SECTION_HEADER imageSectionHeader = reader.ReadStructure <IMAGE_SECTION_HEADER>(); imageSectionHeaders[section] = imageSectionHeader; string name = imageSectionHeader.Section; if (imageSectionHeader.Name[0] == '/') { uint position = stringTablePosition + uint.Parse(imageSectionHeader.Section.Substring(1)); name = reader.ReadString((int)position); } switch (name) { case ".debug_info": DebugData = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".debug_abbrev": DebugDataDescription = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".debug_line": DebugLine = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".debug_frame": DebugFrame = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".debug_str": DebugDataStrings = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".eh_frame": EhFrame = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); EhFrameAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset; break; case ".data": DataSectionAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset; break; case ".text": TextSectionAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset; break; } } // Load image symbols List <PublicSymbol> publicSymbols = new List <PublicSymbol>(); byte toSkip = 0; reader.Position = (int)fileHeader.PointerToSymbolTable; for (uint i = 0; i < fileHeader.NumberOfSymbols; i++) { int position = reader.Position; IMAGE_SYMBOL symbol = reader.ReadStructure <IMAGE_SYMBOL>(); if (toSkip == 0) { string name = symbol.SymbolName; if (string.IsNullOrEmpty(name)) { int stringPosition = (int)reader.ReadUint(position); stringPosition = (int)reader.ReadUint(position + 4); name = reader.ReadString((int)stringTablePosition + stringPosition); } if (symbol.SectionNumber > 0 && symbol.SectionNumber <= imageSectionHeaders.Length) { uint sectionAddress = imageSectionHeaders[symbol.SectionNumber - 1].VirtualAddress; sectionAddress += symbol.Value; publicSymbols.Add(new PublicSymbol(name, sectionAddress)); } toSkip = symbol.NumberOfAuxSymbols; } else { toSkip--; } } PublicSymbols = publicSymbols; } }
public IntPtr GetRemoteProcAddress(IntPtr ptrHandle, IntPtr hBaseAddress, string sProcName) { IMAGE_DOS_HEADER32 dosHeader = new IMAGE_DOS_HEADER32(); uint uiSignature = 0; IMAGE_FILE_HEADER fileHeader = new IMAGE_FILE_HEADER(); IMAGE_OPTIONAL_HEADER32 optHeader32 = new IMAGE_OPTIONAL_HEADER32(); IMAGE_DATA_DIRECTORY exportDirectory = new IMAGE_DATA_DIRECTORY(); IMAGE_EXPORT_DIRECTORY exportTable = new IMAGE_EXPORT_DIRECTORY(); IntPtr ptrFunctionTable = IntPtr.Zero; IntPtr ptrNameTable = IntPtr.Zero; IntPtr ptrOrdinalTable = IntPtr.Zero; if (ptrHandle == IntPtr.Zero || hBaseAddress == IntPtr.Zero) { WriteError("Invalid call."); return(IntPtr.Zero); } IntPtr ptrNumBytesRead = IntPtr.Zero; if (!ReadProcessMemory(ptrHandle, hBaseAddress, &dosHeader, Marshal.SizeOf(dosHeader), out ptrNumBytesRead)) { WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString()); return(IntPtr.Zero); } if (dosHeader.e_magic != 0x5A4D) { WriteError("Image is not a valid DLL. " + dosHeader.e_magic.ToString()); return(IntPtr.Zero); } if (!ReadProcessMemory(ptrHandle, hBaseAddress + (dosHeader.e_lfanew), &uiSignature, Marshal.SizeOf(uiSignature), out ptrNumBytesRead)) { WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString()); return(IntPtr.Zero); } if (uiSignature != 0x4550) { WriteError("Invalid NT signature..."); return(IntPtr.Zero); } if (!ReadProcessMemory(ptrHandle, hBaseAddress + (dosHeader.e_lfanew + Marshal.SizeOf(uiSignature)), &fileHeader, Marshal.SizeOf(fileHeader), out ptrNumBytesRead)) { WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString()); return(IntPtr.Zero); } if (!ReadProcessMemory(ptrHandle, hBaseAddress + (dosHeader.e_lfanew + Marshal.SizeOf(uiSignature) + Marshal.SizeOf(fileHeader)), &optHeader32, Marshal.SizeOf(optHeader32), out ptrNumBytesRead)) { WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString()); return(IntPtr.Zero); } if (optHeader32.NumberOfRvaAndSizes >= 1) { exportDirectory.VirtualAddress = (optHeader32.ExportTable.VirtualAddress); exportDirectory.Size = (optHeader32.ExportTable.Size); } else { WriteError("No export table found."); return(IntPtr.Zero); } if (!ReadProcessMemory(ptrHandle, hBaseAddress + (int)(exportDirectory.VirtualAddress), &exportTable, Marshal.SizeOf(exportTable), out ptrNumBytesRead)) { WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString()); return(IntPtr.Zero); } uint[] uiExportFuncTable = ReadUIntArray(ptrHandle, hBaseAddress + (int)(exportTable.AddressOfFunctions), (int)exportTable.NumberOfFunctions); uint[] uiExportNameTable = ReadUIntArray(ptrHandle, hBaseAddress + (int)(exportTable.AddressOfNames), (int)exportTable.NumberOfNames); short[] usExportOrdinalTable = ReadShortArray(ptrHandle, hBaseAddress + (int)(exportTable.AddressOfNameOrdinals), (int)exportTable.NumberOfNames); for (int i = 0; i < exportTable.NumberOfNames; i++) { if (ReadString(ptrHandle, hBaseAddress + (int)(uiExportNameTable[i])) == sProcName) { return(new IntPtr((int)hBaseAddress + uiExportFuncTable[usExportOrdinalTable[i]])); } } WriteError("Unable to find the provided procedure name!"); return(IntPtr.Zero); }
private void parsePEbytes(string sBytes) { byte[] bytes = Encoding.Default.GetBytes(sBytes); List <string> results = new List <string>(); // IMAGE_DOS_HEADER IMAGE_DOS_HEADER dosHeader = BytesToStructure <IMAGE_DOS_HEADER>(bytes); results.Add("IMAGE_DOS_HEADER.e_magic;" + dosHeader.e_magic + ";0x" + dosHeader.e_magic.ToString("x") + ";Magic number"); results.Add("IMAGE_DOS_HEADER.e_cblp;" + dosHeader.e_cblp + ";;Bytes on last page of file"); results.Add("IMAGE_DOS_HEADER.e_cp;" + dosHeader.e_cp + ";;Relocations"); results.Add("IMAGE_DOS_HEADER.e_crlc;" + dosHeader.e_crlc + ";;Bytes on last page of file"); results.Add("IMAGE_DOS_HEADER.e_cparhdr;" + dosHeader.e_cparhdr + ";;Size of header in paragraphs"); results.Add("IMAGE_DOS_HEADER.e_minalloc;" + dosHeader.e_minalloc + ";;Minimum extra paragraphs needed"); results.Add("IMAGE_DOS_HEADER.e_maxalloc;" + dosHeader.e_maxalloc + ";;Maximum extra paragraphs needed"); results.Add("IMAGE_DOS_HEADER.e_ss;" + dosHeader.e_ss + ";;Initial (relative) SS value"); results.Add("IMAGE_DOS_HEADER.e_sp;" + dosHeader.e_sp + ";;Initial SP value"); results.Add("IMAGE_DOS_HEADER.e_csum;" + dosHeader.e_csum + ";;Checksum"); results.Add("IMAGE_DOS_HEADER.e_ip;" + dosHeader.e_ip + ";;Initial IP value"); results.Add("IMAGE_DOS_HEADER.e_cs;" + dosHeader.e_cs + ";;Initial (relative) CS value"); results.Add("IMAGE_DOS_HEADER.e_lfarlc;" + dosHeader.e_lfarlc + ";;File address of relocation table"); results.Add("IMAGE_DOS_HEADER.e_ovno;" + dosHeader.e_ovno + ";;Overlay number"); results.Add("IMAGE_DOS_HEADER.e_res_0;" + dosHeader.e_res_0 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res_1;" + dosHeader.e_res_1 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res_2;" + dosHeader.e_res_2 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res_3;" + dosHeader.e_res_3 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_oemid;" + dosHeader.e_oemid + ";;OEM identifier (for e_oeminfo)"); results.Add("IMAGE_DOS_HEADER.e_oeminfo;" + dosHeader.e_oeminfo + ";;OEM information (e_oemid specific)"); results.Add("IMAGE_DOS_HEADER.e_res2_0;" + dosHeader.e_res2_0 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_1;" + dosHeader.e_res2_1 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_2;" + dosHeader.e_res2_2 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_3;" + dosHeader.e_res2_3 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_4;" + dosHeader.e_res2_4 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_5;" + dosHeader.e_res2_5 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_6;" + dosHeader.e_res2_6 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_7;" + dosHeader.e_res2_7 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_8;" + dosHeader.e_res2_8 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_res2_9;" + dosHeader.e_res2_9 + ";;Reserved words"); results.Add("IMAGE_DOS_HEADER.e_lfanew;" + dosHeader.e_lfanew + ";;File address of new exe header"); // IMAGE_FILE_HEADER IMAGE_FILE_HEADER fileHeader = BytesToStructure <IMAGE_FILE_HEADER>(bytes.Skip((int)dosHeader.e_lfanew + 4).ToArray()); results.Add("IMAGE_FILE_HEADER.Machine;" + fileHeader.Machine + ";0x" + fileHeader.Machine.ToString("x")); results.Add("IMAGE_FILE_HEADER.NumberOfSections;" + fileHeader.NumberOfSections); results.Add("IMAGE_FILE_HEADER.TimeDateStamp;" + fileHeader.TimeDateStamp); results.Add("IMAGE_FILE_HEADER.PointerToSymbolTable;" + fileHeader.PointerToSymbolTable); results.Add("IMAGE_FILE_HEADER.NumberOfSymbols;" + fileHeader.NumberOfSymbols); results.Add("IMAGE_FILE_HEADER.SizeOfOptionalHeader;" + fileHeader.SizeOfOptionalHeader); results.Add("IMAGE_FILE_HEADER.Characteristics;" + fileHeader.Characteristics + ";0x" + fileHeader.Characteristics.ToString("x")); bool Is32BitHeader = fileHeader.Machine != 0 && fileHeader.Machine != 0x8664; UInt64 ImageBase = 0; // IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER32 optionalHeader32; IMAGE_OPTIONAL_HEADER64 optionalHeader64; IMAGE_DATA_DIRECTORIES[] dataDirectories = new IMAGE_DATA_DIRECTORIES[16]; long offset = dosHeader.e_lfanew + 4 + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)); if (Is32BitHeader) { optionalHeader32 = BytesToStructure <IMAGE_OPTIONAL_HEADER32>(bytes.Skip((int)offset).ToArray()); offset += Marshal.SizeOf(typeof(IMAGE_OPTIONAL_HEADER32)); ImageBase = optionalHeader32.ImageBase; results.Add("IMAGE_OPTIONAL_HEADER32.Magic;" + optionalHeader32.Magic); results.Add("IMAGE_OPTIONAL_HEADER32.MajorLinkerVersion;" + optionalHeader32.MajorLinkerVersion); results.Add("IMAGE_OPTIONAL_HEADER32.MinorLinkerVersion;" + optionalHeader32.MinorLinkerVersion); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfCode;" + optionalHeader32.SizeOfCode); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfInitializedData;" + optionalHeader32.SizeOfInitializedData); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfUninitializedData;" + optionalHeader32.SizeOfUninitializedData); results.Add(string.Format("IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint;{0};0x{1:x}", optionalHeader32.AddressOfEntryPoint, optionalHeader32.AddressOfEntryPoint.ToString("x"))); results.Add("IMAGE_OPTIONAL_HEADER32.BaseOfCode;" + optionalHeader32.BaseOfCode); results.Add("IMAGE_OPTIONAL_HEADER32.BaseOfData;" + optionalHeader32.BaseOfData); results.Add("IMAGE_OPTIONAL_HEADER32.ImageBase;" + optionalHeader32.ImageBase + ";0x" + optionalHeader32.ImageBase.ToString("x")); results.Add("IMAGE_OPTIONAL_HEADER32.SectionAlignment;" + optionalHeader32.SectionAlignment); results.Add("IMAGE_OPTIONAL_HEADER32.FileAlignment;" + optionalHeader32.FileAlignment); results.Add("IMAGE_OPTIONAL_HEADER32.MajorOperatingSystemVersion;" + optionalHeader32.MajorOperatingSystemVersion); results.Add("IMAGE_OPTIONAL_HEADER32.MinorOperatingSystemVersion;" + optionalHeader32.MinorOperatingSystemVersion); results.Add("IMAGE_OPTIONAL_HEADER32.MajorImageVersion;" + optionalHeader32.MajorImageVersion); results.Add("IMAGE_OPTIONAL_HEADER32.MinorImageVersion;" + optionalHeader32.MinorImageVersion); results.Add("IMAGE_OPTIONAL_HEADER32.MajorSubsystemVersion;" + optionalHeader32.MajorSubsystemVersion); results.Add("IMAGE_OPTIONAL_HEADER32.MinorSubsystemVersion;" + optionalHeader32.MinorSubsystemVersion); results.Add("IMAGE_OPTIONAL_HEADER32.Win32VersionValue;" + optionalHeader32.Win32VersionValue); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfImage;" + optionalHeader32.SizeOfImage); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfHeaders;" + optionalHeader32.SizeOfHeaders); results.Add("IMAGE_OPTIONAL_HEADER32.CheckSum;" + optionalHeader32.CheckSum); results.Add("IMAGE_OPTIONAL_HEADER32.Subsystem;" + optionalHeader32.Subsystem); results.Add("IMAGE_OPTIONAL_HEADER32.DllCharacteristics;" + optionalHeader32.DllCharacteristics); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfStackReserve;" + optionalHeader32.SizeOfStackReserve); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfStackCommit;" + optionalHeader32.SizeOfStackCommit); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfHeapReserve;" + optionalHeader32.SizeOfHeapReserve); results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfHeapCommit;" + optionalHeader32.SizeOfHeapCommit); results.Add("IMAGE_OPTIONAL_HEADER32.LoaderFlags;" + optionalHeader32.LoaderFlags); results.Add("IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes;" + optionalHeader32.NumberOfRvaAndSizes); } else { optionalHeader64 = BytesToStructure <IMAGE_OPTIONAL_HEADER64>(bytes.Skip((int)offset).ToArray()); offset += Marshal.SizeOf(typeof(IMAGE_OPTIONAL_HEADER64)); ImageBase = optionalHeader64.ImageBase; results.Add("IMAGE_OPTIONAL_HEADER64.Magic;" + optionalHeader64.Magic); results.Add("IMAGE_OPTIONAL_HEADER64.MajorLinkerVersion;" + optionalHeader64.MajorLinkerVersion); results.Add("IMAGE_OPTIONAL_HEADER64.MinorLinkerVersion;" + optionalHeader64.MinorLinkerVersion); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfCode;" + optionalHeader64.SizeOfCode); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfInitializedData;" + optionalHeader64.SizeOfInitializedData); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfUninitializedData;" + optionalHeader64.SizeOfUninitializedData); results.Add("IMAGE_OPTIONAL_HEADER64.AddressOfEntryPoint;" + (optionalHeader64.ImageBase + optionalHeader64.AddressOfEntryPoint) + ";0x" + (optionalHeader64.ImageBase + optionalHeader64.AddressOfEntryPoint).ToString("x")); results.Add("IMAGE_OPTIONAL_HEADER64.BaseOfCode;" + optionalHeader64.BaseOfCode); results.Add("IMAGE_OPTIONAL_HEADER64.ImageBase;" + optionalHeader64.ImageBase + ";0x" + optionalHeader64.ImageBase.ToString("x")); results.Add("IMAGE_OPTIONAL_HEADER64.SectionAlignment;" + optionalHeader64.SectionAlignment); results.Add("IMAGE_OPTIONAL_HEADER64.FileAlignment;" + optionalHeader64.FileAlignment); results.Add("IMAGE_OPTIONAL_HEADER64.MajorOperatingSystemVersion;" + optionalHeader64.MajorOperatingSystemVersion); results.Add("IMAGE_OPTIONAL_HEADER64.MinorOperatingSystemVersion;" + optionalHeader64.MinorOperatingSystemVersion); results.Add("IMAGE_OPTIONAL_HEADER64.MajorImageVersion;" + optionalHeader64.MajorImageVersion); results.Add("IMAGE_OPTIONAL_HEADER64.MinorImageVersion;" + optionalHeader64.MinorImageVersion); results.Add("IMAGE_OPTIONAL_HEADER64.MajorSubsystemVersion;" + optionalHeader64.MajorSubsystemVersion); results.Add("IMAGE_OPTIONAL_HEADER64.MinorSubsystemVersion;" + optionalHeader64.MinorSubsystemVersion); results.Add("IMAGE_OPTIONAL_HEADER64.Win32VersionValue;" + optionalHeader64.Win32VersionValue); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfImage;" + optionalHeader64.SizeOfImage); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfHeaders;" + optionalHeader64.SizeOfHeaders); results.Add("IMAGE_OPTIONAL_HEADER64.CheckSum;" + optionalHeader64.CheckSum); results.Add("IMAGE_OPTIONAL_HEADER64.Subsystem;" + optionalHeader64.Subsystem); results.Add("IMAGE_OPTIONAL_HEADER64.DllCharacteristics;" + optionalHeader64.DllCharacteristics); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfStackReserve;" + optionalHeader64.SizeOfStackReserve); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfStackCommit;" + optionalHeader64.SizeOfStackCommit); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfHeapReserve;" + optionalHeader64.SizeOfHeapReserve); results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfHeapCommit;" + optionalHeader64.SizeOfHeapCommit); results.Add("IMAGE_OPTIONAL_HEADER64.LoaderFlags;" + optionalHeader64.LoaderFlags); results.Add("IMAGE_OPTIONAL_HEADER64.NumberOfRvaAndSizes;" + optionalHeader64.NumberOfRvaAndSizes); } // IMAGE_DATA_DIRECTORIES for (int i = 0; i < 16; i++) { long dd_offset = offset + i * Marshal.SizeOf(typeof(IMAGE_DATA_DIRECTORIES)); dataDirectories[i] = BytesToStructure <IMAGE_DATA_DIRECTORIES>(bytes.Skip((int)dd_offset).ToArray()); } for (int i = 0; i < 16; i++) { if (dataDirectories[i].VirtualAddress == 0 && dataDirectories[i].Size == 0) { continue; } results.Add("IMAGE_DATA_DIRECTORIES[" + i + "].VirtualAddress;" + dataDirectories[i].VirtualAddress + ";0x" + dataDirectories[i].VirtualAddress.ToString("x") + ";" + ((Dir)i).ToString()); results.Add("IMAGE_DATA_DIRECTORIES[" + i + "].Size;" + dataDirectories[i].Size); } //number of sections int ns = Math.Min((int)fileHeader.NumberOfSections, 32); //IMAGE_SECTION_HEADER offset += 16 * Marshal.SizeOf(typeof(IMAGE_DATA_DIRECTORIES)); IMAGE_SECTION_HEADER[] sectHeaders = new IMAGE_SECTION_HEADER[ns]; for (int i = 0; i < ns; i++) { long dd_offset = offset + i * Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); sectHeaders[i] = BytesToStructure <IMAGE_SECTION_HEADER>(bytes.Skip((int)dd_offset).ToArray()); } results.Add("IMAGE_SECTION_HEADER.Columns;Name;VirtualSize;VirtualAddress;VirtualAddress;SizeOfRawData;PointerToRawData;PointerToRawData;PointerToRelocations;PointerToLinenumbers;NumberOfRelocations;NumberOfLinenumbers;Characteristics_dec;Characteristics_hex;Characteristics"); for (int i = 0; sectHeaders != null && i < ns; i++) { String sectName = sectHeaders[i].Name.ToString("X"); StringBuilder secname = new StringBuilder(8); for (int x = sectName.Length - 2; x >= 0; x -= 2) { int value = Convert.ToInt32(sectName.Substring(x, 2), 16); if (value > 0) { secname.Append(Char.ConvertFromUtf32(value)); } } results.Add("IMAGE_SECTION_HEADER[" + i + "];" + secname + ";" + sectHeaders[i].VirtualSize + ";" + (ImageBase + sectHeaders[i].VirtualAddress) + ";" + "0x" + (ImageBase + sectHeaders[i].VirtualAddress).ToString("x") + ";" + sectHeaders[i].SizeOfRawData + ";" + sectHeaders[i].PointerToRawData + ";" + "0x" + sectHeaders[i].PointerToRawData.ToString("x") + ";" + sectHeaders[i].PointerToRelocations + ";" + sectHeaders[i].PointerToLinenumbers + ";" + sectHeaders[i].NumberOfRelocations + ";" + sectHeaders[i].NumberOfLinenumbers + ";" + sectHeaders[i].Characteristics + ";" + "0x" + sectHeaders[i].Characteristics.ToString("x") + ";" + "characteristics"); } offset = sectHeaders[(int)Dir.Resource].PointerToRawData; RESOURCE_DIRECTORY ResourceDir = BytesToStructure <RESOURCE_DIRECTORY>(bytes.Skip((int)offset).ToArray()); results.Add("RESOURCE_DIR_ROOT.Characteristics;" + ResourceDir.Characteristics); results.Add("RESOURCE_DIR_ROOT.TimeDateStamp;" + ResourceDir.TimeDateStamp); results.Add("RESOURCE_DIR_ROOT.MajorVersion;" + ResourceDir.MajorVersion); results.Add("RESOURCE_DIR_ROOT.MinorVersion;" + ResourceDir.MinorVersion); results.Add("RESOURCE_DIR_ROOT.NumberOfNamedEntries;" + ResourceDir.NumberOfNamedEntries); results.Add("RESOURCE_DIR_ROOT.NumberOfldEntries;" + ResourceDir.NumberOfldEntries); offset += Marshal.SizeOf(typeof(RESOURCE_DIRECTORY_ENTRY)) + 8; // RESOURCE_DIRECTORY_ENTRY List <RESOURCE_DIRECTORY_ENTRY> res_entries = new List <RESOURCE_DIRECTORY_ENTRY>(); RESOURCE_DIRECTORY_ENTRY res_ent; for (int ie = 0; ie < ResourceDir.NumberOfNamedEntries + ResourceDir.NumberOfldEntries; ie++) { // read resource entries long dd_offset = offset + ie * Marshal.SizeOf(typeof(RESOURCE_DIRECTORY_ENTRY)); res_ent = BytesToStructure <RESOURCE_DIRECTORY_ENTRY>(bytes.Skip((int)dd_offset).ToArray()); res_entries.Add(res_ent); // TODO //long name_offset = sectHeaders[(int)Dir.Resource].PointerToRawData + (res_ent.Name); //resname //string name=string.Concat(bytes.Skip((int)name_offset).Take(32).Where(b => b > 0).Select(c => (char)c)); } for (int i = 0; i < res_entries.Count; i++) { //string resname = res_entry_names[i].Length > 0 ? res_entry_names[i] : resType(res_entries[i].Name); results.Add("RESOURCE_ENTRY[" + i + "];" + res_entries[i].Name // + ";" + //"name" /*res_entries[i].OffsetToData + ";" + * res_dirs[i].Characteristics + ";" + * res_dirs[i].TimeDateStamp + ";" + * res_dirs[i].MajorVersion + ";" + * res_dirs[i].MinorVersion + ";" + * res_dirs[i].NumberOfNamedEntries + ";" + * res_dirs[i].NumberOfldEntries*/ ); } // finaly ConsoleWrite_Atom(string.Join("\n", results)); }
/// <summary> /// Process a PE executable header /// </summary> private ExecutableType ProcessPe(ref bool searchAgainAtEnd) { inputFile.Seek(dataBase + currentFormat.ExecutableOffset + 4); IMAGE_FILE_HEADER ifh = IMAGE_FILE_HEADER.Deserialize(inputFile); IMAGE_OPTIONAL_HEADER ioh = IMAGE_OPTIONAL_HEADER.Deserialize(inputFile); // Read sections until we have the ones we need IMAGE_SECTION_HEADER temp = null; IMAGE_SECTION_HEADER resource = null; for (int i = 0; i < ifh.NumberOfSections; i++) { IMAGE_SECTION_HEADER sectionHeader = IMAGE_SECTION_HEADER.Deserialize(inputFile); string headerName = Encoding.ASCII.GetString(sectionHeader.Name, 0, 8); // .text if (headerName.StartsWith(".text")) { currentFormat.CodeSectionLength = sectionHeader.VirtualSize; } // .rdata else if (headerName.StartsWith(".rdata")) { // No-op } // .data else if (headerName.StartsWith(".data")) { currentFormat.DataSectionLength = sectionHeader.VirtualSize; if ((ifh.Characteristics & (1 << 0)) == 0) { temp = sectionHeader; } } // .rsrc else if (headerName.StartsWith(".rsrc")) { resource = sectionHeader; if ((ifh.Characteristics & (1 << 0)) != 0) { temp = sectionHeader; } } } // the unpacker of the self-extractor does not use any resource functions either. if (temp.SizeOfRawData > 20000) { for (int f = 0; f <= 20000 - 0x80; f++) { inputFile.Seek(dataBase + temp.PointerToRawData + f); IMAGE_DOS_HEADER exeHdr = IMAGE_DOS_HEADER.Deserialize(inputFile); if ((exeHdr.Magic == Constants.IMAGE_NT_SIGNATURE || exeHdr.Magic == Constants.IMAGE_DOS_SIGNATURE) && exeHdr.HeaderParagraphSize >= 4 && exeHdr.NewExeHeaderAddr >= 0x40 && (exeHdr.Relocations == 0 || exeHdr.Relocations == 3)) { currentFormat.ExecutableOffset = (int)temp.PointerToRawData + f; fileEnd = (int)(dataBase + temp.PointerToRawData + ioh.DataDirectory[2].Size); searchAgainAtEnd = true; break; } } } currentFormat.ExecutableOffset = (int)(resource.PointerToRawData + resource.SizeOfRawData); return(ExecutableType.PE); }