예제 #1
0
        private void ReadSignatures(IBinaryAccessor accessor, ProjectReadState state)
        {
            int blobSize = accessor.Read7BitEncodedInt();
            var blob     = new Blob(accessor.ReadBytes(blobSize));

            state.Signatures = new ReadSignatureSerializer(new BlobAccessor(blob), state.Strings);
        }
        public virtual void Deserialize(IBinaryAccessor accessor)
        {
            _count = accessor.Read7BitEncodedInt();
            int bufferLength = accessor.Read7BitEncodedInt();

            if (_count > 0)
            {
                _buckets = new int[_count];
                for (int i = 0; i < _count; i++)
                {
                    _buckets[i] = -1;
                }

                _entries = new Entry[_count];

                for (int i = 0; i < _count; i++)
                {
                    var entry = new Entry();
                    entry.Offset   = accessor.Read7BitEncodedInt();
                    entry.HashCode = accessor.Read7BitEncodedInt();

                    int hashIndex = entry.HashCode % _buckets.Length;
                    entry.Next          = _buckets[hashIndex];
                    _buckets[hashIndex] = i;

                    _entries[i] = entry;
                }
            }

            _blob = new Blob(accessor.ReadBytes(bufferLength));
        }
예제 #3
0
        public void Deserialize(IBinaryAccessor accessor)
        {
            _count        = _capacity = accessor.Read7BitEncodedInt();
            _bufferLength = accessor.Read7BitEncodedInt();

            if (_capacity > 0)
            {
                _entries = new Entry[_capacity];

                for (int i = 0; i < _capacity; i++)
                {
                    var entry = new Entry();
                    entry.Offset = accessor.Read7BitEncodedInt();
                    entry.Size   = accessor.Read7BitEncodedInt();
                    _entries[i]  = entry;
                }

                _lastValidIndex = _capacity - 1;
            }

            if (_bufferLength > 0)
            {
                _buffer = accessor.ReadBytes(_bufferLength);
            }
        }
        public static byte[] ReadAllBytes(this IBinaryAccessor accessor)
        {
            if (accessor == null)
            {
                throw new ArgumentNullException("accessor");
            }

            return(accessor.ReadBytes((int)(accessor.Length - accessor.Position)));
        }
예제 #5
0
        public static unsafe CorHeader Read(IBinaryAccessor accessor, string location)
        {
            CorHeader corHeader;

            fixed(byte *pBuff = accessor.ReadBytes(sizeof(CorHeader)))
            {
                corHeader = *(CorHeader *)pBuff;
            }

            if (corHeader.Cb != Signature)
            {
                throw new BadImageFormatException(string.Format(SR.MetadataImageNotValid, location));
            }

            return(corHeader);
        }
예제 #6
0
        internal static CertificateEntry Load(IBinaryAccessor accessor)
        {
            var entry = new CertificateEntry();

            int length = accessor.ReadInt32();

            entry._revision = (CertificateRevision)accessor.ReadUInt16();
            entry._type     = (CertificateType)accessor.ReadUInt16();

            // Subtract header length (length, revision, type).
            int dataLength = length - 8;

            entry._data = accessor.ReadBytes(dataLength);

            return(entry);
        }
예제 #7
0
        internal static unsafe PESection Read(IBinaryAccessor accessor)
        {
            var section = new PESection();

            SectionHeader header;

            fixed(byte *pBuff = accessor.ReadBytes(PEConstants.SectionHeaderSize))
            {
                header = *(SectionHeader *)pBuff;
            }

            section._name             = Marshal.PtrToStringAnsi(new IntPtr(header.Name));
            section._virtualSize      = header.VirtualSize;
            section._virtualAddress   = header.VirtualAddress;
            section._sizeOfRawData    = header.SizeOfRawData;
            section._pointerToRawData = header.PointerToRawData;
            section._characteristics  = header.Characteristics;

            return(section);
        }
