public override void ApplyFixup()
            {
                // Sort blocks by RVA
                _blocks.Sort(delegate(BuildBlock block1, BuildBlock block2)
                {
                    return(Comparer <uint> .Default.Compare(block1.Blob.RVA, block2.Blob.RVA));
                });

                int pos = 0;

                foreach (var block in _blocks)
                {
                    uint pageRVA = block.Blob.RVA + (uint)block.Offset;
                    _blob.Write(ref pos, (uint)pageRVA);                     // PageRVA

                    int entrySize        = (block.Entries.Count * 2);
                    int alignedEntrySize = entrySize.Align(4);
                    int blockSize        = 8 + alignedEntrySize;
                    _blob.Write(ref pos, (int)blockSize);                     // BlockSize

                    foreach (var entry in block.Entries)
                    {
                        ushort value = (ushort)(((uint)entry.Offset & 0xFFF) | ((uint)entry.Type << 12));
                        _blob.Write(ref pos, (ushort)value);
                    }

                    int alignCount = alignedEntrySize - entrySize;
                    if (alignCount > 0)
                    {
                        _blob.Write(ref pos, 0, alignCount);
                    }
                }
            }
 public override void ApplyFixup()
 {
     if (PE.Is32Bits)
     {
         _blob.Write(ref _pos, (uint)(PE.ImageBase + _rvaBlob.RVA + (uint)_offset));
     }
     else
     {
         _blob.Write(ref _pos, (ulong)(PE.ImageBase + _rvaBlob.RVA + (uint)_offset));
     }
 }
