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 ClrPlusException("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);

#if TODO
                DependencyInformation = new CacheEnumerable<DependencyInformation>(DependencyInformationImpl);
#endif
                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 ClrPlusException("Invalid DOS header.", true);
                    }

                    reader.ReadBytes(58);
                    reader.BaseStream.Position = reader.ReadUInt32();

                    // Read "PE\0\0" signature
                    if (reader.ReadUInt32() != 0x00004550) {
                        throw new ClrPlusException("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 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 ClrPlusException("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);

#if TODO
                DependencyInformation = new CacheEnumerable <DependencyInformation>(DependencyInformationImpl);
#endif
                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 ClrPlusException("Invalid DOS header.", true);
                    }

                    reader.ReadBytes(58);
                    reader.BaseStream.Position = reader.ReadUInt32();

                    // Read "PE\0\0" signature
                    if (reader.ReadUInt32() != 0x00004550)
                    {
                        throw new ClrPlusException("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 #3
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;
                }
            }));
        }