/[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 379 - (hide annotations) (download)
Tue Jun 19 08:09:02 2012 UTC (9 years, 11 months ago) by william
File size: 43400 byte(s)
+ correctly read linker timedatestamp
// This field holds the number of seconds since December 31st, 1969, at 4:00 P.M.

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 347 using Sojaner.MemoryScanner.MemoryProviers;
14     using RomCheater.PluginFramework.Interfaces;
15 william 159
16 william 323 namespace RomCheater.PluginFramework.Events
17     {
18     public interface IAcceptPEData
19     {
20 william 357 void SetPEViewerData(IPEDData peData);
21 william 323 }
22     public interface IAcceptsPEData
23     {
24     event BaseEventHandler<PEViewerDataUpdatedEvent> OnPEDataUpdated;
25     }
26     public interface IPEViewerDataUpdatedEvent
27     {
28 william 357 IPEDData peData { get; }
29 william 323 }
30     public class PEViewerDataUpdatedEvent : BaseEventArgs, IPEViewerDataUpdatedEvent
31     {
32 william 357 public PEViewerDataUpdatedEvent() : this(PEData.Empty) { }
33     public PEViewerDataUpdatedEvent(object sender) : this(sender, PEData.Empty) { }
34     public PEViewerDataUpdatedEvent(IPEDData peData) : base() { this.peData = peData; }
35     public PEViewerDataUpdatedEvent(object sender, IPEDData peData) : base(sender) { this.peData = peData; }
36 william 323 #region IPEViewerDataUpdatedEvent members
37 william 357 public IPEDData peData { get; private set; }
38 william 323 #endregion
39     }
40     }
41 william 159 namespace Sojaner.MemoryScanner
42     {
43 william 357
44     #region Structs
45     #region helpers
46     [Flags]
47     public enum MachineTypeFlags
48 william 159 {
49 william 357 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     [Flags]
102     public enum FileCharacteristicType : ushort
103     {
104     RelocationInformationStrippedFromFile = 0x1,
105     Executable = 0x2,
106     LineNumbersStripped = 0x4,
107     SymbolTableStripped = 0x8,
108     AggresiveTrimWorkingSet = 0x10,
109     LargeAddressAware = 0x20,
110     Supports16Bit = 0x40,
111     ReservedBytesWo = 0x80,
112     Supports32Bit = 0x100,
113     DebugInfoStripped = 0x200,
114     RunFromSwapIfInRemovableMedia = 0x400,
115     RunFromSwapIfInNetworkMedia = 0x800,
116     IsSytemFile = 0x1000,
117     IsDLL = 0x2000,
118     IsOnlyForSingleCoreProcessor = 0x4000,
119     BytesOfWordReserved = 0x8000,
120     }
121     #region DataSectionFlags
122     [Flags]
123     public enum DataSectionFlags : uint
124     {
125     /// <summary>
126     /// Reserved for future use.
127     /// </summary>
128     TypeReg = 0x00000000,
129     /// <summary>
130     /// Reserved for future use.
131     /// </summary>
132     TypeDsect = 0x00000001,
133     /// <summary>
134     /// Reserved for future use.
135     /// </summary>
136     TypeNoLoad = 0x00000002,
137     /// <summary>
138     /// Reserved for future use.
139     /// </summary>
140     TypeGroup = 0x00000004,
141     /// <summary>
142     /// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
143     /// </summary>
144     TypeNoPadded = 0x00000008,
145     /// <summary>
146     /// Reserved for future use.
147     /// </summary>
148     TypeCopy = 0x00000010,
149     /// <summary>
150     /// The section contains executable code.
151     /// </summary>
152     ContentCode = 0x00000020,
153     /// <summary>
154     /// The section contains initialized data.
155     /// </summary>
156     ContentInitializedData = 0x00000040,
157     /// <summary>
158     /// The section contains uninitialized data.
159     /// </summary>
160     ContentUninitializedData = 0x00000080,
161     /// <summary>
162     /// Reserved for future use.
163     /// </summary>
164     LinkOther = 0x00000100,
165     /// <summary>
166     /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
167     /// </summary>
168     LinkInfo = 0x00000200,
169     /// <summary>
170     /// Reserved for future use.
171     /// </summary>
172     TypeOver = 0x00000400,
173     /// <summary>
174     /// The section will not become part of the image. This is valid only for object files.
175     /// </summary>
176     LinkRemove = 0x00000800,
177     /// <summary>
178     /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
179     /// </summary>
180     LinkComDat = 0x00001000,
181     /// <summary>
182     /// Reset speculative exceptions handling bits in the TLB entries for this section.
183     /// </summary>
184     NoDeferSpecExceptions = 0x00004000,
185     /// <summary>
186     /// The section contains data referenced through the global pointer (GP).
187     /// </summary>
188     RelativeGP = 0x00008000,
189     /// <summary>
190     /// Reserved for future use.
191     /// </summary>
192     MemPurgeable = 0x00020000,
193     /// <summary>
194     /// Reserved for future use.
195     /// </summary>
196     Memory16Bit = 0x00020000,
197     /// <summary>
198     /// Reserved for future use.
199     /// </summary>
200     MemoryLocked = 0x00040000,
201     /// <summary>
202     /// Reserved for future use.
203     /// </summary>
204     MemoryPreload = 0x00080000,
205     /// <summary>
206     /// Align data on a 1-byte boundary. Valid only for object files.
207     /// </summary>
208     Align1Bytes = 0x00100000,
209     /// <summary>
210     /// Align data on a 2-byte boundary. Valid only for object files.
211     /// </summary>
212     Align2Bytes = 0x00200000,
213     /// <summary>
214     /// Align data on a 4-byte boundary. Valid only for object files.
215     /// </summary>
216     Align4Bytes = 0x00300000,
217     /// <summary>
218     /// Align data on an 8-byte boundary. Valid only for object files.
219     /// </summary>
220     Align8Bytes = 0x00400000,
221     /// <summary>
222     /// Align data on a 16-byte boundary. Valid only for object files.
223     /// </summary>
224     Align16Bytes = 0x00500000,
225     /// <summary>
226     /// Align data on a 32-byte boundary. Valid only for object files.
227     /// </summary>
228     Align32Bytes = 0x00600000,
229     /// <summary>
230     /// Align data on a 64-byte boundary. Valid only for object files.
231     /// </summary>
232     Align64Bytes = 0x00700000,
233     /// <summary>
234     /// Align data on a 128-byte boundary. Valid only for object files.
235     /// </summary>
236     Align128Bytes = 0x00800000,
237     /// <summary>
238     /// Align data on a 256-byte boundary. Valid only for object files.
239     /// </summary>
240     Align256Bytes = 0x00900000,
241     /// <summary>
242     /// Align data on a 512-byte boundary. Valid only for object files.
243     /// </summary>
244     Align512Bytes = 0x00A00000,
245     /// <summary>
246     /// Align data on a 1024-byte boundary. Valid only for object files.
247     /// </summary>
248     Align1024Bytes = 0x00B00000,
249     /// <summary>
250     /// Align data on a 2048-byte boundary. Valid only for object files.
251     /// </summary>
252     Align2048Bytes = 0x00C00000,
253     /// <summary>
254     /// Align data on a 4096-byte boundary. Valid only for object files.
255     /// </summary>
256     Align4096Bytes = 0x00D00000,
257     /// <summary>
258     /// Align data on an 8192-byte boundary. Valid only for object files.
259     /// </summary>
260     Align8192Bytes = 0x00E00000,
261     /// <summary>
262     /// The section contains extended relocations.
263     /// </summary>
264     LinkExtendedRelocationOverflow = 0x01000000,
265     /// <summary>
266     /// The section can be discarded as needed.
267     /// </summary>
268     MemoryDiscardable = 0x02000000,
269     /// <summary>
270     /// The section cannot be cached.
271     /// </summary>
272     MemoryNotCached = 0x04000000,
273     /// <summary>
274     /// The section is not pageable.
275     /// </summary>
276     MemoryNotPaged = 0x08000000,
277     /// <summary>
278     /// The section can be shared in memory.
279     /// </summary>
280     MemoryShared = 0x10000000,
281     /// <summary>
282     /// The section can be executed as code.
283     /// </summary>
284     MemoryExecute = 0x20000000,
285     /// <summary>
286     /// The section can be read.
287     /// </summary>
288     MemoryRead = 0x40000000,
289     /// <summary>
290     /// The section can be written to.
291     /// </summary>
292     MemoryWrite = 0x80000000
293     }
294     #endregion
295     #endregion
296     [TypeConverter(typeof(ExpandableObjectConverter))]
297     [StructLayout(LayoutKind.Sequential)]
298     public struct IMAGE_DOS_HEADER
299     {
300     public UInt16 _e_magic;
301     public UInt16 _e_cblp;
302     public UInt16 _e_cp;
303     public UInt16 _e_crlc;
304     public UInt16 _e_cparhdr;
305     public UInt16 _e_minalloc;
306     public UInt16 _e_maxalloc;
307     public UInt16 _e_ss;
308     public UInt16 _e_sp;
309     public UInt16 _e_csum;
310     public UInt16 _e_ip;
311     public UInt16 _e_cs;
312     public UInt16 _e_lfarlc;
313     public UInt16 _e_ovno;
314     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
315     public UInt16[] _e_res1;
316     public UInt16 _e_oemid;
317     public UInt16 _e_oeminfo;
318     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
319     public UInt16[] _e_res2;
320     public UInt32 _e_lfanew;
321    
322     public string e_magic { get { return string.Format("0x{0:x4}", _e_magic); } }
323     public string e_cblp { get { return string.Format("0x{0:x4}", _e_cblp); } }
324     public string e_cp { get { return string.Format("0x{0:x4}", _e_cp); } }
325     public string e_crlc { get { return string.Format("0x{0:x4}", _e_crlc); } }
326     public string e_cparhdr { get { return string.Format("0x{0:x4}", _e_cparhdr); } }
327     public string e_minalloc { get { return string.Format("0x{0:x4}", _e_minalloc); } }
328     public string e_maxalloc { get { return string.Format("0x{0:x4}", _e_maxalloc); } }
329     public string e_ss { get { return string.Format("0x{0:x4}", _e_ss); } }
330     public string e_sp { get { return string.Format("0x{0:x4}", _e_sp); } }
331     public string e_csum { get { return string.Format("0x{0:x4}", _e_csum); } }
332     public string e_ip { get { return string.Format("0x{0:x4}", _e_ip); } }
333     public string e_cs { get { return string.Format("0x{0:x4}", _e_cs); } }
334     public string e_lfarlc { get { return string.Format("0x{0:x4}", _e_lfarlc); } }
335     public string e_ovno { get { return string.Format("0x{0:x4}", _e_ovno); } }
336     public ushort[] e_res1 { get { return _e_res1; } }
337     public string e_oemid { get { return string.Format("0x{0:x4}", _e_oemid); } }
338     public string e_oeminfo { get { return string.Format("0x{0:x4}", _e_oeminfo); } }
339     public ushort[] e_res2 { get { return _e_res2; } }
340     public string e_lfanew { get { return string.Format("0x{0:x8}", _e_lfanew); } }
341    
342     public override string ToString()
343 william 319 {
344 william 357 return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic));
345 william 319 }
346 william 357 }
347     [TypeConverter(typeof(ExpandableObjectConverter))]
348     [StructLayout(LayoutKind.Sequential)]
349     public struct IMAGE_NT_HEADERS
350     {
351     public UInt32 _Signature;
352     public IMAGE_FILE_HEADER _FileHeader;
353     public IMAGE_OPTIONAL_HEADER32 _OptionalHeader32;
354     public IMAGE_OPTIONAL_HEADER64 _OptionalHeader64;
355    
356     public string Signature { get { return string.Format("0x{0:x8}", _Signature); } }
357     public IMAGE_FILE_HEADER FileHeader { get { return _FileHeader; } }
358     public IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get { return _OptionalHeader32; } }
359     public IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get { return _OptionalHeader64; } }
360    
361     public override string ToString()
362 william 320 {
363 william 357 return Encoding.UTF8.GetString(BitConverter.GetBytes(_Signature));
364 william 320 }
365 william 357 }
366     [TypeConverter(typeof(ExpandableObjectConverter))]
367     [StructLayout(LayoutKind.Sequential)]
368     public struct IMAGE_FILE_HEADER
369     {
370     public UInt16 _MachineType;
371     public UInt16 _NumberOfSections;
372 william 379 public Int32 _LinkerTime; // The time that the linker (or compiler for an OBJ file) produced this file. This field holds the number of seconds since December 31st, 1969, at 4:00 P.M.
373 william 357 public UInt32 _PointerToSymbolTable;
374     public UInt32 _NumberOfSymbols;
375     public UInt16 _SizeOfOptionalHeader;
376     public FileCharacteristicType _Characteristics;
377 william 319
378 william 357
379     public string MachineType { get { return ((MachineTypeFlags)_MachineType).ToString(); } }
380     public string NumberOfSections { get { return string.Format("0x{0:x4}", _NumberOfSections); } }
381 william 379 public string LinkerTime { get { return string.Format("{0} (0x{1:x8})", GetDateTimeFromLinkerTime(_LinkerTime).ToString(), _LinkerTime); } }
382 william 357 public string PointerToSymbolTable { get { return string.Format("0x{0:x8}", _PointerToSymbolTable); } }
383     public string NumberOfSymbols { get { return string.Format("0x{0:x8}", _NumberOfSymbols); } }
384     public string SizeOfOptionalHeader { get { return string.Format("0x{0:x4}", _SizeOfOptionalHeader); } }
385     public FileCharacteristicType Characteristics { get { return _Characteristics; } }
386     public override string ToString()
387 william 320 {
388 william 357 return MachineType;
389 william 320 }
390 william 357
391 william 379 private DateTime GetDateTimeFromLinkerTime(Int32 linker_timer)
392 william 347 {
393 william 379 // http://msdn.microsoft.com/en-us/library/ms809762.aspx
394     // This field holds the number of seconds since December 31st, 1969, at 4:00 P.M.
395     DateTime t = new DateTime(1969, 12, 31, 16, 0, 0);
396     t = t.AddSeconds(linker_timer);
397     return t;
398 william 343 }
399 william 319
400 william 357 }
401     [TypeConverter(typeof(ExpandableObjectConverter))]
402     [StructLayout(LayoutKind.Sequential)]
403     public struct IMAGE_OPTIONAL_HEADER32
404     {
405     public UInt16 _Magic;
406     public Byte _MajorLinkerVersion;
407     public Byte _MinorLinkerVersion;
408     public UInt32 _SizeOfCode;
409     public UInt32 _SizeOfInitializedData;
410     public UInt32 _SizeOfUninitializedData;
411     public UInt32 _AddressOfEntryPoint;
412     public UInt32 _BaseOfCode;
413     public UInt32 _BaseOfData; // 32-but specific
414     public UInt32 _ImageBase;
415     public UInt32 _SectionAlignment;
416     public UInt32 _FileAlignment;
417     public UInt16 _MajorOperatingSystemVersion;
418     public UInt16 _MinorOperatingSystemVersion;
419     public UInt16 _MajorImageVersion;
420     public UInt16 _MinorImageVersion;
421     public UInt16 _MajorSubsystemVersion;
422     public UInt16 _MinorSubsystemVersion;
423     public UInt32 _Win32VersionValue;
424     public UInt32 _SizeOfImage;
425     public UInt32 _SizeOfHeaders;
426     public UInt32 _CheckSum;
427     public UInt16 _Subsystem;
428     public UInt16 _DllCharacteristics;
429     public UInt32 _SizeOfStackReserve;
430     public UInt32 _SizeOfStackCommit;
431     public UInt32 _SizeOfHeapReserve;
432     public UInt32 _SizeOfHeapCommit;
433     public UInt32 _LoaderFlags;
434     public UInt32 _NumberOfRvaAndSizes;
435     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
436     public IMAGE_DATA_DIRECTORY[] _DataDirectory;
437 william 319
438    
439 william 357 public string Magic { get { return ((MagicType)_Magic).ToString(); } }
440     public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
441     public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
442 william 319
443 william 357 public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } }
444     public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } }
445     public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } }
446     public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } }
447     public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } }
448     public string BaseOfData { get { return string.Format("0x{0:x8}", _BaseOfData); } }
449     public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } }
450 william 320
451 william 357 public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } }
452     public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } }
453 william 320
454 william 357 public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } }
455     public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } }
456     public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } }
457     public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } }
458     public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } }
459     public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } }
460 william 320
461 william 357 public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } }
462     public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } }
463     public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } }
464     public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } }
465 william 320
466 william 357 public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } }
467     public string DllCharacteristics { get { return string.Format("0x{0:x4}", _DllCharacteristics); } }
468 william 320
469 william 357 public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } }
470     public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } }
471     public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } }
472     public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } }
473 william 320
474 william 357 public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } }
475     public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } }
476     public override string ToString()
477     {
478     return Magic;
479     }
480     }
481     [TypeConverter(typeof(ExpandableObjectConverter))]
482     [StructLayout(LayoutKind.Sequential)]
483     public struct IMAGE_OPTIONAL_HEADER64
484     {
485     public UInt16 _Magic;
486     public Byte _MajorLinkerVersion;
487     public Byte _MinorLinkerVersion;
488     public UInt32 _SizeOfCode;
489     public UInt32 _SizeOfInitializedData;
490     public UInt32 _SizeOfUninitializedData;
491     public UInt32 _AddressOfEntryPoint;
492     public UInt32 _BaseOfCode;
493     public UInt64 _ImageBase;
494     public UInt32 _SectionAlignment;
495     public UInt32 _FileAlignment;
496     public UInt16 _MajorOperatingSystemVersion;
497     public UInt16 _MinorOperatingSystemVersion;
498     public UInt16 _MajorImageVersion;
499     public UInt16 _MinorImageVersion;
500     public UInt16 _MajorSubsystemVersion;
501     public UInt16 _MinorSubsystemVersion;
502     public UInt32 _Win32VersionValue;
503     public UInt32 _SizeOfImage;
504     public UInt32 _SizeOfHeaders;
505     public UInt32 _CheckSum;
506     public UInt16 _Subsystem;
507     public UInt16 _DllCharacteristics;
508     public UInt64 _SizeOfStackReserve;
509     public UInt64 _SizeOfStackCommit;
510     public UInt64 _SizeOfHeapReserve;
511     public UInt64 _SizeOfHeapCommit;
512     public UInt32 _LoaderFlags;
513     public UInt32 _NumberOfRvaAndSizes;
514     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
515     public IMAGE_DATA_DIRECTORY[] _DataDirectory;
516 william 320
517    
518 william 357 public string Magic { get { return ((MagicType)_Magic).ToString(); } }
519     public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
520     public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
521 william 320
522 william 357 public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } }
523     public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } }
524     public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } }
525     public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } }
526     public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } }
527 william 320
528 william 357 public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } }
529 william 320
530 william 357 public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } }
531     public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } }
532 william 320
533 william 357 public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } }
534     public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } }
535     public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } }
536     public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } }
537     public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } }
538     public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } }
539 william 320
540 william 357 public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } }
541     public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } }
542     public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } }
543     public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } }
544 william 320
545 william 357 public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } }
546     public string DllCharacteristics { get { return string.Format("0x{0:x4}", _DllCharacteristics); } }
547 william 320
548 william 357 public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } }
549     public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } }
550     public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } }
551     public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } }
552 william 320
553 william 357 public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } }
554     public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } }
555 william 320
556 william 357 public override string ToString()
557     {
558     return Magic;
559     }
560     }
561     [TypeConverter(typeof(ExpandableObjectConverter))]
562     [StructLayout(LayoutKind.Sequential)]
563     public struct IMAGE_DATA_DIRECTORY
564     {
565     public UInt32 _VirtualAddress;
566     public UInt32 _Size;
567 william 320
568 william 357 public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
569     public string Size { get { return string.Format("0x{0:x8}", _Size); } }
570     }
571     [TypeConverter(typeof(ExpandableObjectConverter))]
572     [StructLayout(LayoutKind.Sequential)]
573     public struct IMAGE_SECTION_HEADER
574     {
575     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
576     public string _Name;
577     public Misc _Misc;
578     public UInt32 _VirtualAddress;
579     public UInt32 _SizeOfRawData;
580     public UInt32 _PointerToRawData;
581     public UInt32 _PointerToRelocations;
582     public UInt32 _PointerToLinenumbers;
583     public UInt16 _NumberOfRelocations;
584     public UInt16 _NumberOfLinenumbers;
585     public DataSectionFlags _Characteristics;
586 william 320
587 william 357 public string Name { get { return _Name; } }
588     public Misc Misc { get { return _Misc; } }
589     public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
590     public string SizeOfRawData { get { return string.Format("0x{0:x8}", _SizeOfRawData); } }
591     public string PointerToRawData { get { return string.Format("0x{0:x8}", _PointerToRawData); } }
592     public string PointerToRelocations { get { return string.Format("0x{0:x8}", _PointerToRelocations); } }
593     public string PointerToLinenumbers { get { return string.Format("0x{0:x8}", _PointerToLinenumbers); } }
594     public string NumberOfRelocations { get { return string.Format("0x{0:x4}", _NumberOfRelocations); } }
595     public string NumberOfLinenumbers { get { return string.Format("0x{0:x4}", _NumberOfLinenumbers); } }
596     public string Characteristics { get { return _Characteristics.ToString(); } }
597     public override string ToString()
598     {
599     return Name;
600     }
601     }
602     [TypeConverter(typeof(ExpandableObjectConverter))]
603     [StructLayout(LayoutKind.Explicit)]
604     public struct Misc
605     {
606     [FieldOffset(0)]
607     public UInt32 _PhysicalAddress;
608     [FieldOffset(0)]
609     public UInt32 _VirtualSize;
610 william 320
611 william 357 public string PhysicalAddress { get { return string.Format("0x{0:x8}", _PhysicalAddress); } }
612     public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } }
613    
614     }
615    
616     #endregion
617     #region SECTION_DATA_ARRAY
618     [TypeConverter(typeof(ExpandableObjectConverter))]
619     public class SECTION_DATA_ARRAY
620     {
621     public SECTION_DATA_ARRAY() { Name = ""; Data = new byte[] { }; _Address = 0; _PointerToData = 0; }
622 william 358 public SECTION_DATA_ARRAY(string name, uint address, int pointertodata, byte[] data)
623 william 357 {
624     Name = name;
625     _Address = address;
626     _PointerToData = pointertodata;
627     Data = data;
628 william 159 }
629 william 357
630     public string Name { get; private set; }
631 william 358 private uint _Address;
632 william 359 public string Address { get { return string.Format("0x{0:x8}", _Address); } }
633 william 377 public string AddressEnd { get { return string.Format("0x{0:x8}", _Address + Data.Count()); } }
634 william 357 private int _PointerToData;
635     public string PointerToData { get { return string.Format("0x{0:x8}", _PointerToData); } }
636     public byte[] Data { get; set; }
637 william 377 public string DataSize { get { return string.Format("0x{0:x8}",Data.Count()); } }
638 william 357 public override string ToString()
639 william 159 {
640 william 377 return string.Format("{0} ({1}) ({2}) {3}", Name, Address, AddressEnd, DataSize);
641 william 159 }
642 william 357 }
643     #endregion
644     #region IMAGE_SECTION_DATA
645     public class IMAGE_SECTION_DATA
646     {
647     private List<SECTION_DATA_ARRAY> sdas = new List<SECTION_DATA_ARRAY>();
648     public IMAGE_SECTION_DATA() { }
649 william 358 public void AddData(string SectionName, uint SectionAddress, int PointerToData, byte[] SectionData)
650 william 159 {
651 william 357 SECTION_DATA_ARRAY sda = new SECTION_DATA_ARRAY(SectionName, SectionAddress, PointerToData, SectionData);
652     sdas.Add(sda);
653     }
654     public SECTION_DATA_ARRAY[] SectionData
655     {
656     get
657 william 319 {
658 william 357 return sdas.ToArray();
659 william 319 }
660 william 159 }
661 william 357 }
662     #endregion
663 william 319
664    
665 william 357 #region PEData
666     public interface IPEDData
667     {
668     IMAGE_DOS_HEADER DosHeader { get; }
669     IMAGE_NT_HEADERS NTHeader { get; }
670     IMAGE_SECTION_HEADER[] SectionHeaders { get; }
671     SECTION_DATA_ARRAY[] SectionData { get; }
672     bool Is32bitAssembly();
673     }
674     public class PEDataWrapper
675     {
676     #region static members
677 william 358 public static IPEDData GetPEData(IAcceptsProcessAndConfig p) { return GetPEData((IAcceptsProcess)p); }
678 william 357 public static IPEDData GetPEData(IAcceptsProcess p) { return GetPEData(p.AcceptedProcess); }
679     public static IPEDData GetPEData(Process p)
680     {
681     if (p == null)
682     return PEData.Empty;
683     return new PEData(p);
684 william 294 }
685 william 357 public static IPEDData GetPEData()
686     {
687     return PEData.Empty;
688     }
689 william 294 #endregion
690 william 357 }
691     internal class PEData : IPEDData
692     {
693     //public PEData() : this(new IMAGE_DOS_HEADER(), new IMAGE_NT_HEADERS(), new IMAGE_SECTION_HEADER[] { }, new IMAGE_SECTION_DATA()) { }
694     //public PEData(IMAGE_DOS_HEADER DosHeader, IMAGE_NT_HEADERS NTHeader, IMAGE_SECTION_HEADER[] SectionHeaders, IMAGE_SECTION_DATA isd)
695     //{
696     // this.DosHeader = DosHeader;
697     // this.NTHeader = NTHeader;
698     // this.SectionHeaders = SectionHeaders;
699     // this.isd = isd;
700     //}
701     public static readonly IPEDData Empty = new PEData();
702     public PEData()
703 william 344 {
704 william 357 SourceProcess = null;
705     DosHeader = new IMAGE_DOS_HEADER();
706     NTHeader = new IMAGE_NT_HEADERS();
707     SectionHeaders = new IMAGE_SECTION_HEADER[] { };
708     isd = new IMAGE_SECTION_DATA();
709 william 344 }
710 william 357 public PEData(IAcceptsProcessAndConfig p) : this((IAcceptsProcess)p.AcceptedProcess) { }
711     public PEData(IAcceptsProcess p) : this(p.AcceptedProcess) { }
712     public PEData(Process p)
713 william 344 {
714 william 357 SourceProcess = p;
715     if (SourceProcess == null)
716     throw new NullReferenceException("Supplied process cannot be null");
717     PEReader reader = new PEReader(SourceProcess);
718     this.DosHeader = reader._dosHeader;
719     this.NTHeader = reader._ntHeaders;
720     this.SectionHeaders = reader._sectionHeaders.ToArray();
721     isd = reader._SectionData;
722 william 344 }
723 william 357 private Process SourceProcess { get; set; }
724     #region IPEDData members
725 william 358
726     private IMAGE_DOS_HEADER _DosHeader;
727     private IMAGE_NT_HEADERS _NTHeader;
728     private IMAGE_SECTION_HEADER[] _SectionHeaders;
729    
730     public IMAGE_DOS_HEADER DosHeader { get { return _DosHeader; } private set { _DosHeader = value; } }
731     public IMAGE_NT_HEADERS NTHeader { get { return _NTHeader; } private set { _NTHeader = value; } }
732     public IMAGE_SECTION_HEADER[] SectionHeaders { get { return _SectionHeaders; } private set { _SectionHeaders = value; } }
733 william 357 private IMAGE_SECTION_DATA isd;
734     public SECTION_DATA_ARRAY[] SectionData { get { return isd.SectionData; } }
735     public bool Is32bitAssembly()
736     {
737     return NTHeader.FileHeader._Characteristics.HasFlag(FileCharacteristicType.Supports32Bit);
738     }
739     #endregion
740     }
741     #endregion
742 william 344
743 william 357 internal class PEReader
744     {
745     // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
746    
747     #region Fields
748    
749     internal readonly IMAGE_DOS_HEADER _dosHeader;
750     internal IMAGE_NT_HEADERS _ntHeaders;
751     internal readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
752     internal readonly IMAGE_SECTION_DATA _SectionData = new IMAGE_SECTION_DATA();
753     #endregion
754 william 299 #region logging implementation
755     private static class log
756     {
757     public static class verbose
758     {
759     public static class debug
760     {
761     public static void writeline(string format, params object[] args)
762     {
763     #if ENABLE_LOGGING
764     logger.VerboseDebug.WriteLine(format, args);
765     #endif
766     }
767     public static void write(string format, params object[] args)
768     {
769     #if ENABLE_LOGGING
770     logger.VerboseDebug.Write(format, args);
771     #endif
772     }
773     }
774     public static class error
775     {
776     public static void writeline(string format, params object[] args)
777     {
778     #if ENABLE_LOGGING
779     logger.VerboseError.WriteLine(format, args);
780     #endif
781     }
782     public static void write(string format, params object[] args)
783     {
784     #if ENABLE_LOGGING
785     logger.VerboseError.Write(format, args);
786     #endif
787     }
788     }
789     }
790     }
791     #endregion
792    
793    
794 william 357 public PEReader(Process p)
795 william 318 {
796 william 357 string filename = p.MainModule.FileName;
797 william 294 Exception ErrorInfo = null;
798 william 345 _SectionData = new IMAGE_SECTION_DATA();
799 william 294 using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
800     {
801     try
802     {
803 william 299 log.verbose.debug.writeline("Reading PE Format from: {0}", filename);
804 william 294 BinaryReader reader = new BinaryReader(fs);
805     // Reset reader position, just in case
806     reader.BaseStream.Seek(0, SeekOrigin.Begin);
807 william 159
808 william 294 // Read MS-DOS header section
809     _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
810     // MS-DOS magic number should read 'MZ'
811 william 318 if (_dosHeader._e_magic != 0x5a4d)
812 william 294 {
813     throw new InvalidOperationException("File is not a portable executable.");
814     }
815 william 159
816 william 294 // Skip MS-DOS stub and seek reader to NT Headers
817 william 318 reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
818 william 159
819 william 347
820 william 294 // Read NT Headers
821 william 319 _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
822 william 159
823 william 294 // Make sure we have 'PE' in the pe signature
824 william 319 if (_ntHeaders._Signature != 0x4550)
825 william 294 {
826     throw new InvalidOperationException("Invalid portable executable signature in NT header.");
827     }
828 william 159
829 william 341 _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);
830 william 294 // Read optional headers
831     if (Is32bitAssembly())
832     {
833 william 299 log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
834 william 294 Load32bitOptionalHeaders(reader);
835     }
836     else
837     {
838 william 299 log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
839 william 294 Load64bitOptionalHeaders(reader);
840     }
841 william 159
842 william 294 // Read section data
843 william 299 log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
844 william 358 ulong image_base = 0;
845     ulong p_image_base = (ulong)p.MainModule.BaseAddress.ToInt64();
846 william 361 if (Is32bitAssembly())
847 william 358 {
848 william 361 image_base = (ulong)_ntHeaders.OptionalHeader32._ImageBase;
849     if (image_base != p_image_base)
850     {
851     image_base = p_image_base;
852     _ntHeaders._OptionalHeader32._ImageBase = (uint)image_base;
853     }
854 william 358 }
855 william 361 else
856     {
857     image_base = _ntHeaders.OptionalHeader64._ImageBase;
858     if (image_base != p_image_base)
859     {
860     image_base = p_image_base;
861     _ntHeaders._OptionalHeader64._ImageBase = (ulong)image_base;
862     }
863     }
864 william 294 foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
865     {
866     int section_index = _sectionHeaders.IndexOf(header) + 1;
867 william 299 log.verbose.debug.writeline("\tSection Header: {0} of {1}", section_index, _sectionHeaders.Count);
868     log.verbose.debug.writeline("\t\tName: {0}", header.Name);
869     log.verbose.debug.writeline("\t\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
870     log.verbose.debug.writeline("\t\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
871     log.verbose.debug.writeline("\t\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
872     log.verbose.debug.writeline("\t\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
873     log.verbose.debug.writeline("\t\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
874 william 159
875 william 358
876 william 347 // Skip to beginning of a section
877 william 357 reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
878 william 294 // Read section data... and do something with it
879 william 319 byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
880 william 358 _SectionData.AddData(header.Name, header._VirtualAddress + (uint)image_base, (int)header._PointerToRawData, sectiondata);
881 william 294 }
882     reader.Close();
883     }
884     catch (Exception ex)
885     {
886     ErrorInfo = ex;
887     throw ErrorInfo;
888     }
889     }
890     if (ErrorInfo != null)
891     {
892 william 299 log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
893     log.verbose.error.writeline(ErrorInfo.ToString());
894 william 294 }
895     }
896 william 159
897 william 294 public IMAGE_DOS_HEADER GetDOSHeader()
898     {
899     return _dosHeader;
900     }
901 william 159
902 william 294 public UInt32 GetPESignature()
903     {
904 william 319 return _ntHeaders._Signature;
905 william 294 }
906 william 159
907 william 294 public IMAGE_FILE_HEADER GetFileHeader()
908     {
909     return _ntHeaders.FileHeader;
910     }
911 william 159
912 william 294 public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
913     {
914     return _ntHeaders.OptionalHeader32;
915     }
916 william 159
917 william 294 public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
918     {
919     return _ntHeaders.OptionalHeader64;
920     }
921 william 159
922 william 294 public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
923     {
924     return _sectionHeaders;
925     }
926 william 159
927 william 294 public bool Is32bitAssembly()
928 william 159 {
929 william 347 return _ntHeaders.FileHeader._Characteristics.HasFlag(FileCharacteristicType.Supports32Bit);
930 william 159 }
931 william 294
932     private void Load64bitOptionalHeaders(BinaryReader reader)
933 william 293 {
934 william 319 _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
935 william 293
936 william 294 // Should have 10 data directories
937 william 320 if (_ntHeaders.OptionalHeader64._NumberOfRvaAndSizes != 0x10)
938 william 294 {
939     throw new InvalidOperationException("Invalid number of data directories in NT header");
940     }
941 william 293
942 william 294 // Scan data directories and load section headers
943 william 341 for (int i = 0; i < _ntHeaders.OptionalHeader64._NumberOfRvaAndSizes; i++)
944     {
945     if (_ntHeaders._OptionalHeader64._DataDirectory[i]._Size > 0)
946     {
947 william 342 IMAGE_SECTION_HEADER ish = MarshalBytesTo<IMAGE_SECTION_HEADER>(reader);
948     if (ish._SizeOfRawData != 0)
949     _sectionHeaders.Add(ish);
950 william 341 }
951     }
952 william 294 }
953 william 293
954 william 294 private void Load32bitOptionalHeaders(BinaryReader reader)
955     {
956 william 319 _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
957 william 293
958 william 294 // Should have 10 data directories
959 william 320 if (_ntHeaders.OptionalHeader32._NumberOfRvaAndSizes != 0x10)
960 william 294 {
961     throw new InvalidOperationException("Invalid number of data directories in NT header");
962     }
963 william 339
964 william 341 // Scan data directories and load section headers
965     for (int i = 0; i < _ntHeaders.OptionalHeader32._NumberOfRvaAndSizes; i++)
966     {
967     if (_ntHeaders._OptionalHeader32._DataDirectory[i]._Size > 0)
968     {
969 william 342 IMAGE_SECTION_HEADER ish = MarshalBytesTo<IMAGE_SECTION_HEADER>(reader);
970     if (ish._SizeOfRawData != 0)
971     _sectionHeaders.Add(ish);
972 william 341 }
973     }
974 william 294 }
975 william 293
976 william 294 private static T MarshalBytesTo<T>(BinaryReader reader)
977     {
978     // Unmanaged data
979     byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
980 william 293
981 william 294 // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
982     GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
983 william 293
984 william 294 // Use our previously created pointer to unmanaged data and marshal to the specified type
985     T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
986 william 293
987 william 294 // Deallocate pointer
988     handle.Free();
989 william 293
990 william 294 return theStructure;
991 william 293 }
992 william 159 }
993     }

  ViewVC Help
Powered by ViewVC 1.1.22