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; } } }
public static Metadata Read(string filePath) { using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); var dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); var fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); var is32bit = (fileHeader.Machine == 332); uint vaddr = 0; uint cbDebug = 0; if (is32bit) { var optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); cbDebug = optionalHeader32.Debug.Size; vaddr = optionalHeader32.Debug.VirtualAddress; } else { var optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); cbDebug = optionalHeader64.Debug.Size; vaddr = optionalHeader64.Debug.VirtualAddress; } uint offDebug = 0; long cbFromHeader = 0; int loopexit = 0; var imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { var header = imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); if (header.PointerToRawData != 0 && header.SizeOfRawData != 0 && cbFromHeader < (long)(header.PointerToRawData + header.SizeOfRawData)) { cbFromHeader = (long)(header.PointerToRawData + header.SizeOfRawData); } if (cbDebug != 0) { if (header.VirtualAddress <= vaddr && (header.VirtualAddress + header.SizeOfRawData) > vaddr) { offDebug = vaddr - header.VirtualAddress + header.PointerToRawData; } } } stream.Seek(offDebug, SeekOrigin.Begin); IMAGE_DEBUG_DIRECTORY_RAW debugInfo = default(IMAGE_DEBUG_DIRECTORY_RAW); while (cbDebug >= Marshal.SizeOf(typeof(IMAGE_DEBUG_DIRECTORY))) { if (loopexit == 0) { var 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) { var name = new string(debugInfo.name); name = name.Remove(name.IndexOf("\0")); return(new Metadata() { PdbName = name, PdbAge = debugInfo.age.ToString("X"), DebugGUID = debugInfo.guid }); } } return(null); }