Esempio n. 3
0
 public override void ApplyFixup()
 {
     if (PE.Is32Bits)
     {
         uint hintNameRVA = (uint)((_blob.RVA + _hintNameTablePos) & 0x7fffffff);
         _blob.Write(ref _pos, (uint)hintNameRVA);
     }
     else
     {
         ulong hintNameRVA = (ulong)((_blob.RVA + _hintNameTablePos) & 0x7fffffffffffffff);
         _blob.Write(ref _pos, (ulong)hintNameRVA);
     }
 }
        public override void Build()
        {
            if (_table == null || _table.Count == 0)
            {
                return;
            }

            _blob = new BuildBlob();

            int pos = 0;

            for (int i = 0; i < _table.Count; i++)
            {
                var entry = _table[i];

                if (entry.Data == null)
                {
                    continue;
                }

                int alignLength = entry.Data.Length.Align(8);

                int length = 8 + alignLength;
                _blob.Write(ref pos, (int)length);
                _blob.Write(ref pos, (ushort)entry.Revision);
                _blob.Write(ref pos, (ushort)entry.Type);
                _blob.Write(ref pos, entry.Data);

                int alignCount = alignLength - entry.Data.Length;
                if (alignCount > 0)
                {
                    _blob.Write(ref pos, 0, alignCount);
                }
            }

            // Set data directories
            PE.Fixups.Add(new SetDataDirectoryFixup(_blob));

            // Add blobs
            var section = PE.GetSection(_sectionName);

            section.Blobs.Add(_blob, _blobPriority);
        }
        public override void Build()
        {
            if (_table == null)
            {
                return;
            }

            _blob = new BuildBlob();

            // Calculate
            int addressTablePos  = 40;            // entry header
            int addressTableSize = _table.Count * 4;
            int nameTableSize    = (_table.DllName ?? "").Length + 1;
            var ordinals         = new List <int>();

            for (int i = 0; i < _table.Count; i++)
            {
                var entry = _table[i];

                if (!string.IsNullOrEmpty(entry.Name))
                {
                    nameTableSize += entry.Name.Length + 1;
                    ordinals.Add(i);
                }

                if (entry is BuildForwarderEntry)
                {
                    var forwarderEntry = (BuildForwarderEntry)entry;
                    nameTableSize += forwarderEntry.Forwarder.Length + 1;
                }
            }

            ordinals.Sort(delegate(int x, int y)
            {
                return(string.Compare(_table[x].Name, _table[y].Name));
            });

            int namePointerTablePos  = addressTablePos + addressTableSize;
            int namePointerTableSize = ordinals.Count * 4;
            int ordinalTablePos      = namePointerTablePos + namePointerTableSize;
            int ordinalTableSize     = ordinals.Count * 2;
            int nameTablePos         = ordinalTablePos + ordinalTableSize;

            // Write
            // Header
            int headerPos = 0;

            _blob.Write(ref headerPos, (uint)0);             // Characteristics
            _blob.Write(ref headerPos, (uint)PE.TimeDateStamp.To_time_t());
            _blob.Write(ref headerPos, (ushort)_table.MajorVersion);
            _blob.Write(ref headerPos, (ushort)_table.MinorVersion);

            PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, nameTablePos));
            _blob.Write(ref headerPos, (uint)0);                  // Name

            _blob.Write(ref headerPos, (uint)_table.OrdinalBase); // Base
            _blob.Write(ref headerPos, (uint)_table.Count);       // NumberOfFunctions
            _blob.Write(ref headerPos, (uint)ordinals.Count);     // NumberOfNames

            PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, addressTablePos));
            _blob.Write(ref headerPos, (uint)0);             // AddressOfFunctions

            PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, namePointerTablePos));
            _blob.Write(ref headerPos, (uint)0);             // AddressOfNames

            PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, ordinalTablePos));
            _blob.Write(ref headerPos, (uint)0);             // AddressOfNameOrdinals

            // Dll name
            string dllName = _table.DllName + '\0';

            _blob.Write(ref nameTablePos, dllName, Encoding.ASCII);

            // Export Address Table
            for (int i = 0; i < _table.Count; i++)
            {
                var entry = _table[i];
                if (entry is BuildRVAEntry)
                {
                    var rvaEntry = (BuildRVAEntry)entry;

                    PE.Fixups.Add(new WriteFunctionRVAFixup(_blob, addressTablePos, rvaEntry));
                    _blob.Write(ref addressTablePos, (uint)0);
                }
                else
                {
                    var forwarderEntry = (BuildForwarderEntry)entry;

                    PE.Fixups.Add(new WriteRVAFixup(_blob, addressTablePos, nameTablePos));
                    _blob.Write(ref addressTablePos, (uint)0);

                    string forwarder = forwarderEntry.Forwarder + '\0';
                    _blob.Write(ref nameTablePos, forwarder, Encoding.ASCII);
                }
            }

            // Name pointer/Ordinal
            for (int i = 0; i < ordinals.Count; i++)
            {
                int ordinal = ordinals[i];

                PE.Fixups.Add(new WriteRVAFixup(_blob, namePointerTablePos, nameTablePos));
                _blob.Write(ref namePointerTablePos, (uint)0);

                _blob.Write(ref ordinalTablePos, (ushort)ordinal);

                string name = _table[ordinal].Name + '\0';
                _blob.Write(ref nameTablePos, name, Encoding.ASCII);
            }

            // Set data directories
            PE.Fixups.Add(
                new PEBuilder.SetDataDirectoryFromBlobRVAFixup(
                    DataDirectories.ExportTable, _blob));

            // Add blobs
            BuildSection section = PE.GetSection(_sectionName);

            section.Blobs.Add(_blob, _blobPriority);
        }
            public override void ApplyFixup()
            {
                uint rva = (uint)(_rvaEntry.Blob.RVA + _rvaEntry.Offset);

                _blob.Write(ref _pos, rva);
            }
        public unsafe override void Build()
        {
            if (_dataBlob == null || _dataBlob.Length == 0)
            {
                return;
            }

            var relocBuilder = PE.Tasks.Get <BaseRelocationBuilder>();

            if (relocBuilder == null)
            {
                return;
            }

            var relocTable = relocBuilder.GetOrCreateTable();

            _blob = new BuildBlob();

            int pos = 0;

            if (PE.Is32Bits)
            {
                // Header
                PE.Fixups.Add(new WriteVAFixup(_blob, pos, _dataBlob, 0));
                relocTable.Add(_blob, pos, BaseRelocationType.HIGHLOW);
                _blob.Write(ref pos, (uint)0);                 // StartAddressOfRawData

                PE.Fixups.Add(new WriteVAFixup(_blob, pos, _dataBlob, _dataBlob.Length));
                relocTable.Add(_blob, pos, BaseRelocationType.HIGHLOW);
                _blob.Write(ref pos, (uint)0);                  // EndAddressOfRawData

                PE.Fixups.Add(new WriteVAFixup(_blob, pos, _dataBlob, sizeof(TLSHeader32) + 4));
                relocTable.Add(_blob, pos, BaseRelocationType.HIGHLOW);
                _blob.Write(ref pos, (uint)0);                 // AddressOfIndex

                PE.Fixups.Add(new WriteVAFixup(_blob, pos, _dataBlob, sizeof(TLSHeader32)));
                relocTable.Add(_blob, pos, BaseRelocationType.HIGHLOW);
                _blob.Write(ref pos, (uint)0);                // AddressOfCallBacks

                _blob.Write(ref pos, (int)0);                 // SizeOfZeroFill
                _blob.Write(ref pos, (uint)0);                // Characteristics

                // CallBacks
                _blob.Write(ref pos, (uint)0);

                // Index
                _blob.Write(ref pos, (uint)0xCCCCCCCC);                 // Does't really matter, the OS will fill it in
            }
            else
            {
                PE.Fixups.Add(new WriteVAFixup(_blob, pos, _dataBlob, 0));
                relocTable.Add(_blob, pos, BaseRelocationType.HIGHLOW);
                _blob.Write(ref pos, (ulong)0);                 // StartAddressOfRawData

                PE.Fixups.Add(new WriteVAFixup(_blob, pos, _dataBlob, _dataBlob.Length));
                relocTable.Add(_blob, pos, BaseRelocationType.HIGHLOW);
                _blob.Write(ref pos, (ulong)0);                  // EndAddressOfRawData

                PE.Fixups.Add(new WriteVAFixup(_blob, pos, _dataBlob, sizeof(TLSHeader64) + 8));
                relocTable.Add(_blob, pos, BaseRelocationType.HIGHLOW);
                _blob.Write(ref pos, (ulong)0);                 // AddressOfIndex

                PE.Fixups.Add(new WriteVAFixup(_blob, pos, _dataBlob, sizeof(TLSHeader64)));
                relocTable.Add(_blob, pos, BaseRelocationType.HIGHLOW);
                _blob.Write(ref pos, (ulong)0);               // AddressOfCallBacks

                _blob.Write(ref pos, (int)0);                 // SizeOfZeroFill
                _blob.Write(ref pos, (uint)0);                // Characteristics

                // CallBacks
                _blob.Write(ref pos, (ulong)0);

                // Index
                _blob.Write(ref pos, (ulong)0xCCCCCCCC);                 // Does't really matter, the OS will fill it in
            }

            // Set data directories
            PE.Fixups.Add(new SetDataDirectoryFixup(_blob));

            // Add _blobs
            BuildSection section = PE.GetSection(_sectionName);

            section.Blobs.Add(_blob, _blobPriority);
        }
