Example #1
0
        internal void Attach(BuildSection section)
        {
            if (_section != null)
            {
                throw new BuildException(SR.BuildBlobAlreadyAttached);
            }

            _section = section;
        }
Example #2
0
        public override void Build()
        {
            if (_table == null || _table.Count == 0)
            {
                return;
            }

            _state = new State();

            var _tableData = new TableData();

            _tableData.Table = _table;

            BuildTable(_tableData);
            BuildEntries(_tableData);

            _state.StringPos          = _state.TreeSize;
            _state.DataDescriptionPos = _state.StringPos + _state.StringSize;
            _state.DataPos            = _state.DataDescriptionPos + _state.DataDescriptionSize;
            _state.DataPos            = _state.DataPos.Align(4);

            WriteTable(_tableData);
            WriteChildTables(_tableData);

            // Set data directories
            PE.Fixups.Add(
                new PEBuilder.SetDataDirectoryFromBlobRVAFixup(
                    DataDirectories.ResourceTable, _state.Blob));

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

            section.Blobs.Add(_state.Blob, _blobPriority);

            // Set state
            _blob = _state.Blob;

            _state = null;
        }
        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);
        }
 internal BuildBlobCollection(BuildSection section)
 {
     _section = section;
 }
        public BuildSection GetSection(string name)
        {
            var section = _sections.FirstOrDefault(s => s.Name == name);

            if (section == null)
            {
                section      = new BuildSection();
                section.Name = name;

                switch (name)
                {
                // Executable code (free format)
                case PESectionNames.Text:
                    section.Priority        = 1000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsCode |
                        SectionCharacteristics.MemExecute |
                        SectionCharacteristics.MemoryRead;
                    break;

                // Initialized data (free format)
                case PESectionNames.Data:
                case PESectionNames.SData:
                    section.Priority        = 2000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsInitializedData |
                        SectionCharacteristics.MemoryRead |
                        SectionCharacteristics.MemoryWrite;
                    break;

                // Export tables
                case PESectionNames.EData:
                    section.Priority        = 3000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsInitializedData |
                        SectionCharacteristics.MemoryRead;
                    break;

                // Import tables
                case PESectionNames.IData:
                    section.Priority        = 4000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsInitializedData |
                        SectionCharacteristics.MemoryRead |
                        SectionCharacteristics.MemoryWrite;
                    break;

                // Exception information
                case PESectionNames.PData:
                    section.Priority        = 5000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsInitializedData |
                        SectionCharacteristics.MemoryRead;
                    break;

                // Read-only initialized data
                case PESectionNames.RData:
                    section.Priority        = 6000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsInitializedData |
                        SectionCharacteristics.MemoryRead;
                    break;

                // Thread-local storage
                case PESectionNames.Tls:
                    section.Priority        = 7000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsInitializedData |
                        SectionCharacteristics.MemoryRead |
                        SectionCharacteristics.MemoryWrite;
                    break;

                // Resource directory
                case PESectionNames.Rsrc:
                    section.Priority        = 8000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsInitializedData |
                        SectionCharacteristics.MemoryRead;
                    break;

                // Image relocations
                case PESectionNames.Reloc:
                    section.Priority        = 9000;
                    section.Characteristics =
                        SectionCharacteristics.ContainsInitializedData |
                        SectionCharacteristics.MemDiscardable |
                        SectionCharacteristics.MemoryRead;
                    break;

                default:
                    throw new NotImplementedException(string.Format("Section name '{0}' is not supported.", name));
                }

                Sections.Add(section, section.Priority);
            }

            return(section);
        }
        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);
        }
Example #7
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);
        }
Example #9
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);
        }