/// <summary>
        /// Reads a single resource directory from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the resource.</param>
        /// <param name="entry">The entry to read. If this value is <c>null</c>, the root directory is assumed.</param>
        /// <param name="directoryReader">The input stream.</param>
        /// <param name="depth">
        /// The current depth of the resource directory tree structure.
        /// If this value exceeds <see cref="MaxDepth"/>, this class will not initialize any entries.
        /// </param>
        public SerializedResourceDirectory(IPEFile peFile, ResourceDirectoryEntry?entry,
                                           IBinaryStreamReader directoryReader, int depth = 0)
        {
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));

            _depth = depth;

            if (entry.HasValue)
            {
                var value = entry.Value;
                if (value.IsByName)
                {
                    Name = value.Name;
                }
                else
                {
                    Id = value.IdOrNameOffset;
                }
            }

            if (directoryReader != null)
            {
                Characteristics = directoryReader.ReadUInt32();
                TimeDateStamp   = directoryReader.ReadUInt32();
                MajorVersion    = directoryReader.ReadUInt16();
                MinorVersion    = directoryReader.ReadUInt16();

                _namedEntries = directoryReader.ReadUInt16();
                _idEntries    = directoryReader.ReadUInt16();
                _entriesRva   = directoryReader.Rva;

                directoryReader.Offset =
                    (directoryReader.Offset + (ulong)((_namedEntries + _idEntries) * ResourceDirectoryEntry.EntrySize));
            }
        }
        /// <summary>
        /// Reads a .NET directory from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the .NET directory.</param>
        /// <param name="reader">The input stream.</param>
        /// <param name="metadataStreamReader"></param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        public SerializedDotNetDirectory(IPEFile peFile, IBinaryStreamReader reader,
                                         IMetadataStreamReader metadataStreamReader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));
            _metadataStreamReader = metadataStreamReader;

            Offset = reader.Offset;

            uint cb = reader.ReadUInt32();

            MajorRuntimeVersion = reader.ReadUInt16();
            MinorRuntimeVersion = reader.ReadUInt16();
            _metadataDirectory  = DataDirectory.FromReader(reader);
            Flags                  = (DotNetDirectoryFlags)reader.ReadUInt32();
            Entrypoint             = reader.ReadUInt32();
            _resourcesDirectory    = DataDirectory.FromReader(reader);
            _strongNameDirectory   = DataDirectory.FromReader(reader);
            _codeManagerDirectory  = DataDirectory.FromReader(reader);
            _vtableFixupsDirectory = DataDirectory.FromReader(reader);
            _exportsDirectory      = DataDirectory.FromReader(reader);
            _nativeHeaderDirectory = DataDirectory.FromReader(reader);
        }
        private byte[] GetHashToSign(
            Stream imageStream,
            IPEFile file,
            IPEImage image,
            AssemblyHashAlgorithm hashAlgorithm)
        {
            var hashBuilder = new StrongNameDataHashBuilder(imageStream, hashAlgorithm);

            // Include DOS, NT and section headers in the hash.
            hashBuilder.IncludeRange(new OffsetRange(0,
                                                     (uint)(file.DosHeader.GetPhysicalSize()
                                                            + sizeof(uint)
                                                            + file.FileHeader.GetPhysicalSize()
                                                            + file.OptionalHeader.GetPhysicalSize()
                                                            + file.Sections.Count * SectionHeader.SectionHeaderSize)));

            // Include section data.
            foreach (var section in file.Sections)
            {
                hashBuilder.IncludeRange(new OffsetRange(
                                             section.Offset,
                                             section.Offset + section.GetPhysicalSize()));
            }

            // Zero checksum in optional header.
            ulong peChecksumOffset = file.OptionalHeader.Offset + 0x40;

            hashBuilder.ZeroRange(new OffsetRange(peChecksumOffset, peChecksumOffset + sizeof(uint)));

            // Zero certificate directory entry.
            uint optionalHeaderSize = file.OptionalHeader.Magic == OptionalHeaderMagic.Pe32
                ? OptionalHeader.OptionalHeader32SizeExcludingDataDirectories
                : OptionalHeader.OptionalHeader64SizeExcludingDataDirectories;
            ulong certificateEntryOffset = file.OptionalHeader.Offset
                                           + optionalHeaderSize
                                           + (int)DataDirectoryIndex.CertificateDirectory * DataDirectory.DataDirectorySize;

            hashBuilder.ZeroRange(new OffsetRange(certificateEntryOffset, certificateEntryOffset + DataDirectory.DataDirectorySize));

            // Exclude certificate directory contents.
            var certificateDirectory = file.OptionalHeader.GetDataDirectory(DataDirectoryIndex.CertificateDirectory);

            if (certificateDirectory.IsPresentInPE)
            {
                ulong offset = file.RvaToFileOffset(certificateDirectory.VirtualAddress);
                hashBuilder.ExcludeRange(new OffsetRange(offset, offset + certificateDirectory.Size));
            }

            // Exclude strong name directory.
            var strongNameDirectory = image.DotNetDirectory.StrongName;

            hashBuilder.ExcludeRange(new OffsetRange(
                                         strongNameDirectory.Offset,
                                         strongNameDirectory.Offset + strongNameDirectory.GetPhysicalSize()));

            return(hashBuilder.ComputeHash());
        }
        /// <summary>
        /// Opens a PE image from a file.
        /// </summary>
        /// <param name="peFile">The file to base the image from.</param>
        /// <param name="readParameters">The parameters to use while reading the PE image.</param>
        public SerializedPEImage(IPEFile peFile, PEReadParameters readParameters)
        {
            PEFile         = peFile ?? throw new ArgumentNullException(nameof(peFile));
            ReadParameters = readParameters;

            MachineType        = PEFile.FileHeader.Machine;
            Characteristics    = PEFile.FileHeader.Characteristics;
            TimeDateStamp      = new DateTime(1970, 1, 1) + TimeSpan.FromSeconds(peFile.FileHeader.TimeDateStamp);
            PEKind             = PEFile.OptionalHeader.Magic;
            SubSystem          = PEFile.OptionalHeader.SubSystem;
            DllCharacteristics = PEFile.OptionalHeader.DllCharacteristics;
            ImageBase          = PEFile.OptionalHeader.ImageBase;
        }
        /// <summary>
        /// Reads a resource data entry from the provided input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the resource.</param>
        /// <param name="entry">The entry to read.</param>
        /// <param name="entryReader">The input stream to read the data from.</param>
        public SerializedResourceData(IPEFile peFile, ResourceDirectoryEntry entry, IBinaryStreamReader entryReader)
        {
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));

            if (entry.IsByName)
            {
                Name = entry.Name;
            }
            else
            {
                Id = entry.IdOrNameOffset;
            }

            _contentsRva  = entryReader.ReadUInt32();
            _contentsSize = entryReader.ReadUInt32();
            CodePage      = entryReader.ReadUInt32();
        }
