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

  ViewVC Help
Powered by ViewVC 1.1.22