/[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 377 - (show annotations) (download)
Sun Jun 10 07:55:18 2012 UTC (8 years, 5 months ago) by william
File size: 43989 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 namespace RomCheater.PluginFramework.Events
17 {
18 public interface IAcceptPEData
19 {
20 void SetPEViewerData(IPEDData peData);
21 }
22 public interface IAcceptsPEData
23 {
24 event BaseEventHandler<PEViewerDataUpdatedEvent> OnPEDataUpdated;
25 }
26 public interface IPEViewerDataUpdatedEvent
27 {
28 IPEDData peData { get; }
29 }
30 public class PEViewerDataUpdatedEvent : BaseEventArgs, IPEViewerDataUpdatedEvent
31 {
32 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 #region IPEViewerDataUpdatedEvent members
37 public IPEDData peData { get; private set; }
38 #endregion
39 }
40 }
41 namespace Sojaner.MemoryScanner
42 {
43
44 #region Structs
45 #region helpers
46 [Flags]
47 public enum MachineTypeFlags
48 {
49 x86 = 0x14C,
50 Alpha = 0x184,
51 ARM = 0x1C0,
52 MIPS16R3000 = 0x162,
53 MIPS16R4000 = 0x166,
54 MIPS16R10000 = 0x168,
55 PowerPCLE = 0x1F0,
56 PowerPCBE = 0x1F2,
57 Itanium = 0x200,
58 MIPS16 = 0x266,
59 Alpha64 = 0x284,
60 MIPSFPU = 0x366,
61 MIPSFPU16 = 0x466,
62 x64 = 0x8664,
63 }
64 public enum MagicType : ushort
65 {
66 NT_OPTIONAL_HEADER_NOT_PRESENT, // 0
67 NT_OPTIONAL_HEADER_32 = 0x10b,
68 NT_OPTIONAL_HEADER_64 = 0x20b
69 }
70 public enum SubSystemType : ushort
71 {
72 IMAGE_SUBSYSTEM_UNKNOWN = 0,
73 IMAGE_SUBSYSTEM_NATIVE = 1,
74 IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
75 IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
76 IMAGE_SUBSYSTEM_POSIX_CUI = 7,
77 IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
78 IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
79 IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
80 IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
81 IMAGE_SUBSYSTEM_EFI_ROM = 13,
82 IMAGE_SUBSYSTEM_XBOX = 14
83
84 }
85 public enum DllCharacteristicsType : ushort
86 {
87 RES_0 = 0x0001,
88 RES_1 = 0x0002,
89 RES_2 = 0x0004,
90 RES_3 = 0x0008,
91 IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
92 IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
93 IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
94 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
95 IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
96 IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
97 RES_4 = 0x1000,
98 IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
99 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
100 }
101 [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 {
344 return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic));
345 }
346 }
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 {
363 return Encoding.UTF8.GetString(BitConverter.GetBytes(_Signature));
364 }
365 }
366 [TypeConverter(typeof(ExpandableObjectConverter))]
367 [StructLayout(LayoutKind.Sequential)]
368 public struct IMAGE_FILE_HEADER
369 {
370 public UInt16 _MachineType;
371 public UInt16 _NumberOfSections;
372 public Int32 _TimeDateStamp;
373 public UInt32 _PointerToSymbolTable;
374 public UInt32 _NumberOfSymbols;
375 public UInt16 _SizeOfOptionalHeader;
376 public FileCharacteristicType _Characteristics;
377
378
379 public string MachineType { get { return ((MachineTypeFlags)_MachineType).ToString(); } }
380 public string NumberOfSections { get { return string.Format("0x{0:x4}", _NumberOfSections); } }
381 public string TimeDateStamp { get { return string.Format("{0} (0x{1:x8})", GetDateTimeFromDosDateTime(_TimeDateStamp).ToString(), _TimeDateStamp); } }
382 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 {
388 return MachineType;
389 }
390
391 private DateTime GetDateTimeFromDosDateTime(Int32 i32TimeDate)
392 {
393 Int16 i16Time = (Int16)(i32TimeDate & 0xFFFF);
394 Int16 i16Date = (Int16)((i32TimeDate & 0xFFFF0000) >> 16);
395 return GetDateTimeFromDosDateTime(i16Time, i16Date);
396 }
397 private DateTime GetDateTimeFromDosDateTime(Int16 i16Time, Int16 i16Date)
398 {
399 try
400 {
401 int iYear = 0;
402 int iMonth = 1;
403 int iDay = 1;
404 int iHour = 0;
405 int iMinute = 0;
406 int iSecond = 0;
407 iDay = (i16Date & 0x1F);
408 iMonth = ((i16Date & 0x01E0) >> 5);
409 iYear = 1980 + ((i16Date & 0xFE00) >> 9);
410 iSecond = (i16Time & 0x1F) * 2;
411 iMinute = ((i16Time & 0x07E0) >> 5);
412 iHour = ((i16Time & 0x0F800) >> 11);
413 return new DateTime(iYear, iMonth, iDay, iHour, iMinute, iSecond);
414 }
415 catch
416 {
417 return new DateTime();
418 }
419 }
420
421 }
422 [TypeConverter(typeof(ExpandableObjectConverter))]
423 [StructLayout(LayoutKind.Sequential)]
424 public struct IMAGE_OPTIONAL_HEADER32
425 {
426 public UInt16 _Magic;
427 public Byte _MajorLinkerVersion;
428 public Byte _MinorLinkerVersion;
429 public UInt32 _SizeOfCode;
430 public UInt32 _SizeOfInitializedData;
431 public UInt32 _SizeOfUninitializedData;
432 public UInt32 _AddressOfEntryPoint;
433 public UInt32 _BaseOfCode;
434 public UInt32 _BaseOfData; // 32-but specific
435 public UInt32 _ImageBase;
436 public UInt32 _SectionAlignment;
437 public UInt32 _FileAlignment;
438 public UInt16 _MajorOperatingSystemVersion;
439 public UInt16 _MinorOperatingSystemVersion;
440 public UInt16 _MajorImageVersion;
441 public UInt16 _MinorImageVersion;
442 public UInt16 _MajorSubsystemVersion;
443 public UInt16 _MinorSubsystemVersion;
444 public UInt32 _Win32VersionValue;
445 public UInt32 _SizeOfImage;
446 public UInt32 _SizeOfHeaders;
447 public UInt32 _CheckSum;
448 public UInt16 _Subsystem;
449 public UInt16 _DllCharacteristics;
450 public UInt32 _SizeOfStackReserve;
451 public UInt32 _SizeOfStackCommit;
452 public UInt32 _SizeOfHeapReserve;
453 public UInt32 _SizeOfHeapCommit;
454 public UInt32 _LoaderFlags;
455 public UInt32 _NumberOfRvaAndSizes;
456 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
457 public IMAGE_DATA_DIRECTORY[] _DataDirectory;
458
459
460 public string Magic { get { return ((MagicType)_Magic).ToString(); } }
461 public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
462 public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
463
464 public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } }
465 public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } }
466 public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } }
467 public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } }
468 public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } }
469 public string BaseOfData { get { return string.Format("0x{0:x8}", _BaseOfData); } }
470 public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } }
471
472 public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } }
473 public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } }
474
475 public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } }
476 public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } }
477 public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } }
478 public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } }
479 public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } }
480 public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } }
481
482 public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } }
483 public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } }
484 public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } }
485 public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } }
486
487 public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } }
488 public string DllCharacteristics { get { return string.Format("0x{0:x4}", _DllCharacteristics); } }
489
490 public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } }
491 public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } }
492 public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } }
493 public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } }
494
495 public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } }
496 public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } }
497 public override string ToString()
498 {
499 return Magic;
500 }
501 }
502 [TypeConverter(typeof(ExpandableObjectConverter))]
503 [StructLayout(LayoutKind.Sequential)]
504 public struct IMAGE_OPTIONAL_HEADER64
505 {
506 public UInt16 _Magic;
507 public Byte _MajorLinkerVersion;
508 public Byte _MinorLinkerVersion;
509 public UInt32 _SizeOfCode;
510 public UInt32 _SizeOfInitializedData;
511 public UInt32 _SizeOfUninitializedData;
512 public UInt32 _AddressOfEntryPoint;
513 public UInt32 _BaseOfCode;
514 public UInt64 _ImageBase;
515 public UInt32 _SectionAlignment;
516 public UInt32 _FileAlignment;
517 public UInt16 _MajorOperatingSystemVersion;
518 public UInt16 _MinorOperatingSystemVersion;
519 public UInt16 _MajorImageVersion;
520 public UInt16 _MinorImageVersion;
521 public UInt16 _MajorSubsystemVersion;
522 public UInt16 _MinorSubsystemVersion;
523 public UInt32 _Win32VersionValue;
524 public UInt32 _SizeOfImage;
525 public UInt32 _SizeOfHeaders;
526 public UInt32 _CheckSum;
527 public UInt16 _Subsystem;
528 public UInt16 _DllCharacteristics;
529 public UInt64 _SizeOfStackReserve;
530 public UInt64 _SizeOfStackCommit;
531 public UInt64 _SizeOfHeapReserve;
532 public UInt64 _SizeOfHeapCommit;
533 public UInt32 _LoaderFlags;
534 public UInt32 _NumberOfRvaAndSizes;
535 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
536 public IMAGE_DATA_DIRECTORY[] _DataDirectory;
537
538
539 public string Magic { get { return ((MagicType)_Magic).ToString(); } }
540 public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
541 public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } }
542
543 public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } }
544 public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } }
545 public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } }
546 public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } }
547 public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } }
548
549 public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } }
550
551 public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } }
552 public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } }
553
554 public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } }
555 public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } }
556 public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } }
557 public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } }
558 public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } }
559 public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } }
560
561 public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } }
562 public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } }
563 public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } }
564 public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } }
565
566 public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } }
567 public string DllCharacteristics { get { return string.Format("0x{0:x4}", _DllCharacteristics); } }
568
569 public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } }
570 public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } }
571 public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } }
572 public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } }
573
574 public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } }
575 public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } }
576
577 public override string ToString()
578 {
579 return Magic;
580 }
581 }
582 [TypeConverter(typeof(ExpandableObjectConverter))]
583 [StructLayout(LayoutKind.Sequential)]
584 public struct IMAGE_DATA_DIRECTORY
585 {
586 public UInt32 _VirtualAddress;
587 public UInt32 _Size;
588
589 public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
590 public string Size { get { return string.Format("0x{0:x8}", _Size); } }
591 }
592 [TypeConverter(typeof(ExpandableObjectConverter))]
593 [StructLayout(LayoutKind.Sequential)]
594 public struct IMAGE_SECTION_HEADER
595 {
596 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
597 public string _Name;
598 public Misc _Misc;
599 public UInt32 _VirtualAddress;
600 public UInt32 _SizeOfRawData;
601 public UInt32 _PointerToRawData;
602 public UInt32 _PointerToRelocations;
603 public UInt32 _PointerToLinenumbers;
604 public UInt16 _NumberOfRelocations;
605 public UInt16 _NumberOfLinenumbers;
606 public DataSectionFlags _Characteristics;
607
608 public string Name { get { return _Name; } }
609 public Misc Misc { get { return _Misc; } }
610 public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
611 public string SizeOfRawData { get { return string.Format("0x{0:x8}", _SizeOfRawData); } }
612 public string PointerToRawData { get { return string.Format("0x{0:x8}", _PointerToRawData); } }
613 public string PointerToRelocations { get { return string.Format("0x{0:x8}", _PointerToRelocations); } }
614 public string PointerToLinenumbers { get { return string.Format("0x{0:x8}", _PointerToLinenumbers); } }
615 public string NumberOfRelocations { get { return string.Format("0x{0:x4}", _NumberOfRelocations); } }
616 public string NumberOfLinenumbers { get { return string.Format("0x{0:x4}", _NumberOfLinenumbers); } }
617 public string Characteristics { get { return _Characteristics.ToString(); } }
618 public override string ToString()
619 {
620 return Name;
621 }
622 }
623 [TypeConverter(typeof(ExpandableObjectConverter))]
624 [StructLayout(LayoutKind.Explicit)]
625 public struct Misc
626 {
627 [FieldOffset(0)]
628 public UInt32 _PhysicalAddress;
629 [FieldOffset(0)]
630 public UInt32 _VirtualSize;
631
632 public string PhysicalAddress { get { return string.Format("0x{0:x8}", _PhysicalAddress); } }
633 public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } }
634
635 }
636
637 #endregion
638 #region SECTION_DATA_ARRAY
639 [TypeConverter(typeof(ExpandableObjectConverter))]
640 public class SECTION_DATA_ARRAY
641 {
642 public SECTION_DATA_ARRAY() { Name = ""; Data = new byte[] { }; _Address = 0; _PointerToData = 0; }
643 public SECTION_DATA_ARRAY(string name, uint address, int pointertodata, byte[] data)
644 {
645 Name = name;
646 _Address = address;
647 _PointerToData = pointertodata;
648 Data = data;
649 }
650
651 public string Name { get; private set; }
652 private uint _Address;
653 public string Address { get { return string.Format("0x{0:x8}", _Address); } }
654 public string AddressEnd { get { return string.Format("0x{0:x8}", _Address + Data.Count()); } }
655 private int _PointerToData;
656 public string PointerToData { get { return string.Format("0x{0:x8}", _PointerToData); } }
657 public byte[] Data { get; set; }
658 public string DataSize { get { return string.Format("0x{0:x8}",Data.Count()); } }
659 public override string ToString()
660 {
661 return string.Format("{0} ({1}) ({2}) {3}", Name, Address, AddressEnd, DataSize);
662 }
663 }
664 #endregion
665 #region IMAGE_SECTION_DATA
666 public class IMAGE_SECTION_DATA
667 {
668 private List<SECTION_DATA_ARRAY> sdas = new List<SECTION_DATA_ARRAY>();
669 public IMAGE_SECTION_DATA() { }
670 public void AddData(string SectionName, uint SectionAddress, int PointerToData, byte[] SectionData)
671 {
672 SECTION_DATA_ARRAY sda = new SECTION_DATA_ARRAY(SectionName, SectionAddress, PointerToData, SectionData);
673 sdas.Add(sda);
674 }
675 public SECTION_DATA_ARRAY[] SectionData
676 {
677 get
678 {
679 return sdas.ToArray();
680 }
681 }
682 }
683 #endregion
684
685
686 #region PEData
687 public interface IPEDData
688 {
689 IMAGE_DOS_HEADER DosHeader { get; }
690 IMAGE_NT_HEADERS NTHeader { get; }
691 IMAGE_SECTION_HEADER[] SectionHeaders { get; }
692 SECTION_DATA_ARRAY[] SectionData { get; }
693 bool Is32bitAssembly();
694 }
695 public class PEDataWrapper
696 {
697 #region static members
698 public static IPEDData GetPEData(IAcceptsProcessAndConfig p) { return GetPEData((IAcceptsProcess)p); }
699 public static IPEDData GetPEData(IAcceptsProcess p) { return GetPEData(p.AcceptedProcess); }
700 public static IPEDData GetPEData(Process p)
701 {
702 if (p == null)
703 return PEData.Empty;
704 return new PEData(p);
705 }
706 public static IPEDData GetPEData()
707 {
708 return PEData.Empty;
709 }
710 #endregion
711 }
712 internal class PEData : IPEDData
713 {
714 //public PEData() : this(new IMAGE_DOS_HEADER(), new IMAGE_NT_HEADERS(), new IMAGE_SECTION_HEADER[] { }, new IMAGE_SECTION_DATA()) { }
715 //public PEData(IMAGE_DOS_HEADER DosHeader, IMAGE_NT_HEADERS NTHeader, IMAGE_SECTION_HEADER[] SectionHeaders, IMAGE_SECTION_DATA isd)
716 //{
717 // this.DosHeader = DosHeader;
718 // this.NTHeader = NTHeader;
719 // this.SectionHeaders = SectionHeaders;
720 // this.isd = isd;
721 //}
722 public static readonly IPEDData Empty = new PEData();
723 public PEData()
724 {
725 SourceProcess = null;
726 DosHeader = new IMAGE_DOS_HEADER();
727 NTHeader = new IMAGE_NT_HEADERS();
728 SectionHeaders = new IMAGE_SECTION_HEADER[] { };
729 isd = new IMAGE_SECTION_DATA();
730 }
731 public PEData(IAcceptsProcessAndConfig p) : this((IAcceptsProcess)p.AcceptedProcess) { }
732 public PEData(IAcceptsProcess p) : this(p.AcceptedProcess) { }
733 public PEData(Process p)
734 {
735 SourceProcess = p;
736 if (SourceProcess == null)
737 throw new NullReferenceException("Supplied process cannot be null");
738 PEReader reader = new PEReader(SourceProcess);
739 this.DosHeader = reader._dosHeader;
740 this.NTHeader = reader._ntHeaders;
741 this.SectionHeaders = reader._sectionHeaders.ToArray();
742 isd = reader._SectionData;
743 }
744 private Process SourceProcess { get; set; }
745 #region IPEDData members
746
747 private IMAGE_DOS_HEADER _DosHeader;
748 private IMAGE_NT_HEADERS _NTHeader;
749 private IMAGE_SECTION_HEADER[] _SectionHeaders;
750
751 public IMAGE_DOS_HEADER DosHeader { get { return _DosHeader; } private set { _DosHeader = value; } }
752 public IMAGE_NT_HEADERS NTHeader { get { return _NTHeader; } private set { _NTHeader = value; } }
753 public IMAGE_SECTION_HEADER[] SectionHeaders { get { return _SectionHeaders; } private set { _SectionHeaders = value; } }
754 private IMAGE_SECTION_DATA isd;
755 public SECTION_DATA_ARRAY[] SectionData { get { return isd.SectionData; } }
756 public bool Is32bitAssembly()
757 {
758 return NTHeader.FileHeader._Characteristics.HasFlag(FileCharacteristicType.Supports32Bit);
759 }
760 #endregion
761 }
762 #endregion
763
764 internal class PEReader
765 {
766 // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
767
768 #region Fields
769
770 internal readonly IMAGE_DOS_HEADER _dosHeader;
771 internal IMAGE_NT_HEADERS _ntHeaders;
772 internal readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
773 internal readonly IMAGE_SECTION_DATA _SectionData = new IMAGE_SECTION_DATA();
774 #endregion
775 #region logging implementation
776 private static class log
777 {
778 public static class verbose
779 {
780 public static class debug
781 {
782 public static void writeline(string format, params object[] args)
783 {
784 #if ENABLE_LOGGING
785 logger.VerboseDebug.WriteLine(format, args);
786 #endif
787 }
788 public static void write(string format, params object[] args)
789 {
790 #if ENABLE_LOGGING
791 logger.VerboseDebug.Write(format, args);
792 #endif
793 }
794 }
795 public static class error
796 {
797 public static void writeline(string format, params object[] args)
798 {
799 #if ENABLE_LOGGING
800 logger.VerboseError.WriteLine(format, args);
801 #endif
802 }
803 public static void write(string format, params object[] args)
804 {
805 #if ENABLE_LOGGING
806 logger.VerboseError.Write(format, args);
807 #endif
808 }
809 }
810 }
811 }
812 #endregion
813
814
815 public PEReader(Process p)
816 {
817 string filename = p.MainModule.FileName;
818 Exception ErrorInfo = null;
819 _SectionData = new IMAGE_SECTION_DATA();
820 using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
821 {
822 try
823 {
824 log.verbose.debug.writeline("Reading PE Format from: {0}", filename);
825 BinaryReader reader = new BinaryReader(fs);
826 // Reset reader position, just in case
827 reader.BaseStream.Seek(0, SeekOrigin.Begin);
828
829 // Read MS-DOS header section
830 _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
831 // MS-DOS magic number should read 'MZ'
832 if (_dosHeader._e_magic != 0x5a4d)
833 {
834 throw new InvalidOperationException("File is not a portable executable.");
835 }
836
837 // Skip MS-DOS stub and seek reader to NT Headers
838 reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
839
840
841 // Read NT Headers
842 _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
843
844 // Make sure we have 'PE' in the pe signature
845 if (_ntHeaders._Signature != 0x4550)
846 {
847 throw new InvalidOperationException("Invalid portable executable signature in NT header.");
848 }
849
850 _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);
851 // Read optional headers
852 if (Is32bitAssembly())
853 {
854 log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
855 Load32bitOptionalHeaders(reader);
856 }
857 else
858 {
859 log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
860 Load64bitOptionalHeaders(reader);
861 }
862
863 // Read section data
864 log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
865 ulong image_base = 0;
866 ulong p_image_base = (ulong)p.MainModule.BaseAddress.ToInt64();
867 if (Is32bitAssembly())
868 {
869 image_base = (ulong)_ntHeaders.OptionalHeader32._ImageBase;
870 if (image_base != p_image_base)
871 {
872 image_base = p_image_base;
873 _ntHeaders._OptionalHeader32._ImageBase = (uint)image_base;
874 }
875 }
876 else
877 {
878 image_base = _ntHeaders.OptionalHeader64._ImageBase;
879 if (image_base != p_image_base)
880 {
881 image_base = p_image_base;
882 _ntHeaders._OptionalHeader64._ImageBase = (ulong)image_base;
883 }
884 }
885 foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
886 {
887 int section_index = _sectionHeaders.IndexOf(header) + 1;
888 log.verbose.debug.writeline("\tSection Header: {0} of {1}", section_index, _sectionHeaders.Count);
889 log.verbose.debug.writeline("\t\tName: {0}", header.Name);
890 log.verbose.debug.writeline("\t\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
891 log.verbose.debug.writeline("\t\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
892 log.verbose.debug.writeline("\t\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
893 log.verbose.debug.writeline("\t\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
894 log.verbose.debug.writeline("\t\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
895
896
897 // Skip to beginning of a section
898 reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
899 // Read section data... and do something with it
900 byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
901 _SectionData.AddData(header.Name, header._VirtualAddress + (uint)image_base, (int)header._PointerToRawData, sectiondata);
902 }
903 reader.Close();
904 }
905 catch (Exception ex)
906 {
907 ErrorInfo = ex;
908 throw ErrorInfo;
909 }
910 }
911 if (ErrorInfo != null)
912 {
913 log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
914 log.verbose.error.writeline(ErrorInfo.ToString());
915 }
916 }
917
918 public IMAGE_DOS_HEADER GetDOSHeader()
919 {
920 return _dosHeader;
921 }
922
923 public UInt32 GetPESignature()
924 {
925 return _ntHeaders._Signature;
926 }
927
928 public IMAGE_FILE_HEADER GetFileHeader()
929 {
930 return _ntHeaders.FileHeader;
931 }
932
933 public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
934 {
935 return _ntHeaders.OptionalHeader32;
936 }
937
938 public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
939 {
940 return _ntHeaders.OptionalHeader64;
941 }
942
943 public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
944 {
945 return _sectionHeaders;
946 }
947
948 public bool Is32bitAssembly()
949 {
950 return _ntHeaders.FileHeader._Characteristics.HasFlag(FileCharacteristicType.Supports32Bit);
951 }
952
953 private void Load64bitOptionalHeaders(BinaryReader reader)
954 {
955 _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
956
957 // Should have 10 data directories
958 if (_ntHeaders.OptionalHeader64._NumberOfRvaAndSizes != 0x10)
959 {
960 throw new InvalidOperationException("Invalid number of data directories in NT header");
961 }
962
963 // Scan data directories and load section headers
964 for (int i = 0; i < _ntHeaders.OptionalHeader64._NumberOfRvaAndSizes; i++)
965 {
966 if (_ntHeaders._OptionalHeader64._DataDirectory[i]._Size > 0)
967 {
968 IMAGE_SECTION_HEADER ish = MarshalBytesTo<IMAGE_SECTION_HEADER>(reader);
969 if (ish._SizeOfRawData != 0)
970 _sectionHeaders.Add(ish);
971 }
972 }
973 }
974
975 private void Load32bitOptionalHeaders(BinaryReader reader)
976 {
977 _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
978
979 // Should have 10 data directories
980 if (_ntHeaders.OptionalHeader32._NumberOfRvaAndSizes != 0x10)
981 {
982 throw new InvalidOperationException("Invalid number of data directories in NT header");
983 }
984
985 // Scan data directories and load section headers
986 for (int i = 0; i < _ntHeaders.OptionalHeader32._NumberOfRvaAndSizes; i++)
987 {
988 if (_ntHeaders._OptionalHeader32._DataDirectory[i]._Size > 0)
989 {
990 IMAGE_SECTION_HEADER ish = MarshalBytesTo<IMAGE_SECTION_HEADER>(reader);
991 if (ish._SizeOfRawData != 0)
992 _sectionHeaders.Add(ish);
993 }
994 }
995 }
996
997 private static T MarshalBytesTo<T>(BinaryReader reader)
998 {
999 // Unmanaged data
1000 byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
1001
1002 // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
1003 GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
1004
1005 // Use our previously created pointer to unmanaged data and marshal to the specified type
1006 T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
1007
1008 // Deallocate pointer
1009 handle.Free();
1010
1011 return theStructure;
1012 }
1013 }
1014 }

  ViewVC Help
Powered by ViewVC 1.1.22