ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/PEReader.cs
Revision: 321
Committed: Tue Jun 5 23:12:53 2012 UTC (11 years, 3 months ago) by william
File size: 31252 byte(s)
Log Message:
GetDateTimeFromDosDateTime iYear = 1970 (not 1980)

File Contents

# User Rev Content
1 william 299 #define ENABLE_LOGGING
2     using System;
3 william 159 using System.Collections.Generic;
4     using System.Linq;
5     using System.Text;
6     using System.IO;
7     using RomCheater.Logging;
8     using System.Runtime.InteropServices;
9     using System.Diagnostics;
10 william 318 using System.ComponentModel;
11 william 159
12     namespace Sojaner.MemoryScanner
13     {
14     public class PEReader
15     {
16 william 294 // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
17     #region Structs
18 william 319
19     [Flags]
20     public enum MachineTypeFlags
21     {
22     x86 = 0x14C,
23     Alpha = 0x184,
24     ARM = 0x1C0,
25     MIPS16R3000 = 0x162,
26     MIPS16R4000 = 0x166,
27     MIPS16R10000 = 0x168,
28     PowerPCLE = 0x1F0,
29     PowerPCBE = 0x1F2,
30     Itanium = 0x200,
31     MIPS16 = 0x266,
32     Alpha64 = 0x284,
33     MIPSFPU = 0x366,
34     MIPSFPU16 = 0x466,
35     x64 = 0x8664,
36     }
37 william 320 public enum MagicType : ushort
38     {
39     NT_OPTIONAL_HEADER_NOT_PRESENT, // 0
40     NT_OPTIONAL_HEADER_32 = 0x10b,
41     NT_OPTIONAL_HEADER_64 = 0x20b
42     }
43     public enum SubSystemType : ushort
44     {
45     IMAGE_SUBSYSTEM_UNKNOWN = 0,
46     IMAGE_SUBSYSTEM_NATIVE = 1,
47     IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
48     IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
49     IMAGE_SUBSYSTEM_POSIX_CUI = 7,
50     IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
51     IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
52     IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
53     IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
54     IMAGE_SUBSYSTEM_EFI_ROM = 13,
55     IMAGE_SUBSYSTEM_XBOX = 14
56 william 319
57 william 320 }
58     public enum DllCharacteristicsType : ushort
59     {
60     RES_0 = 0x0001,
61     RES_1 = 0x0002,
62     RES_2 = 0x0004,
63     RES_3 = 0x0008,
64     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
65     IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
66     IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
67     IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
68     IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
69     IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
70     RES_4 = 0x1000,
71     IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
72     IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
73     }
74 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
75 william 294 [StructLayout(LayoutKind.Sequential)]
76     public struct IMAGE_DOS_HEADER
77 william 290 {
78 william 318 public UInt16 _e_magic;
79     public UInt16 _e_cblp;
80     public UInt16 _e_cp;
81     public UInt16 _e_crlc;
82     public UInt16 _e_cparhdr;
83     public UInt16 _e_minalloc;
84     public UInt16 _e_maxalloc;
85     public UInt16 _e_ss;
86     public UInt16 _e_sp;
87     public UInt16 _e_csum;
88     public UInt16 _e_ip;
89     public UInt16 _e_cs;
90     public UInt16 _e_lfarlc;
91     public UInt16 _e_ovno;
92 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
93 william 318 public UInt16[] _e_res1;
94     public UInt16 _e_oemid;
95     public UInt16 _e_oeminfo;
96 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
97 william 318 public UInt16[] _e_res2;
98     public UInt32 _e_lfanew;
99    
100     public string e_magic { get { return string.Format("0x{0:x4}", _e_magic); } }
101     public string e_cblp { get { return string.Format("0x{0:x4}", _e_cblp); } }
102     public string e_cp { get { return string.Format("0x{0:x4}", _e_cp); } }
103     public string e_crlc { get { return string.Format("0x{0:x4}", _e_crlc); } }
104     public string e_cparhdr { get { return string.Format("0x{0:x4}", _e_cparhdr); } }
105     public string e_minalloc { get { return string.Format("0x{0:x4}", _e_minalloc); } }
106     public string e_maxalloc { get { return string.Format("0x{0:x4}", _e_maxalloc); } }
107     public string e_ss { get { return string.Format("0x{0:x4}", _e_ss); } }
108     public string e_sp { get { return string.Format("0x{0:x4}", _e_sp); } }
109     public string e_csum { get { return string.Format("0x{0:x4}", _e_csum); } }
110     public string e_ip { get { return string.Format("0x{0:x4}", _e_ip); } }
111     public string e_cs { get { return string.Format("0x{0:x4}", _e_cs); } }
112     public string e_lfarlc { get { return string.Format("0x{0:x4}", _e_lfarlc); } }
113     public string e_ovno { get { return string.Format("0x{0:x4}", _e_ovno); } }
114     public ushort[] e_res1 { get { return _e_res1; } }
115     public string e_oemid { get { return string.Format("0x{0:x4}", _e_oemid); } }
116     public string e_oeminfo { get { return string.Format("0x{0:x4}", _e_oeminfo); } }
117     public ushort[] e_res2 { get { return _e_res2; } }
118     public string e_lfanew { get { return string.Format("0x{0:x8}", _e_lfanew); } }
119    
120 william 319 public override string ToString()
121     {
122     return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic));
123     }
124 william 290 }
125 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
126 william 294 [StructLayout(LayoutKind.Sequential)]
127     public struct IMAGE_NT_HEADERS
128 william 159 {
129 william 319 public UInt32 _Signature;
130     public IMAGE_FILE_HEADER _FileHeader;
131     public IMAGE_OPTIONAL_HEADER32 _OptionalHeader32;
132     public IMAGE_OPTIONAL_HEADER64 _OptionalHeader64;
133    
134     public string Signature { get { return string.Format("0x{0:x8}", _Signature); } }
135     public IMAGE_FILE_HEADER FileHeader { get { return _FileHeader; } }
136     public IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get { return _OptionalHeader32;} }
137     public IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get { return _OptionalHeader64;} }
138    
139     public override string ToString()
140     {
141     return Encoding.UTF8.GetString(BitConverter.GetBytes(_Signature));
142     }
143 william 159 }
144 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
145 william 159 [StructLayout(LayoutKind.Sequential)]
146     public struct IMAGE_FILE_HEADER
147     {
148 william 319 public UInt16 _MachineType;
149     public UInt16 _NumberOfSections;
150     public UInt32 _TimeDateStamp;
151     public UInt32 _PointerToSymbolTable;
152     public UInt32 _NumberOfSymbols;
153     public UInt16 _SizeOfOptionalHeader;
154     public UInt16 _Characteristics;
155    
156    
157     public string MachineType { get { return ((MachineTypeFlags)_MachineType).ToString(); } }
158     public string NumberOfSections { get { return string.Format("0x{0:x4}", _NumberOfSections); } }
159     public string TimeDateStamp { get { return string.Format("{0} (0x{1:x8})", GetDateTimeFromDosDateTime(_TimeDateStamp).ToString(), _TimeDateStamp); } }
160     public string PointerToSymbolTable { get { return string.Format("0x{0:x8}", _PointerToSymbolTable); } }
161     public string NumberOfSymbols { get { return string.Format("0x{0:x8}", _NumberOfSymbols); } }
162     public string SizeOfOptionalHeader { get { return string.Format("0x{0:x4}", _SizeOfOptionalHeader); } }
163     public string Characteristics { get { return string.Format("0x{0:x4}", _Characteristics); } }
164     public override string ToString()
165     {
166     return MachineType;
167     }
168    
169     private DateTime GetDateTimeFromDosDateTime(UInt32 i32TimeDate)
170     {
171     UInt16 i16Time = (UInt16)(i32TimeDate & 0xFFFF);
172     UInt16 i16Date = (UInt16)((i32TimeDate & 0xFFFF0000) >> 16);
173     return GetDateTimeFromDosDateTime(i16Time, i16Date);
174     }
175     private DateTime GetDateTimeFromDosDateTime(UInt16 i16Time, UInt16 i16Date)
176     {
177     int iYear = 0;
178     int iMonth = 1;
179     int iDay = 1;
180     int iHour = 0;
181     int iMinute = 0;
182     int iSecond = 0;
183     iDay = (i16Date & 0x1F);
184     iMonth = ((i16Date & 0x01E0) >> 5);
185 william 321 iYear = 1970 + ((i16Date & 0xFE00) >> 9);
186 william 319 iSecond = (i16Time & 0x1F) * 2;
187     iMinute = ((i16Time & 0x07E0) >> 5);
188     iHour = ((i16Time & 0x0F800) >> 11);
189     return new DateTime(iYear, iMonth, iDay, iHour, iMinute, iSecond);
190     }
191    
192 william 159 }
193 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
194 william 159 [StructLayout(LayoutKind.Sequential)]
195 william 294 public struct IMAGE_OPTIONAL_HEADER32
196 william 159 {
197 william 320 public UInt16 _Magic;
198     public Byte _MajorLinkerVersion;
199     public Byte _MinorLinkerVersion;
200     public UInt32 _SizeOfCode;
201     public UInt32 _SizeOfInitializedData;
202     public UInt32 _SizeOfUninitializedData;
203     public UInt32 _AddressOfEntryPoint;
204     public UInt32 _BaseOfCode;
205     public UInt32 _BaseOfData; // 32-but specific
206     public UInt32 _ImageBase;
207     public UInt32 _SectionAlignment;
208     public UInt32 _FileAlignment;
209     public UInt16 _MajorOperatingSystemVersion;
210     public UInt16 _MinorOperatingSystemVersion;
211     public UInt16 _MajorImageVersion;
212     public UInt16 _MinorImageVersion;
213     public UInt16 _MajorSubsystemVersion;
214     public UInt16 _MinorSubsystemVersion;
215     public UInt32 _Win32VersionValue;
216     public UInt32 _SizeOfImage;
217     public UInt32 _SizeOfHeaders;
218     public UInt32 _CheckSum;
219     public UInt16 _Subsystem;
220     public UInt16 _DllCharacteristics;
221     public UInt32 _SizeOfStackReserve;
222     public UInt32 _SizeOfStackCommit;
223     public UInt32 _SizeOfHeapReserve;
224     public UInt32 _SizeOfHeapCommit;
225     public UInt32 _LoaderFlags;
226     public UInt32 _NumberOfRvaAndSizes;
227 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
228 william 320 public IMAGE_DATA_DIRECTORY[] _DataDirectory;
229    
230    
231     public string Magic { get { return ((MagicType)_Magic).ToString(); } }
232     public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
233     public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
234    
235     public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } }
236     public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } }
237     public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } }
238     public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } }
239     public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } }
240     public string BaseOfData { get { return string.Format("0x{0:x8}", _BaseOfData); } }
241     public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } }
242    
243     public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } }
244     public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } }
245    
246     public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } }
247     public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } }
248     public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } }
249     public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } }
250     public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } }
251     public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } }
252    
253     public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } }
254     public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } }
255     public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } }
256     public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } }
257    
258     public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } }
259     public string DllCharacteristics { get { return string.Format("0x{0:x4}", _DllCharacteristics); } }
260    
261     public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } }
262     public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } }
263     public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } }
264     public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } }
265    
266     public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } }
267     public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } }
268     public override string ToString()
269     {
270     return Magic;
271     }
272 william 159 }
273 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
274 william 294 [StructLayout(LayoutKind.Sequential)]
275     public struct IMAGE_OPTIONAL_HEADER64
276 william 159 {
277 william 320 public UInt16 _Magic;
278     public Byte _MajorLinkerVersion;
279     public Byte _MinorLinkerVersion;
280     public UInt32 _SizeOfCode;
281     public UInt32 _SizeOfInitializedData;
282     public UInt32 _SizeOfUninitializedData;
283     public UInt32 _AddressOfEntryPoint;
284     public UInt32 _BaseOfCode;
285     public UInt64 _ImageBase;
286     public UInt32 _SectionAlignment;
287     public UInt32 _FileAlignment;
288     public UInt16 _MajorOperatingSystemVersion;
289     public UInt16 _MinorOperatingSystemVersion;
290     public UInt16 _MajorImageVersion;
291     public UInt16 _MinorImageVersion;
292     public UInt16 _MajorSubsystemVersion;
293     public UInt16 _MinorSubsystemVersion;
294     public UInt32 _Win32VersionValue;
295     public UInt32 _SizeOfImage;
296     public UInt32 _SizeOfHeaders;
297     public UInt32 _CheckSum;
298     public UInt16 _Subsystem;
299     public UInt16 _DllCharacteristics;
300     public UInt64 _SizeOfStackReserve;
301     public UInt64 _SizeOfStackCommit;
302     public UInt64 _SizeOfHeapReserve;
303     public UInt64 _SizeOfHeapCommit;
304     public UInt32 _LoaderFlags;
305     public UInt32 _NumberOfRvaAndSizes;
306 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
307 william 320 public IMAGE_DATA_DIRECTORY[] _DataDirectory;
308    
309    
310     public string Magic { get { return ((MagicType)_Magic).ToString(); } }
311     public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
312     public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
313    
314     public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } }
315     public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } }
316     public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } }
317     public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } }
318     public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } }
319    
320     public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } }
321    
322     public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } }
323     public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } }
324    
325     public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } }
326     public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } }
327     public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } }
328     public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } }
329     public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } }
330     public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } }
331    
332     public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } }
333     public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } }
334     public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } }
335     public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } }
336    
337     public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } }
338     public string DllCharacteristics { get { return string.Format("0x{0:x4}", _DllCharacteristics); } }
339    
340     public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } }
341     public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } }
342     public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } }
343     public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } }
344    
345     public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } }
346     public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } }
347    
348     public override string ToString()
349     {
350     return Magic;
351     }
352 william 159 }
353 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
354 william 294 [StructLayout(LayoutKind.Sequential)]
355     public struct IMAGE_DATA_DIRECTORY
356 william 159 {
357 william 320 public UInt32 _VirtualAddress;
358     public UInt32 _Size;
359    
360     public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
361     public string Size { get { return string.Format("0x{0:x8}", _Size); } }
362 william 159 }
363 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
364 william 294 [StructLayout(LayoutKind.Sequential)]
365     public struct IMAGE_SECTION_HEADER
366 william 159 {
367 william 294 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
368 william 319 public string _Name;
369     public Misc _Misc;
370     public UInt32 _VirtualAddress;
371     public UInt32 _SizeOfRawData;
372     public UInt32 _PointerToRawData;
373     public UInt32 _PointerToRelocations;
374     public UInt32 _PointerToLinenumbers;
375     public UInt16 _NumberOfRelocations;
376     public UInt16 _NumberOfLinenumbers;
377     public UInt32 _Characteristics;
378    
379     public string Name { get { return _Name; } }
380     public Misc Misc { get { return _Misc; } }
381     public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
382     public string SizeOfRawData { get { return string.Format("0x{0:x8}", _SizeOfRawData); } }
383     public string PointerToRawData { get { return string.Format("0x{0:x8}", _PointerToRawData); } }
384     public string PointerToRelocations { get { return string.Format("0x{0:x8}", _PointerToRelocations); } }
385     public string PointerToLinenumbers { get { return string.Format("0x{0:x8}", _PointerToLinenumbers); } }
386     public string NumberOfRelocations { get { return string.Format("0x{0:x4}", _NumberOfRelocations); } }
387     public string NumberOfLinenumbers { get { return string.Format("0x{0:x4}", _NumberOfLinenumbers); } }
388     public string Characteristics { get { return string.Format("0x{0:x8}", _Characteristics); } }
389     public override string ToString()
390     {
391     return Name;
392     }
393 william 159 }
394 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
395 william 159 [StructLayout(LayoutKind.Explicit)]
396 william 294 public struct Misc
397 william 159 {
398     [FieldOffset(0)]
399 william 319 public UInt32 _PhysicalAddress;
400 william 294 [FieldOffset(0)]
401 william 319 public UInt32 _VirtualSize;
402    
403     public string PhysicalAddress { get { return string.Format("0x{0:x8}", _PhysicalAddress); } }
404     public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } }
405    
406 william 294 }
407 william 159
408 william 294 #endregion
409 william 159
410 william 294 #region Fields
411 william 159
412 william 294 private readonly IMAGE_DOS_HEADER _dosHeader;
413     private IMAGE_NT_HEADERS _ntHeaders;
414     private readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
415     #endregion
416 william 159
417 william 299 #region logging implementation
418     private static class log
419     {
420     public static class verbose
421     {
422     public static class debug
423     {
424     public static void writeline(string format, params object[] args)
425     {
426     #if ENABLE_LOGGING
427     logger.VerboseDebug.WriteLine(format, args);
428     #endif
429     }
430     public static void write(string format, params object[] args)
431     {
432     #if ENABLE_LOGGING
433     logger.VerboseDebug.Write(format, args);
434     #endif
435     }
436     }
437     public static class error
438     {
439     public static void writeline(string format, params object[] args)
440     {
441     #if ENABLE_LOGGING
442     logger.VerboseError.WriteLine(format, args);
443     #endif
444     }
445     public static void write(string format, params object[] args)
446     {
447     #if ENABLE_LOGGING
448     logger.VerboseError.Write(format, args);
449     #endif
450     }
451     }
452     }
453     }
454     #endregion
455    
456    
457 william 318 public PEData GetData
458     {
459     get
460     {
461 william 319 PEData _data = new PEData(_dosHeader, _ntHeaders, _sectionHeaders.ToArray());
462 william 318 return _data;
463     }
464     }
465     #region t
466     public class PEData
467     {
468 william 319 public PEData() : this(new IMAGE_DOS_HEADER(), new IMAGE_NT_HEADERS(), new IMAGE_SECTION_HEADER[] { }) { }
469     public PEData(IMAGE_DOS_HEADER DosHeader, IMAGE_NT_HEADERS NTHeader, IMAGE_SECTION_HEADER[] SectionHeaders)
470 william 318 {
471     this.DosHeader = DosHeader;
472     this.NTHeader = NTHeader;
473     this.SectionHeaders = SectionHeaders;
474     }
475     public IMAGE_DOS_HEADER DosHeader { get; private set; }
476     public IMAGE_NT_HEADERS NTHeader { get; private set; }
477 william 319 public IMAGE_SECTION_HEADER[] SectionHeaders { get; private set; }
478 william 318 }
479    
480     #endregion
481    
482 william 294 public PEReader(FileInfo fi) : this(fi.FullName) { }
483     public PEReader(string filename)
484 william 299 {
485 william 294 Exception ErrorInfo = null;
486     using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
487     {
488     try
489     {
490 william 299 log.verbose.debug.writeline("Reading PE Format from: {0}", filename);
491 william 294 BinaryReader reader = new BinaryReader(fs);
492     // Reset reader position, just in case
493     reader.BaseStream.Seek(0, SeekOrigin.Begin);
494 william 159
495 william 294 // Read MS-DOS header section
496     _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
497     // MS-DOS magic number should read 'MZ'
498 william 318 if (_dosHeader._e_magic != 0x5a4d)
499 william 294 {
500     throw new InvalidOperationException("File is not a portable executable.");
501     }
502 william 159
503 william 294 // Skip MS-DOS stub and seek reader to NT Headers
504 william 318 reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
505 william 159
506 william 294 // Read NT Headers
507 william 319 _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
508 william 159
509 william 294 // Make sure we have 'PE' in the pe signature
510 william 319 if (_ntHeaders._Signature != 0x4550)
511 william 294 {
512     throw new InvalidOperationException("Invalid portable executable signature in NT header.");
513     }
514 william 159
515 william 319 _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);
516 william 294 // Read optional headers
517     if (Is32bitAssembly())
518     {
519 william 299 log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
520 william 294 Load32bitOptionalHeaders(reader);
521     }
522     else
523     {
524 william 299 log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
525 william 294 Load64bitOptionalHeaders(reader);
526     }
527 william 159
528 william 294 // Read section data
529 william 299 log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
530 william 294 foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
531     {
532     int section_index = _sectionHeaders.IndexOf(header) + 1;
533 william 299 log.verbose.debug.writeline("\tSection Header: {0} of {1}", section_index, _sectionHeaders.Count);
534     log.verbose.debug.writeline("\t\tName: {0}", header.Name);
535     log.verbose.debug.writeline("\t\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
536     log.verbose.debug.writeline("\t\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
537     log.verbose.debug.writeline("\t\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
538     log.verbose.debug.writeline("\t\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
539     log.verbose.debug.writeline("\t\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
540 william 159
541 william 294 // Skip to beginning of a section
542 william 319 reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
543 william 159
544 william 294 // Read section data... and do something with it
545 william 319 byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
546 william 294 }
547     reader.Close();
548     }
549     catch (Exception ex)
550     {
551     ErrorInfo = ex;
552     throw ErrorInfo;
553     }
554     }
555     if (ErrorInfo != null)
556     {
557 william 299 log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
558     log.verbose.error.writeline(ErrorInfo.ToString());
559 william 294 }
560     }
561 william 159
562 william 294 public IMAGE_DOS_HEADER GetDOSHeader()
563     {
564     return _dosHeader;
565     }
566 william 159
567 william 294 public UInt32 GetPESignature()
568     {
569 william 319 return _ntHeaders._Signature;
570 william 294 }
571 william 159
572 william 294 public IMAGE_FILE_HEADER GetFileHeader()
573     {
574     return _ntHeaders.FileHeader;
575     }
576 william 159
577 william 294 public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
578     {
579     return _ntHeaders.OptionalHeader32;
580     }
581 william 159
582 william 294 public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
583     {
584     return _ntHeaders.OptionalHeader64;
585     }
586 william 159
587 william 294 public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
588     {
589     return _sectionHeaders;
590     }
591 william 159
592 william 294 public bool Is32bitAssembly()
593 william 159 {
594 william 319 return ((_ntHeaders.FileHeader._Characteristics & 0x0100) == 0x0100);
595 william 159 }
596 william 294
597     private void Load64bitOptionalHeaders(BinaryReader reader)
598 william 293 {
599 william 319 _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
600 william 293
601 william 294 // Should have 10 data directories
602 william 320 if (_ntHeaders.OptionalHeader64._NumberOfRvaAndSizes != 0x10)
603 william 294 {
604     throw new InvalidOperationException("Invalid number of data directories in NT header");
605     }
606 william 293
607 william 294 // Scan data directories and load section headers
608 william 320 for (int i = 0; i < _ntHeaders.OptionalHeader64._NumberOfRvaAndSizes; i++)
609 william 294 {
610 william 320 if (_ntHeaders._OptionalHeader64._DataDirectory[i]._Size > 0)
611 william 294 {
612     _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
613     }
614     }
615     }
616 william 293
617 william 294 private void Load32bitOptionalHeaders(BinaryReader reader)
618     {
619 william 319 _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
620 william 293
621 william 294 // Should have 10 data directories
622 william 320 if (_ntHeaders.OptionalHeader32._NumberOfRvaAndSizes != 0x10)
623 william 294 {
624     throw new InvalidOperationException("Invalid number of data directories in NT header");
625     }
626 william 293
627 william 294 // Scan data directories and load section headers
628 william 320 for (int i = 0; i < _ntHeaders.OptionalHeader32._NumberOfRvaAndSizes; i++)
629 william 294 {
630 william 320 if (_ntHeaders._OptionalHeader32._DataDirectory[i]._Size > 0)
631 william 294 {
632     _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
633     }
634     }
635     }
636 william 293
637 william 294 private static T MarshalBytesTo<T>(BinaryReader reader)
638     {
639     // Unmanaged data
640     byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
641 william 293
642 william 294 // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
643     GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
644 william 293
645 william 294 // Use our previously created pointer to unmanaged data and marshal to the specified type
646     T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
647 william 293
648 william 294 // Deallocate pointer
649     handle.Free();
650 william 293
651 william 294 return theStructure;
652 william 293 }
653 william 159 }
654     }