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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 322 - (hide annotations) (download)
Tue Jun 5 23:20:12 2012 UTC (8 years, 11 months ago) by william
File size: 31460 byte(s)

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 william 322 public Int32 _TimeDateStamp;
151 william 319 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 william 322 private DateTime GetDateTimeFromDosDateTime(Int32 i32TimeDate)
170 william 319 {
171 william 322 Int16 i16Time = (Int16)(i32TimeDate & 0xFFFF);
172     Int16 i16Date = (Int16)((i32TimeDate & 0xFFFF0000) >> 16);
173 william 319 return GetDateTimeFromDosDateTime(i16Time, i16Date);
174     }
175 william 322 private DateTime GetDateTimeFromDosDateTime(Int16 i16Time, Int16 i16Date)
176 william 319 {
177 william 322 try
178     {
179     int iYear = 0;
180     int iMonth = 1;
181     int iDay = 1;
182     int iHour = 0;
183     int iMinute = 0;
184     int iSecond = 0;
185     iDay = (i16Date & 0x1F);
186     iMonth = ((i16Date & 0x01E0) >> 5);
187     iYear = 1980 + ((i16Date & 0xFE00) >> 9);
188     iSecond = (i16Time & 0x1F) * 2;
189     iMinute = ((i16Time & 0x07E0) >> 5);
190     iHour = ((i16Time & 0x0F800) >> 11);
191     return new DateTime(iYear, iMonth, iDay, iHour, iMinute, iSecond);
192     }
193     catch
194     {
195     return new DateTime();
196     }
197 william 319 }
198    
199 william 159 }
200 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
201 william 159 [StructLayout(LayoutKind.Sequential)]
202 william 294 public struct IMAGE_OPTIONAL_HEADER32
203 william 159 {
204 william 320 public UInt16 _Magic;
205     public Byte _MajorLinkerVersion;
206     public Byte _MinorLinkerVersion;
207     public UInt32 _SizeOfCode;
208     public UInt32 _SizeOfInitializedData;
209     public UInt32 _SizeOfUninitializedData;
210     public UInt32 _AddressOfEntryPoint;
211     public UInt32 _BaseOfCode;
212     public UInt32 _BaseOfData; // 32-but specific
213     public UInt32 _ImageBase;
214     public UInt32 _SectionAlignment;
215     public UInt32 _FileAlignment;
216     public UInt16 _MajorOperatingSystemVersion;
217     public UInt16 _MinorOperatingSystemVersion;
218     public UInt16 _MajorImageVersion;
219     public UInt16 _MinorImageVersion;
220     public UInt16 _MajorSubsystemVersion;
221     public UInt16 _MinorSubsystemVersion;
222     public UInt32 _Win32VersionValue;
223     public UInt32 _SizeOfImage;
224     public UInt32 _SizeOfHeaders;
225     public UInt32 _CheckSum;
226     public UInt16 _Subsystem;
227     public UInt16 _DllCharacteristics;
228     public UInt32 _SizeOfStackReserve;
229     public UInt32 _SizeOfStackCommit;
230     public UInt32 _SizeOfHeapReserve;
231     public UInt32 _SizeOfHeapCommit;
232     public UInt32 _LoaderFlags;
233     public UInt32 _NumberOfRvaAndSizes;
234 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
235 william 320 public IMAGE_DATA_DIRECTORY[] _DataDirectory;
236    
237    
238     public string Magic { get { return ((MagicType)_Magic).ToString(); } }
239     public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
240     public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
241    
242     public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } }
243     public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } }
244     public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } }
245     public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } }
246     public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } }
247     public string BaseOfData { get { return string.Format("0x{0:x8}", _BaseOfData); } }
248     public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } }
249    
250     public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } }
251     public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } }
252    
253     public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } }
254     public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } }
255     public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } }
256     public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } }
257     public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } }
258     public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } }
259    
260     public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } }
261     public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } }
262     public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } }
263     public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } }
264    
265     public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } }
266     public string DllCharacteristics { get { return string.Format("0x{0:x4}", _DllCharacteristics); } }
267    
268     public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } }
269     public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } }
270     public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } }
271     public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } }
272    
273     public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } }
274     public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } }
275     public override string ToString()
276     {
277     return Magic;
278     }
279 william 159 }
280 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
281 william 294 [StructLayout(LayoutKind.Sequential)]
282     public struct IMAGE_OPTIONAL_HEADER64
283 william 159 {
284 william 320 public UInt16 _Magic;
285     public Byte _MajorLinkerVersion;
286     public Byte _MinorLinkerVersion;
287     public UInt32 _SizeOfCode;
288     public UInt32 _SizeOfInitializedData;
289     public UInt32 _SizeOfUninitializedData;
290     public UInt32 _AddressOfEntryPoint;
291     public UInt32 _BaseOfCode;
292     public UInt64 _ImageBase;
293     public UInt32 _SectionAlignment;
294     public UInt32 _FileAlignment;
295     public UInt16 _MajorOperatingSystemVersion;
296     public UInt16 _MinorOperatingSystemVersion;
297     public UInt16 _MajorImageVersion;
298     public UInt16 _MinorImageVersion;
299     public UInt16 _MajorSubsystemVersion;
300     public UInt16 _MinorSubsystemVersion;
301     public UInt32 _Win32VersionValue;
302     public UInt32 _SizeOfImage;
303     public UInt32 _SizeOfHeaders;
304     public UInt32 _CheckSum;
305     public UInt16 _Subsystem;
306     public UInt16 _DllCharacteristics;
307     public UInt64 _SizeOfStackReserve;
308     public UInt64 _SizeOfStackCommit;
309     public UInt64 _SizeOfHeapReserve;
310     public UInt64 _SizeOfHeapCommit;
311     public UInt32 _LoaderFlags;
312     public UInt32 _NumberOfRvaAndSizes;
313 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
314 william 320 public IMAGE_DATA_DIRECTORY[] _DataDirectory;
315    
316    
317     public string Magic { get { return ((MagicType)_Magic).ToString(); } }
318     public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
319     public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
320    
321     public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } }
322     public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } }
323     public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } }
324     public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } }
325     public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } }
326    
327     public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } }
328    
329     public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } }
330     public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } }
331    
332     public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } }
333     public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } }
334     public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } }
335     public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } }
336     public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } }
337     public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } }
338    
339     public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } }
340     public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } }
341     public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } }
342     public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } }
343    
344     public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } }
345     public string DllCharacteristics { get { return string.Format("0x{0:x4}", _DllCharacteristics); } }
346    
347     public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } }
348     public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } }
349     public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } }
350     public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } }
351    
352     public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } }
353     public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } }
354    
355     public override string ToString()
356     {
357     return Magic;
358     }
359 william 159 }
360 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
361 william 294 [StructLayout(LayoutKind.Sequential)]
362     public struct IMAGE_DATA_DIRECTORY
363 william 159 {
364 william 320 public UInt32 _VirtualAddress;
365     public UInt32 _Size;
366    
367     public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
368     public string Size { get { return string.Format("0x{0:x8}", _Size); } }
369 william 159 }
370 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
371 william 294 [StructLayout(LayoutKind.Sequential)]
372     public struct IMAGE_SECTION_HEADER
373 william 159 {
374 william 294 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
375 william 319 public string _Name;
376     public Misc _Misc;
377     public UInt32 _VirtualAddress;
378     public UInt32 _SizeOfRawData;
379     public UInt32 _PointerToRawData;
380     public UInt32 _PointerToRelocations;
381     public UInt32 _PointerToLinenumbers;
382     public UInt16 _NumberOfRelocations;
383     public UInt16 _NumberOfLinenumbers;
384     public UInt32 _Characteristics;
385    
386     public string Name { get { return _Name; } }
387     public Misc Misc { get { return _Misc; } }
388     public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
389     public string SizeOfRawData { get { return string.Format("0x{0:x8}", _SizeOfRawData); } }
390     public string PointerToRawData { get { return string.Format("0x{0:x8}", _PointerToRawData); } }
391     public string PointerToRelocations { get { return string.Format("0x{0:x8}", _PointerToRelocations); } }
392     public string PointerToLinenumbers { get { return string.Format("0x{0:x8}", _PointerToLinenumbers); } }
393     public string NumberOfRelocations { get { return string.Format("0x{0:x4}", _NumberOfRelocations); } }
394     public string NumberOfLinenumbers { get { return string.Format("0x{0:x4}", _NumberOfLinenumbers); } }
395     public string Characteristics { get { return string.Format("0x{0:x8}", _Characteristics); } }
396     public override string ToString()
397     {
398     return Name;
399     }
400 william 159 }
401 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
402 william 159 [StructLayout(LayoutKind.Explicit)]
403 william 294 public struct Misc
404 william 159 {
405     [FieldOffset(0)]
406 william 319 public UInt32 _PhysicalAddress;
407 william 294 [FieldOffset(0)]
408 william 319 public UInt32 _VirtualSize;
409    
410     public string PhysicalAddress { get { return string.Format("0x{0:x8}", _PhysicalAddress); } }
411     public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } }
412    
413 william 294 }
414 william 159
415 william 294 #endregion
416 william 159
417 william 294 #region Fields
418 william 159
419 william 294 private readonly IMAGE_DOS_HEADER _dosHeader;
420     private IMAGE_NT_HEADERS _ntHeaders;
421     private readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
422     #endregion
423 william 159
424 william 299 #region logging implementation
425     private static class log
426     {
427     public static class verbose
428     {
429     public static class debug
430     {
431     public static void writeline(string format, params object[] args)
432     {
433     #if ENABLE_LOGGING
434     logger.VerboseDebug.WriteLine(format, args);
435     #endif
436     }
437     public static void write(string format, params object[] args)
438     {
439     #if ENABLE_LOGGING
440     logger.VerboseDebug.Write(format, args);
441     #endif
442     }
443     }
444     public static class error
445     {
446     public static void writeline(string format, params object[] args)
447     {
448     #if ENABLE_LOGGING
449     logger.VerboseError.WriteLine(format, args);
450     #endif
451     }
452     public static void write(string format, params object[] args)
453     {
454     #if ENABLE_LOGGING
455     logger.VerboseError.Write(format, args);
456     #endif
457     }
458     }
459     }
460     }
461     #endregion
462    
463    
464 william 318 public PEData GetData
465     {
466     get
467     {
468 william 319 PEData _data = new PEData(_dosHeader, _ntHeaders, _sectionHeaders.ToArray());
469 william 318 return _data;
470     }
471     }
472     #region t
473     public class PEData
474     {
475 william 319 public PEData() : this(new IMAGE_DOS_HEADER(), new IMAGE_NT_HEADERS(), new IMAGE_SECTION_HEADER[] { }) { }
476     public PEData(IMAGE_DOS_HEADER DosHeader, IMAGE_NT_HEADERS NTHeader, IMAGE_SECTION_HEADER[] SectionHeaders)
477 william 318 {
478     this.DosHeader = DosHeader;
479     this.NTHeader = NTHeader;
480     this.SectionHeaders = SectionHeaders;
481     }
482     public IMAGE_DOS_HEADER DosHeader { get; private set; }
483     public IMAGE_NT_HEADERS NTHeader { get; private set; }
484 william 319 public IMAGE_SECTION_HEADER[] SectionHeaders { get; private set; }
485 william 318 }
486    
487     #endregion
488    
489 william 294 public PEReader(FileInfo fi) : this(fi.FullName) { }
490     public PEReader(string filename)
491 william 299 {
492 william 294 Exception ErrorInfo = null;
493     using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
494     {
495     try
496     {
497 william 299 log.verbose.debug.writeline("Reading PE Format from: {0}", filename);
498 william 294 BinaryReader reader = new BinaryReader(fs);
499     // Reset reader position, just in case
500     reader.BaseStream.Seek(0, SeekOrigin.Begin);
501 william 159
502 william 294 // Read MS-DOS header section
503     _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
504     // MS-DOS magic number should read 'MZ'
505 william 318 if (_dosHeader._e_magic != 0x5a4d)
506 william 294 {
507     throw new InvalidOperationException("File is not a portable executable.");
508     }
509 william 159
510 william 294 // Skip MS-DOS stub and seek reader to NT Headers
511 william 318 reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
512 william 159
513 william 294 // Read NT Headers
514 william 319 _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
515 william 159
516 william 294 // Make sure we have 'PE' in the pe signature
517 william 319 if (_ntHeaders._Signature != 0x4550)
518 william 294 {
519     throw new InvalidOperationException("Invalid portable executable signature in NT header.");
520     }
521 william 159
522 william 319 _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);
523 william 294 // Read optional headers
524     if (Is32bitAssembly())
525     {
526 william 299 log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
527 william 294 Load32bitOptionalHeaders(reader);
528     }
529     else
530     {
531 william 299 log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
532 william 294 Load64bitOptionalHeaders(reader);
533     }
534 william 159
535 william 294 // Read section data
536 william 299 log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
537 william 294 foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
538     {
539     int section_index = _sectionHeaders.IndexOf(header) + 1;
540 william 299 log.verbose.debug.writeline("\tSection Header: {0} of {1}", section_index, _sectionHeaders.Count);
541     log.verbose.debug.writeline("\t\tName: {0}", header.Name);
542     log.verbose.debug.writeline("\t\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
543     log.verbose.debug.writeline("\t\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
544     log.verbose.debug.writeline("\t\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
545     log.verbose.debug.writeline("\t\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
546     log.verbose.debug.writeline("\t\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
547 william 159
548 william 294 // Skip to beginning of a section
549 william 319 reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
550 william 159
551 william 294 // Read section data... and do something with it
552 william 319 byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
553 william 294 }
554     reader.Close();
555     }
556     catch (Exception ex)
557     {
558     ErrorInfo = ex;
559     throw ErrorInfo;
560     }
561     }
562     if (ErrorInfo != null)
563     {
564 william 299 log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
565     log.verbose.error.writeline(ErrorInfo.ToString());
566 william 294 }
567     }
568 william 159
569 william 294 public IMAGE_DOS_HEADER GetDOSHeader()
570     {
571     return _dosHeader;
572     }
573 william 159
574 william 294 public UInt32 GetPESignature()
575     {
576 william 319 return _ntHeaders._Signature;
577 william 294 }
578 william 159
579 william 294 public IMAGE_FILE_HEADER GetFileHeader()
580     {
581     return _ntHeaders.FileHeader;
582     }
583 william 159
584 william 294 public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
585     {
586     return _ntHeaders.OptionalHeader32;
587     }
588 william 159
589 william 294 public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
590     {
591     return _ntHeaders.OptionalHeader64;
592     }
593 william 159
594 william 294 public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
595     {
596     return _sectionHeaders;
597     }
598 william 159
599 william 294 public bool Is32bitAssembly()
600 william 159 {
601 william 319 return ((_ntHeaders.FileHeader._Characteristics & 0x0100) == 0x0100);
602 william 159 }
603 william 294
604     private void Load64bitOptionalHeaders(BinaryReader reader)
605 william 293 {
606 william 319 _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
607 william 293
608 william 294 // Should have 10 data directories
609 william 320 if (_ntHeaders.OptionalHeader64._NumberOfRvaAndSizes != 0x10)
610 william 294 {
611     throw new InvalidOperationException("Invalid number of data directories in NT header");
612     }
613 william 293
614 william 294 // Scan data directories and load section headers
615 william 320 for (int i = 0; i < _ntHeaders.OptionalHeader64._NumberOfRvaAndSizes; i++)
616 william 294 {
617 william 320 if (_ntHeaders._OptionalHeader64._DataDirectory[i]._Size > 0)
618 william 294 {
619     _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
620     }
621     }
622     }
623 william 293
624 william 294 private void Load32bitOptionalHeaders(BinaryReader reader)
625     {
626 william 319 _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
627 william 293
628 william 294 // Should have 10 data directories
629 william 320 if (_ntHeaders.OptionalHeader32._NumberOfRvaAndSizes != 0x10)
630 william 294 {
631     throw new InvalidOperationException("Invalid number of data directories in NT header");
632     }
633 william 293
634 william 294 // Scan data directories and load section headers
635 william 320 for (int i = 0; i < _ntHeaders.OptionalHeader32._NumberOfRvaAndSizes; i++)
636 william 294 {
637 william 320 if (_ntHeaders._OptionalHeader32._DataDirectory[i]._Size > 0)
638 william 294 {
639     _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
640     }
641     }
642     }
643 william 293
644 william 294 private static T MarshalBytesTo<T>(BinaryReader reader)
645     {
646     // Unmanaged data
647     byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
648 william 293
649 william 294 // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
650     GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
651 william 293
652 william 294 // Use our previously created pointer to unmanaged data and marshal to the specified type
653     T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
654 william 293
655 william 294 // Deallocate pointer
656     handle.Free();
657 william 293
658 william 294 return theStructure;
659 william 293 }
660 william 159 }
661     }

  ViewVC Help
Powered by ViewVC 1.1.22