internal void Attach(BuildSection section) { if (_section != null) { throw new BuildException(SR.BuildBlobAlreadyAttached); } _section = section; }
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); }
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); }
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); }