ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/PEReader.cs
Revision: 324
Committed: Thu Jun 7 17:42:57 2012 UTC (10 years, 11 months ago) by william
File size: 32712 byte(s)
Log Message:
PEData add Is32bitAssembly()

File Contents

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