/// <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)); }
/// <summary> /// For side by side dlls, the manifest that decribes the binding information is stored as the RT_MANIFEST resource, and it /// is an XML string. This routine returns this. /// </summary> /// <returns></returns> public string GetSxSManfest() { ResourceNode resources = GetResources(); ResourceNode manifest = ResourceNode.GetChild(ResourceNode.GetChild(resources, "RT_MANIFEST"), "1"); if (manifest == null) { return(null); } if (!manifest.IsLeaf && manifest.Children.Count == 1) { manifest = manifest.Children[0]; } PEBuffer buff = AllocBuff(); byte * bytes = manifest.FetchData(0, manifest.DataLength, buff); string ret = null; using (UnmanagedMemoryStream stream = new UnmanagedMemoryStream(bytes, manifest.DataLength)) using (StreamReader textReader = new StreamReader(stream)) ret = textReader.ReadToEnd(); FreeBuff(buff); return(ret); }
public FileVersionInfo GetFileVersionInfo() { PEBuffer buff = _file.AllocBuff(); byte * bytes = FetchData(0, DataLength, buff); FileVersionInfo ret = new FileVersionInfo(bytes, DataLength); _file.FreeBuff(buff); return(ret); }
/// <summary> /// Parses a PEFile from a given stream. If it is valid, a new PEFile object is /// constructed and returned. Otherwise, null is returned. /// </summary> public static PEFile TryLoad(Stream stream, bool virt) { PEBuffer headerBuff = new PEBuffer(stream); PEHeader hdr = PEHeader.FromBuffer(headerBuff, virt); if (hdr == null) return null; PEFile pefile = new PEFile(); pefile.Init(stream, "stream", virt, headerBuff, hdr); return pefile; }
internal PEBuffer AllocBuff() { PEBuffer ret = _freeBuff; if (ret == null) { return(new PEBuffer(_stream)); } _freeBuff = null; return(ret); }
/// <summary> /// Looks up the debug signature information in the EXE. Returns true and sets the parameters if it is found. /// If 'first' is true then the first entry is returned, otherwise (by default) the last entry is used /// (this is what debuggers do today). Thus NGEN images put the IL PDB last (which means debuggers /// pick up that one), but we can set it to 'first' if we want the NGEN PDB. /// </summary> public bool GetPdbSignature(out string pdbName, out Guid pdbGuid, out int pdbAge, bool first = false) { pdbName = null; pdbGuid = Guid.Empty; pdbAge = 0; bool ret = false; if (Header == null) { return(false); } if (Header.DebugDirectory.VirtualAddress != 0) { PEBuffer buff = AllocBuff(); IMAGE_DEBUG_DIRECTORY *debugEntries = (IMAGE_DEBUG_DIRECTORY *)FetchRVA((int)Header.DebugDirectory.VirtualAddress, (int)Header.DebugDirectory.Size, buff); if (Header.DebugDirectory.Size % sizeof(IMAGE_DEBUG_DIRECTORY) != 0) { return(false); } int debugCount = (int)Header.DebugDirectory.Size / sizeof(IMAGE_DEBUG_DIRECTORY); for (int i = 0; i < debugCount; i++) { if (debugEntries[i].Type == IMAGE_DEBUG_TYPE.CODEVIEW) { PEBuffer stringBuff = AllocBuff(); int ptr = _virt ? debugEntries[i].AddressOfRawData : debugEntries[i].PointerToRawData; CV_INFO_PDB70 *info = (CV_INFO_PDB70 *)stringBuff.Fetch(ptr, debugEntries[i].SizeOfData); if (info->CvSignature == CV_INFO_PDB70.PDB70CvSignature) { // If there are several this picks the last one. pdbGuid = info->Signature; pdbAge = info->Age; pdbName = info->PdbFileName; ret = true; if (first) { break; } } FreeBuff(stringBuff); } } FreeBuff(buff); } return(ret); }
private void Init(Stream stream, string filePath, bool virt) { m_virt = virt; m_stream = stream; m_headerBuff = new PEBuffer(m_stream); Header = new PEHeader(m_headerBuff.Fetch(0, 512), virt); // We did not read in the complete header, Try again using the right sized buffer. if (Header.PEHeaderSize > m_headerBuff.Length) Header = new PEHeader(m_headerBuff.Fetch(0, Header.PEHeaderSize), virt); if (Header.PEHeaderSize > m_headerBuff.Length) throw new InvalidOperationException("Bad PE Header in " + filePath); }
private void Init(Stream stream, string filePath, bool virt, PEBuffer buffer = null, PEHeader header = null) { if (buffer == null) buffer = new PEBuffer(stream); if (header == null) header = PEHeader.FromBuffer(buffer, virt); _virt = virt; _stream = stream; _headerBuff = buffer; Header = header; if (header != null && header.PEHeaderSize > _headerBuff.Length) throw new InvalidOperationException("Bad PE Header in " + filePath); }
private PEHeader(PEBuffer buffer, bool virt) { _virt = virt; byte *ptr = buffer.Fetch(0, 0x300); _dosHeader = (IMAGE_DOS_HEADER *)ptr; _ntHeader = (IMAGE_NT_HEADERS *)(ptr + _dosHeader->e_lfanew); _sections = (IMAGE_SECTION_HEADER *)((byte *)_ntHeader + sizeof(IMAGE_NT_HEADERS) + _ntHeader->FileHeader.SizeOfOptionalHeader); if (buffer.Length < PEHeaderSize) { throw new BadImageFormatException(); } }
/// <summary> /// Parses a PEFile from a given stream. If it is valid, a new PEFile object is /// constructed and returned. Otherwise, null is returned. /// </summary> public static PEFile TryLoad(Stream stream, bool virt) { PEBuffer headerBuff = new PEBuffer(stream); PEHeader hdr = PEHeader.FromBuffer(headerBuff, virt); if (hdr == null) { return(null); } PEFile pefile = new PEFile(); pefile.Init(stream, "stream", virt, headerBuff, hdr); return(pefile); }
internal ResourceNode(string name, int nodeFileOffset, PEFile file, bool isLeaf, bool isTop = false) { _file = file; _nodeFileOffset = nodeFileOffset; _isTop = isTop; IsLeaf = isLeaf; Name = name; if (isLeaf) { PEBuffer buff = _file.AllocBuff(); IMAGE_RESOURCE_DATA_ENTRY *dataDescr = (IMAGE_RESOURCE_DATA_ENTRY *)buff.Fetch(nodeFileOffset, sizeof(IMAGE_RESOURCE_DATA_ENTRY)); DataLength = dataDescr->Size; _dataFileOffset = file.Header.RvaToFileOffset(dataDescr->RvaToData); byte *data = FetchData(0, DataLength, buff); _file.FreeBuff(buff); } }
private void Init(Stream stream, string filePath, bool virt, PEBuffer buffer = null, PEHeader header = null) { if (buffer == null) { buffer = new PEBuffer(stream); } if (header == null) { header = PEHeader.FromBuffer(buffer, virt); } _virt = virt; _stream = stream; _headerBuff = buffer; Header = header; if (header != null && header.PEHeaderSize > _headerBuff.Length) { throw new InvalidOperationException("Bad PE Header in " + filePath); } }
/// <summary> /// Gets the File Version Information that is stored as a resource in the PE file. (This is what the /// version tab a file's property page is populated with). /// </summary> public FileVersionInfo GetFileVersionInfo() { ResourceNode resources = GetResources(); ResourceNode versionNode = ResourceNode.GetChild(ResourceNode.GetChild(resources, "Version"), "1"); if (versionNode == null) { return(null); } if (!versionNode.IsLeaf && versionNode.Children.Count == 1) { versionNode = versionNode.Children[0]; } PEBuffer buff = AllocBuff(); byte * bytes = versionNode.FetchData(0, versionNode.DataLength, buff); FileVersionInfo ret = new FileVersionInfo(bytes, versionNode.DataLength); FreeBuff(buff); return(ret); }
internal PEBuffer AllocBuff() { var ret = _freeBuff; if (ret == null) return new PEBuffer(_stream); _freeBuff = null; return ret; }
internal void FreeBuff(PEBuffer buffer) { _freeBuff = buffer; }
internal unsafe string GetName(PEBuffer buff, int resourceStartFileOffset) { if (IsStringName) { int nameLen = *((ushort*)buff.Fetch(NameOffset + resourceStartFileOffset, 2)); char* namePtr = (char*)buff.Fetch(NameOffset + resourceStartFileOffset + 2, nameLen); return new string(namePtr); } else return Id.ToString(); }
internal IntPtr SafeFetchRVA(int rva, int size, PEBuffer buffer) { return(new IntPtr(FetchRVA(rva, size, buffer))); }
internal byte *FetchRVA(int rva, int size, PEBuffer buffer) { int offset = Header.RvaToFileOffset(rva); return(buffer.Fetch(offset, size)); }
internal byte* FetchRVA(int rva, int size, PEBuffer buffer) { int offset = Header.RvaToFileOffset(rva); return buffer.Fetch(offset, size); }
/// <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); var 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); }
internal IntPtr SafeFetchRVA(int rva, int size, PEBuffer buffer) { return new IntPtr(FetchRVA(rva, size, buffer)); }
public byte* FetchData(int offsetInResourceData, int size, PEBuffer buff) { return buff.Fetch(_dataFileOffset + offsetInResourceData, size); }
public byte *FetchData(int offsetInResourceData, int size, PEBuffer buff) { return(buff.Fetch(_dataFileOffset + offsetInResourceData, size)); }
private PEHeader(PEBuffer buffer, bool virt) { _virt = virt; byte* ptr = buffer.Fetch(0, 0x300); _dosHeader = (IMAGE_DOS_HEADER*)ptr; _ntHeader = (IMAGE_NT_HEADERS*)((byte*)ptr + _dosHeader->e_lfanew); _sections = (IMAGE_SECTION_HEADER*)(((byte*)_ntHeader) + sizeof(IMAGE_NT_HEADERS) + _ntHeader->FileHeader.SizeOfOptionalHeader); if (buffer.Length < PEHeaderSize) throw new BadImageFormatException(); }