2 * Copyright (c) 2002 Sergey Chaban <serge@wildwestsoftware.com>
\r
7 using System.Runtime.InteropServices;
\r
9 namespace Mono.PEToolkit {
\r
11 // IMAGE_OPTIONAL_HEADER
\r
13 [StructLayoutAttribute(LayoutKind.Sequential)]
\r
14 public struct PEHeader {
\r
17 /// Standard PE/COFF fields.
\r
19 [StructLayoutAttribute(LayoutKind.Sequential)]
\r
20 public struct StdFields {
\r
21 internal short magic; // always 0x10B?
\r
22 internal byte lMajor;
\r
23 internal byte lMinor;
\r
24 internal uint codeSize;
\r
25 internal uint initDataSize;
\r
26 internal uint uninitDataSize;
\r
27 internal RVA entryRVA;
\r
28 internal RVA codeBase;
\r
29 internal RVA dataBase;
\r
34 public string LinkerVersion {
\r
36 return String.Format("{0}.{1}", lMajor, lMinor);
\r
43 /// <returns></returns>
\r
44 public override string ToString() {
\r
45 return String.Format(
\r
46 "Magic : 0x{0}" + Environment.NewLine +
\r
47 "Linker ver. : {1}" + Environment.NewLine +
\r
48 "Size of code : {2}" + Environment.NewLine +
\r
49 "Size of initialized data : {3}" + Environment.NewLine +
\r
50 "Size of uinitialized data (BSS) : {4}" + Environment.NewLine,
\r
51 magic.ToString("X"), LinkerVersion,
\r
52 codeSize, initDataSize, uninitDataSize
\r
59 /// Windows-specific fields.
\r
62 /// See Partition II, 24.2.3.2
\r
64 [StructLayoutAttribute(LayoutKind.Sequential)]
\r
65 public struct NTFields {
\r
66 internal uint imgBase;
\r
67 internal uint sectAlign;
\r
68 internal uint fileAlign;
\r
69 internal short osMaj;
\r
70 internal short osMin;
\r
71 internal short imgMaj;
\r
72 internal short imgMin;
\r
73 internal short subSysMaj;
\r
74 internal short subSysMin;
\r
75 internal int reserved_win32ver;
\r
76 internal uint imgSize;
\r
77 internal uint hdrSize;
\r
78 internal uint chksum;
\r
79 internal Subsystem subSys;
\r
80 internal short dllFlags;
\r
81 internal uint stackRes;
\r
82 internal uint stackCommit;
\r
83 internal uint heapRes;
\r
84 internal uint heapCommit;
\r
85 internal uint ldrFlags;
\r
86 internal uint numDirs;
\r
88 public string OSVersion {
\r
90 return String.Format("{0}.{1}", osMaj, osMin);
\r
94 public string ImageVersion {
\r
96 return String.Format("{0}.{1}", imgMaj, imgMin);
\r
100 public string SubsysVersion {
\r
102 return String.Format("{0}.{1}", subSysMaj, subSysMin);
\r
109 /// <returns></returns>
\r
110 public override string ToString() {
\r
111 return String.Format(
\r
112 "Image Base : 0x{0}" + Environment.NewLine +
\r
113 "Section Alignment : 0x{1}" + Environment.NewLine +
\r
114 "File Alignment : 0x{2}" + Environment.NewLine +
\r
115 "OS Version : {3}" + Environment.NewLine +
\r
116 "Image Version : {4}" + Environment.NewLine +
\r
117 "Subsystem Version : {5}" + Environment.NewLine +
\r
118 "Reserved/Win32Ver : {6}" + Environment.NewLine +
\r
119 "Image Size : {7}" + Environment.NewLine +
\r
120 "Header Size : {8}" + Environment.NewLine +
\r
121 "Checksum : 0x{9}" + Environment.NewLine +
\r
122 "Subsystem : {10}" + Environment.NewLine +
\r
123 "DLL Flags : {11}" + Environment.NewLine +
\r
124 "Stack Reserve Size : 0x{12}" + Environment.NewLine +
\r
125 "Stack Commit Size : 0x{13}" + Environment.NewLine +
\r
126 "Heap Reserve Size : 0x{14}" + Environment.NewLine +
\r
127 "Heap Commit Size : 0x{15}" + Environment.NewLine +
\r
128 "Loader Flags : {16}" + Environment.NewLine +
\r
129 "Number of Directories : {17}" + Environment.NewLine,
\r
130 imgBase.ToString("X"), sectAlign.ToString("X"), fileAlign.ToString("X"),
\r
131 OSVersion, ImageVersion, SubsysVersion,
\r
133 imgSize, hdrSize, chksum.ToString("X"), subSys, dllFlags,
\r
134 stackRes.ToString("X"), stackCommit.ToString("X"), heapRes.ToString("X"), heapCommit.ToString ("X"),
\r
141 internal StdFields stdFlds;
\r
142 internal NTFields ntFlds;
\r
144 internal DataDir exportDir;
\r
145 internal DataDir importDir;
\r
146 internal DataDir resourceDir;
\r
147 internal DataDir exceptionDir;
\r
148 internal DataDir securityDir;
\r
149 internal DataDir baseRelocDir;
\r
150 internal DataDir debugDir;
\r
151 internal DataDir copyrightDir;
\r
152 internal DataDir GPDir;
\r
153 internal DataDir TLSDir;
\r
154 internal DataDir loadCfgDir;
\r
155 internal DataDir boundImpDir;
\r
156 internal DataDir IATDir;
\r
157 internal DataDir delayImpDir;
\r
158 internal DataDir CLIHdrDir;
\r
159 internal DataDir reservedDir;
\r
162 public bool IsCLIImage {
\r
164 return (CLIHdrDir.virtAddr.Value != 0);
\r
170 // Accessors for standard COFF fields.
\r
173 public short Magic {
\r
175 return stdFlds.magic;
\r
178 stdFlds.magic = value;
\r
182 public byte MajorLinkerVersion {
\r
184 return stdFlds.lMajor;
\r
187 stdFlds.lMajor = value;
\r
191 public byte MinorLinkerVersion {
\r
193 return stdFlds.lMinor;
\r
196 stdFlds.lMinor = value;
\r
200 public uint SizeOfCode {
\r
202 return stdFlds.codeSize;
\r
205 stdFlds.codeSize = value;
\r
209 public uint SizeOfInitializedData {
\r
211 return stdFlds.initDataSize;
\r
214 stdFlds.initDataSize = value;
\r
218 public uint SizeOfUninitializedData {
\r
220 return stdFlds.uninitDataSize;
\r
223 stdFlds.uninitDataSize = value;
\r
227 public RVA AddressOfEntryPoint {
\r
229 return stdFlds.entryRVA;
\r
232 stdFlds.entryRVA.value = value.value;
\r
236 public RVA BaseOfCode {
\r
238 return stdFlds.codeBase;
\r
241 stdFlds.codeBase.value = value.value;
\r
245 public RVA BaseOfData {
\r
247 return stdFlds.dataBase;
\r
250 stdFlds.dataBase.value = value.value;
\r
256 // Accessors for Windows-specific fields.
\r
261 /// Preferred address of image when loaded into memory.
\r
265 /// This is a linear address and not RVA,
\r
266 /// and must be a multiple of 64K.
\r
269 /// Table in the Partition II states that for CIL images
\r
270 /// it must be 0x400000.
\r
273 public uint ImageBase {
\r
275 return ntFlds.imgBase;
\r
278 ntFlds.imgBase = value;
\r
283 /// Alignment of section when loaded into memory.
\r
286 /// Must be greater or equal to FileAlignment.
\r
287 /// Default is the native page size.
\r
288 /// According to specs for CIL images it must be set to 8K.
\r
290 public uint SectionAlignment {
\r
292 return ntFlds.sectAlign;
\r
295 ntFlds.sectAlign = value;
\r
300 /// Byte alignment of pages in image file.
\r
303 /// Valid values are powers of 2 between 512 and 64K.
\r
304 /// For CIL images it must be either 512 or 4K.
\r
306 public uint FileAlignment {
\r
308 return ntFlds.fileAlign;
\r
311 ntFlds.fileAlign = value;
\r
316 public short MajorOperatingSystemVersion {
\r
318 return ntFlds.osMaj;
\r
321 ntFlds.osMaj = value;
\r
325 public short MinorOperatingSystemVersion {
\r
327 return ntFlds.osMin;
\r
330 ntFlds.osMin = value;
\r
334 public short MajorImageVersion {
\r
336 return ntFlds.imgMaj;
\r
339 ntFlds.imgMaj = value;
\r
343 public short MinorImageVersion {
\r
345 return ntFlds.imgMin;
\r
348 ntFlds.imgMin = value;
\r
352 public short MajorSubsystemVersion {
\r
354 return ntFlds.subSysMaj;
\r
357 ntFlds.subSysMaj = value;
\r
361 public short MinorSubsystemVersion {
\r
363 return ntFlds.subSysMin;
\r
366 ntFlds.subSysMin = value;
\r
370 public int Win32VersionValue {
\r
372 return ntFlds.reserved_win32ver;
\r
375 ntFlds.reserved_win32ver = value;
\r
379 public int Reserved {
\r
381 return ntFlds.reserved_win32ver;
\r
384 ntFlds.reserved_win32ver = value;
\r
388 public uint SizeOfImage {
\r
390 return ntFlds.imgSize;
\r
393 ntFlds.imgSize = value;
\r
397 public uint SizeOfHeaders {
\r
399 return ntFlds.hdrSize;
\r
402 ntFlds.hdrSize = value;
\r
406 public uint CheckSum {
\r
408 return ntFlds.chksum;
\r
411 ntFlds.chksum = value;
\r
415 public Subsystem Subsystem {
\r
417 return ntFlds.subSys;
\r
420 ntFlds.subSys = value;
\r
424 public short DllCharacteristics {
\r
426 return ntFlds.dllFlags;
\r
429 ntFlds.dllFlags = value;
\r
434 public uint SizeOfStackReserve {
\r
436 return ntFlds.stackRes;
\r
439 ntFlds.stackRes = value;
\r
443 public uint SizeOfStackCommit {
\r
445 return ntFlds.stackCommit;
\r
448 ntFlds.stackCommit = value;
\r
452 public uint SizeOfHeapReserve {
\r
454 return ntFlds.heapRes;
\r
457 ntFlds.heapRes = value;
\r
461 public uint SizeOfHeapCommit {
\r
463 return ntFlds.heapCommit;
\r
466 ntFlds.heapCommit = value;
\r
470 public uint LoaderFlags {
\r
472 return ntFlds.ldrFlags;
\r
475 ntFlds.ldrFlags = value;
\r
479 public uint NumberOfRvaAndSizes {
\r
481 return ntFlds.numDirs;
\r
484 ntFlds.numDirs = value;
\r
494 unsafe public void Read(BinaryReader reader)
\r
496 fixed (void* pThis = &this) {
\r
497 int hdrSize = sizeof (StdFields) + sizeof (NTFields);
\r
498 PEUtils.ReadStruct(reader, pThis, hdrSize);
\r
499 PEUtils.ReadStruct(reader, (byte*)pThis + hdrSize, (int) NumberOfRvaAndSizes * sizeof (DataDir));
\r
501 if (!System.BitConverter.IsLittleEndian) {
\r
502 PEUtils.ChangeStructEndianess(pThis, typeof (PEHeader));
\r
511 public void Dump(TextWriter writer)
\r
513 string dirs = String.Format(
\r
514 "Export Table : {0}" + Environment.NewLine +
\r
515 "Import Table : {1}" + Environment.NewLine +
\r
516 "Win32 Resource Table : {2}" + Environment.NewLine +
\r
517 "Exception Table : {3}" + Environment.NewLine +
\r
518 "Certificate Table : {4}" + Environment.NewLine +
\r
519 "Base Relocation Table : {5}" + Environment.NewLine +
\r
520 "Debug Table : {6}" + Environment.NewLine +
\r
521 "Copyright : {7}" + Environment.NewLine +
\r
522 "MIPS Global Ptr : {8}" + Environment.NewLine +
\r
523 "TLS Table : {9}" + Environment.NewLine +
\r
524 "Load Config Table : {10}" + Environment.NewLine +
\r
525 "Bound Import : {11}" + Environment.NewLine +
\r
526 "IAT : {12}" + Environment.NewLine +
\r
527 "Delay Import Descriptor : {13}" + Environment.NewLine +
\r
528 "CLI Header : {14}" + Environment.NewLine +
\r
529 "Reserved : {15}" + Environment.NewLine,
\r
530 exportDir, importDir, resourceDir, exceptionDir,
\r
531 securityDir, baseRelocDir, debugDir, copyrightDir,
\r
532 GPDir, TLSDir, loadCfgDir, boundImpDir, IATDir, delayImpDir,
\r
533 CLIHdrDir, reservedDir
\r
537 stdFlds.ToString() + Environment.NewLine +
\r
538 ntFlds.ToString() + Environment.NewLine +
\r
539 "Directories: "+ Environment.NewLine +
\r
547 /// <returns></returns>
\r
548 public override string ToString()
\r
550 StringWriter sw = new StringWriter();
\r
552 return sw.ToString();
\r