private CorFlagsReader(ushort majorRuntimeVersion, ushort minorRuntimeVersion, CorFlags corflags, PEFormat peFormat) { this.majorRuntimeVersion = majorRuntimeVersion; this.minorRuntimeVersion = minorRuntimeVersion; this.corflags = corflags; this.peFormat = peFormat; }
public void Load(Stream stream) { ILibraryFormat baseFormat; if ((baseFormat = new IconFormat()).IsRecognizedFormat(stream)) { if (mSelectedIndex == -1) { this.Clear(); this.Add(baseFormat.Load(stream)[0]); this[0].Name = "Untitled"; } else { string currentName = this[mSelectedIndex].Name; this[mSelectedIndex] = baseFormat.Load(stream)[0]; this[mSelectedIndex].Name = currentName; } } else if ((baseFormat = new NEFormat()).IsRecognizedFormat(stream)) { CopyFrom(baseFormat.Load(stream)); } else if ((baseFormat = new PEFormat()).IsRecognizedFormat(stream)) { CopyFrom(baseFormat.Load(stream)); } else { throw new InvalidFileException(); } SelectedIndex = Count > 0 ? 0 : -1; }
private AssemblyMetadata(ushort majorRuntimeVersion, ushort minorRuntimeVersion, CorFlags corflags, PEFormat peFormat, AssemblyName assemblyName, IList <AssemblyName> assemblyReferences, string runtimeVersion) { this.majorRuntimeVersion = majorRuntimeVersion; this.minorRuntimeVersion = minorRuntimeVersion; this.corflags = corflags; this.peFormat = peFormat; this.assemblyName = assemblyName; this.assemblyReferences = assemblyReferences; this.runtimeVersion = runtimeVersion; }
private AssemblyMetadata(ushort majorRuntimeVersion, ushort minorRuntimeVersion, CorFlags corflags, PEFormat peFormat, AssemblyName assemblyName, IList<AssemblyName> assemblyReferences, string runtimeVersion) { this.majorRuntimeVersion = majorRuntimeVersion; this.minorRuntimeVersion = minorRuntimeVersion; this.corflags = corflags; this.peFormat = peFormat; this.assemblyName = assemblyName; this.assemblyReferences = assemblyReferences; this.runtimeVersion = runtimeVersion; }
public static PEFormat GetPEFormat(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } long length = stream.Length; if (length < 0x40) { return(PEFormat.UNKNOWN); } BinaryReader reader = new BinaryReader(stream); // Read the pointer to the PE header. stream.Position = 0x3c; uint peHeaderPtr = reader.ReadUInt32(); if (peHeaderPtr == 0) { peHeaderPtr = 0x80; } if (peHeaderPtr > length - 256) { return(PEFormat.UNKNOWN); } // Check the PE signature. Should equal 'PE\0\0'. stream.Position = peHeaderPtr; uint peSignature = reader.ReadUInt32(); if (peSignature != 0x00004550) { return(PEFormat.UNKNOWN); } // Read PE header stream point for (int i = 0; i < 5; i++) { reader.ReadUInt32(); } // Read PE magic number from Standard Fields to determine format. PEFormat p = (PEFormat)reader.ReadUInt16(); return(p); }
public IMAGE_NT_HEADERS(BinaryReader reader) { IMAGE_NT_HEADERS hdr = new IMAGE_NT_HEADERS(); this = hdr; byte[] buffer = new byte[Marshal.SizeOf(this)]; reader.Read(buffer, 0, buffer.Length); hdr = buffer.ToStructure <IMAGE_NT_HEADERS>(); Extensions.Int64Words w = hdr.OptionalHeader.ToInt64().GetWords(); PEFormat _magic = (PEFormat)w.Word0; reader.BaseStream.Position -= (Marshal.SizeOf(new IntPtr()) + sizeof(PEFormat)); // Correct the position of the Stream for continued reading switch (_magic) { case PEFormat.PE32: buffer = new byte[Marshal.SizeOf(new IMAGE_OPTIONAL_HEADER32())]; GCHandle handle32 = GCHandle.Alloc(buffer, GCHandleType.Pinned); reader.Read(buffer, 0, buffer.Length); hdr.OptionalHeader = handle32.AddrOfPinnedObject(); handle32.Free(); // hopefully this is right hdr.Magic = PEFormat.PE32; break; case PEFormat.PE32plus: buffer = new byte[Marshal.SizeOf(new IMAGE_OPTIONAL_HEADER64())]; GCHandle handle64 = GCHandle.Alloc(buffer, GCHandleType.Pinned); reader.Read(buffer, 0, buffer.Length); hdr.OptionalHeader = handle64.AddrOfPinnedObject(); handle64.Free(); // hopefully this is right hdr.Magic = PEFormat.PE32plus; break; default: break; } this = hdr; }
internal static AssemblyMetadata ReadAssemblyMetadata(Stream stream, AssemblyMetadataFields fields) { long length = stream.Length; if (length < 0x40) { return(null); } BinaryReader reader = new BinaryReader(stream); // Read the pointer to the PE header. stream.Position = 0x3c; uint peHeaderPtr = reader.ReadUInt32(); if (peHeaderPtr == 0) { peHeaderPtr = 0x80; } // Ensure there is at least enough room for the following structures: // 24 byte PE Signature & Header // 28 byte Standard Fields (24 bytes for PE32+) // 68 byte NT Fields (88 bytes for PE32+) // >= 128 byte Data Dictionary Table if (peHeaderPtr > length - 256) { return(null); } // Check the PE signature. Should equal 'PE\0\0'. stream.Position = peHeaderPtr; uint peSignature = reader.ReadUInt32(); if (peSignature != 0x00004550) { return(null); } // Read PE header fields. ushort machine = reader.ReadUInt16(); ushort numberOfSections = reader.ReadUInt16(); uint timeStamp = reader.ReadUInt32(); uint symbolTablePtr = reader.ReadUInt32(); uint numberOfSymbols = reader.ReadUInt32(); ushort optionalHeaderSize = reader.ReadUInt16(); ushort characteristics = reader.ReadUInt16(); // Read PE magic number from Standard Fields to determine format. PEFormat peFormat = (PEFormat)reader.ReadUInt16(); if (peFormat != PEFormat.PE32 && peFormat != PEFormat.PE32Plus) { return(null); } // Read the 15th Data Dictionary RVA field which contains the CLI header RVA. // When this is non-zero then the file contains CLI data otherwise not. stream.Position = peHeaderPtr + (peFormat == PEFormat.PE32 ? 232 : 248); uint cliHeaderRva = reader.ReadUInt32(); if (cliHeaderRva == 0) { return(null); } // Read section headers. Each one is 40 bytes. // 8 byte Name // 4 byte Virtual Size // 4 byte Virtual Address // 4 byte Data Size // 4 byte Data Pointer // ... total of 40 bytes uint sectionTablePtr = peHeaderPtr + 24 + optionalHeaderSize; Section[] sections = new Section[numberOfSections]; for (int i = 0; i < numberOfSections; i++) { stream.Position = sectionTablePtr + i * 40 + 8; Section section = new Section(); section.VirtualSize = reader.ReadUInt32(); section.VirtualAddress = reader.ReadUInt32(); reader.ReadUInt32(); section.Pointer = reader.ReadUInt32(); sections[i] = section; } // Read parts of the CLI header. uint cliHeaderPtr = ResolveRva(sections, cliHeaderRva); if (cliHeaderPtr == 0) { return(null); } stream.Position = cliHeaderPtr + 4; ushort majorRuntimeVersion = reader.ReadUInt16(); ushort minorRuntimeVersion = reader.ReadUInt16(); uint metadataRva = reader.ReadUInt32(); uint metadataSize = reader.ReadUInt32(); CorFlags corflags = (CorFlags)reader.ReadUInt32(); // Read optional fields. AssemblyName assemblyName = null; IList <AssemblyName> assemblyReferences = null; string runtimeVersion = null; if ((fields & AssemblyMetadataFields.RuntimeVersion) != 0) { uint metadataPtr = ResolveRva(sections, metadataRva); stream.Position = metadataPtr + 12; int paddedRuntimeVersionLength = reader.ReadInt32(); byte[] runtimeVersionBytes = reader.ReadBytes(paddedRuntimeVersionLength); int runtimeVersionLength = 0; while (runtimeVersionLength < paddedRuntimeVersionLength && runtimeVersionBytes[runtimeVersionLength] != 0) { runtimeVersionLength += 1; } runtimeVersion = Encoding.UTF8.GetString(runtimeVersionBytes, 0, runtimeVersionLength); } if ((fields & (AssemblyMetadataFields.AssemblyName | AssemblyMetadataFields.AssemblyReferences)) != 0) { // Using Cecil. stream.Position = 0; var imageReader = new ImageReader(stream); if ((fields & AssemblyMetadataFields.AssemblyName) != 0) { assemblyName = imageReader.GetAssemblyName(); } if ((fields & AssemblyMetadataFields.AssemblyReferences) != 0) { assemblyReferences = imageReader.GetAssemblyReferences(); } } // Done. return(new AssemblyMetadata(majorRuntimeVersion, minorRuntimeVersion, corflags, peFormat, assemblyName, assemblyReferences, runtimeVersion)); }
private CorFlagsReader(ushort majorRuntimeVersion, ushort minorRuntimeVersion, CorFlags corflags, PEFormat peFormat) { MajorRuntimeVersion = majorRuntimeVersion; MinorRuntimeVersion = minorRuntimeVersion; IsPureIL = (corflags & CorFlags.ILOnly) == CorFlags.ILOnly; Is32BitReq = (corflags & CorFlags.Requires32Bit) == CorFlags.Requires32Bit; Is32BitPref = (corflags & CorFlags.Prefers32Bit) == CorFlags.Prefers32Bit; IsSigned = (corflags & CorFlags.StrongNameSigned) == CorFlags.StrongNameSigned; ProcessorArchitecture = peFormat == PEFormat.PE32Plus ? ProcessorArchitecture.Amd64 : (corflags & CorFlags.Requires32Bit) == CorFlags.Requires32Bit || !IsPureIL ? ProcessorArchitecture.X86 : ProcessorArchitecture.MSIL; }
/// <summary> /// Read the PE file /// </summary> /// <param name="stream">PE file stream to read from.</param> /// <returns>null if the PE file was not valid. /// an instance of the CorFlagsReader class containing the requested data.</returns> public static CorFlagsReader ReadAssemblyMetadata(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } long length = stream.Length; if (length < 0x40) { return(null); } BinaryReader reader = new BinaryReader(stream); // Read the pointer to the PE header. stream.Position = 0x3c; uint peHeaderPtr = reader.ReadUInt32(); if (peHeaderPtr == 0) { peHeaderPtr = 0x80; } // Ensure there is at least enough room for the following structures: // 24 byte PE Signature & Header // 28 byte Standard Fields (24 bytes for PE32+) // 68 byte NT Fields (88 bytes for PE32+) // >= 128 byte Data Dictionary Table if (peHeaderPtr > length - 256) { return(null); } // Check the PE signature. Should equal 'PE\0\0'. stream.Position = peHeaderPtr; uint peSignature = reader.ReadUInt32(); if (peSignature != 0x00004550) { return(null); } // Read PE header fields. ushort machine = reader.ReadUInt16(); ushort numberOfSections = reader.ReadUInt16(); uint timeStamp = reader.ReadUInt32(); uint symbolTablePtr = reader.ReadUInt32(); uint numberOfSymbols = reader.ReadUInt32(); ushort optionalHeaderSize = reader.ReadUInt16(); ushort characteristics = reader.ReadUInt16(); // Read PE magic number from Standard Fields to determine format. PEFormat peFormat = (PEFormat)reader.ReadUInt16(); if (peFormat != PEFormat.PE32 && peFormat != PEFormat.PE32Plus) { return(null); } // Read the 15th Data Dictionary RVA field which contains the CLI header RVA. // When this is non-zero then the file contains CLI data otherwise not. stream.Position = peHeaderPtr + (peFormat == PEFormat.PE32 ? 232 : 248); uint cliHeaderRva = reader.ReadUInt32(); if (cliHeaderRva == 0) { return(new CorFlagsReader(0, 0, 0, peFormat)); } // Read section headers. Each one is 40 bytes. // 8 byte Name // 4 byte Virtual Size // 4 byte Virtual Address // 4 byte Data Size // 4 byte Data Pointer // ... total of 40 bytes uint sectionTablePtr = peHeaderPtr + 24 + optionalHeaderSize; Section[] sections = new Section[numberOfSections]; for (int i = 0; i < numberOfSections; i++) { stream.Position = sectionTablePtr + i * 40 + 8; Section section = new Section(); section.VirtualSize = reader.ReadUInt32(); section.VirtualAddress = reader.ReadUInt32(); reader.ReadUInt32(); section.Pointer = reader.ReadUInt32(); sections[i] = section; } // Read parts of the CLI header. uint cliHeaderPtr = ResolveRva(sections, cliHeaderRva); if (cliHeaderPtr == 0) { return(null); } stream.Position = cliHeaderPtr + 4; ushort majorRuntimeVersion = reader.ReadUInt16(); ushort minorRuntimeVersion = reader.ReadUInt16(); uint metadataRva = reader.ReadUInt32(); uint metadataSize = reader.ReadUInt32(); CorFlags corflags = (CorFlags)reader.ReadUInt32(); // Done. return(new CorFlagsReader(majorRuntimeVersion, minorRuntimeVersion, corflags, peFormat)); }