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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 339 - (show annotations) (download)
Fri Jun 8 00:20:39 2012 UTC (9 years, 3 months ago) by william
File size: 34081 byte(s)

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 _SectionAlignment.ToString();} }
278 public string FileAlignment { get { return _FileAlignment.ToString(); } }
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 public override string ToString()
398 {
399 return string.Format("(Size={0}) (VirtualAddress={1})", Size, VirtualAddress);
400 }
401
402 }
403 [TypeConverter(typeof(ExpandableObjectConverter))]
404 [StructLayout(LayoutKind.Sequential)]
405 public struct IMAGE_SECTION_HEADER
406 {
407 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
408 public string _Name;
409 public Misc _Misc;
410 public UInt32 _VirtualAddress;
411 public UInt32 _SizeOfRawData;
412 public UInt32 _PointerToRawData;
413 public UInt32 _PointerToRelocations;
414 public UInt32 _PointerToLinenumbers;
415 public UInt16 _NumberOfRelocations;
416 public UInt16 _NumberOfLinenumbers;
417 public UInt32 _Characteristics;
418
419 public string Name { get { return _Name; } }
420 public Misc Misc { get { return _Misc; } }
421 public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
422 public string SizeOfRawData { get { return string.Format("0x{0:x8}", _SizeOfRawData); } }
423 public string PointerToRawData { get { return string.Format("0x{0:x8}", _PointerToRawData); } }
424 public string PointerToRelocations { get { return string.Format("0x{0:x8}", _PointerToRelocations); } }
425 public string PointerToLinenumbers { get { return string.Format("0x{0:x8}", _PointerToLinenumbers); } }
426 public string NumberOfRelocations { get { return string.Format("0x{0:x4}", _NumberOfRelocations); } }
427 public string NumberOfLinenumbers { get { return string.Format("0x{0:x4}", _NumberOfLinenumbers); } }
428 public string Characteristics { get { return string.Format("0x{0:x8}", _Characteristics); } }
429 public override string ToString()
430 {
431 return Name;
432 }
433 }
434 [TypeConverter(typeof(ExpandableObjectConverter))]
435 [StructLayout(LayoutKind.Explicit)]
436 public struct Misc
437 {
438 [FieldOffset(0)]
439 public UInt32 _PhysicalAddress;
440 [FieldOffset(0)]
441 public UInt32 _VirtualSize;
442
443 public string PhysicalAddress { get { return string.Format("0x{0:x8}", _PhysicalAddress); } }
444 public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } }
445
446 }
447
448 #endregion
449
450 #region Fields
451
452 private readonly IMAGE_DOS_HEADER _dosHeader;
453 private IMAGE_NT_HEADERS _ntHeaders;
454 private readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
455 #endregion
456
457 #region logging implementation
458 private static class log
459 {
460 public static class verbose
461 {
462 public static class debug
463 {
464 public static void writeline(string format, params object[] args)
465 {
466 #if ENABLE_LOGGING
467 logger.VerboseDebug.WriteLine(format, args);
468 #endif
469 }
470 public static void write(string format, params object[] args)
471 {
472 #if ENABLE_LOGGING
473 logger.VerboseDebug.Write(format, args);
474 #endif
475 }
476 }
477 public static class error
478 {
479 public static void writeline(string format, params object[] args)
480 {
481 #if ENABLE_LOGGING
482 logger.VerboseError.WriteLine(format, args);
483 #endif
484 }
485 public static void write(string format, params object[] args)
486 {
487 #if ENABLE_LOGGING
488 logger.VerboseError.Write(format, args);
489 #endif
490 }
491 }
492 }
493 }
494 #endregion
495
496
497 public PEData GetPEData
498 {
499 get
500 {
501 PEData _data = new PEData(_dosHeader, _ntHeaders, _sectionHeaders.ToArray());
502 return _data;
503 }
504 }
505 #region PEData
506 public class PEData
507 {
508 public PEData() : this(new IMAGE_DOS_HEADER(), new IMAGE_NT_HEADERS(), new IMAGE_SECTION_HEADER[] { }) { }
509 public PEData(IMAGE_DOS_HEADER DosHeader, IMAGE_NT_HEADERS NTHeader, IMAGE_SECTION_HEADER[] SectionHeaders)
510 {
511 this.DosHeader = DosHeader;
512 this.NTHeader = NTHeader;
513 this.SectionHeaders = SectionHeaders;
514 }
515 public IMAGE_DOS_HEADER DosHeader { get; private set; }
516 public IMAGE_NT_HEADERS NTHeader { get; private set; }
517 public IMAGE_SECTION_HEADER[] SectionHeaders { get; private set; }
518
519 public bool Is32bitAssembly()
520 {
521 return ((NTHeader.FileHeader._Characteristics & 0x0100) == 0x0100);
522 }
523 }
524
525 #endregion
526
527 public PEReader(FileInfo fi) : this(fi.FullName) { }
528 public PEReader(string filename)
529 {
530 Exception ErrorInfo = null;
531 using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
532 {
533 try
534 {
535 log.verbose.debug.writeline("Reading PE Format from: {0}", filename);
536 BinaryReader reader = new BinaryReader(fs);
537 // Reset reader position, just in case
538 reader.BaseStream.Seek(0, SeekOrigin.Begin);
539
540 // Read MS-DOS header section
541 _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
542 // MS-DOS magic number should read 'MZ'
543 if (_dosHeader._e_magic != 0x5a4d)
544 {
545 throw new InvalidOperationException("File is not a portable executable.");
546 }
547
548 // Skip MS-DOS stub and seek reader to NT Headers
549 reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
550
551 // Read NT Headers
552 _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
553
554 // Make sure we have 'PE' in the pe signature
555 if (_ntHeaders._Signature != 0x4550)
556 {
557 throw new InvalidOperationException("Invalid portable executable signature in NT header.");
558 }
559
560 _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);
561 // Read optional headers
562 if (Is32bitAssembly())
563 {
564 log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
565 Load32bitOptionalHeaders(reader);
566 }
567 else
568 {
569 log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
570 Load64bitOptionalHeaders(reader);
571 }
572
573 // Read section data
574 log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
575 List<int> section_header_indexes_to_remove = new List<int>();
576 for (int i = 0; i < _sectionHeaders.Count; i++)
577 {
578 if (_sectionHeaders[i]._VirtualAddress == 0)
579 section_header_indexes_to_remove.Add(i);
580 }
581 foreach (int i in section_header_indexes_to_remove)
582 {
583 _sectionHeaders.RemoveAt(i);
584 }
585 foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
586 {
587 int section_index = _sectionHeaders.IndexOf(header) + 1;
588 log.verbose.debug.writeline("\tSection Header: {0} of {1}", section_index, _sectionHeaders.Count);
589 log.verbose.debug.writeline("\t\tName: {0}", header.Name);
590 log.verbose.debug.writeline("\t\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
591 log.verbose.debug.writeline("\t\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
592 log.verbose.debug.writeline("\t\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
593 log.verbose.debug.writeline("\t\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
594 log.verbose.debug.writeline("\t\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
595
596 // Skip to beginning of a section
597 reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
598
599 // Read section data... and do something with it
600 byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
601 }
602 reader.Close();
603 }
604 catch (Exception ex)
605 {
606 ErrorInfo = ex;
607 throw ErrorInfo;
608 }
609 }
610 if (ErrorInfo != null)
611 {
612 log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
613 log.verbose.error.writeline(ErrorInfo.ToString());
614 }
615 }
616
617 public IMAGE_DOS_HEADER GetDOSHeader()
618 {
619 return _dosHeader;
620 }
621
622 public UInt32 GetPESignature()
623 {
624 return _ntHeaders._Signature;
625 }
626
627 public IMAGE_FILE_HEADER GetFileHeader()
628 {
629 return _ntHeaders.FileHeader;
630 }
631
632 public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
633 {
634 return _ntHeaders.OptionalHeader32;
635 }
636
637 public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
638 {
639 return _ntHeaders.OptionalHeader64;
640 }
641
642 public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
643 {
644 return _sectionHeaders;
645 }
646
647 public bool Is32bitAssembly()
648 {
649 return ((_ntHeaders.FileHeader._Characteristics & 0x0100) == 0x0100);
650 }
651
652 private void Load64bitOptionalHeaders(BinaryReader reader)
653 {
654 _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
655
656 // Should have 10 data directories
657 if (_ntHeaders.OptionalHeader64._NumberOfRvaAndSizes != 0x10)
658 {
659 throw new InvalidOperationException("Invalid number of data directories in NT header");
660 }
661
662 List<IMAGE_DATA_DIRECTORY> idds = new List<IMAGE_DATA_DIRECTORY>();
663 // Scan data directories and load section headers
664 for (int i = 0; i < _ntHeaders.OptionalHeader64._NumberOfRvaAndSizes; i++)
665 {
666 IMAGE_DATA_DIRECTORY idd = _ntHeaders.OptionalHeader64._DataDirectory[i];
667 uint size = idd._Size;
668 uint va = idd._VirtualAddress;
669
670 if (size != 0 && va != 0) { idds.Add(idd); }
671 }
672 foreach (IMAGE_DATA_DIRECTORY idd in idds)
673 {
674 if (idd._Size != 0 && idd._VirtualAddress != 0)
675 _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
676 }
677 }
678
679 private void Load32bitOptionalHeaders(BinaryReader reader)
680 {
681 _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
682
683 // Should have 10 data directories
684 if (_ntHeaders.OptionalHeader32._NumberOfRvaAndSizes != 0x10)
685 {
686 throw new InvalidOperationException("Invalid number of data directories in NT header");
687 }
688 List<IMAGE_DATA_DIRECTORY> idds = new List<IMAGE_DATA_DIRECTORY>();
689 // Scan data directories and load section headers
690 for (int i = 0; i < _ntHeaders.OptionalHeader32._NumberOfRvaAndSizes; i++)
691 {
692 IMAGE_DATA_DIRECTORY idd = _ntHeaders.OptionalHeader32._DataDirectory[i];
693 uint size = idd._Size;
694 uint va = idd._VirtualAddress;
695
696 if (size != 0 && va != 0) { idds.Add(idd); }
697 }
698 foreach (IMAGE_DATA_DIRECTORY idd in idds)
699 {
700 if(idd._Size != 0 && idd._VirtualAddress != 0)
701 _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
702 }
703 }
704
705 private static T MarshalBytesTo<T>(BinaryReader reader)
706 {
707 // Unmanaged data
708 byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
709
710 // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
711 GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
712
713 // Use our previously created pointer to unmanaged data and marshal to the specified type
714 T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
715
716 // Deallocate pointer
717 handle.Free();
718
719 return theStructure;
720 }
721 }
722 }

  ViewVC Help
Powered by ViewVC 1.1.22