Beispiel #6
0
        /// <summary>
        /// Reads a module import entry from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the module import.</param>
        /// <param name="reader">The input stream.</param>
        public SerializedImportedModule(IPEFile peFile, IBinaryStreamReader reader)
        {
            _peFile        = peFile;
            _lookupRva     = reader.ReadUInt32();
            TimeDateStamp  = reader.ReadUInt32();
            ForwarderChain = reader.ReadUInt32();
            uint nameRva = reader.ReadUInt32();

            if (nameRva != 0)
            {
                if (_peFile.TryCreateReaderAtRva(nameRva, out var nameReader))
                {
                    Name = nameReader.ReadAsciiString();
                }
            }

            _addressRva = reader.ReadUInt32();
        }
Beispiel #7
0
        private static void TryInitializePEFiles(GFXTypes file, IPEFile peFile)
        {
            var number = ((int)file).ToString("D3");

            try
            {
                peFile.Initialize();
            }
            catch (IOException)
            {
                throw new LibraryLoadException(number, file);
            }

            if (!peFile.Initialized)
            {
                throw new LibraryLoadException(number, file);
            }
        }
        /// <summary>
        /// Reads a single export directory from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the export directory.</param>
        /// <param name="reader">The input stream.</param>
        public SerializedExportDirectory(IPEFile peFile, IBinaryStreamReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));

            ExportFlags        = reader.ReadUInt32();
            TimeDateStamp      = reader.ReadUInt32();
            MajorVersion       = reader.ReadUInt16();
            MinorVersion       = reader.ReadUInt16();
            _nameRva           = reader.ReadUInt32();
            BaseOrdinal        = reader.ReadUInt32();
            _numberOfFunctions = reader.ReadUInt32();
            _numberOfNames     = reader.ReadUInt32();
            _addressTableRva   = reader.ReadUInt32();
            _namePointerRva    = reader.ReadUInt32();
            _ordinalTableRva   = reader.ReadUInt32();
        }
Beispiel #9
0
        /// <summary>
        /// Reads a new resource directory entry from the reader.
        /// </summary>
        /// <param name="peFile">The containing PE file.</param>
        /// <param name="reader">The input stream to read from.</param>
        public ResourceDirectoryEntry(IPEFile peFile, IBinaryStreamReader reader)
        {
            _idOrNameOffset     = reader.ReadUInt32();
            _dataOrSubDirOffset = reader.ReadUInt32();
            Name = null;

            if (IsByName)
            {
                uint baseRva = peFile.OptionalHeader
                               .GetDataDirectory(DataDirectoryIndex.ResourceDirectory)
                               .VirtualAddress;

                if (peFile.TryCreateReaderAtRva(baseRva + IdOrNameOffset, out var nameReader))
                {
                    int length = nameReader.ReadUInt16() * 2;
                    var data   = new byte[length];
                    length = nameReader.ReadBytes(data, 0, length);

                    Name = Encoding.Unicode.GetString(data, 0, length);
                }
            }
        }
