// private MemoryBlock _win32ResourceBlock; private void ReadOptionalHeaderDirectoryEntries(MemoryReader memReader) { // ExportTableDirectory // ImportTableDirectory memReader.SeekRelative(2 * 2 * sizeof(uint)); _optionalHeaderDirectoryEntries.ResourceTableDirectory.RelativeVirtualAddress = memReader.ReadUInt32(); _optionalHeaderDirectoryEntries.ResourceTableDirectory.Size = memReader.ReadUInt32(); // ExceptionTableDirectory // CertificateTableDirectory // BaseRelocationTableDirectory // DebugTableDirectory // CopyrightTableDirectory // GlobalPointerTableDirectory // ThreadLocalStorageTableDirectory // LoadConfigTableDirectory // BoundImportTableDirectory // ImportAddressTableDirectory // DelayImportTableDirectory memReader.SeekRelative(11 * 2 * sizeof(uint)); _optionalHeaderDirectoryEntries.COR20HeaderTableDirectory.RelativeVirtualAddress = memReader.ReadUInt32(); _optionalHeaderDirectoryEntries.COR20HeaderTableDirectory.Size = memReader.ReadUInt32(); // ReservedDirectory memReader.SeekRelative(1 * 2 * sizeof(uint)); }
private void ReadSectionHeaders(MemoryReader memReader) { if (memReader.RemainingBytes < _numberOfSections * PEFileConstants.SizeofSectionHeader) { throw new BadImageFormatException(); } _sectionHeaders = new SectionHeader[_numberOfSections]; SectionHeader[] sectionHeaderArray = _sectionHeaders; for (int i = 0; i < _numberOfSections; i++) { memReader.SeekRelative(PEFileConstants.SizeofSectionName); sectionHeaderArray[i].VirtualSize = memReader.ReadUInt32(); sectionHeaderArray[i].VirtualAddress = memReader.ReadUInt32(); sectionHeaderArray[i].SizeOfRawData = memReader.ReadUInt32(); sectionHeaderArray[i].OffsetToRawData = memReader.ReadUInt32(); //sectionHeaderArray[i].RVAToRelocations = memReader.ReadInt32(); //sectionHeaderArray[i].PointerToLineNumbers = memReader.ReadInt32(); //sectionHeaderArray[i].NumberOfRelocations = memReader.ReadUInt16(); //sectionHeaderArray[i].NumberOfLineNumbers = memReader.ReadUInt16(); //sectionHeaderArray[i].SectionCharacteristics = (SectionCharacteristics)memReader.ReadUInt32(); memReader.SeekRelative(2 * sizeof(int) + 2 * sizeof(ushort) + sizeof(uint)); } }
private void ReadPEFileLevelData() { if (_image.Length < PEFileConstants.BasicPEHeaderSize) { throw new BadImageFormatException(); } MemoryReader memReader = new MemoryReader(_image); // Look for DOS Signature "MZ" ushort dosSig = _image.ReadUInt16(0); if (dosSig != PEFileConstants.DosSignature) { throw new BadImageFormatException(); } // Skip the DOS Header int ntHeaderOffset = _image.ReadInt32(PEFileConstants.PESignatureOffsetLocation); memReader.Seek(ntHeaderOffset); // Look for PESignature "PE\0\0" uint signature = memReader.ReadUInt32(); if (signature != PEFileConstants.PESignature) { throw new BadImageFormatException(); } // Read the COFF Header _numberOfSections = memReader.Block.ReadUInt16(memReader.Position + sizeof(ushort)); memReader.SeekRelative(PEFileConstants.SizeofCOFFFileHeader); // Read the magic to determine if its PE or PE+ switch ((PEMagic)memReader.ReadUInt16()) { case PEMagic.PEMagic32: memReader.SeekRelative(PEFileConstants.SizeofOptionalHeaderStandardFields32 - sizeof(ushort)); memReader.SeekRelative(PEFileConstants.SizeofOptionalHeaderNTAdditionalFields32); break; case PEMagic.PEMagic64: memReader.SeekRelative(PEFileConstants.SizeofOptionalHeaderStandardFields64 - sizeof(ushort)); memReader.SeekRelative(PEFileConstants.SizeofOptionalHeaderNTAdditionalFields64); break; default: throw new BadImageFormatException(); } ReadOptionalHeaderDirectoryEntries(memReader); ReadSectionHeaders(memReader); // _win32ResourceBlock = DirectoryToMemoryBlock(_optionalHeaderDirectoryEntries.ResourceTableDirectory); }
private void ReadMetadataLevelData() { MemoryReader memReader = new MemoryReader(_metadataTableStream); ReadMetadataTableInformation(memReader); ProcessAndCacheMetadataTableBlocks(memReader.GetRemainingBlock()); if (ModuleTable.NumberOfRows != 1) { throw new BadImageFormatException(); } }
private void ReadMetadataTableInformation(MemoryReader memReader) { if (memReader.RemainingBytes < MetadataStreamConstants.SizeOfMetadataTableHeader) { throw new BadImageFormatException(); } // Reserved memReader.SeekRelative(sizeof(uint)); _metadataTableHeader.MajorVersion = memReader.ReadByte(); _metadataTableHeader.MinorVersion = memReader.ReadByte(); _metadataTableHeader.HeapSizeFlags = (HeapSizeFlag)memReader.ReadByte(); // Rid memReader.SeekRelative(sizeof(byte)); _metadataTableHeader.ValidTables = (TableMask)memReader.ReadUInt64(); _metadataTableHeader.SortedTables = (TableMask)memReader.ReadUInt64(); ulong presentTables = (ulong)_metadataTableHeader.ValidTables; ulong validTablesForVersion = 0; int version = _metadataTableHeader.MajorVersion << 8 | _metadataTableHeader.MinorVersion; switch (version) { case 0x0100: validTablesForVersion = (ulong)TableMask.V1_0_TablesMask; break; case 0x0101: validTablesForVersion = (ulong)TableMask.V1_1_TablesMask; break; case 0x0200: validTablesForVersion = (ulong)TableMask.V2_0_TablesMask; break; default: throw new BadImageFormatException(); } if ((presentTables & ~validTablesForVersion) != 0) { throw new BadImageFormatException(); } if (_metadataStreamKind == MetadataStreamKind.Compressed && (presentTables & (ulong)TableMask.CompressedStreamNotAllowedMask) != 0) { throw new BadImageFormatException(); } ulong requiredSortedTables = presentTables & validTablesForVersion & (ulong)TableMask.SortedTablesMask; if ((requiredSortedTables & (ulong)_metadataTableHeader.SortedTables) != requiredSortedTables) { throw new BadImageFormatException(); } int numberOfTables = _metadataTableHeader.GetNumberOfTablesPresent(); if (memReader.RemainingBytes < numberOfTables * sizeof(Int32)) { throw new BadImageFormatException(); } int[] metadataTableRowCount = _metadataTableHeader.CompressedMetadataTableRowCount = new int[numberOfTables]; for (int i = 0; i < numberOfTables; i++) { uint rowCount = memReader.ReadUInt32(); if (rowCount > 0x00ffffff) { throw new BadImageFormatException(); } metadataTableRowCount[i] = (int)rowCount; } }
private void ReadCORModuleLevelData() { ReadCOR20Header(); MemoryBlock metadataRoot = DirectoryToMemoryBlock(_cor20Header.MetaDataDirectory); if (metadataRoot == null || metadataRoot.Length < _cor20Header.MetaDataDirectory.Size) { throw new BadImageFormatException(); } MemoryReader memReader = new MemoryReader(metadataRoot); ReadMetadataHeader(memReader); ReadStorageHeader(memReader); ReadStreamHeaders(memReader); ProcessAndCacheStreams(metadataRoot); // _resourceMemoryBlock = DirectoryToMemoryBlock(_cor20Header.ResourcesDirectory); // _strongNameSignatureBlock = DirectoryToMemoryBlock(_cor20Header.StrongNameSignatureDirectory); }
private void ReadStreamHeaders(MemoryReader memReader) { int numberOfStreams = _storageHeader.NumberOfStreams; _streamHeaders = new StreamHeader[numberOfStreams]; StreamHeader[] streamHeaders = _streamHeaders; for (int i = 0; i < numberOfStreams; i++) { if (memReader.RemainingBytes < COR20Constants.MinimumSizeofStreamHeader) { throw new BadImageFormatException(); } streamHeaders[i].Offset = memReader.ReadUInt32(); streamHeaders[i].Size = memReader.ReadUInt32(); streamHeaders[i].Name = memReader.ReadAscii(32); memReader.Align(4); } }
private void ReadStorageHeader(MemoryReader memReader) { _storageHeader.Flags = memReader.ReadUInt16(); _storageHeader.NumberOfStreams = memReader.ReadUInt16(); }
private void ReadMetadataHeader(MemoryReader memReader) { uint signature = memReader.ReadUInt32(); if (signature != COR20Constants.COR20MetadataSignature) { throw new BadImageFormatException(); } // MajorVersion = memReader.ReadUInt16(); // MinorVersion = memReader.ReadUInt16(); memReader.SeekRelative(2 * sizeof(ushort)); uint reserved = memReader.ReadUInt32(); if (reserved != 0) { throw new BadImageFormatException(); } int versionStringSize = memReader.ReadInt32(); memReader.SeekRelative(versionStringSize); }
// private MemoryBlock _resourceMemoryBlock; // private MemoryBlock _strongNameSignatureBlock; private void ReadCOR20Header() { MemoryBlock memBlock = DirectoryToMemoryBlock(_optionalHeaderDirectoryEntries.COR20HeaderTableDirectory); if (memBlock == null || memBlock.Length < _optionalHeaderDirectoryEntries.COR20HeaderTableDirectory.Size) { throw new BadImageFormatException(); } MemoryReader memReader = new MemoryReader(memBlock); // CountBytes = memReader.ReadInt32(); // MajorRuntimeVersion = memReader.ReadUInt16(); // MinorRuntimeVersion = memReader.ReadUInt16(); memReader.SeekRelative(sizeof(int) + 2 * sizeof(short)); _cor20Header.MetaDataDirectory.RelativeVirtualAddress = memReader.ReadUInt32(); _cor20Header.MetaDataDirectory.Size = memReader.ReadUInt32(); // COR20Header.COR20Flags = (COR20Flags)memReader.ReadUInt32(); // COR20Header.EntryPointTokenOrRVA = memReader.ReadUInt32(); memReader.SeekRelative(2 * sizeof(uint)); _cor20Header.ResourcesDirectory.RelativeVirtualAddress = memReader.ReadUInt32(); _cor20Header.ResourcesDirectory.Size = memReader.ReadUInt32(); _cor20Header.StrongNameSignatureDirectory.RelativeVirtualAddress = memReader.ReadUInt32(); _cor20Header.StrongNameSignatureDirectory.Size = memReader.ReadUInt32(); // CodeManagerTableDirectory // VtableFixupsDirectory // ExportAddressTableJumpsDirectory // ManagedNativeHeaderDirectory memReader.SeekRelative(4 * 2 * sizeof(uint)); }