예제 #8
0
        private void ReadStrings(IBinaryAccessor accessor, ProjectReadState state)
        {
            int blobSize = accessor.Read7BitEncodedInt();

            byte[] buffer = accessor.ReadBytes(blobSize);
            StrongCryptoUtils.Decrypt(buffer, 0, blobSize);

            var blob = new Blob(buffer);
            int pos  = 0;

            int count    = blob.Read7BitEncodedInt(ref pos);
            var strings  = new string[count];
            var encoding = Encoding.UTF8;

            for (int i = 0; i < count; i++)
            {
                strings[i] = blob.ReadLengthPrefixedString(ref pos, encoding);
            }

            state.Strings = strings;
        }
        internal static unsafe void Load(IBinaryAccessor accessor, ResourceTable table, long basePosition)
        {
            ResourceTableHeader tableHeader;

            fixed(byte *pBuff = accessor.ReadBytes(sizeof(ResourceTableHeader)))
            {
                tableHeader = *(ResourceTableHeader *)pBuff;
            }

            table._majorVersion  = tableHeader.MajorVersion;
            table._minorVersion  = tableHeader.MinorVersion;
            table._timeDateStamp = ConvertUtils.ToDateTime(tableHeader.TimeDateStamp);

            int numberOfEntries = tableHeader.NumberOfNamedEntries + tableHeader.NumberOfIdEntries;

            for (int i = 0; i < numberOfEntries; i++)
            {
                var entry = ResourceEntry.Load(accessor, basePosition);
                entry._parent = table;
                table._list.Add(entry);
            }
        }
예제 #10
0
        private void Deserialize(IBinaryAccessor accessor)
        {
            _count   = accessor.Read7BitEncodedInt();
            _entries = new Entry[_count];
            _items   = new StateObject[Math.Max(_count, 0x10)];

            for (int i = 0; i < _count; i++)
            {
                _entries[i] =
                    new Entry()
                {
                    Offset = accessor.Read7BitEncodedInt(),
                    Size   = accessor.Read7BitEncodedInt(),
                };
            }

            int bufferLength = accessor.Read7BitEncodedInt();

            if (bufferLength > 0)
            {
                _buffer = accessor.ReadBytes(bufferLength);
            }
        }
