5
// Jb Evain (jbevain@gmail.com)
7
// Copyright (c) 2008 - 2010 Jb Evain
9
// Permission is hereby granted, free of charge, to any person obtaining
10
// a copy of this software and associated documentation files (the
11
// "Software"), to deal in the Software without restriction, including
12
// without limitation the rights to use, copy, modify, merge, publish,
13
// distribute, sublicense, and/or sell copies of the Software, and to
14
// permit persons to whom the Software is furnished to do so, subject to
15
// the following conditions:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
using Mono.Cecil.Metadata;
37
using RVA = System.UInt32;
39
namespace Mono.Cecil.PE {
41
sealed class ImageWriter : BinaryStreamWriter {
43
readonly ModuleDefinition module;
44
readonly MetadataBuilder metadata;
45
readonly TextMap text_map;
47
ImageDebugDirectory debug_directory;
50
ByteBuffer win32_resources;
52
const uint pe_header_size = 0x178u;
53
const uint section_header_size = 0x28u;
54
const uint file_alignment = 0x200;
55
const uint section_alignment = 0x2000;
56
const ulong image_base = 0x00400000;
58
internal const RVA text_rva = 0x2000;
61
readonly uint time_stamp;
63
internal Section text;
64
internal Section rsrc;
65
internal Section reloc;
69
ImageWriter (ModuleDefinition module, MetadataBuilder metadata, Stream stream)
73
this.metadata = metadata;
74
this.GetDebugHeader ();
75
this.GetWin32Resources ();
76
this.text_map = BuildTextMap ();
77
this.sections = 2; // text + reloc
78
this.pe64 = module.Architecture != TargetArchitecture.I386;
79
this.time_stamp = (uint) DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds;
82
void GetDebugHeader ()
84
var symbol_writer = metadata.symbol_writer;
85
if (symbol_writer == null)
88
if (!symbol_writer.GetDebugHeader (out debug_directory, out debug_data))
89
debug_data = Empty<byte>.Array;
92
void GetWin32Resources ()
94
var rsrc = GetImageResourceSection ();
98
var raw_resources = new byte [rsrc.Data.Length];
99
Buffer.BlockCopy (rsrc.Data, 0, raw_resources, 0, rsrc.Data.Length);
100
win32_resources = new ByteBuffer (raw_resources);
103
Section GetImageResourceSection ()
105
if (!module.HasImage)
108
const string rsrc_section = ".rsrc";
110
return module.Image.GetSection (rsrc_section);
113
public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Stream stream)
115
var writer = new ImageWriter (module, metadata, stream);
116
writer.BuildSections ();
120
void BuildSections ()
122
var has_win32_resources = win32_resources != null;
123
if (has_win32_resources)
126
text = CreateSection (".text", text_map.GetLength (), null);
129
if (has_win32_resources) {
130
rsrc = CreateSection (".rsrc", (uint) win32_resources.length, previous);
132
PatchWin32Resources (win32_resources);
136
reloc = CreateSection (".reloc", 12u, previous);
139
Section CreateSection (string name, uint size, Section previous)
143
VirtualAddress = previous != null
144
? previous.VirtualAddress + Align (previous.VirtualSize, section_alignment)
147
PointerToRawData = previous != null
148
? previous.PointerToRawData + previous.SizeOfRawData
149
: Align (GetHeaderSize (), file_alignment),
150
SizeOfRawData = Align (size, file_alignment)
154
static uint Align (uint value, uint align)
157
return (value + align) & ~align;
160
void WriteDOSHeader ()
164
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00,
165
0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff,
166
0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00,
167
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
168
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172
0x00, 0x00, 0x00, 0x00,
174
0x80, 0x00, 0x00, 0x00,
176
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09,
177
0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21,
178
0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72,
179
0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x63,
180
0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62,
181
0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69,
182
0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, 0x6d,
183
0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,
184
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189
void WritePEFileHeader ()
191
WriteUInt32 (0x00004550); // Magic
192
WriteUInt16 (GetMachine ()); // Machine
193
WriteUInt16 (sections); // NumberOfSections
194
WriteUInt32 (time_stamp);
195
WriteUInt32 (0); // PointerToSymbolTable
196
WriteUInt32 (0); // NumberOfSymbols
197
WriteUInt16 ((ushort) (!pe64 ? 0xe0 : 0xf0)); // SizeOfOptionalHeader
199
// ExecutableImage | (pe64 ? 32BitsMachine : LargeAddressAware)
200
var characteristics = (ushort) (0x0002 | (!pe64 ? 0x0100 : 0x0020));
201
if (module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule)
202
characteristics |= 0x2000;
203
WriteUInt16 (characteristics); // Characteristics
208
switch (module.Architecture) {
209
case TargetArchitecture.I386:
211
case TargetArchitecture.AMD64:
213
case TargetArchitecture.IA64:
217
throw new NotSupportedException ();
220
void WriteOptionalHeaders ()
222
WriteUInt16 ((ushort) (!pe64 ? 0x10b : 0x20b)); // Magic
223
WriteByte (8); // LMajor
224
WriteByte (0); // LMinor
225
WriteUInt32 (text.SizeOfRawData); // CodeSize
226
WriteUInt32 (reloc.SizeOfRawData
227
+ (rsrc != null ? rsrc.SizeOfRawData : 0)); // InitializedDataSize
228
WriteUInt32 (0); // UninitializedDataSize
230
var entry_point_rva = text_map.GetRVA (TextSegment.StartupStub);
231
if (module.Architecture == TargetArchitecture.IA64)
232
entry_point_rva += 0x20;
233
WriteUInt32 (entry_point_rva); // EntryPointRVA
234
WriteUInt32 (text_rva); // BaseOfCode
237
WriteUInt32 (0); // BaseOfData
238
WriteUInt32 ((uint) image_base); // ImageBase
240
WriteUInt64 (image_base); // ImageBase
243
WriteUInt32 (section_alignment); // SectionAlignment
244
WriteUInt32 (file_alignment); // FileAlignment
246
WriteUInt16 (4); // OSMajor
247
WriteUInt16 (0); // OSMinor
248
WriteUInt16 (0); // UserMajor
249
WriteUInt16 (0); // UserMinor
250
WriteUInt16 (4); // SubSysMajor
251
WriteUInt16 (0); // SubSysMinor
252
WriteUInt32 (0); // Reserved
254
WriteUInt32 (reloc.VirtualAddress + Align (reloc.VirtualSize, section_alignment)); // ImageSize
255
WriteUInt32 (text.PointerToRawData); // HeaderSize
257
WriteUInt32 (0); // Checksum
258
WriteUInt16 (GetSubSystem ()); // SubSystem
259
WriteUInt16 (0x8540); // DLLFlags
261
const ulong stack_reserve = 0x100000;
262
const ulong stack_commit = 0x1000;
263
const ulong heap_reserve = 0x100000;
264
const ulong heap_commit = 0x1000;
267
WriteUInt32 ((uint) stack_reserve);
268
WriteUInt32 ((uint) stack_commit);
269
WriteUInt32 ((uint) heap_reserve);
270
WriteUInt32 ((uint) heap_commit);
272
WriteUInt64 (stack_reserve);
273
WriteUInt64 (stack_commit);
274
WriteUInt64 (heap_reserve);
275
WriteUInt64 (heap_commit);
278
WriteUInt32 (0); // LoaderFlags
279
WriteUInt32 (16); // NumberOfDataDir
281
WriteZeroDataDirectory (); // ExportTable
282
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.ImportDirectory)); // ImportTable
283
if (rsrc != null) { // ResourceTable
284
WriteUInt32 (rsrc.VirtualAddress);
285
WriteUInt32 (rsrc.VirtualSize);
287
WriteZeroDataDirectory ();
289
WriteZeroDataDirectory (); // ExceptionTable
290
WriteZeroDataDirectory (); // CertificateTable
291
WriteUInt32 (reloc.VirtualAddress); // BaseRelocationTable
292
WriteUInt32 (reloc.VirtualSize);
294
if (text_map.GetLength (TextSegment.DebugDirectory) > 0) {
295
WriteUInt32 (text_map.GetRVA (TextSegment.DebugDirectory));
298
WriteZeroDataDirectory ();
300
WriteZeroDataDirectory (); // Copyright
301
WriteZeroDataDirectory (); // GlobalPtr
302
WriteZeroDataDirectory (); // TLSTable
303
WriteZeroDataDirectory (); // LoadConfigTable
304
WriteZeroDataDirectory (); // BoundImport
305
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.ImportAddressTable)); // IAT
306
WriteZeroDataDirectory (); // DelayImportDesc
307
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.CLIHeader)); // CLIHeader
308
WriteZeroDataDirectory (); // Reserved
311
void WriteZeroDataDirectory ()
317
ushort GetSubSystem ()
319
switch (module.Kind) {
320
case ModuleKind.Console:
322
case ModuleKind.NetModule:
324
case ModuleKind.Windows:
327
throw new ArgumentOutOfRangeException ();
331
void WriteSectionHeaders ()
333
WriteSection (text, 0x60000020);
336
WriteSection (rsrc, 0x40000040);
338
WriteSection (reloc, 0x42000040);
341
void WriteSection (Section section, uint characteristics)
343
var name = new byte [8];
344
var sect_name = section.Name;
345
for (int i = 0; i < sect_name.Length; i++)
346
name [i] = (byte) sect_name [i];
349
WriteUInt32 (section.VirtualSize);
350
WriteUInt32 (section.VirtualAddress);
351
WriteUInt32 (section.SizeOfRawData);
352
WriteUInt32 (section.PointerToRawData);
353
WriteUInt32 (0); // PointerToRelocations
354
WriteUInt32 (0); // PointerToLineNumbers
355
WriteUInt16 (0); // NumberOfRelocations
356
WriteUInt16 (0); // NumberOfLineNumbers
357
WriteUInt32 (characteristics);
360
void MoveTo (uint pointer)
362
BaseStream.Seek (pointer, SeekOrigin.Begin);
365
void MoveToRVA (Section section, RVA rva)
367
BaseStream.Seek (section.PointerToRawData + rva - section.VirtualAddress, SeekOrigin.Begin);
370
void MoveToRVA (TextSegment segment)
372
MoveToRVA (text, text_map.GetRVA (segment));
375
void WriteRVA (RVA rva)
385
MoveTo (text.PointerToRawData);
387
// ImportAddressTable
389
WriteRVA (text_map.GetRVA (TextSegment.ImportHintNameTable));
396
WriteUInt16 ((ushort) ((module.Runtime <= TargetRuntime.Net_1_1) ? 0 : 5));
398
WriteUInt32 (text_map.GetRVA (TextSegment.MetadataHeader));
399
WriteUInt32 (GetMetadataLength ());
400
WriteUInt32 ((uint) module.Attributes);
401
WriteUInt32 (metadata.entry_point.ToUInt32 ());
402
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.Resources));
403
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.StrongNameSignature));
404
WriteZeroDataDirectory (); // CodeManagerTable
405
WriteZeroDataDirectory (); // VTableFixups
406
WriteZeroDataDirectory (); // ExportAddressTableJumps
407
WriteZeroDataDirectory (); // ManagedNativeHeader
411
MoveToRVA (TextSegment.Code);
412
WriteBuffer (metadata.code);
416
MoveToRVA (TextSegment.Resources);
417
WriteBuffer (metadata.resources);
421
if (metadata.data.length > 0) {
422
MoveToRVA (TextSegment.Data);
423
WriteBuffer (metadata.data);
426
// StrongNameSignature
431
MoveToRVA (TextSegment.MetadataHeader);
432
WriteMetadataHeader ();
437
if (text_map.GetLength (TextSegment.DebugDirectory) > 0) {
438
MoveToRVA (TextSegment.DebugDirectory);
439
WriteDebugDirectory ();
443
MoveToRVA (TextSegment.ImportDirectory);
444
WriteImportDirectory ();
447
MoveToRVA (TextSegment.StartupStub);
451
uint GetMetadataLength ()
453
return text_map.GetRVA (TextSegment.DebugDirectory) - text_map.GetRVA (TextSegment.MetadataHeader);
456
void WriteMetadataHeader ()
458
WriteUInt32 (0x424a5342); // Signature
459
WriteUInt16 (1); // MajorVersion
460
WriteUInt16 (1); // MinorVersion
461
WriteUInt32 (0); // Reserved
463
var version = GetZeroTerminatedString (GetVersion ());
464
WriteUInt32 ((uint) version.Length);
465
WriteBytes (version);
466
WriteUInt16 (0); // Flags
467
WriteUInt16 (GetStreamCount ());
469
uint offset = text_map.GetRVA (TextSegment.TableHeap) - text_map.GetRVA (TextSegment.MetadataHeader);
471
WriteStreamHeader (ref offset, TextSegment.TableHeap, "#~");
472
WriteStreamHeader (ref offset, TextSegment.StringHeap, "#Strings");
473
WriteStreamHeader (ref offset, TextSegment.UserStringHeap, "#US");
474
WriteStreamHeader (ref offset, TextSegment.GuidHeap, "#GUID");
475
WriteStreamHeader (ref offset, TextSegment.BlobHeap, "#Blob");
480
switch (module.Runtime) {
481
case TargetRuntime.Net_1_0:
483
case TargetRuntime.Net_1_1:
485
case TargetRuntime.Net_2_0:
487
case TargetRuntime.Net_4_0:
493
ushort GetStreamCount ()
498
+ (metadata.user_string_heap.IsEmpty ? 0 : 1) // #US
500
+ (metadata.blob_heap.IsEmpty ? 0 : 1)); // #Blob
503
void WriteStreamHeader (ref uint offset, TextSegment heap, string name)
505
var length = (uint) text_map.GetLength (heap);
509
WriteUInt32 (offset);
510
WriteUInt32 (length);
511
WriteBytes (GetZeroTerminatedString (name));
515
static byte [] GetZeroTerminatedString (string @string)
517
return GetString (@string, (@string.Length + 1 + 3) & ~3);
520
static byte [] GetSimpleString (string @string)
522
return GetString (@string, @string.Length);
525
static byte [] GetString (string @string, int length)
527
var bytes = new byte [length];
528
for (int i = 0; i < @string.Length; i++)
529
bytes [i] = (byte) @string [i];
534
void WriteMetadata ()
536
WriteHeap (TextSegment.TableHeap, metadata.table_heap);
537
WriteHeap (TextSegment.StringHeap, metadata.string_heap);
538
WriteHeap (TextSegment.UserStringHeap, metadata.user_string_heap);
540
WriteHeap (TextSegment.BlobHeap, metadata.blob_heap);
543
void WriteHeap (TextSegment heap, HeapBuffer buffer)
549
WriteBuffer (buffer);
552
void WriteGuidHeap ()
554
MoveToRVA (TextSegment.GuidHeap);
555
WriteBytes (module.Mvid.ToByteArray ());
558
void WriteDebugDirectory ()
560
WriteInt32 (debug_directory.Characteristics);
561
WriteUInt32 (time_stamp);
562
WriteInt16 (debug_directory.MajorVersion);
563
WriteInt16 (debug_directory.MinorVersion);
564
WriteInt32 (debug_directory.Type);
565
WriteInt32 (debug_directory.SizeOfData);
566
WriteInt32 (debug_directory.AddressOfRawData);
567
WriteInt32 ((int) BaseStream.Position + 4);
569
WriteBytes (debug_data);
572
void WriteImportDirectory ()
574
WriteUInt32 (text_map.GetRVA (TextSegment.ImportDirectory) + 40); // ImportLookupTable
575
WriteUInt32 (0); // DateTimeStamp
576
WriteUInt32 (0); // ForwarderChain
577
WriteUInt32 (text_map.GetRVA (TextSegment.ImportHintNameTable) + 14);
578
WriteUInt32 (text_map.GetRVA (TextSegment.ImportAddressTable));
582
WriteUInt32 (text_map.GetRVA (TextSegment.ImportHintNameTable));
584
// ImportHintNameTable
585
MoveToRVA (TextSegment.ImportHintNameTable);
587
WriteUInt16 (0); // Hint
588
WriteBytes (GetRuntimeMain ());
590
WriteBytes (GetSimpleString ("mscoree.dll"));
594
byte [] GetRuntimeMain ()
596
return module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule
597
? GetSimpleString ("_CorDllMain")
598
: GetSimpleString ("_CorExeMain");
601
void WriteStartupStub ()
603
switch (module.Architecture) {
604
case TargetArchitecture.I386:
605
WriteUInt16 (0x25ff);
606
WriteUInt32 ((uint) image_base + text_map.GetRVA (TextSegment.ImportAddressTable));
608
case TargetArchitecture.AMD64:
609
WriteUInt16 (0xa148);
610
WriteUInt32 ((uint) image_base + text_map.GetRVA (TextSegment.ImportAddressTable));
611
WriteUInt16 (0xe0ff);
613
case TargetArchitecture.IA64:
614
WriteBytes (new byte [] {
615
0x0b, 0x48, 0x00, 0x02, 0x18, 0x10, 0xa0, 0x40, 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00,
616
0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50, 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00
618
WriteUInt32 ((uint) image_base + text_map.GetRVA (TextSegment.StartupStub));
619
WriteUInt32 ((uint) image_base + text_rva);
626
MoveTo (rsrc.PointerToRawData);
627
WriteBuffer (win32_resources);
632
MoveTo (reloc.PointerToRawData);
634
var reloc_rva = text_map.GetRVA (TextSegment.StartupStub);
635
reloc_rva += module.Architecture == TargetArchitecture.IA64 ? 0x20u : 2;
636
var page_rva = reloc_rva & ~0xfffu;
638
WriteUInt32 (page_rva); // PageRVA
639
WriteUInt32 (0x000c); // Block Size
641
switch (module.Architecture) {
642
case TargetArchitecture.I386:
643
WriteUInt32 (0x3000 + reloc_rva - page_rva);
645
case TargetArchitecture.AMD64:
646
WriteUInt32 (0xa000 + reloc_rva - page_rva);
648
case TargetArchitecture.IA64:
649
WriteUInt16 ((ushort) (0xa000 + reloc_rva - page_rva));
650
WriteUInt16 ((ushort) (0xa000 + reloc_rva - page_rva + 8));
654
WriteBytes (new byte [file_alignment - reloc.VirtualSize]);
657
public void WriteImage ()
660
WritePEFileHeader ();
661
WriteOptionalHeaders ();
662
WriteSectionHeaders ();
669
TextMap BuildTextMap ()
671
var map = metadata.text_map;
673
map.AddMap (TextSegment.Code, metadata.code.length, !pe64 ? 4 : 16);
674
map.AddMap (TextSegment.Resources, metadata.resources.length, 8);
675
map.AddMap (TextSegment.Data, metadata.data.length, 4);
676
if (metadata.data.length > 0)
677
metadata.table_heap.FixupData (map.GetRVA (TextSegment.Data));
678
map.AddMap (TextSegment.StrongNameSignature, GetStrongNameLength (), 4);
680
map.AddMap (TextSegment.MetadataHeader, GetMetadataHeaderLength ());
681
map.AddMap (TextSegment.TableHeap, metadata.table_heap.length, 4);
682
map.AddMap (TextSegment.StringHeap, metadata.string_heap.length, 4);
683
map.AddMap (TextSegment.UserStringHeap, metadata.user_string_heap.IsEmpty ? 0 : metadata.user_string_heap.length, 4);
684
map.AddMap (TextSegment.GuidHeap, 16);
685
map.AddMap (TextSegment.BlobHeap, metadata.blob_heap.IsEmpty ? 0 : metadata.blob_heap.length, 4);
687
int debug_dir_len = 0;
688
if (!debug_data.IsNullOrEmpty ()) {
689
const int debug_dir_header_len = 28;
691
debug_directory.AddressOfRawData = (int) map.GetNextRVA (TextSegment.BlobHeap) + debug_dir_header_len;
692
debug_dir_len = debug_data.Length + debug_dir_header_len;
695
map.AddMap (TextSegment.DebugDirectory, debug_dir_len, 4);
697
RVA import_dir_rva = map.GetNextRVA (TextSegment.DebugDirectory);
698
RVA import_hnt_rva = import_dir_rva + (!pe64 ? 48u : 52u);
699
import_hnt_rva = (import_hnt_rva + 15u) & ~15u;
700
uint import_dir_len = (import_hnt_rva - import_dir_rva) + 27u;
702
RVA startup_stub_rva = import_dir_rva + import_dir_len;
703
startup_stub_rva = module.Architecture == TargetArchitecture.IA64
704
? (startup_stub_rva + 15u) & ~15u
705
: 2 + ((startup_stub_rva + 3u) & ~3u);
707
map.AddMap (TextSegment.ImportDirectory, new Range (import_dir_rva, import_dir_len));
708
map.AddMap (TextSegment.ImportHintNameTable, new Range (import_hnt_rva, 0));
709
map.AddMap (TextSegment.StartupStub, new Range (startup_stub_rva, GetStartupStubLength ()));
714
uint GetStartupStubLength ()
716
switch (module.Architecture) {
717
case TargetArchitecture.I386:
719
case TargetArchitecture.AMD64:
721
case TargetArchitecture.IA64:
724
throw new InvalidOperationException ();
728
int GetMetadataHeaderLength ()
738
+ (metadata.user_string_heap.IsEmpty ? 0 : 12)
742
+ (metadata.blob_heap.IsEmpty ? 0 : 16);
745
int GetStrongNameLength ()
747
if ((module.Attributes & ModuleAttributes.StrongNameSigned) == 0)
750
if (module.Assembly == null)
751
throw new InvalidOperationException ();
753
var public_key = module.Assembly.Name.PublicKey;
755
if (public_key != null) {
756
// in fx 2.0 the key may be from 384 to 16384 bits
757
// so we must calculate the signature size based on
758
// the size of the public key (minus the 32 byte header)
759
int size = public_key.Length;
762
// note: size == 16 for the ECMA "key" which is replaced
763
// by the runtime with a 1024 bits key (128 bytes)
766
return 128; // default strongname signature size
769
public DataDirectory GetStrongNameSignatureDirectory ()
771
return text_map.GetDataDirectory (TextSegment.StrongNameSignature);
774
public uint GetHeaderSize ()
776
return pe_header_size + (sections * section_header_size);
779
void PatchWin32Resources (ByteBuffer resources)
781
PatchResourceDirectoryTable (resources);
784
void PatchResourceDirectoryTable (ByteBuffer resources)
786
resources.Advance (12);
788
var entries = resources.ReadUInt16 () + resources.ReadUInt16 ();
790
for (int i = 0; i < entries; i++)
791
PatchResourceDirectoryEntry (resources);
794
void PatchResourceDirectoryEntry (ByteBuffer resources)
796
resources.Advance (4);
797
var child = resources.ReadUInt32 ();
799
var position = resources.position;
800
resources.position = (int) child & 0x7fffffff;
802
if ((child & 0x80000000) != 0)
803
PatchResourceDirectoryTable (resources);
805
PatchResourceDataEntry (resources);
807
resources.position = position;
810
void PatchResourceDataEntry (ByteBuffer resources)
812
var old_rsrc = GetImageResourceSection ();
813
var rva = resources.ReadUInt32 ();
814
resources.position -= 4;
815
resources.WriteUInt32 (rva - old_rsrc.VirtualAddress + rsrc.VirtualAddress);