/[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 323 - (hide annotations) (download)
Thu Jun 7 16:33:41 2012 UTC (8 years, 11 months ago) by william
File size: 32552 byte(s)
+ add event for being able to subscribe to PEReader updates

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 323 using RomCheater.PluginFramework.Events;
12     using Sojaner.MemoryScanner;
13 william 159
14 william 323 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 william 159 namespace Sojaner.MemoryScanner
40     {
41     public class PEReader
42     {
43 william 294 // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
44     #region Structs
45 william 319
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 william 320 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 william 319
84 william 320 }
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 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
102 william 294 [StructLayout(LayoutKind.Sequential)]
103     public struct IMAGE_DOS_HEADER
104 william 290 {
105 william 318 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 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
120 william 318 public UInt16[] _e_res1;
121     public UInt16 _e_oemid;
122     public UInt16 _e_oeminfo;
123 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
124 william 318 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 william 319 public override string ToString()
148     {
149     return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic));
150     }
151 william 290 }
152 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
153 william 294 [StructLayout(LayoutKind.Sequential)]
154     public struct IMAGE_NT_HEADERS
155 william 159 {
156 william 319 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 william 159 }
171 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
172 william 159 [StructLayout(LayoutKind.Sequential)]
173     public struct IMAGE_FILE_HEADER
174     {
175 william 319 public UInt16 _MachineType;
176     public UInt16 _NumberOfSections;
177 william 322 public Int32 _TimeDateStamp;
178 william 319 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 william 322 private DateTime GetDateTimeFromDosDateTime(Int32 i32TimeDate)
197 william 319 {
198 william 322 Int16 i16Time = (Int16)(i32TimeDate & 0xFFFF);
199     Int16 i16Date = (Int16)((i32TimeDate & 0xFFFF0000) >> 16);
200 william 319 return GetDateTimeFromDosDateTime(i16Time, i16Date);
201     }
202 william 322 private DateTime GetDateTimeFromDosDateTime(Int16 i16Time, Int16 i16Date)
203 william 319 {
204 william 322 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 william 319 }
225    
226 william 159 }
227 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
228 william 159 [StructLayout(LayoutKind.Sequential)]
229 william 294 public struct IMAGE_OPTIONAL_HEADER32
230 william 159 {
231 william 320 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 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
262 william 320 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 william 159 }
307 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
308 william 294 [StructLayout(LayoutKind.Sequential)]
309     public struct IMAGE_OPTIONAL_HEADER64
310 william 159 {
311 william 320 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 william 294 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
341 william 320 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 william 159 }
387 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
388 william 294 [StructLayout(LayoutKind.Sequential)]
389     public struct IMAGE_DATA_DIRECTORY
390 william 159 {
391 william 320 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 william 159 }
397 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
398 william 294 [StructLayout(LayoutKind.Sequential)]
399     public struct IMAGE_SECTION_HEADER
400 william 159 {
401 william 294 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
402 william 319 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 william 159 }
428 william 318 [TypeConverter(typeof(ExpandableObjectConverter))]
429 william 159 [StructLayout(LayoutKind.Explicit)]
430 william 294 public struct Misc
431 william 159 {
432     [FieldOffset(0)]
433 william 319 public UInt32 _PhysicalAddress;
434 william 294 [FieldOffset(0)]
435 william 319 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 william 294 }
441 william 159
442 william 294 #endregion
443 william 159
444 william 294 #region Fields
445 william 159
446 william 294 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 william 159
451 william 299 #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 william 323 public PEData GetPEData
492 william 318 {
493     get
494     {
495 william 319 PEData _data = new PEData(_dosHeader, _ntHeaders, _sectionHeaders.ToArray());
496 william 318 return _data;
497     }
498     }
499 william 323 #region PEData
500 william 318 public class PEData
501     {
502 william 319 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 william 318 {
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 william 319 public IMAGE_SECTION_HEADER[] SectionHeaders { get; private set; }
512 william 318 }
513    
514     #endregion
515    
516 william 294 public PEReader(FileInfo fi) : this(fi.FullName) { }
517     public PEReader(string filename)
518 william 299 {
519 william 294 Exception ErrorInfo = null;
520     using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
521     {
522     try
523     {
524 william 299 log.verbose.debug.writeline("Reading PE Format from: {0}", filename);
525 william 294 BinaryReader reader = new BinaryReader(fs);
526     // Reset reader position, just in case
527     reader.BaseStream.Seek(0, SeekOrigin.Begin);
528 william 159
529 william 294 // Read MS-DOS header section
530     _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
531     // MS-DOS magic number should read 'MZ'
532 william 318 if (_dosHeader._e_magic != 0x5a4d)
533 william 294 {
534     throw new InvalidOperationException("File is not a portable executable.");
535     }
536 william 159
537 william 294 // Skip MS-DOS stub and seek reader to NT Headers
538 william 318 reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
539 william 159
540 william 294 // Read NT Headers
541 william 319 _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
542 william 159
543 william 294 // Make sure we have 'PE' in the pe signature
544 william 319 if (_ntHeaders._Signature != 0x4550)
545 william 294 {
546     throw new InvalidOperationException("Invalid portable executable signature in NT header.");
547     }
548 william 159
549 william 319 _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);
550 william 294 // Read optional headers
551     if (Is32bitAssembly())
552     {
553 william 299 log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
554 william 294 Load32bitOptionalHeaders(reader);
555     }
556     else
557     {
558 william 299 log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
559 william 294 Load64bitOptionalHeaders(reader);
560     }
561 william 159
562 william 294 // Read section data
563 william 299 log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
564 william 294 foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
565     {
566     int section_index = _sectionHeaders.IndexOf(header) + 1;
567 william 299 log.verbose.debug.writeline("\tSection Header: {0} of {1}", section_index, _sectionHeaders.Count);
568     log.verbose.debug.writeline("\t\tName: {0}", header.Name);
569     log.verbose.debug.writeline("\t\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
570     log.verbose.debug.writeline("\t\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
571     log.verbose.debug.writeline("\t\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
572     log.verbose.debug.writeline("\t\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
573     log.verbose.debug.writeline("\t\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
574 william 159
575 william 294 // Skip to beginning of a section
576 william 319 reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
577 william 159
578 william 294 // Read section data... and do something with it
579 william 319 byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
580 william 294 }
581     reader.Close();
582     }
583     catch (Exception ex)
584     {
585     ErrorInfo = ex;
586     throw ErrorInfo;
587     }
588     }
589     if (ErrorInfo != null)
590     {
591 william 299 log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
592     log.verbose.error.writeline(ErrorInfo.ToString());
593 william 294 }
594     }
595 william 159
596 william 294 public IMAGE_DOS_HEADER GetDOSHeader()
597     {
598     return _dosHeader;
599     }
600 william 159
601 william 294 public UInt32 GetPESignature()
602     {
603 william 319 return _ntHeaders._Signature;
604 william 294 }
605 william 159
606 william 294 public IMAGE_FILE_HEADER GetFileHeader()
607     {
608     return _ntHeaders.FileHeader;
609     }
610 william 159
611 william 294 public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
612     {
613     return _ntHeaders.OptionalHeader32;
614     }
615 william 159
616 william 294 public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
617     {
618     return _ntHeaders.OptionalHeader64;
619     }
620 william 159
621 william 294 public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
622     {
623     return _sectionHeaders;
624     }
625 william 159
626 william 294 public bool Is32bitAssembly()
627 william 159 {
628 william 319 return ((_ntHeaders.FileHeader._Characteristics & 0x0100) == 0x0100);
629 william 159 }
630 william 294
631     private void Load64bitOptionalHeaders(BinaryReader reader)
632 william 293 {
633 william 319 _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
634 william 293
635 william 294 // Should have 10 data directories
636 william 320 if (_ntHeaders.OptionalHeader64._NumberOfRvaAndSizes != 0x10)
637 william 294 {
638     throw new InvalidOperationException("Invalid number of data directories in NT header");
639     }
640 william 293
641 william 294 // Scan data directories and load section headers
642 william 320 for (int i = 0; i < _ntHeaders.OptionalHeader64._NumberOfRvaAndSizes; i++)
643 william 294 {
644 william 320 if (_ntHeaders._OptionalHeader64._DataDirectory[i]._Size > 0)
645 william 294 {
646     _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
647     }
648     }
649     }
650 william 293
651 william 294 private void Load32bitOptionalHeaders(BinaryReader reader)
652     {
653 william 319 _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
654 william 293
655 william 294 // Should have 10 data directories
656 william 320 if (_ntHeaders.OptionalHeader32._NumberOfRvaAndSizes != 0x10)
657 william 294 {
658     throw new InvalidOperationException("Invalid number of data directories in NT header");
659     }
660 william 293
661 william 294 // Scan data directories and load section headers
662 william 320 for (int i = 0; i < _ntHeaders.OptionalHeader32._NumberOfRvaAndSizes; i++)
663 william 294 {
664 william 320 if (_ntHeaders._OptionalHeader32._DataDirectory[i]._Size > 0)
665 william 294 {
666     _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
667     }
668     }
669     }
670 william 293
671 william 294 private static T MarshalBytesTo<T>(BinaryReader reader)
672     {
673     // Unmanaged data
674     byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
675 william 293
676 william 294 // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
677     GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
678 william 293
679 william 294 // Use our previously created pointer to unmanaged data and marshal to the specified type
680     T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
681 william 293
682 william 294 // Deallocate pointer
683     handle.Free();
684 william 293
685 william 294 return theStructure;
686 william 293 }
687 william 159 }
688     }

  ViewVC Help
Powered by ViewVC 1.1.22