예제 #11
0
        public void Deserialize(IBinaryAccessor accessor)
        {
            _count          = accessor.Read7BitEncodedInt();
            _bufferLength   = accessor.Read7BitEncodedInt();
            _lastValidIndex = _count - 1;
            _entries        = new Entry[_count];

            for (int i = 0; i < _count; i++)
            {
                var entry = new Entry();
                entry.Offset = accessor.Read7BitEncodedInt();
                entry.Size   = accessor.Read7BitEncodedInt();
                _entries[i]  = entry;
            }

            if (_bufferLength > 0)
            {
                _buffer = accessor.ReadBytes(_bufferLength);
            }
            else
            {
                _buffer = BufferUtils.EmptyArray;
            }
        }
        private void ReadVersionString(IBinaryAccessor accessor)
        {
            int versionLength = accessor.ReadInt32();

            if (versionLength == 0)
            {
                return;
            }

            byte[] buffer = accessor.ReadBytes(versionLength);
            int    count  = 0;

            for (int i = 0; i < buffer.Length; i++)
            {
                if (buffer[i] == 0)
                {
                    break;
                }

                count++;
            }

            _frameworkVersionMoniker = Encoding.UTF8.GetString(buffer, 0, count);
        }
        internal static unsafe DelayImportModuleTable Load(IBinaryAccessor accessor, PEImage image)
        {
            DelayImportTableHeader header;

            fixed(byte *pBuff = accessor.ReadBytes(sizeof(DelayImportTableHeader)))
            {
                header = *(DelayImportTableHeader *)pBuff;
            }

            if (header.Name == 0 || header.DelayImportAddressTable == 0)
            {
                return(null);
            }

            // Save position
            long position = accessor.Position;

            var module = new DelayImportModuleTable();

            module._moduleHandleRVA = header.ModuleHandle;

            // Dll name
            accessor.Position = image.ResolvePositionToSectionData(header.Name);
            module._dllName   = accessor.ReadNullTerminatedString(Encoding.ASCII);

            // DelayImportAddressTable
            accessor.Position = image.ResolvePositionToSectionData(header.DelayImportAddressTable);

            var funcRVAList = new List <uint>();

            while (true)
            {
                uint funcRVA = accessor.ReadUInt32();
                if (funcRVA == 0)
                {
                    break;
                }

                funcRVAList.Add(funcRVA);
            }

            accessor.Position = image.ResolvePositionToSectionData(header.DelayImportNameTable);

            if (image.Is32Bits)
            {
                var entryDataList = new List <uint>();
                for (int i = 0; i < funcRVAList.Count; i++)
                {
                    entryDataList.Add(accessor.ReadUInt32());
                }

                for (int i = 0; i < funcRVAList.Count; i++)
                {
                    uint funcRVA   = funcRVAList[i];
                    uint entryData = entryDataList[i];

                    string name = null;
                    int    ordinal;
                    if ((entryData & 0x80000000) != 0)
                    {
                        // DelayImport by ordinal.
                        ordinal = (int)(entryData & 0x7fffffff);
                    }
                    else
                    {
                        // DelayImport by name.
                        uint hintNameRVA = (entryData & 0x7fffffff);
                        accessor.Position = image.ResolvePositionToSectionData(hintNameRVA);
                        ordinal           = accessor.ReadUInt16();
                        name = accessor.ReadNullTerminatedString(Encoding.ASCII);
                    }

                    var entry = new DelayImportEntry(funcRVA, name, ordinal);
                    entry._parent = module;
                    module._list.Add(entry);
                }
            }
            else
            {
                var entryDataList = new List <ulong>();
                for (int i = 0; i < funcRVAList.Count; i++)
                {
                    entryDataList.Add(accessor.ReadUInt64());
                }

                for (int i = 0; i < funcRVAList.Count; i++)
                {
                    uint  funcRVA   = funcRVAList[i];
                    ulong entryData = entryDataList[i];

                    string name = null;
                    int    ordinal;
                    if ((entryData & 0x8000000000000000) != 0)
                    {
                        // Import by ordinal.
                        ordinal = (int)(entryData & 0x7fffffffffffffff);
                    }
                    else
                    {
                        // Import by name.
                        uint hintNameRVA = (uint)(entryData & 0x7fffffffffffffff);
                        accessor.Position = image.ResolvePositionToSectionData(hintNameRVA);
                        ordinal           = accessor.ReadUInt16();
                        name = accessor.ReadNullTerminatedString(Encoding.ASCII);
                    }

                    var entry = new DelayImportEntry(funcRVA, name, ordinal);
                    entry._parent = module;
                    module._list.Add(entry);
                }
            }

            // Restore position
            accessor.Position = position;

            return(module);
        }
 public static Guid ReadGuid(this IBinaryAccessor accessor)
 {
     return(new Guid(accessor.ReadBytes(16)));
 }
        private void ReadStreams(IBinaryAccessor accessor, long metadataOffset)
        {
            int numberOfStream = accessor.ReadUInt16();

            int[]    offsets = new int[numberOfStream];
            int[]    sizes   = new int[numberOfStream];
            string[] names   = new string[numberOfStream];

            for (int i = 0; i < numberOfStream; i++)
            {
                offsets[i] = accessor.ReadInt32();
                sizes[i]   = accessor.ReadInt32();

                // Name of the stream; a zero-terminated ASCII string no longer than 31 characters (plus zero terminator).
                // The name might be shorter, in which case the size of the stream header is correspondingly reduced,
                // padded to the 4-byte boundary.
                long startPos = accessor.Position;
                names[i] = accessor.ReadNullTerminatedString(Encoding.ASCII);
                accessor.Align(startPos, 4);
            }

            int tableIndex = -1;

            for (int i = 0; i < numberOfStream; i++)
            {
                int    offset = offsets[i];
                int    size   = sizes[i];
                string name   = names[i];

                if (name == MetadataConstants.StreamTable)
                {
                    tableIndex          = i;
                    _tables.IsOptimized = true;
                }
                else if (name == MetadataConstants.StreamTableUnoptimized)
                {
                    tableIndex          = i;
                    _tables.IsOptimized = false;
                }
                else if (name == MetadataConstants.StreamStrings)
                {
                    accessor.Position = offset + metadataOffset;
                    _strings.Blob     = new Blob(accessor.ReadBytes(size));
                }
                else if (name == MetadataConstants.StreamUserStrings)
                {
                    accessor.Position = offset + metadataOffset;
                    _userStrings.Blob = new Blob(accessor.ReadBytes(size));
                }
                else if (name == MetadataConstants.StreamGuid)
                {
                    accessor.Position = offset + metadataOffset;
                    _guids.Blob       = new Blob(accessor.ReadBytes(size));
                }
                else if (name == MetadataConstants.StreamBlob)
                {
                    accessor.Position = offset + metadataOffset;
                    _blobs.Blob       = new Blob(accessor.ReadBytes(size));
                }
                else
                {
                    accessor.Position = offset + metadataOffset;
                    var stream = new MetadataExternalStream(name, new Blob(accessor.ReadBytes(size)));
                    ExternalStreams.Add(stream);
                }
            }

            if (tableIndex >= 0)
            {
                // Read table last as it relies on heaps.
                accessor.Position = offsets[tableIndex] + metadataOffset;
                _tables.Read(accessor);
            }
        }