Esempio n. 8
0
        public override void Build()
        {
            if (_info == null)
            {
                return;
            }

            var _blob = new BuildBlob();

            int pos = 0;

            if (PE.Is32Bits)
            {
                _blob.Write(ref pos, (int)_info.Characteristics);
                _blob.Write(ref pos, (int)_info.TimeDateStamp.To_time_t());
                _blob.Write(ref pos, (short)_info.MajorVersion);
                _blob.Write(ref pos, (short)_info.MinorVersion);
                _blob.Write(ref pos, (uint)_info.GlobalFlagsClear);
                _blob.Write(ref pos, (uint)_info.GlobalFlagsSet);
                _blob.Write(ref pos, (int)_info.CriticalSectionDefaultTimeout);
                _blob.Write(ref pos, (int)_info.DeCommitFreeBlockThreshold);
                _blob.Write(ref pos, (int)_info.DeCommitTotalFreeThreshold);
                _blob.Write(ref pos, (uint)_info.LockPrefixTable);
                _blob.Write(ref pos, (int)_info.MaximumAllocationSize);
                _blob.Write(ref pos, (int)_info.VirtualMemoryThreshold);
                _blob.Write(ref pos, (int)_info.ProcessHeapFlags);
                _blob.Write(ref pos, (uint)_info.ProcessAffinityMask);
                _blob.Write(ref pos, (short)_info.CSDVersion);
                _blob.Write(ref pos, (short)_info.Reserved1);
                _blob.Write(ref pos, (uint)_info.EditList);
                _blob.Write(ref pos, (uint)_info.SecurityCookie);
                _blob.Write(ref pos, (uint)_info.SEHandlerTable);
                _blob.Write(ref pos, (uint)_info.SEHandlerCount);
            }
            else
            {
                _blob.Write(ref pos, (int)_info.Characteristics);
                _blob.Write(ref pos, (int)_info.TimeDateStamp.To_time_t());
                _blob.Write(ref pos, (short)_info.MajorVersion);
                _blob.Write(ref pos, (short)_info.MinorVersion);
                _blob.Write(ref pos, (uint)_info.GlobalFlagsClear);
                _blob.Write(ref pos, (uint)_info.GlobalFlagsSet);
                _blob.Write(ref pos, (int)_info.CriticalSectionDefaultTimeout);
                _blob.Write(ref pos, (long)_info.DeCommitFreeBlockThreshold);
                _blob.Write(ref pos, (long)_info.DeCommitTotalFreeThreshold);
                _blob.Write(ref pos, (ulong)_info.LockPrefixTable);
                _blob.Write(ref pos, (long)_info.MaximumAllocationSize);
                _blob.Write(ref pos, (long)_info.VirtualMemoryThreshold);
                _blob.Write(ref pos, (ulong)_info.ProcessAffinityMask);
                _blob.Write(ref pos, (int)_info.ProcessHeapFlags);
                _blob.Write(ref pos, (short)_info.CSDVersion);
                _blob.Write(ref pos, (short)_info.Reserved1);
                _blob.Write(ref pos, (ulong)_info.EditList);
                _blob.Write(ref pos, (ulong)_info.SecurityCookie);
                _blob.Write(ref pos, (ulong)_info.SEHandlerTable);
                _blob.Write(ref pos, (ulong)_info.SEHandlerCount);
            }

            // Set data directories
            // For compatibility with Windows XP and earlier versions of Windows,
            // the size must be 64 for x86 images.
            PE.Fixups.Add(
                new PEBuilder.SetDataDirectoryFromBlobRVAFixup(
                    DataDirectories.LoadConfigTable, _blob, 0, 64));

            // Add _blobs
            BuildSection section = PE.GetSection(_sectionName);

            section.Blobs.Add(_blob, _blobPriority);
        }
        public override void Build()
        {
            if (_table == null || _table.Count == 0)
            {
                return;
            }

            _blob    = new BuildBlob();
            _iatBlob = new BuildBlob();

            // Calculate
            int lookupTableSize   = 0;
            int hintNameTableSize = 0;
            int lookupEntrySize   = PE.Is32Bits ? 4 : 8;

            for (int i = 0; i < _table.Count; i++)
            {
                var module = _table[i];

                for (int j = 0; j < module.Count; j++)
                {
                    var entry = module[j];

                    lookupTableSize += lookupEntrySize;

                    if (!string.IsNullOrEmpty(entry.Name))
                    {
                        hintNameTableSize += 2;                         // hint
                        hintNameTableSize += entry.Name.Length + 1;
                    }
                }

                lookupTableSize += lookupEntrySize;                 // null
            }

            int iatPos           = 0;
            int lookupTablePos   = (_table.Count + 1) * 20;           // header + null
            int hintNameTablePos = lookupTablePos + lookupTableSize;
            int dllNamePos       = hintNameTablePos + hintNameTableSize;

            // Write
            int headerPos = 0;

            for (int i = 0; i < _table.Count; i++)
            {
                var module = _table[i];

                // Header
                PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, lookupTablePos));
                _blob.Write(ref headerPos, (uint)0);                    // ImportLookupTableRVA

                _blob.Write(ref headerPos, (uint)0);                    // TimeDateStamp

                _blob.Write(ref headerPos, (int)module.ForwarderChain); // ForwarderChain

                PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, dllNamePos));
                _blob.Write(ref headerPos, (uint)0);                 // Name

                PE.Fixups.Add(new WriteRVAFixup(_blob, _iatBlob, headerPos, iatPos));
                _blob.Write(ref headerPos, (uint)0);                 // ImportAddressTableRVA

                // DllName
                string dllName = (module.DllName ?? "") + '\0';
                _blob.Write(ref dllNamePos, dllName, Encoding.ASCII);

                // ImportLookupTable / ImportAddressTable
                for (int j = 0; j < module.Count; j++)
                {
                    var entry = module[j];

                    if (PE.Is32Bits)
                    {
                        if (!string.IsNullOrEmpty(entry.Name))
                        {
                            // Import by name.
                            PE.Fixups.Add(
                                new WriteHintNameRVAFixup(
                                    _blob, _iatBlob, lookupTablePos, iatPos, hintNameTablePos));
                            _blob.Write(ref lookupTablePos, (uint)0);
                            _iatBlob.Write(ref iatPos, (uint)0);

                            // Hint/Name
                            _blob.Write(ref hintNameTablePos, (ushort)entry.Ordinal);
                            string name = entry.Name + '\0';
                            _blob.Write(ref hintNameTablePos, name, Encoding.ASCII);
                        }
                        else
                        {
                            // Import by ordinal.
                            uint ordinal = (uint)entry.Ordinal | 0x80000000;
                            _blob.Write(ref lookupTablePos, (uint)ordinal);
                            _iatBlob.Write(ref iatPos, (uint)ordinal);
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(entry.Name))
                        {
                            // Import by name.
                            PE.Fixups.Add(
                                new WriteHintNameRVAFixup(
                                    _blob, _iatBlob, lookupTablePos, iatPos, hintNameTablePos));
                            _blob.Write(ref lookupTablePos, (ulong)0);
                            _iatBlob.Write(ref iatPos, (ulong)0);

                            // Hint/Name
                            _blob.Write(ref hintNameTablePos, (ushort)entry.Ordinal);
                            string name = entry.Name + '\0';
                            _blob.Write(ref hintNameTablePos, name, Encoding.ASCII);
                        }
                        else
                        {
                            // Import by ordinal.
                            ulong ordinal = (uint)entry.Ordinal | 0x8000000000000000;
                            _blob.Write(ref lookupTablePos, (ulong)ordinal);
                            _iatBlob.Write(ref iatPos, (ulong)ordinal);
                        }
                    }
                }

                if (PE.Is32Bits)
                {
                    // Null ImportLookupTable / ImportAddressTable
                    _blob.Write(ref lookupTablePos, 0, 4);
                    _iatBlob.Write(ref iatPos, 0, 4);
                }
                else
                {
                    // Null ImportLookupTable / ImportAddressTable
                    _blob.Write(ref lookupTablePos, 0, 8);
                    _iatBlob.Write(ref iatPos, 0, 8);
                }
            }

            // Null header
            _blob.Write(ref headerPos, 0, 20);

            // Set data directories
            PE.Fixups.Add(
                new PEBuilder.SetDataDirectoryFromBlobRVAFixup(
                    DataDirectories.ImportTable, _blob));

            PE.Fixups.Add(
                new PEBuilder.SetDataDirectoryFromBlobRVAFixup(
                    DataDirectories.IAT, _iatBlob));

            // Add _blobs
            BuildSection section = PE.GetSection(_sectionName);

            section.Blobs.Add(_blob, _blobPriority);

            BuildSection iatSection = PE.GetSection(_iatSectionName);

            iatSection.Blobs.Add(_iatBlob, _iatBlobPriority);
        }
