Example #1
0
        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;
            }
        }
Example #2
0
        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;
                }
            }));
        }
Example #3
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();
        }