예제 #16
0
        protected unsafe void Read(IBinaryAccessor accessor)
        {
            // DOS
            DOSHeader dosHeader;

            fixed(byte *pBuff = accessor.ReadBytes(PEConstants.DosHeaderSize))
            {
                dosHeader = *(DOSHeader *)pBuff;
            }

            if (dosHeader.Signature != PEConstants.DosSignature)
            {
                throw new BadImageFormatException(SR.DOSHeaderSignatureNotValid);
            }

            accessor.Position = dosHeader.Lfanew;

            // NT Signature
            if (accessor.ReadUInt32() != PEConstants.NTSignature)
            {
                throw new BadImageFormatException(SR.PESignatureNotValid);
            }

            // COFF
            COFFHeader coffHeader;

            fixed(byte *pBuff = accessor.ReadBytes(PEConstants.COFFHeaderSize))
            {
                coffHeader = *(COFFHeader *)pBuff;
            }

            _characteristics = coffHeader.Characteristics;
            _machine         = coffHeader.Machine;

            // PE
            ushort peMagic = accessor.ReadUInt16();

            accessor.Position -= 2;
            if (peMagic == PEConstants.PEMagic32)
            {
                _is32Bits = true;

                PEHeader peHeader;
                fixed(byte *pBuff = accessor.ReadBytes(PEConstants.PEHeaderSize))
                {
                    peHeader = *(PEHeader *)pBuff;
                }

                _addressOfEntryPoint = peHeader.AddressOfEntryPoint;
                _imageBase           = peHeader.ImageBase;
                _sectionAlignment    = peHeader.SectionAlignment;
                _fileAlignment       = peHeader.FileAlignment;
                _subsystem           = peHeader.Subsystem;
                _dllCharacteristics  = peHeader.DllCharacteristics;
                _sizeOfStackReserve  = peHeader.SizeOfStackReserve;
            }
            else if (peMagic == 0x20b)
            {
                _is32Bits = false;

                PEHeader64 peHeader;
                fixed(byte *pBuff = accessor.ReadBytes(PEConstants.PEHeader64Size))
                {
                    peHeader = *(PEHeader64 *)pBuff;
                }

                _addressOfEntryPoint = peHeader.AddressOfEntryPoint;
                _imageBase           = peHeader.ImageBase;
                _sectionAlignment    = peHeader.SectionAlignment;
                _fileAlignment       = peHeader.FileAlignment;
                _subsystem           = peHeader.Subsystem;
                _dllCharacteristics  = peHeader.DllCharacteristics;
                _sizeOfStackReserve  = peHeader.SizeOfStackReserve;
            }
            else
            {
                throw new BadImageFormatException(SR.PEHeaderSignatureNotValid);
            }

            // Directories
            for (int i = 0; i < PEConstants.NumberOfRvaAndSizes; i++)
            {
                fixed(byte *pBuff = accessor.ReadBytes(8))
                {
                    _directories[i] = *(DataDirectory *)pBuff;
                }
            }

            // Sections
            _sections = new PESection[coffHeader.NumberOfSections];
            for (int i = 0; i < coffHeader.NumberOfSections; i++)
            {
                _sections[i] = PESection.Read(accessor);
            }
        }
        private static unsafe void Load(IBinaryAccessor accessor, PEImage image, ExportTable table)
        {
            ExportTableHeader header;

            fixed(byte *pBuff = accessor.ReadBytes(sizeof(ExportTableHeader)))
            {
                header = *(ExportTableHeader *)pBuff;
            }

            table._ordinalBase   = (int)header.Base;
            table._timeDateStamp = ConvertUtils.ToDateTime(header.TimeDateStamp);

            // Name
            accessor.Position = image.ResolvePositionToSectionData(header.Name);
            table._dllName    = accessor.ReadNullTerminatedString(Encoding.ASCII);

            if (header.AddressOfFunctions != 0)
            {
                // Export Address Table
                accessor.Position = image.ResolvePositionToSectionData(header.AddressOfFunctions);
                uint[] arrayOfExportRVA = new uint[header.NumberOfFunctions];
                for (int i = 0; i < header.NumberOfFunctions; i++)
                {
                    arrayOfExportRVA[i] = accessor.ReadUInt32();
                }

                // Name pointer table
                accessor.Position = image.ResolvePositionToSectionData(header.AddressOfNames);
                uint[] arrayOfNameRVA = new uint[header.NumberOfNames];
                for (int i = 0; i < header.NumberOfNames; i++)
                {
                    arrayOfNameRVA[i] = accessor.ReadUInt32();
                }

                // Ordinal table
                accessor.Position = image.ResolvePositionToSectionData(header.AddressOfNameOrdinals);
                ushort[] arrayOfOrdinals = new ushort[header.NumberOfNames];
                for (int i = 0; i < header.NumberOfNames; i++)
                {
                    arrayOfOrdinals[i] = accessor.ReadUInt16();
                }

                // Read names and map against export rva
                string[] names = new string[header.NumberOfFunctions];
                for (int i = 0; i < header.NumberOfNames; i++)
                {
                    accessor.Position = image.ResolvePositionToSectionData(arrayOfNameRVA[i]);
                    string name = accessor.ReadNullTerminatedString(Encoding.ASCII);

                    int ordinal = arrayOfOrdinals[i];
                    names[ordinal] = name;
                }

                var exportDirectory = image.Directories[DataDirectories.ExportTable];

                // Build entries
                for (int i = 0; i < header.NumberOfFunctions; i++)
                {
                    uint   exportRVA = arrayOfExportRVA[i];
                    string name      = names[i];

                    ExportEntry entry;

                    // Each entry in the export address table is a field that uses one of two formats in the
                    // following table. If the address specified is not within the export section (as defined
                    // by the address and length that are indicated in the optional header), the field is an
                    // export RVA, which is an actual address in code or data. Otherwise, the field is a
                    // forwarder RVA, which names a symbol in another DLL.
                    if (exportDirectory.Contains(exportRVA))
                    {
                        accessor.Position = image.ResolvePositionToSectionData(exportRVA);
                        string forwarder = accessor.ReadNullTerminatedString(Encoding.ASCII);
                        entry = new ExportForwarderEntry(name, forwarder);
                    }
                    else
                    {
                        entry = new ExportRVAEntry(name, exportRVA);
                    }

                    entry._parent = table;
                    table._list.Add(entry);
                }
            }
        }
