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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 609 - (hide annotations) (download)
Sat Jun 8 03:19:35 2013 UTC (7 years, 1 month ago) by william
File size: 28696 byte(s)

1 william 607 #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 william 608 using System.ComponentModel;
22 william 609 using System.Text;
23 william 607
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 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
64 william 607 public struct IMAGE_DOS_HEADER
65     { // DOS .EXE header
66 william 609 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 william 607 }
113 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
114 william 607 [StructLayout(LayoutKind.Sequential)]
115     public struct IMAGE_DATA_DIRECTORY
116     {
117     public UInt32 VirtualAddress;
118     public UInt32 Size;
119     }
120 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
121 william 607 [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 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
175 william 607 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 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
227 william 607 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 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
241 william 607 [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 william 609 stream.Seek(dosHeader._e_lfanew, SeekOrigin.Begin);
572 william 607
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