/[RomCheater]/trunk/Win32/Sojaner.MemoryScanner/PEData.cs
ViewVC logotype

Contents of /trunk/Win32/Sojaner.MemoryScanner/PEData.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 611 - (show annotations) (download)
Sat Jun 8 03:35:12 2013 UTC (7 years, 1 month ago) by william
File size: 30242 byte(s)

1 #region Logging Defines
2 // include this any class or method that required logging, and comment-out what is not needed
3
4 #region Enabled logging levels
5 #define LOGGING_ENABLE_INFO
6 #define LOGGING_ENABLE_WARN
7 #define LOGGING_ENABLE_DEBUG
8 //#define LOGGING_ENABLE_VERBOSEDEBUG
9 #define LOGGING_ENABLE_ERROR
10 #define LOGGING_ENABLE_VERBOSEERROR
11 #define LOGGING_ENABLE_PROFILER
12 #endregion
13 #endregion
14
15 using System;
16 using System.Collections.Generic;
17 using System.Runtime.InteropServices;
18 using System.IO;
19 using System.Diagnostics;
20 using RomCheater.PluginFramework.Interfaces;
21 using System.ComponentModel;
22 using System.Text;
23
24 namespace Sojaner.MemoryScanner
25 {
26 public interface IPEDData
27 {
28 IMAGE_DOS_HEADER DosHeader { get; }
29 string NTSignature { get; }
30 IMAGE_FILE_HEADER FileHeader { get; }
31 IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get; }
32 IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get; }
33 //IMAGE_SECTION_HEADER[] SectionHeaders { get; }
34 bool Is32bitAssembly();
35 }
36
37 public class PEData : IPEDData
38 {
39 #region IPEDData Members
40 public IMAGE_DOS_HEADER DosHeader { get { if (reader == null) { return new IMAGE_DOS_HEADER(); } else { return reader.DosHeader; } } }
41 public string NTSignature { get { if (reader == null) { return "0"; } else { return reader.NTSignature; } } }
42 public IMAGE_FILE_HEADER FileHeader { get { if (reader == null) { return new IMAGE_FILE_HEADER(); } else { return reader.FileHeader; } } }
43 public IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get { if (reader == null) { return new IMAGE_OPTIONAL_HEADER32(); } else { return reader.OptionalHeader32; } } }
44 public IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get { if (reader == null) { return new IMAGE_OPTIONAL_HEADER64(); } else { return reader.OptionalHeader64; } } }
45 public Boolean Is32bitAssembly() { if (reader == null) { return true; } else { return reader.Is32BitHeader; } }
46 #endregion
47
48 private PeHeaderReader reader = null;
49
50 public static readonly IPEDData Empty = new PEData();
51
52 protected PEData() { }
53 public PEData(IAcceptsProcess iap)
54 {
55 if (iap == null) { throw new ArgumentNullException("iap", "The selected process cannot be null"); }
56 Process p = iap.AcceptedProcess;
57 string filename = p.MainModule.FileName;
58 reader = new PeHeaderReader(filename);
59 }
60 public PEData(IAcceptsProcessAndConfig iapc) : this((IAcceptsProcess)iapc) { }
61 }
62
63 #region File Header Structures
64 [TypeConverter(typeof(ExpandableObjectConverter))]
65 public struct IMAGE_DOS_HEADER
66 { // DOS .EXE header
67 public UInt16 _e_magic; // Magic number
68 public UInt16 _e_cblp; // Bytes on last page of file
69 public UInt16 _e_cp; // Pages in file
70 public UInt16 _e_crlc; // Relocations
71 public UInt16 _e_cparhdr; // Size of header in paragraphs
72 public UInt16 _e_minalloc; // Minimum extra paragraphs needed
73 public UInt16 _e_maxalloc; // Maximum extra paragraphs needed
74 public UInt16 _e_ss; // Initial (relative) SS value
75 public UInt16 _e_sp; // Initial SP value
76 public UInt16 _e_csum; // Checksum
77 public UInt16 _e_ip; // Initial IP value
78 public UInt16 _e_cs; // Initial (relative) CS value
79 public UInt16 _e_lfarlc; // File address of relocation table
80 public UInt16 _e_ovno; // Overlay number
81 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
82 public UInt16[] _e_res1;
83 public UInt16 _e_oemid; // OEM identifier (for e_oeminfo)
84 public UInt16 _e_oeminfo; // OEM information; e_oemid specific
85 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
86 public UInt16[] _e_res2;
87 public UInt32 _e_lfanew; // File address of new exe header
88
89 public string e_magic { get { return string.Format("0x{0:x4}", _e_magic); } }
90 public string e_cblp { get { return string.Format("0x{0:x4}", _e_cblp); } }
91 public string e_cp { get { return string.Format("0x{0:x4}", _e_cp); } }
92 public string e_crlc { get { return string.Format("0x{0:x4}", _e_crlc); } }
93 public string e_cparhdr { get { return string.Format("0x{0:x4}", _e_cparhdr); } }
94 public string e_minalloc { get { return string.Format("0x{0:x4}", _e_minalloc); } }
95 public string e_maxalloc { get { return string.Format("0x{0:x4}", _e_maxalloc); } }
96 public string e_ss { get { return string.Format("0x{0:x4}", _e_ss); } }
97 public string e_sp { get { return string.Format("0x{0:x4}", _e_sp); } }
98 public string e_csum { get { return string.Format("0x{0:x4}", _e_csum); } }
99 public string e_ip { get { return string.Format("0x{0:x4}", _e_ip); } }
100 public string e_cs { get { return string.Format("0x{0:x4}", _e_cs); } }
101 public string e_lfarlc { get { return string.Format("0x{0:x4}", _e_lfarlc); } }
102 public string e_ovno { get { return string.Format("0x{0:x4}", _e_ovno); } }
103 public ushort[] e_res1 { get { return _e_res1; } }
104 public string e_oemid { get { return string.Format("0x{0:x4}", _e_oemid); } }
105 public string e_oeminfo { get { return string.Format("0x{0:x4}", _e_oeminfo); } }
106 public ushort[] e_res2 { get { return _e_res2; } }
107 public string e_lfanew { get { return string.Format("0x{0:x8}", _e_lfanew); } }
108
109 public override string ToString()
110 {
111 return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic));
112 }
113 }
114 [TypeConverter(typeof(ExpandableObjectConverter))]
115 [StructLayout(LayoutKind.Sequential)]
116 public struct IMAGE_DATA_DIRECTORY
117 {
118 public UInt32 VirtualAddress;
119 public UInt32 Size;
120 }
121 [TypeConverter(typeof(ExpandableObjectConverter))]
122 [StructLayout(LayoutKind.Sequential, Pack = 1)]
123 public struct IMAGE_OPTIONAL_HEADER32
124 {
125 public UInt16 Magic;
126 public Byte MajorLinkerVersion;
127 public Byte MinorLinkerVersion;
128 public UInt32 SizeOfCode;
129 public UInt32 SizeOfInitializedData;
130 public UInt32 SizeOfUninitializedData;
131 public UInt32 AddressOfEntryPoint;
132 public UInt32 BaseOfCode;
133 public UInt32 BaseOfData;
134 public UInt32 ImageBase;
135 public UInt32 SectionAlignment;
136 public UInt32 FileAlignment;
137 public UInt16 MajorOperatingSystemVersion;
138 public UInt16 MinorOperatingSystemVersion;
139 public UInt16 MajorImageVersion;
140 public UInt16 MinorImageVersion;
141 public UInt16 MajorSubsystemVersion;
142 public UInt16 MinorSubsystemVersion;
143 public UInt32 Win32VersionValue;
144 public UInt32 SizeOfImage;
145 public UInt32 SizeOfHeaders;
146 public UInt32 CheckSum;
147 public SubSystemType Subsystem;
148 public DllCharacteristicsType DllCharacteristics;
149 public UInt32 SizeOfStackReserve;
150 public UInt32 SizeOfStackCommit;
151 public UInt32 SizeOfHeapReserve;
152 public UInt32 SizeOfHeapCommit;
153 public UInt32 LoaderFlags;
154 public UInt32 NumberOfRvaAndSizes;
155
156 public IMAGE_DATA_DIRECTORY ExportTable;
157 public IMAGE_DATA_DIRECTORY ImportTable;
158 public IMAGE_DATA_DIRECTORY ResourceTable;
159 public IMAGE_DATA_DIRECTORY ExceptionTable;
160 public IMAGE_DATA_DIRECTORY CertificateTable;
161 public IMAGE_DATA_DIRECTORY BaseRelocationTable;
162 public IMAGE_DATA_DIRECTORY Debug;
163 public IMAGE_DATA_DIRECTORY Architecture;
164 public IMAGE_DATA_DIRECTORY GlobalPtr;
165 public IMAGE_DATA_DIRECTORY TLSTable;
166 public IMAGE_DATA_DIRECTORY LoadConfigTable;
167 public IMAGE_DATA_DIRECTORY BoundImport;
168 public IMAGE_DATA_DIRECTORY IAT;
169 public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
170 public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
171 public IMAGE_DATA_DIRECTORY Reserved;
172 }
173
174 [StructLayout(LayoutKind.Sequential, Pack = 1)]
175 [TypeConverter(typeof(ExpandableObjectConverter))]
176 public struct IMAGE_OPTIONAL_HEADER64
177 {
178 public UInt16 Magic;
179 public Byte MajorLinkerVersion;
180 public Byte MinorLinkerVersion;
181 public UInt32 SizeOfCode;
182 public UInt32 SizeOfInitializedData;
183 public UInt32 SizeOfUninitializedData;
184 public UInt32 AddressOfEntryPoint;
185 public UInt32 BaseOfCode;
186 public UInt64 ImageBase;
187 public UInt32 SectionAlignment;
188 public UInt32 FileAlignment;
189 public UInt16 MajorOperatingSystemVersion;
190 public UInt16 MinorOperatingSystemVersion;
191 public UInt16 MajorImageVersion;
192 public UInt16 MinorImageVersion;
193 public UInt16 MajorSubsystemVersion;
194 public UInt16 MinorSubsystemVersion;
195 public UInt32 Win32VersionValue;
196 public UInt32 SizeOfImage;
197 public UInt32 SizeOfHeaders;
198 public UInt32 CheckSum;
199 public UInt16 Subsystem;
200 public DllCharacteristicsType DllCharacteristics;
201 public UInt64 SizeOfStackReserve;
202 public UInt64 SizeOfStackCommit;
203 public UInt64 SizeOfHeapReserve;
204 public UInt64 SizeOfHeapCommit;
205 public UInt32 LoaderFlags;
206 public UInt32 NumberOfRvaAndSizes;
207
208 public IMAGE_DATA_DIRECTORY ExportTable;
209 public IMAGE_DATA_DIRECTORY ImportTable;
210 public IMAGE_DATA_DIRECTORY ResourceTable;
211 public IMAGE_DATA_DIRECTORY ExceptionTable;
212 public IMAGE_DATA_DIRECTORY CertificateTable;
213 public IMAGE_DATA_DIRECTORY BaseRelocationTable;
214 public IMAGE_DATA_DIRECTORY Debug;
215 public IMAGE_DATA_DIRECTORY Architecture;
216 public IMAGE_DATA_DIRECTORY GlobalPtr;
217 public IMAGE_DATA_DIRECTORY TLSTable;
218 public IMAGE_DATA_DIRECTORY LoadConfigTable;
219 public IMAGE_DATA_DIRECTORY BoundImport;
220 public IMAGE_DATA_DIRECTORY IAT;
221 public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
222 public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
223 public IMAGE_DATA_DIRECTORY Reserved;
224 }
225
226 [StructLayout(LayoutKind.Sequential, Pack = 1)]
227 [TypeConverter(typeof(ExpandableObjectConverter))]
228 public struct IMAGE_FILE_HEADER
229 {
230 public MachineTypeFlags _Machine;
231 public UInt16 _NumberOfSections;
232 public UInt32 _TimeDateStamp;
233 public UInt32 _PointerToSymbolTable;
234 public UInt32 _NumberOfSymbols;
235 public UInt16 _SizeOfOptionalHeader;
236 public FileCharacteristicType _Characteristics;
237
238 public MachineTypeFlags MachineType { get { return _Machine; } }
239 public string NumberOfSections { get { return string.Format("0x{0:x4}", _NumberOfSections); } }
240 public string TimeDateStamp { get { return string.Format("{0} (0x{1:x8})", GetDateTimeFromLinkerTime(_TimeDateStamp).ToString(), _TimeDateStamp); } }
241 public string PointerToSymbolTable { get { return string.Format("0x{0:x8}", _PointerToSymbolTable); } }
242 public string NumberOfSymbols { get { return string.Format("0x{0:x8}", _NumberOfSymbols); } }
243 public string SizeOfOptionalHeader { get { return string.Format("0x{0:x4}", _SizeOfOptionalHeader); } }
244 public FileCharacteristicType Characteristics { get { return _Characteristics; } }
245 public override string ToString()
246 {
247 return MachineType.ToString();
248 }
249
250 private DateTime GetDateTimeFromLinkerTime(UInt32 linker_timer)
251 {
252 // http://msdn.microsoft.com/en-us/library/ms809762.aspx
253 // This field holds the number of seconds since December 31st, 1969, at 4:00 P.M.
254 DateTime t = new DateTime(1969, 12, 31, 16, 0, 0);
255 t = t.AddSeconds(linker_timer);
256 t += TimeZone.CurrentTimeZone.GetUtcOffset(t);
257 return t;
258 }
259 }
260
261 // Grabbed the following 2 definitions from http://www.pinvoke.net/default.aspx/Structures/IMAGE_SECTION_HEADER.html
262
263 [TypeConverter(typeof(ExpandableObjectConverter))]
264 [StructLayout(LayoutKind.Explicit)]
265 public struct IMAGE_SECTION_HEADER
266 {
267 [FieldOffset(0)]
268 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
269 public char[] Name;
270 [FieldOffset(8)]
271 public UInt32 VirtualSize;
272 [FieldOffset(12)]
273 public UInt32 VirtualAddress;
274 [FieldOffset(16)]
275 public UInt32 SizeOfRawData;
276 [FieldOffset(20)]
277 public UInt32 PointerToRawData;
278 [FieldOffset(24)]
279 public UInt32 PointerToRelocations;
280 [FieldOffset(28)]
281 public UInt32 PointerToLinenumbers;
282 [FieldOffset(32)]
283 public UInt16 NumberOfRelocations;
284 [FieldOffset(34)]
285 public UInt16 NumberOfLinenumbers;
286 [FieldOffset(36)]
287 public DataSectionFlags Characteristics;
288
289 public string Section
290 {
291 get { return new string(Name); }
292 }
293 }
294 #endregion File Header Structures
295
296
297 #region code
298 #region helpers
299 [Flags]
300 public enum MachineTypeFlags : ushort
301 {
302 x86 = 0x14C,
303 Alpha = 0x184,
304 ARM = 0x1C0,
305 MIPS16R3000 = 0x162,
306 MIPS16R4000 = 0x166,
307 MIPS16R10000 = 0x168,
308 PowerPCLE = 0x1F0,
309 PowerPCBE = 0x1F2,
310 Itanium = 0x200,
311 MIPS16 = 0x266,
312 Alpha64 = 0x284,
313 MIPSFPU = 0x366,
314 MIPSFPU16 = 0x466,
315 x64 = 0x8664,
316 }
317 public enum MagicType : ushort
318 {
319 NT_OPTIONAL_HEADER_NOT_PRESENT, // 0
320 NT_OPTIONAL_HEADER_32 = 0x10b,
321 NT_OPTIONAL_HEADER_64 = 0x20b
322 }
323 public enum SubSystemType : ushort
324 {
325 IMAGE_SUBSYSTEM_UNKNOWN = 0,
326 IMAGE_SUBSYSTEM_NATIVE = 1,
327 IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
328 IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
329 IMAGE_SUBSYSTEM_POSIX_CUI = 7,
330 IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
331 IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
332 IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
333 IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
334 IMAGE_SUBSYSTEM_EFI_ROM = 13,
335 IMAGE_SUBSYSTEM_XBOX = 14
336
337 }
338 public enum DllCharacteristicsType : ushort
339 {
340 RES_0 = 0x0001,
341 RES_1 = 0x0002,
342 RES_2 = 0x0004,
343 RES_3 = 0x0008,
344 IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
345 IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
346 IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
347 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
348 IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
349 IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
350 RES_4 = 0x1000,
351 IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
352 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
353 }
354 [Flags]
355 public enum FileCharacteristicType : ushort
356 {
357 RelocationInformationStrippedFromFile = 0x1,
358 Executable = 0x2,
359 LineNumbersStripped = 0x4,
360 SymbolTableStripped = 0x8,
361 AggresiveTrimWorkingSet = 0x10,
362 LargeAddressAware = 0x20,
363 Supports16Bit = 0x40,
364 ReservedBytesWo = 0x80,
365 Supports32Bit = 0x100,
366 DebugInfoStripped = 0x200,
367 RunFromSwapIfInRemovableMedia = 0x400,
368 RunFromSwapIfInNetworkMedia = 0x800,
369 IsSytemFile = 0x1000,
370 IsDLL = 0x2000,
371 IsOnlyForSingleCoreProcessor = 0x4000,
372 BytesOfWordReserved = 0x8000,
373 }
374 #region DataSectionFlags
375 [Flags]
376 public enum DataSectionFlags : uint
377 {
378 /// <summary>
379 /// Reserved for future use.
380 /// </summary>
381 TypeReg = 0x00000000,
382 /// <summary>
383 /// Reserved for future use.
384 /// </summary>
385 TypeDsect = 0x00000001,
386 /// <summary>
387 /// Reserved for future use.
388 /// </summary>
389 TypeNoLoad = 0x00000002,
390 /// <summary>
391 /// Reserved for future use.
392 /// </summary>
393 TypeGroup = 0x00000004,
394 /// <summary>
395 /// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
396 /// </summary>
397 TypeNoPadded = 0x00000008,
398 /// <summary>
399 /// Reserved for future use.
400 /// </summary>
401 TypeCopy = 0x00000010,
402 /// <summary>
403 /// The section contains executable code.
404 /// </summary>
405 ContentCode = 0x00000020,
406 /// <summary>
407 /// The section contains initialized data.
408 /// </summary>
409 ContentInitializedData = 0x00000040,
410 /// <summary>
411 /// The section contains uninitialized data.
412 /// </summary>
413 ContentUninitializedData = 0x00000080,
414 /// <summary>
415 /// Reserved for future use.
416 /// </summary>
417 LinkOther = 0x00000100,
418 /// <summary>
419 /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
420 /// </summary>
421 LinkInfo = 0x00000200,
422 /// <summary>
423 /// Reserved for future use.
424 /// </summary>
425 TypeOver = 0x00000400,
426 /// <summary>
427 /// The section will not become part of the image. This is valid only for object files.
428 /// </summary>
429 LinkRemove = 0x00000800,
430 /// <summary>
431 /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
432 /// </summary>
433 LinkComDat = 0x00001000,
434 /// <summary>
435 /// Reset speculative exceptions handling bits in the TLB entries for this section.
436 /// </summary>
437 NoDeferSpecExceptions = 0x00004000,
438 /// <summary>
439 /// The section contains data referenced through the global pointer (GP).
440 /// </summary>
441 RelativeGP = 0x00008000,
442 /// <summary>
443 /// Reserved for future use.
444 /// </summary>
445 MemPurgeable = 0x00020000,
446 /// <summary>
447 /// Reserved for future use.
448 /// </summary>
449 Memory16Bit = 0x00020000,
450 /// <summary>
451 /// Reserved for future use.
452 /// </summary>
453 MemoryLocked = 0x00040000,
454 /// <summary>
455 /// Reserved for future use.
456 /// </summary>
457 MemoryPreload = 0x00080000,
458 /// <summary>
459 /// Align data on a 1-byte boundary. Valid only for object files.
460 /// </summary>
461 Align1Bytes = 0x00100000,
462 /// <summary>
463 /// Align data on a 2-byte boundary. Valid only for object files.
464 /// </summary>
465 Align2Bytes = 0x00200000,
466 /// <summary>
467 /// Align data on a 4-byte boundary. Valid only for object files.
468 /// </summary>
469 Align4Bytes = 0x00300000,
470 /// <summary>
471 /// Align data on an 8-byte boundary. Valid only for object files.
472 /// </summary>
473 Align8Bytes = 0x00400000,
474 /// <summary>
475 /// Align data on a 16-byte boundary. Valid only for object files.
476 /// </summary>
477 Align16Bytes = 0x00500000,
478 /// <summary>
479 /// Align data on a 32-byte boundary. Valid only for object files.
480 /// </summary>
481 Align32Bytes = 0x00600000,
482 /// <summary>
483 /// Align data on a 64-byte boundary. Valid only for object files.
484 /// </summary>
485 Align64Bytes = 0x00700000,
486 /// <summary>
487 /// Align data on a 128-byte boundary. Valid only for object files.
488 /// </summary>
489 Align128Bytes = 0x00800000,
490 /// <summary>
491 /// Align data on a 256-byte boundary. Valid only for object files.
492 /// </summary>
493 Align256Bytes = 0x00900000,
494 /// <summary>
495 /// Align data on a 512-byte boundary. Valid only for object files.
496 /// </summary>
497 Align512Bytes = 0x00A00000,
498 /// <summary>
499 /// Align data on a 1024-byte boundary. Valid only for object files.
500 /// </summary>
501 Align1024Bytes = 0x00B00000,
502 /// <summary>
503 /// Align data on a 2048-byte boundary. Valid only for object files.
504 /// </summary>
505 Align2048Bytes = 0x00C00000,
506 /// <summary>
507 /// Align data on a 4096-byte boundary. Valid only for object files.
508 /// </summary>
509 Align4096Bytes = 0x00D00000,
510 /// <summary>
511 /// Align data on an 8192-byte boundary. Valid only for object files.
512 /// </summary>
513 Align8192Bytes = 0x00E00000,
514 /// <summary>
515 /// The section contains extended relocations.
516 /// </summary>
517 LinkExtendedRelocationOverflow = 0x01000000,
518 /// <summary>
519 /// The section can be discarded as needed.
520 /// </summary>
521 MemoryDiscardable = 0x02000000,
522 /// <summary>
523 /// The section cannot be cached.
524 /// </summary>
525 MemoryNotCached = 0x04000000,
526 /// <summary>
527 /// The section is not pageable.
528 /// </summary>
529 MemoryNotPaged = 0x08000000,
530 /// <summary>
531 /// The section can be shared in memory.
532 /// </summary>
533 MemoryShared = 0x10000000,
534 /// <summary>
535 /// The section can be executed as code.
536 /// </summary>
537 MemoryExecute = 0x20000000,
538 /// <summary>
539 /// The section can be read.
540 /// </summary>
541 MemoryRead = 0x40000000,
542 /// <summary>
543 /// The section can be written to.
544 /// </summary>
545 MemoryWrite = 0x80000000
546 }
547 #endregion
548 #endregion
549 /// <summary>
550 /// Reads in the header information of the Portable Executable format.
551 /// Provides information such as the date the assembly was compiled.
552 /// </summary>
553 public class PeHeaderReader
554 {
555
556
557 #region Private Fields
558
559 private UInt32 ntSignature;
560 /// <summary>
561 /// The DOS header
562 /// </summary>
563 private IMAGE_DOS_HEADER dosHeader;
564 /// <summary>
565 /// The file header
566 /// </summary>
567 private IMAGE_FILE_HEADER fileHeader;
568 /// <summary>
569 /// Optional 32 bit file header
570 /// </summary>
571 private IMAGE_OPTIONAL_HEADER32 optionalHeader32;
572 /// <summary>
573 /// Optional 64 bit file header
574 /// </summary>
575 private IMAGE_OPTIONAL_HEADER64 optionalHeader64;
576 /// <summary>
577 /// Image Section headers. Number of sections is in the file header.
578 /// </summary>
579 private IMAGE_SECTION_HEADER[] imageSectionHeaders;
580
581 #endregion Private Fields
582
583 #region Public Methods
584
585 public PeHeaderReader(string filePath)
586 {
587 // Read in the DLL or EXE and get the timestamp
588 using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
589 {
590 BinaryReader reader = new BinaryReader(stream);
591 dosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(reader);
592
593 // Add 4 bytes to the offset
594 stream.Seek(dosHeader._e_lfanew, SeekOrigin.Begin);
595
596 UInt32 ntHeadersSignature = reader.ReadUInt32();
597 ntSignature = ntHeadersSignature;
598 fileHeader = FromBinaryReader<IMAGE_FILE_HEADER>(reader);
599 if (this.Is32BitHeader)
600 {
601 optionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(reader);
602 }
603 else
604 {
605 optionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(reader);
606 }
607
608 imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader._NumberOfSections];
609 for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
610 {
611 imageSectionHeaders[headerNo] = FromBinaryReader<IMAGE_SECTION_HEADER>(reader);
612 }
613
614 }
615 }
616
617 /// <summary>
618 /// Gets the header of the .NET assembly that called this function
619 /// </summary>
620 /// <returns></returns>
621 public static PeHeaderReader GetCallingAssemblyHeader()
622 {
623 // Get the path to the calling assembly, which is the path to the
624 // DLL or EXE that we want the time of
625 string filePath = System.Reflection.Assembly.GetCallingAssembly().Location;
626
627 // Get and return the timestamp
628 return new PeHeaderReader(filePath);
629 }
630
631 /// <summary>
632 /// Gets the header of the .NET assembly that called this function
633 /// </summary>
634 /// <returns></returns>
635 public static PeHeaderReader GetAssemblyHeader()
636 {
637 // Get the path to the calling assembly, which is the path to the
638 // DLL or EXE that we want the time of
639 string filePath = System.Reflection.Assembly.GetAssembly(typeof(PeHeaderReader)).Location;
640
641 // Get and return the timestamp
642 return new PeHeaderReader(filePath);
643 }
644
645 /// <summary>
646 /// Reads in a block from a file and converts it to the struct
647 /// type specified by the template parameter
648 /// </summary>
649 /// <typeparam name="T"></typeparam>
650 /// <param name="reader"></param>
651 /// <returns></returns>
652 public static T FromBinaryReader<T>(BinaryReader reader)
653 {
654 // Read in a byte array
655 byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
656
657 // Pin the managed memory while, copy it out the data, then unpin it
658 GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
659 T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
660 handle.Free();
661
662 return theStructure;
663 }
664
665 #endregion Public Methods
666
667 #region Properties
668
669 /// <summary>
670 /// Gets if the file header is 32 bit or not
671 /// </summary>
672 public bool Is32BitHeader
673 {
674 get
675 {
676 return FileHeader.Characteristics.HasFlag(FileCharacteristicType.Supports32Bit);
677 }
678 }
679
680 /// <summary>
681 /// Gets the file header
682 /// </summary>
683 public IMAGE_FILE_HEADER FileHeader
684 {
685 get
686 {
687 return fileHeader;
688 }
689 }
690 /// <summary>
691 /// Gets the file header
692 /// </summary>
693 public string NTSignature
694 {
695 get
696 {
697 ushort sig = (ushort)ntSignature;
698 return string.Format("0x{0:x4} [{1}]", sig, Encoding.ASCII.GetString(BitConverter.GetBytes(sig)));
699 }
700 }
701 /// <summary>
702 /// Gets the file header
703 /// </summary>
704 public IMAGE_DOS_HEADER DosHeader
705 {
706 get
707 {
708 return dosHeader;
709 }
710 }
711 /// <summary>
712 /// Gets the optional header
713 /// </summary>
714 public IMAGE_OPTIONAL_HEADER32 OptionalHeader32
715 {
716 get
717 {
718 return optionalHeader32;
719 }
720 }
721
722 /// <summary>
723 /// Gets the optional header
724 /// </summary>
725 public IMAGE_OPTIONAL_HEADER64 OptionalHeader64
726 {
727 get
728 {
729 return optionalHeader64;
730 }
731 }
732
733 public IMAGE_SECTION_HEADER[] ImageSectionHeaders
734 {
735 get
736 {
737 return imageSectionHeaders;
738 }
739 }
740
741 ///// <summary>
742 ///// Gets the timestamp from the file header
743 ///// </summary>
744 //public DateTime TimeStamp
745 //{
746 // get
747 // {
748 // // Timestamp is a date offset from 1970
749 // DateTime returnValue = new DateTime(1970, 1, 1, 0, 0, 0);
750
751 // // Add in the number of seconds since 1970/1/1
752 // returnValue = returnValue.AddSeconds(fileHeader.TimeDateStamp);
753 // // Adjust to local timezone
754 // returnValue += TimeZone.CurrentTimeZone.GetUtcOffset(returnValue);
755
756 // return returnValue;
757 // }
758 //}
759
760 #endregion Properties
761 }
762 #endregion
763 }

  ViewVC Help
Powered by ViewVC 1.1.22