/[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 408 - (show annotations) (download)
Thu Jun 21 18:10:21 2012 UTC (8 years, 5 months ago) by william
File size: 42442 byte(s)

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

  ViewVC Help
Powered by ViewVC 1.1.22