예제 #18
0
        internal static unsafe ImportModuleTable Load(IBinaryAccessor accessor, PEImage image)
        {
            ImportTableHeader header;

            fixed(byte *pBuff = accessor.ReadBytes(sizeof(ImportTableHeader)))
            {
                header = *(ImportTableHeader *)pBuff;
            }

            if (header.Name == 0 || (header.ImportLookupTableRVA == 0 && header.ImportAddressTableRVA == 0))
            {
                return(null);
            }

            // Save position
            long position = accessor.Position;

            var module = new ImportModuleTable();

            module._forwarderChain = header.ForwarderChain;

            // Dll name
            accessor.Position = image.ResolvePositionToSectionData(header.Name);
            module._dllName   = accessor.ReadNullTerminatedString(Encoding.ASCII);

            // Set RVA to ImportLookupTable or ImportAddressTable. Both tables are equivalent.
            if (header.ImportLookupTableRVA != 0)
            {
                accessor.Position = image.ResolvePositionToSectionData(header.ImportLookupTableRVA);
            }
            else
            {
                accessor.Position = image.ResolvePositionToSectionData(header.ImportAddressTableRVA);
            }

            if (image.Is32Bits)
            {
                // Read IMAGE_THUNK_DATA32 structures
                var thunkDataList = new List <uint>();
                while (true)
                {
                    uint entryData = accessor.ReadUInt32();
                    if (entryData == 0)
                    {
                        break;
                    }

                    thunkDataList.Add(entryData);
                }

                foreach (uint thunkData in thunkDataList)
                {
                    string name = null;
                    int    ordinal;
                    if ((thunkData & 0x80000000) != 0)
                    {
                        // Import by ordinal.
                        ordinal = (int)(thunkData & 0x7fffffff);
                    }
                    else
                    {
                        // Import by name.
                        uint hintNameRVA = (thunkData & 0x7fffffff);
                        accessor.Position = image.ResolvePositionToSectionData(hintNameRVA);
                        ordinal           = accessor.ReadUInt16();
                        name = accessor.ReadNullTerminatedString(Encoding.ASCII);
                    }

                    var entry = new ImportEntry(name, ordinal);
                    entry._parent = module;
                    module._list.Add(entry);
                }
            }
            else
            {
                // Read IMAGE_THUNK_DATA64 structures
                var thunkDataList = new List <ulong>();
                while (true)
                {
                    ulong entryData = accessor.ReadUInt64();
                    if (entryData == 0)
                    {
                        break;
                    }

                    thunkDataList.Add(entryData);
                }

                foreach (ulong thunkData in thunkDataList)
                {
                    string name = null;
                    int    ordinal;
                    if ((thunkData & 0x8000000000000000) != 0)
                    {
                        // Import by ordinal.
                        ordinal = (int)(thunkData & 0x7fffffffffffffff);
                    }
                    else
                    {
                        // Import by name.
                        uint hintNameRVA = (uint)(thunkData & 0x7fffffffffffffff);
                        accessor.Position = image.ResolvePositionToSectionData(hintNameRVA);
                        ordinal           = accessor.ReadUInt16();
                        name = accessor.ReadNullTerminatedString(Encoding.ASCII);
                    }

                    var entry = new ImportEntry(name, ordinal);
                    entry._parent = module;
                    module._list.Add(entry);
                }
            }

            // Restore position
            accessor.Position = position;

            return(module);
        }