public static string DescribeAssemblyRuntime(string assemblyFile) { using (Stream stream = File.OpenRead(assemblyFile)) { try { var reader = new ImageReader(stream); reader.ReadImage(); Image img = reader.Image; var sb = new StringBuilder(); sb.Append(img.Runtime); sb.Append(", "); if (img.Architecture == TargetArchitecture.AMD64 || img.Architecture == TargetArchitecture.IA64) { sb.Append("x64"); } else if ((img.Attributes & ModuleAttributes.Required32Bit) != 0) { sb.Append("x86"); } else { sb.Append("MSIL"); } return sb.ToString(); } catch (Exception e) { return "???"; } } }
public static Image ReadImageFrom(Stream stream) { try { var reader = new ImageReader (stream); reader.ReadImage (); return reader.image; } catch (EndOfStreamException e) { throw new BadImageFormatException (stream.GetFullyQualifiedName (), e); } }
public static Image ReadImage(Disposable<Stream> stream, string file_name) { try { var reader = new ImageReader (stream, file_name); reader.ReadImage (); return reader.image; } catch (EndOfStreamException e) { throw new BadImageFormatException (stream.value.GetFileName (), e); } }
public static Image ReadPortablePdb(Disposable<Stream> stream, string file_name) { try { var reader = new ImageReader (stream, file_name); var length = (uint) stream.value.Length; reader.image.Sections = new[] { new Section { PointerToRawData = 0, SizeOfRawData = length, VirtualAddress = 0, VirtualSize = length, } }; reader.metadata = new DataDirectory (0, length); reader.ReadMetadata (); return reader.image; } catch (EndOfStreamException e) { throw new BadImageFormatException (stream.value.GetFileName (), e); } }
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); }