private Task LoadPEInfo() { return _loadingPeInfo ?? (_loadingPeInfo = _tasks.Start(() => { // load PE data from working file using (var reader = new BinaryReader(File.Open(WorkingCopy, FileMode.Open, FileAccess.Read, FileShare.Read))) { // Skip DOS Header and seek to PE signature if (reader.ReadUInt16() != 0x5A4D) { IsPEFile.Value = false; Is64BitPE.Value = false; Is32BitPE.Value = false; IsManaged.Value = false; IsNative.Value = false; Is32Bit.Value = false; return; } reader.ReadBytes(58); reader.BaseStream.Position = reader.ReadUInt32(); // Read "PE\0\0" signature if (reader.ReadUInt32() != 0x00004550) { IsPEFile.Value = false; Is64BitPE.Value = false; Is32BitPE.Value = false; IsManaged.Value = false; IsNative.Value = false; Is32Bit.Value = false; return; } // Read COFF header CoffHeader = new ImageCoffHeader { Machine = reader.ReadUInt16(), NumberOfSections = reader.ReadUInt16(), TimeDateStamp = reader.ReadUInt32(), SymbolTablePointer = reader.ReadUInt32(), NumberOfSymbols = reader.ReadUInt32(), OptionalHeaderSize = reader.ReadUInt16(), Characteristics = reader.ReadUInt16() }; // Compute data sections offset var dataSectionsOffset = reader.BaseStream.Position + CoffHeader.OptionalHeaderSize; // Read NT-specific fields NtHeader = new ImageOptionalHeaderNt(); NtHeader.Magic = reader.ReadUInt16(); NtHeader.MajorLinkerVersion = reader.ReadByte(); NtHeader.MinorLinkerVersion = reader.ReadByte(); NtHeader.SizeOfCode = reader.ReadUInt32(); NtHeader.SizeOfInitializedData = reader.ReadUInt32(); NtHeader.SizeOfUninitializedData = reader.ReadUInt32(); NtHeader.AddressOfEntryPoint = reader.ReadUInt32(); NtHeader.BaseOfCode = reader.ReadUInt32(); // identify this as 64bit or 32bit binary Is64BitPE.Value = NtHeader.Magic == 0x20b; Is32BitPE.Value = NtHeader.Magic == 0x10b; IsPEFile.Value = true; if (Is32BitPE) { NtHeader.BaseOfData_32bit = reader.ReadUInt32(); NtHeader.ImageBase_32bit = reader.ReadUInt32(); } if (Is64BitPE) { NtHeader.ImageBase_64bit = reader.ReadUInt64(); } NtHeader.SectionAlignment = reader.ReadUInt32(); NtHeader.FileAlignment = reader.ReadUInt32(); NtHeader.OsMajor = reader.ReadUInt16(); NtHeader.OsMinor = reader.ReadUInt16(); NtHeader.UserMajor = reader.ReadUInt16(); NtHeader.UserMinor = reader.ReadUInt16(); NtHeader.SubSysMajor = reader.ReadUInt16(); NtHeader.SubSysMinor = reader.ReadUInt16(); NtHeader.Reserved = reader.ReadUInt32(); NtHeader.ImageSize = reader.ReadUInt32(); NtHeader.HeaderSize = reader.ReadUInt32(); NtHeader.FileChecksum = reader.ReadUInt32(); NtHeader.SubSystem = reader.ReadUInt16(); NtHeader.DllFlags = reader.ReadUInt16(); if (Is32BitPE) { NtHeader.StackReserveSize_32bit = reader.ReadUInt32(); NtHeader.StackCommitSize_32bit = reader.ReadUInt32(); NtHeader.HeapReserveSize_32bit = reader.ReadUInt32(); NtHeader.HeapCommitSize_32bit = reader.ReadUInt32(); } if (Is64BitPE) { NtHeader.StackReserveSize_64bit = reader.ReadUInt64(); NtHeader.StackCommitSize_64bit = reader.ReadUInt64(); NtHeader.HeapReserveSize_64bit = reader.ReadUInt64(); NtHeader.HeapCommitSize_64bit = reader.ReadUInt64(); } NtHeader.LoaderFlags = reader.ReadUInt32(); NtHeader.NumberOfDataDirectories = reader.ReadUInt32(); if (NtHeader.NumberOfDataDirectories < 16) { IsManaged.Value = false; IsNative.Value = true; Is32Bit.Value = Is32BitPE; return; } // Read data directories _exportTable = ReadDataDirectory(reader); _importTable = ReadDataDirectory(reader); _resourceTable = ReadDataDirectory(reader); _exceptionTable = ReadDataDirectory(reader); _certificateTable = ReadDataDirectory(reader); _baseRelocationTable = ReadDataDirectory(reader); _debug = ReadDataDirectory(reader); _copyright = ReadDataDirectory(reader); _globalPtr = ReadDataDirectory(reader); _tlsTable = ReadDataDirectory(reader); _loadConfigTable = ReadDataDirectory(reader); _boundImport = ReadDataDirectory(reader); _iat = ReadDataDirectory(reader); _delayImportDescriptor = ReadDataDirectory(reader); _runtimeHeader = ReadDataDirectory(reader); _reserved = ReadDataDirectory(reader); if (_runtimeHeader.Size == 0) { IsManaged.Value = false; IsNative.Value = true; Is32Bit.Value = Is32BitPE; return; } // Read data sections reader.BaseStream.Position = dataSectionsOffset; SectionHeaders = new ImageSectionHeader[CoffHeader.NumberOfSections]; for (var i = 0; i < SectionHeaders.Length; i++) { reader.ReadBytes(12); SectionHeaders[i].VirtualAddress = reader.ReadUInt32(); SectionHeaders[i].SizeOfRawData = reader.ReadUInt32(); SectionHeaders[i].PointerToRawData = reader.ReadUInt32(); reader.ReadBytes(16); } // Read COR20 Header reader.BaseStream.Position = RvaToVa(_runtimeHeader.Rva); CorHeader = new ImageCor20Header { Size = reader.ReadUInt32(), MajorRuntimeVersion = reader.ReadUInt16(), MinorRuntimeVersion = reader.ReadUInt16(), MetaData = ReadDataDirectory(reader), Flags = reader.ReadUInt32(), EntryPointToken = reader.ReadUInt32(), Resources = ReadDataDirectory(reader), StrongNameSignature = ReadDataDirectory(reader), CodeManagerTable = ReadDataDirectory(reader), VTableFixups = ReadDataDirectory(reader), ExportAddressTableJumps = ReadDataDirectory(reader) }; // we got a CorHeader -- we must be managed. IsManaged.Value = true; IsNative.Value = false; Is32Bit.Value = (CorHeader.Flags & 0x0002) != 0; } })); }
public PEInfo(string filename) { if( !File.Exists(filename)) throw new FileNotFoundException("Unable to find file",filename); reader = new BinaryReader(File.OpenRead(filename)); // Skip DOS Header and seek to PE signature if (reader.ReadUInt16() != 0x5A4D) { throw new Exception("Invalid DOS header."); } reader.ReadBytes(58); reader.BaseStream.Position = reader.ReadUInt32(); // Read "PE\0\0" signature if (reader.ReadUInt32() != 0x00004550) { throw new Exception("File is not a portable executable."); } // Read COFF header coffHeader = new ImageCoffHeader(); coffHeader.Machine = reader.ReadUInt16(); coffHeader.NumberOfSections = reader.ReadUInt16(); coffHeader.TimeDateStamp = reader.ReadUInt32(); coffHeader.SymbolTablePointer = reader.ReadUInt32(); coffHeader.NumberOfSymbols = reader.ReadUInt32(); coffHeader.OptionalHeaderSize = reader.ReadUInt16(); coffHeader.Characteristics = reader.ReadUInt16(); // Compute data sections offset long dataSectionsOffset = reader.BaseStream.Position + coffHeader.OptionalHeaderSize; // Read NT-specific fields ntHeader = new ImageOptionalHeaderNt(); ntHeader.Magic = reader.ReadUInt16(); ntHeader.MajorLinkerVersion = reader.ReadByte(); ntHeader.MinorLinkerVersion = reader.ReadByte(); ntHeader.SizeOfCode = reader.ReadUInt32(); ntHeader.SizeOfInitializedData = reader.ReadUInt32(); ntHeader.SizeOfUninitializedData = reader.ReadUInt32(); ntHeader.AddressOfEntryPoint = reader.ReadUInt32(); ntHeader.BaseOfCode = reader.ReadUInt32(); if (Is32BitPE) { ntHeader.BaseOfData_32bit = reader.ReadUInt32(); ntHeader.ImageBase_32bit = reader.ReadUInt32(); } if (Is64BitPE) { ntHeader.ImageBase_64bit = reader.ReadUInt64(); } ntHeader.SectionAlignment = reader.ReadUInt32(); ntHeader.FileAlignment = reader.ReadUInt32(); ntHeader.OsMajor = reader.ReadUInt16(); ntHeader.OsMinor = reader.ReadUInt16(); ntHeader.UserMajor = reader.ReadUInt16(); ntHeader.UserMinor = reader.ReadUInt16(); ntHeader.SubSysMajor = reader.ReadUInt16(); ntHeader.SubSysMinor = reader.ReadUInt16(); ntHeader.Reserved = reader.ReadUInt32(); ntHeader.ImageSize = reader.ReadUInt32(); ntHeader.HeaderSize = reader.ReadUInt32(); ntHeader.FileChecksum = reader.ReadUInt32(); ntHeader.SubSystem = reader.ReadUInt16(); ntHeader.DllFlags = reader.ReadUInt16(); if (Is32BitPE) { ntHeader.StackReserveSize_32bit = reader.ReadUInt32(); ntHeader.StackCommitSize_32bit = reader.ReadUInt32(); ntHeader.HeapReserveSize_32bit = reader.ReadUInt32(); ntHeader.HeapCommitSize_32bit = reader.ReadUInt32(); } if (Is64BitPE) { ntHeader.StackReserveSize_64bit = reader.ReadUInt64(); ntHeader.StackCommitSize_64bit = reader.ReadUInt64(); ntHeader.HeapReserveSize_64bit = reader.ReadUInt64(); ntHeader.HeapCommitSize_64bit = reader.ReadUInt64(); } ntHeader.LoaderFlags = reader.ReadUInt32(); ntHeader.NumberOfDataDirectories = reader.ReadUInt32(); if (ntHeader.NumberOfDataDirectories < 16) { return; } // Read data directories exportTable = ReadDataDirectory(); importTable = ReadDataDirectory(); resourceTable = ReadDataDirectory(); exceptionTable = ReadDataDirectory(); certificateTable = ReadDataDirectory(); baseRelocationTable = ReadDataDirectory(); debug = ReadDataDirectory(); copyright = ReadDataDirectory(); globalPtr = ReadDataDirectory(); tlsTable = ReadDataDirectory(); loadConfigTable = ReadDataDirectory(); boundImport = ReadDataDirectory(); iat = ReadDataDirectory(); delayImportDescriptor = ReadDataDirectory(); runtimeHeader = ReadDataDirectory(); reserved = ReadDataDirectory(); if (runtimeHeader.Size == 0) { return; } // Read data sections reader.BaseStream.Position = dataSectionsOffset; sectionHeaders = new ImageSectionHeader[coffHeader.NumberOfSections]; for (int i = 0; i < sectionHeaders.Length; i++) { reader.ReadBytes(12); sectionHeaders[i].VirtualAddress = reader.ReadUInt32(); sectionHeaders[i].SizeOfRawData = reader.ReadUInt32(); sectionHeaders[i].PointerToRawData = reader.ReadUInt32(); reader.ReadBytes(16); } // Read COR20 Header reader.BaseStream.Position = RvaToVa(runtimeHeader.Rva); corHeader = new ImageCor20Header { Size = reader.ReadUInt32(), MajorRuntimeVersion = reader.ReadUInt16(), MinorRuntimeVersion = reader.ReadUInt16(), MetaData = ReadDataDirectory(), Flags = reader.ReadUInt32(), EntryPointToken = reader.ReadUInt32(), Resources = ReadDataDirectory(), StrongNameSignature = ReadDataDirectory(), CodeManagerTable = ReadDataDirectory(), VTableFixups = ReadDataDirectory(), ExportAddressTableJumps = ReadDataDirectory() }; reader.Close(); }
private PEInfo(string filename) { _filename = filename; try { IsPEBinary = true; _executableInfo = new Lazy<ExecutableInfo>(() => { var result = IsManaged ? ExecutableInfo.managed : ExecutableInfo.native; if (IsAny) { result |= ExecutableInfo.any; } else { switch (CoffHeader.Machine) { case 0x01c0: result |= ExecutableInfo.arm; break; case 0x014c: result |= ExecutableInfo.x86; break; case 0x0200: result |= ExecutableInfo.ia64; break; case 0x8664: result |= ExecutableInfo.x64; break; default: throw new CoAppException("Unrecognized Executable Machine Type."); } } return result; }); _fileVersionInfo = new Lazy<FileVersionInfo>(() => FileVersionInfo.GetVersionInfo(_filename)); _fileVersionString = new Lazy<string>( () => string.Format("{0}.{1}.{2}.{3}", _fileVersionInfo.Value.FileMajorPart, _fileVersionInfo.Value.FileMinorPart, _fileVersionInfo.Value.FileBuildPart, _fileVersionInfo.Value.FilePrivatePart)); _fileVersionLong = new Lazy<ulong>( () => (((ulong) _fileVersionInfo.Value.FileMajorPart) << 48) + (((ulong) _fileVersionInfo.Value.FileMinorPart) << 32) + (((ulong) _fileVersionInfo.Value.FileBuildPart) << 16) + (ulong) _fileVersionInfo.Value.FilePrivatePart); DependencyInformation = new LazyEnumerable<DependencyInformation>(DependencyInformationImpl); using (var reader = new BinaryReader(File.OpenRead(_filename))) { // Skip DOS Header and seek to PE signature if (reader.ReadUInt16() != 0x5A4D) { Logger.Warning("File '{0}' does not have a valid PE Header", _filename); throw new CoAppException("Invalid DOS header.", true); } reader.ReadBytes(58); reader.BaseStream.Position = reader.ReadUInt32(); // Read "PE\0\0" signature if (reader.ReadUInt32() != 0x00004550) { throw new CoAppException("File is not a portable executable."); } // Read COFF header CoffHeader = new ImageCoffHeader { Machine = reader.ReadUInt16(), NumberOfSections = reader.ReadUInt16(), TimeDateStamp = reader.ReadUInt32(), SymbolTablePointer = reader.ReadUInt32(), NumberOfSymbols = reader.ReadUInt32(), OptionalHeaderSize = reader.ReadUInt16(), Characteristics = reader.ReadUInt16() }; // Compute data sections offset var dataSectionsOffset = reader.BaseStream.Position + CoffHeader.OptionalHeaderSize; // Read NT-specific fields NtHeader = new ImageOptionalHeaderNt(); NtHeader.Magic = reader.ReadUInt16(); NtHeader.MajorLinkerVersion = reader.ReadByte(); NtHeader.MinorLinkerVersion = reader.ReadByte(); NtHeader.SizeOfCode = reader.ReadUInt32(); NtHeader.SizeOfInitializedData = reader.ReadUInt32(); NtHeader.SizeOfUninitializedData = reader.ReadUInt32(); NtHeader.AddressOfEntryPoint = reader.ReadUInt32(); NtHeader.BaseOfCode = reader.ReadUInt32(); if (Is32BitPE) { NtHeader.BaseOfData_32bit = reader.ReadUInt32(); NtHeader.ImageBase_32bit = reader.ReadUInt32(); } if (Is64BitPE) { NtHeader.ImageBase_64bit = reader.ReadUInt64(); } NtHeader.SectionAlignment = reader.ReadUInt32(); NtHeader.FileAlignment = reader.ReadUInt32(); NtHeader.OsMajor = reader.ReadUInt16(); NtHeader.OsMinor = reader.ReadUInt16(); NtHeader.UserMajor = reader.ReadUInt16(); NtHeader.UserMinor = reader.ReadUInt16(); NtHeader.SubSysMajor = reader.ReadUInt16(); NtHeader.SubSysMinor = reader.ReadUInt16(); NtHeader.Reserved = reader.ReadUInt32(); NtHeader.ImageSize = reader.ReadUInt32(); NtHeader.HeaderSize = reader.ReadUInt32(); NtHeader.FileChecksum = reader.ReadUInt32(); NtHeader.SubSystem = reader.ReadUInt16(); NtHeader.DllFlags = reader.ReadUInt16(); if (Is32BitPE) { NtHeader.StackReserveSize_32bit = reader.ReadUInt32(); NtHeader.StackCommitSize_32bit = reader.ReadUInt32(); NtHeader.HeapReserveSize_32bit = reader.ReadUInt32(); NtHeader.HeapCommitSize_32bit = reader.ReadUInt32(); } if (Is64BitPE) { NtHeader.StackReserveSize_64bit = reader.ReadUInt64(); NtHeader.StackCommitSize_64bit = reader.ReadUInt64(); NtHeader.HeapReserveSize_64bit = reader.ReadUInt64(); NtHeader.HeapCommitSize_64bit = reader.ReadUInt64(); } NtHeader.LoaderFlags = reader.ReadUInt32(); NtHeader.NumberOfDataDirectories = reader.ReadUInt32(); if (NtHeader.NumberOfDataDirectories < 16) { return; } // Read data directories _exportTable = ReadDataDirectory(reader); _importTable = ReadDataDirectory(reader); _resourceTable = ReadDataDirectory(reader); _exceptionTable = ReadDataDirectory(reader); _certificateTable = ReadDataDirectory(reader); _baseRelocationTable = ReadDataDirectory(reader); _debug = ReadDataDirectory(reader); _copyright = ReadDataDirectory(reader); _globalPtr = ReadDataDirectory(reader); _tlsTable = ReadDataDirectory(reader); _loadConfigTable = ReadDataDirectory(reader); _boundImport = ReadDataDirectory(reader); _iat = ReadDataDirectory(reader); _delayImportDescriptor = ReadDataDirectory(reader); _runtimeHeader = ReadDataDirectory(reader); _reserved = ReadDataDirectory(reader); if (_runtimeHeader.Size == 0) { return; } // Read data sections reader.BaseStream.Position = dataSectionsOffset; SectionHeaders = new ImageSectionHeader[CoffHeader.NumberOfSections]; for (var i = 0; i < SectionHeaders.Length; i++) { reader.ReadBytes(12); SectionHeaders[i].VirtualAddress = reader.ReadUInt32(); SectionHeaders[i].SizeOfRawData = reader.ReadUInt32(); SectionHeaders[i].PointerToRawData = reader.ReadUInt32(); reader.ReadBytes(16); } // Read COR20 Header reader.BaseStream.Position = RvaToVa(_runtimeHeader.Rva); CorHeader = new ImageCor20Header { Size = reader.ReadUInt32(), MajorRuntimeVersion = reader.ReadUInt16(), MinorRuntimeVersion = reader.ReadUInt16(), MetaData = ReadDataDirectory(reader), Flags = reader.ReadUInt32(), EntryPointToken = reader.ReadUInt32(), Resources = ReadDataDirectory(reader), StrongNameSignature = ReadDataDirectory(reader), CodeManagerTable = ReadDataDirectory(reader), VTableFixups = ReadDataDirectory(reader), ExportAddressTableJumps = ReadDataDirectory(reader) }; } } catch { IsPEBinary = false; } }
private ImageDataDirectory ReadDataDirectory() { var directory = new ImageDataDirectory(); directory.Rva = reader.ReadUInt32(); directory.Size = reader.ReadUInt32(); return directory; }