/[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 610 - (hide annotations) (download)
Sat Jun 8 03:26:17 2013 UTC (7 years, 1 month ago) by william
File size: 28869 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 william 610 string NTSignature { get; }
30 william 607 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 william 610 public string NTSignature { get { if (reader == null) { return "0"; } else { return reader.NTSignature; } } }
42 william 607 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 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
65 william 607 public struct IMAGE_DOS_HEADER
66     { // DOS .EXE header
67 william 609 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 william 607 }
114 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
115 william 607 [StructLayout(LayoutKind.Sequential)]
116     public struct IMAGE_DATA_DIRECTORY
117     {
118     public UInt32 VirtualAddress;
119     public UInt32 Size;
120     }
121 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
122 william 607 [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 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
176 william 607 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 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
228 william 607 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    
239     // Grabbed the following 2 definitions from http://www.pinvoke.net/default.aspx/Structures/IMAGE_SECTION_HEADER.html
240    
241 william 608 [TypeConverter(typeof(ExpandableObjectConverter))]
242 william 607 [StructLayout(LayoutKind.Explicit)]
243     public struct IMAGE_SECTION_HEADER
244     {
245     [FieldOffset(0)]
246     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
247     public char[] Name;
248     [FieldOffset(8)]
249     public UInt32 VirtualSize;
250     [FieldOffset(12)]
251     public UInt32 VirtualAddress;
252     [FieldOffset(16)]
253     public UInt32 SizeOfRawData;
254     [FieldOffset(20)]
255     public UInt32 PointerToRawData;
256     [FieldOffset(24)]
257     public UInt32 PointerToRelocations;
258     [FieldOffset(28)]
259     public UInt32 PointerToLinenumbers;
260     [FieldOffset(32)]
261     public UInt16 NumberOfRelocations;
262     [FieldOffset(34)]
263     public UInt16 NumberOfLinenumbers;
264     [FieldOffset(36)]
265     public DataSectionFlags Characteristics;
266    
267     public string Section
268     {
269     get { return new string(Name); }
270     }
271     }
272     #endregion File Header Structures
273    
274    
275     #region code
276     #region helpers
277     [Flags]
278     public enum MachineTypeFlags
279     {
280     x86 = 0x14C,
281     Alpha = 0x184,
282     ARM = 0x1C0,
283     MIPS16R3000 = 0x162,
284     MIPS16R4000 = 0x166,
285     MIPS16R10000 = 0x168,
286     PowerPCLE = 0x1F0,
287     PowerPCBE = 0x1F2,
288     Itanium = 0x200,
289     MIPS16 = 0x266,
290     Alpha64 = 0x284,
291     MIPSFPU = 0x366,
292     MIPSFPU16 = 0x466,
293     x64 = 0x8664,
294     }
295     public enum MagicType : ushort
296     {
297     NT_OPTIONAL_HEADER_NOT_PRESENT, // 0
298     NT_OPTIONAL_HEADER_32 = 0x10b,
299     NT_OPTIONAL_HEADER_64 = 0x20b
300     }
301     public enum SubSystemType : ushort
302     {
303     IMAGE_SUBSYSTEM_UNKNOWN = 0,
304     IMAGE_SUBSYSTEM_NATIVE = 1,
305     IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
306     IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
307     IMAGE_SUBSYSTEM_POSIX_CUI = 7,
308     IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
309     IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
310     IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
311     IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
312     IMAGE_SUBSYSTEM_EFI_ROM = 13,
313     IMAGE_SUBSYSTEM_XBOX = 14
314    
315     }
316     public enum DllCharacteristicsType : ushort
317     {
318     RES_0 = 0x0001,
319     RES_1 = 0x0002,
320     RES_2 = 0x0004,
321     RES_3 = 0x0008,
322     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
323     IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
324     IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
325     IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
326     IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
327     IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
328     RES_4 = 0x1000,
329     IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
330     IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
331     }
332     [Flags]
333     public enum FileCharacteristicType : ushort
334     {
335     RelocationInformationStrippedFromFile = 0x1,
336     Executable = 0x2,
337     LineNumbersStripped = 0x4,
338     SymbolTableStripped = 0x8,
339     AggresiveTrimWorkingSet = 0x10,
340     LargeAddressAware = 0x20,
341     Supports16Bit = 0x40,
342     ReservedBytesWo = 0x80,
343     Supports32Bit = 0x100,
344     DebugInfoStripped = 0x200,
345     RunFromSwapIfInRemovableMedia = 0x400,
346     RunFromSwapIfInNetworkMedia = 0x800,
347     IsSytemFile = 0x1000,
348     IsDLL = 0x2000,
349     IsOnlyForSingleCoreProcessor = 0x4000,
350     BytesOfWordReserved = 0x8000,
351     }
352     #region DataSectionFlags
353     [Flags]
354     public enum DataSectionFlags : uint
355     {
356     /// <summary>
357     /// Reserved for future use.
358     /// </summary>
359     TypeReg = 0x00000000,
360     /// <summary>
361     /// Reserved for future use.
362     /// </summary>
363     TypeDsect = 0x00000001,
364     /// <summary>
365     /// Reserved for future use.
366     /// </summary>
367     TypeNoLoad = 0x00000002,
368     /// <summary>
369     /// Reserved for future use.
370     /// </summary>
371     TypeGroup = 0x00000004,
372     /// <summary>
373     /// 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.
374     /// </summary>
375     TypeNoPadded = 0x00000008,
376     /// <summary>
377     /// Reserved for future use.
378     /// </summary>
379     TypeCopy = 0x00000010,
380     /// <summary>
381     /// The section contains executable code.
382     /// </summary>
383     ContentCode = 0x00000020,
384     /// <summary>
385     /// The section contains initialized data.
386     /// </summary>
387     ContentInitializedData = 0x00000040,
388     /// <summary>
389     /// The section contains uninitialized data.
390     /// </summary>
391     ContentUninitializedData = 0x00000080,
392     /// <summary>
393     /// Reserved for future use.
394     /// </summary>
395     LinkOther = 0x00000100,
396     /// <summary>
397     /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
398     /// </summary>
399     LinkInfo = 0x00000200,
400     /// <summary>
401     /// Reserved for future use.
402     /// </summary>
403     TypeOver = 0x00000400,
404     /// <summary>
405     /// The section will not become part of the image. This is valid only for object files.
406     /// </summary>
407     LinkRemove = 0x00000800,
408     /// <summary>
409     /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
410     /// </summary>
411     LinkComDat = 0x00001000,
412     /// <summary>
413     /// Reset speculative exceptions handling bits in the TLB entries for this section.
414     /// </summary>
415     NoDeferSpecExceptions = 0x00004000,
416     /// <summary>
417     /// The section contains data referenced through the global pointer (GP).
418     /// </summary>
419     RelativeGP = 0x00008000,
420     /// <summary>
421     /// Reserved for future use.
422     /// </summary>
423     MemPurgeable = 0x00020000,
424     /// <summary>
425     /// Reserved for future use.
426     /// </summary>
427     Memory16Bit = 0x00020000,
428     /// <summary>
429     /// Reserved for future use.
430     /// </summary>
431     MemoryLocked = 0x00040000,
432     /// <summary>
433     /// Reserved for future use.
434     /// </summary>
435     MemoryPreload = 0x00080000,
436     /// <summary>
437     /// Align data on a 1-byte boundary. Valid only for object files.
438     /// </summary>
439     Align1Bytes = 0x00100000,
440     /// <summary>
441     /// Align data on a 2-byte boundary. Valid only for object files.
442     /// </summary>
443     Align2Bytes = 0x00200000,
444     /// <summary>
445     /// Align data on a 4-byte boundary. Valid only for object files.
446     /// </summary>
447     Align4Bytes = 0x00300000,
448     /// <summary>
449     /// Align data on an 8-byte boundary. Valid only for object files.
450     /// </summary>
451     Align8Bytes = 0x00400000,
452     /// <summary>
453     /// Align data on a 16-byte boundary. Valid only for object files.
454     /// </summary>
455     Align16Bytes = 0x00500000,
456     /// <summary>
457     /// Align data on a 32-byte boundary. Valid only for object files.
458     /// </summary>
459     Align32Bytes = 0x00600000,
460     /// <summary>
461     /// Align data on a 64-byte boundary. Valid only for object files.
462     /// </summary>
463     Align64Bytes = 0x00700000,
464     /// <summary>
465     /// Align data on a 128-byte boundary. Valid only for object files.
466     /// </summary>
467     Align128Bytes = 0x00800000,
468     /// <summary>
469     /// Align data on a 256-byte boundary. Valid only for object files.
470     /// </summary>
471     Align256Bytes = 0x00900000,
472     /// <summary>
473     /// Align data on a 512-byte boundary. Valid only for object files.
474     /// </summary>
475     Align512Bytes = 0x00A00000,
476     /// <summary>
477     /// Align data on a 1024-byte boundary. Valid only for object files.
478     /// </summary>
479     Align1024Bytes = 0x00B00000,
480     /// <summary>
481     /// Align data on a 2048-byte boundary. Valid only for object files.
482     /// </summary>
483     Align2048Bytes = 0x00C00000,
484     /// <summary>
485     /// Align data on a 4096-byte boundary. Valid only for object files.
486     /// </summary>
487     Align4096Bytes = 0x00D00000,
488     /// <summary>
489     /// Align data on an 8192-byte boundary. Valid only for object files.
490     /// </summary>
491     Align8192Bytes = 0x00E00000,
492     /// <summary>
493     /// The section contains extended relocations.
494     /// </summary>
495     LinkExtendedRelocationOverflow = 0x01000000,
496     /// <summary>
497     /// The section can be discarded as needed.
498     /// </summary>
499     MemoryDiscardable = 0x02000000,
500     /// <summary>
501     /// The section cannot be cached.
502     /// </summary>
503     MemoryNotCached = 0x04000000,
504     /// <summary>
505     /// The section is not pageable.
506     /// </summary>
507     MemoryNotPaged = 0x08000000,
508     /// <summary>
509     /// The section can be shared in memory.
510     /// </summary>
511     MemoryShared = 0x10000000,
512     /// <summary>
513     /// The section can be executed as code.
514     /// </summary>
515     MemoryExecute = 0x20000000,
516     /// <summary>
517     /// The section can be read.
518     /// </summary>
519     MemoryRead = 0x40000000,
520     /// <summary>
521     /// The section can be written to.
522     /// </summary>
523     MemoryWrite = 0x80000000
524     }
525     #endregion
526     #endregion
527     /// <summary>
528     /// Reads in the header information of the Portable Executable format.
529     /// Provides information such as the date the assembly was compiled.
530     /// </summary>
531     public class PeHeaderReader
532     {
533    
534    
535     #region Private Fields
536    
537     private UInt32 ntSignature;
538     /// <summary>
539     /// The DOS header
540     /// </summary>
541     private IMAGE_DOS_HEADER dosHeader;
542     /// <summary>
543     /// The file header
544     /// </summary>
545     private IMAGE_FILE_HEADER fileHeader;
546     /// <summary>
547     /// Optional 32 bit file header
548     /// </summary>
549     private IMAGE_OPTIONAL_HEADER32 optionalHeader32;
550     /// <summary>
551     /// Optional 64 bit file header
552     /// </summary>
553     private IMAGE_OPTIONAL_HEADER64 optionalHeader64;
554     /// <summary>
555     /// Image Section headers. Number of sections is in the file header.
556     /// </summary>
557     private IMAGE_SECTION_HEADER[] imageSectionHeaders;
558    
559     #endregion Private Fields
560    
561     #region Public Methods
562    
563     public PeHeaderReader(string filePath)
564     {
565     // Read in the DLL or EXE and get the timestamp
566     using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
567     {
568     BinaryReader reader = new BinaryReader(stream);
569     dosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(reader);
570    
571     // Add 4 bytes to the offset
572 william 609 stream.Seek(dosHeader._e_lfanew, SeekOrigin.Begin);
573 william 607
574     UInt32 ntHeadersSignature = reader.ReadUInt32();
575     ntSignature = ntHeadersSignature;
576     fileHeader = FromBinaryReader<IMAGE_FILE_HEADER>(reader);
577     if (this.Is32BitHeader)
578     {
579     optionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(reader);
580     }
581     else
582     {
583     optionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(reader);
584     }
585    
586     imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
587     for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
588     {
589     imageSectionHeaders[headerNo] = FromBinaryReader<IMAGE_SECTION_HEADER>(reader);
590     }
591    
592     }
593     }
594    
595     /// <summary>
596     /// Gets the header of the .NET assembly that called this function
597     /// </summary>
598     /// <returns></returns>
599     public static PeHeaderReader GetCallingAssemblyHeader()
600     {
601     // Get the path to the calling assembly, which is the path to the
602     // DLL or EXE that we want the time of
603     string filePath = System.Reflection.Assembly.GetCallingAssembly().Location;
604    
605     // Get and return the timestamp
606     return new PeHeaderReader(filePath);
607     }
608    
609     /// <summary>
610     /// Gets the header of the .NET assembly that called this function
611     /// </summary>
612     /// <returns></returns>
613     public static PeHeaderReader GetAssemblyHeader()
614     {
615     // Get the path to the calling assembly, which is the path to the
616     // DLL or EXE that we want the time of
617     string filePath = System.Reflection.Assembly.GetAssembly(typeof(PeHeaderReader)).Location;
618    
619     // Get and return the timestamp
620     return new PeHeaderReader(filePath);
621     }
622    
623     /// <summary>
624     /// Reads in a block from a file and converts it to the struct
625     /// type specified by the template parameter
626     /// </summary>
627     /// <typeparam name="T"></typeparam>
628     /// <param name="reader"></param>
629     /// <returns></returns>
630     public static T FromBinaryReader<T>(BinaryReader reader)
631     {
632     // Read in a byte array
633     byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
634    
635     // Pin the managed memory while, copy it out the data, then unpin it
636     GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
637     T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
638     handle.Free();
639    
640     return theStructure;
641     }
642    
643     #endregion Public Methods
644    
645     #region Properties
646    
647     /// <summary>
648     /// Gets if the file header is 32 bit or not
649     /// </summary>
650     public bool Is32BitHeader
651     {
652     get
653     {
654     return FileHeader.Characteristics.HasFlag(FileCharacteristicType.Supports32Bit);
655     }
656     }
657    
658     /// <summary>
659     /// Gets the file header
660     /// </summary>
661     public IMAGE_FILE_HEADER FileHeader
662     {
663     get
664     {
665     return fileHeader;
666     }
667     }
668     /// <summary>
669     /// Gets the file header
670     /// </summary>
671 william 610 public string NTSignature
672 william 607 {
673     get
674     {
675 william 610 ushort sig = (ushort)ntSignature;
676     return string.Format("0x{0:x4} [{1}]", sig, Encoding.ASCII.GetString(BitConverter.GetBytes(sig)));
677 william 607 }
678     }
679     /// <summary>
680     /// Gets the file header
681     /// </summary>
682     public IMAGE_DOS_HEADER DosHeader
683     {
684     get
685     {
686     return dosHeader;
687     }
688     }
689     /// <summary>
690     /// Gets the optional header
691     /// </summary>
692     public IMAGE_OPTIONAL_HEADER32 OptionalHeader32
693     {
694     get
695     {
696     return optionalHeader32;
697     }
698     }
699    
700     /// <summary>
701     /// Gets the optional header
702     /// </summary>
703     public IMAGE_OPTIONAL_HEADER64 OptionalHeader64
704     {
705     get
706     {
707     return optionalHeader64;
708     }
709     }
710    
711     public IMAGE_SECTION_HEADER[] ImageSectionHeaders
712     {
713     get
714     {
715     return imageSectionHeaders;
716     }
717     }
718    
719     /// <summary>
720     /// Gets the timestamp from the file header
721     /// </summary>
722     public DateTime TimeStamp
723     {
724     get
725     {
726     // Timestamp is a date offset from 1970
727     DateTime returnValue = new DateTime(1970, 1, 1, 0, 0, 0);
728    
729     // Add in the number of seconds since 1970/1/1
730     returnValue = returnValue.AddSeconds(fileHeader.TimeDateStamp);
731     // Adjust to local timezone
732     returnValue += TimeZone.CurrentTimeZone.GetUtcOffset(returnValue);
733    
734     return returnValue;
735     }
736     }
737    
738     #endregion Properties
739     }
740     #endregion
741     }

  ViewVC Help
Powered by ViewVC 1.1.22