/[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 322 - (show annotations) (download)
Tue Jun 5 23:20:12 2012 UTC (8 years, 11 months ago) by william
File size: 31460 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
12 namespace Sojaner.MemoryScanner
13 {
14 public class PEReader
15 {
16 // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
17 #region Structs
18
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 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
57 }
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 [TypeConverter(typeof(ExpandableObjectConverter))]
75 [StructLayout(LayoutKind.Sequential)]
76 public struct IMAGE_DOS_HEADER
77 {
78 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 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
93 public UInt16[] _e_res1;
94 public UInt16 _e_oemid;
95 public UInt16 _e_oeminfo;
96 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
97 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 public override string ToString()
121 {
122 return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic));
123 }
124 }
125 [TypeConverter(typeof(ExpandableObjectConverter))]
126 [StructLayout(LayoutKind.Sequential)]
127 public struct IMAGE_NT_HEADERS
128 {
129 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 }
144 [TypeConverter(typeof(ExpandableObjectConverter))]
145 [StructLayout(LayoutKind.Sequential)]
146 public struct IMAGE_FILE_HEADER
147 {
148 public UInt16 _MachineType;
149 public UInt16 _NumberOfSections;
150 public Int32 _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(Int32 i32TimeDate)
170 {
171 Int16 i16Time = (Int16)(i32TimeDate & 0xFFFF);
172 Int16 i16Date = (Int16)((i32TimeDate & 0xFFFF0000) >> 16);
173 return GetDateTimeFromDosDateTime(i16Time, i16Date);
174 }
175 private DateTime GetDateTimeFromDosDateTime(Int16 i16Time, Int16 i16Date)
176 {
177 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 }
198
199 }
200 [TypeConverter(typeof(ExpandableObjectConverter))]
201 [StructLayout(LayoutKind.Sequential)]
202 public struct IMAGE_OPTIONAL_HEADER32
203 {
204 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 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
235 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 }
280 [TypeConverter(typeof(ExpandableObjectConverter))]
281 [StructLayout(LayoutKind.Sequential)]
282 public struct IMAGE_OPTIONAL_HEADER64
283 {
284 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 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
314 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 }
360 [TypeConverter(typeof(ExpandableObjectConverter))]
361 [StructLayout(LayoutKind.Sequential)]
362 public struct IMAGE_DATA_DIRECTORY
363 {
364 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 }
370 [TypeConverter(typeof(ExpandableObjectConverter))]
371 [StructLayout(LayoutKind.Sequential)]
372 public struct IMAGE_SECTION_HEADER
373 {
374 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
375 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 }
401 [TypeConverter(typeof(ExpandableObjectConverter))]
402 [StructLayout(LayoutKind.Explicit)]
403 public struct Misc
404 {
405 [FieldOffset(0)]
406 public UInt32 _PhysicalAddress;
407 [FieldOffset(0)]
408 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 }
414
415 #endregion
416
417 #region Fields
418
419 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
424 #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 public PEData GetData
465 {
466 get
467 {
468 PEData _data = new PEData(_dosHeader, _ntHeaders, _sectionHeaders.ToArray());
469 return _data;
470 }
471 }
472 #region t
473 public class PEData
474 {
475 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 {
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 public IMAGE_SECTION_HEADER[] SectionHeaders { get; private set; }
485 }
486
487 #endregion
488
489 public PEReader(FileInfo fi) : this(fi.FullName) { }
490 public PEReader(string filename)
491 {
492 Exception ErrorInfo = null;
493 using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
494 {
495 try
496 {
497 log.verbose.debug.writeline("Reading PE Format from: {0}", filename);
498 BinaryReader reader = new BinaryReader(fs);
499 // Reset reader position, just in case
500 reader.BaseStream.Seek(0, SeekOrigin.Begin);
501
502 // Read MS-DOS header section
503 _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
504 // MS-DOS magic number should read 'MZ'
505 if (_dosHeader._e_magic != 0x5a4d)
506 {
507 throw new InvalidOperationException("File is not a portable executable.");
508 }
509
510 // Skip MS-DOS stub and seek reader to NT Headers
511 reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
512
513 // Read NT Headers
514 _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
515
516 // Make sure we have 'PE' in the pe signature
517 if (_ntHeaders._Signature != 0x4550)
518 {
519 throw new InvalidOperationException("Invalid portable executable signature in NT header.");
520 }
521
522 _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);
523 // Read optional headers
524 if (Is32bitAssembly())
525 {
526 log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
527 Load32bitOptionalHeaders(reader);
528 }
529 else
530 {
531 log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
532 Load64bitOptionalHeaders(reader);
533 }
534
535 // Read section data
536 log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
537 foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
538 {
539 int section_index = _sectionHeaders.IndexOf(header) + 1;
540 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
548 // Skip to beginning of a section
549 reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
550
551 // Read section data... and do something with it
552 byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
553 }
554 reader.Close();
555 }
556 catch (Exception ex)
557 {
558 ErrorInfo = ex;
559 throw ErrorInfo;
560 }
561 }
562 if (ErrorInfo != null)
563 {
564 log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
565 log.verbose.error.writeline(ErrorInfo.ToString());
566 }
567 }
568
569 public IMAGE_DOS_HEADER GetDOSHeader()
570 {
571 return _dosHeader;
572 }
573
574 public UInt32 GetPESignature()
575 {
576 return _ntHeaders._Signature;
577 }
578
579 public IMAGE_FILE_HEADER GetFileHeader()
580 {
581 return _ntHeaders.FileHeader;
582 }
583
584 public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
585 {
586 return _ntHeaders.OptionalHeader32;
587 }
588
589 public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
590 {
591 return _ntHeaders.OptionalHeader64;
592 }
593
594 public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
595 {
596 return _sectionHeaders;
597 }
598
599 public bool Is32bitAssembly()
600 {
601 return ((_ntHeaders.FileHeader._Characteristics & 0x0100) == 0x0100);
602 }
603
604 private void Load64bitOptionalHeaders(BinaryReader reader)
605 {
606 _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
607
608 // Should have 10 data directories
609 if (_ntHeaders.OptionalHeader64._NumberOfRvaAndSizes != 0x10)
610 {
611 throw new InvalidOperationException("Invalid number of data directories in NT header");
612 }
613
614 // Scan data directories and load section headers
615 for (int i = 0; i < _ntHeaders.OptionalHeader64._NumberOfRvaAndSizes; i++)
616 {
617 if (_ntHeaders._OptionalHeader64._DataDirectory[i]._Size > 0)
618 {
619 _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
620 }
621 }
622 }
623
624 private void Load32bitOptionalHeaders(BinaryReader reader)
625 {
626 _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
627
628 // Should have 10 data directories
629 if (_ntHeaders.OptionalHeader32._NumberOfRvaAndSizes != 0x10)
630 {
631 throw new InvalidOperationException("Invalid number of data directories in NT header");
632 }
633
634 // Scan data directories and load section headers
635 for (int i = 0; i < _ntHeaders.OptionalHeader32._NumberOfRvaAndSizes; i++)
636 {
637 if (_ntHeaders._OptionalHeader32._DataDirectory[i]._Size > 0)
638 {
639 _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
640 }
641 }
642 }
643
644 private static T MarshalBytesTo<T>(BinaryReader reader)
645 {
646 // Unmanaged data
647 byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
648
649 // 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
652 // 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
655 // Deallocate pointer
656 handle.Free();
657
658 return theStructure;
659 }
660 }
661 }

  ViewVC Help
Powered by ViewVC 1.1.22