Beispiel #10
0
 /// <summary>
 /// Prepares a new lazy-initialized list of base relocations.
 /// </summary>
 /// <param name="peFile">The PE file to read the base relocations from.</param>
 /// <param name="relocDirectory">The directory that contains the base relocations.</param>
 public SerializedRelocationList(IPEFile peFile, DataDirectory relocDirectory)
 {
     _peFile         = peFile;
     _relocDirectory = relocDirectory;
 }
Beispiel #11
0
 /// <summary>
 /// Reads a .NET module from the provided input file.
 /// </summary>
 /// <param name="file">The portable executable file to load.</param>
 /// <returns>The module.</returns>
 /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET metadata directory.</exception>
 public static ModuleDefinition FromFile(IPEFile file) =>
 FromImage(PEImage.FromFile(file));
Beispiel #12
0
 /// <summary>
 /// Reads a .NET module from the provided input file.
 /// </summary>
 /// <param name="file">The portable executable file to load.</param>
 /// <param name="readerParameters">The parameters to use while reading the module.</param>
 /// <returns>The module.</returns>
 /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET metadata directory.</exception>
 public static ModuleDefinition FromFile(IPEFile file, ModuleReaderParameters readerParameters) =>
 FromImage(PEImage.FromFile(file), readerParameters);
 /// <summary>
 /// Opens a PE image from a PE file object.
 /// </summary>
 /// <param name="peFile">The PE file object.</param>
 /// <returns>The PE image that was opened.</returns>
 /// <exception cref="BadImageFormatException">Occurs when the file does not follow the PE file format.</exception>
 public static IPEImage FromFile(IPEFile peFile) => FromFile(peFile, CreateDefaultReadParameters(peFile));
 private static PEReadParameters CreateDefaultReadParameters(IPEFile peFile) => new PEReadParameters(peFile);
 /// <summary>
 /// Opens a PE image from a PE file object.
 /// </summary>
 /// <param name="peFile">The PE file object.</param>
 /// <param name="readParameters">The parameters to use while reading the PE image.</param>
 /// <returns>The PE image that was opened.</returns>
 /// <exception cref="BadImageFormatException">Occurs when the file does not follow the PE file format.</exception>
 public static IPEImage FromFile(IPEFile peFile, PEReadParameters readParameters) =>
 new SerializedPEImage(peFile, readParameters);
Beispiel #16
0
 /// <summary>
 /// Creates a new PE reference.
 /// </summary>
 /// <param name="peFile">The underlying PE file.</param>
 /// <param name="rva">The virtual address of the segment.</param>
 internal PESegmentReference(IPEFile peFile, uint rva)
 {
     _peFile = peFile;
     Rva     = rva;
 }
        /// <summary>
        /// Reads a single module import entry from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the import entry.</param>
        /// <param name="reader">The input stream.</param>
        /// <returns></returns>
        public static IImportedModule FromReader(IPEFile peFile, IBinaryStreamReader reader)
        {
            var entry = new SerializedImportedModule(peFile, reader);

            return(entry.IsEmpty ? null : entry);
        }
Beispiel #18
0
 /// <summary>
 /// Creates a new instance of the <see cref="PEReaderContext"/> class.
 /// </summary>
 /// <param name="file">The original PE file.</param>
 /// <param name="parameters">The reader parameters.</param>
 public PEReaderContext(IPEFile file, PEReaderParameters parameters)
 {
     File       = file;
     Parameters = parameters;
 }
Beispiel #19
0
 /// <summary>
 /// Creates a new instance of the <see cref="PEReaderContext"/> class.
 /// </summary>
 /// <param name="file">The original PE file.</param>
 public PEReaderContext(IPEFile file)
     : this(file, new PEReaderParameters())
 {
 }
Beispiel #20
0
 /// <summary>
 /// Opens a PE image from a PE file object.
 /// </summary>
 /// <param name="peFile">The PE file object.</param>
 /// <returns>The PE image that was opened.</returns>
 /// <exception cref="BadImageFormatException">Occurs when the file does not follow the PE file format.</exception>
 public static IPEImage FromFile(IPEFile peFile) => FromFile(peFile, new PEReaderParameters());
 /// <summary>
 /// Prepares a new lazy-initialized list of module import entries.
 /// </summary>
 /// <param name="peFile">The PE file containing the list of modules.</param>
 /// <param name="dataDirectory">The import data directory.</param>
 public SerializedImportedModuleList(IPEFile peFile, DataDirectory dataDirectory)
 {
     _peFile        = peFile ?? throw new ArgumentNullException(nameof(peFile));
     _dataDirectory = dataDirectory;
 }