Esempio n. 10
0
        public override void Build()
        {
            if (_table == null || _table.Count == 0)
            {
                return;
            }

            _blob = new BuildBlob();

            // Calculate
            int iatSize = 0;
            int namePointerTableSize = 0;
            int namePointerSize      = PE.Is32Bits ? 4 : 8;
            int hintNameTableSize    = 0;

            for (int i = 0; i < _table.Count; i++)
            {
                var module = _table[i];

                for (int j = 0; j < module.Count; j++)
                {
                    var entry = module[j];

                    iatSize += 4;
                    namePointerTableSize += namePointerSize;

                    if (!string.IsNullOrEmpty(entry.Name))
                    {
                        hintNameTableSize += 2;                         // hint
                        hintNameTableSize += entry.Name.Length + 1;
                    }
                }

                iatSize += 4;                            // null IAT
                namePointerTableSize += namePointerSize; // null
            }

            int iatPos = (_table.Count + 1) * 32;             // header + null;
            int namePointerTablePos = iatPos + iatSize;
            int hintNameTablePos    = namePointerTablePos + namePointerTableSize;
            int dllNamePos          = hintNameTablePos + hintNameTableSize;

            // Write
            int headerPos = 0;

            for (int i = 0; i < _table.Count; i++)
            {
                var module = _table[i];

                // Header
                _blob.Write(ref headerPos, (uint)0);                 // Attributes

                PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, dllNamePos));
                _blob.Write(ref headerPos, (uint)0);                      // Name

                _blob.Write(ref headerPos, (uint)module.ModuleHandleRVA); // ModuleHandle

                PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, iatPos));
                _blob.Write(ref headerPos, (uint)0);                 // DelayImportAddressTable

                PE.Fixups.Add(new WriteRVAFixup(_blob, headerPos, namePointerTablePos));
                _blob.Write(ref headerPos, (uint)0);                 // DelayImportNameTable
                _blob.Write(ref headerPos, (uint)0);                 // BoundDelayImportTable
                _blob.Write(ref headerPos, (uint)0);                 // UnloadDelayImportTable
                _blob.Write(ref headerPos, (uint)0);                 // TimeDateStamp

                // DllName
                string dllName = (module.DllName ?? "") + '\0';
                _blob.Write(ref dllNamePos, dllName, Encoding.ASCII);

                // DelayImportNameTable
                for (int j = 0; j < module.Count; j++)
                {
                    var entry = module[j];

                    _blob.Write(ref iatPos, (uint)entry.FuncRVA);

                    if (PE.Is32Bits)
                    {
                        if (!string.IsNullOrEmpty(entry.Name))
                        {
                            // DelayImport by name.
                            PE.Fixups.Add(
                                new WriteHintNameRVAFixup(
                                    _blob, namePointerTablePos, hintNameTablePos));
                            _blob.Write(ref namePointerTablePos, (uint)0);

                            // Hint/Name
                            _blob.Write(ref hintNameTablePos, (ushort)entry.Ordinal);
                            string name = entry.Name + '\0';
                            _blob.Write(ref hintNameTablePos, name, Encoding.ASCII);
                        }
                        else
                        {
                            // DelayImport by ordinal.
                            uint ordinal = (uint)entry.Ordinal | 0x80000000;
                            _blob.Write(ref namePointerTablePos, (uint)ordinal);
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(entry.Name))
                        {
                            // DelayImport by name.
                            PE.Fixups.Add(
                                new WriteHintNameRVAFixup(
                                    _blob, namePointerTablePos, hintNameTablePos));
                            _blob.Write(ref namePointerTablePos, (ulong)0);

                            // Hint/Name
                            _blob.Write(ref hintNameTablePos, (ushort)entry.Ordinal);
                            string name = entry.Name + '\0';
                            _blob.Write(ref hintNameTablePos, name, Encoding.ASCII);
                        }
                        else
                        {
                            // DelayImport by ordinal.
                            ulong ordinal = (uint)entry.Ordinal | 0x8000000000000000;
                            _blob.Write(ref namePointerTablePos, (ulong)ordinal);
                        }
                    }
                }

                // Null IAT
                _blob.Write(ref iatPos, 0, 4);

                // Null DelayImportNameTable
                if (PE.Is32Bits)
                {
                    _blob.Write(ref namePointerTablePos, 0, 4);
                }
                else
                {
                    _blob.Write(ref namePointerTablePos, 0, 8);
                }
            }

            // Null header
            _blob.Write(ref headerPos, 0, 32);

            // Set data directories
            PE.Fixups.Add(
                new PEBuilder.SetDataDirectoryFromBlobRVAFixup(
                    DataDirectories.DelayImportDescriptor, _blob));

            // Add blobs
            BuildSection section = PE.GetSection(_sectionName);

            section.Blobs.Add(_blob, _blobPriority);
        }