Inheritance: Mono.Cecil.PE.BinaryStreamReader
Example #1
1
        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 "???";
            }
              }
        }
Example #2
0
 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);
     }
 }
Example #3
0
 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);
     }
 }
Example #4
0
        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);
        }