/[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 293 - (show annotations) (download)
Tue Jun 5 10:27:16 2012 UTC (9 years, 4 months ago) by william
File size: 22837 byte(s)
fix format of IMAGE_NT_HEADERS

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.IO;
6 using RomCheater.Logging;
7 using System.Runtime.InteropServices;
8 using System.Diagnostics;
9
10 namespace Sojaner.MemoryScanner
11 {
12 public class PEReader
13 {
14 public PEReader(FileInfo fi) : this(fi.FullName) { }
15 public PEReader(string filename)
16 {
17 Exception ErrorInfo = null;
18 try
19 {
20 this.Read(filename, out ErrorInfo);
21 }
22 catch (Exception ex)
23 {
24 logger.Error.WriteLine("PEReader: Failed to read process: {0}", filename);
25 if (ErrorInfo != null)
26 {
27 //logger.Error.WriteLine(ErrorInfo.GetBaseException().ToString());
28 throw ErrorInfo;
29 }
30 else
31 {
32 //logger.Error.WriteLine(ex.GetBaseException().ToString());
33 throw ex;
34 }
35 }
36 }
37
38 #region marshalling
39 private void Read(string filename, out Exception ErrorInfo)
40 {
41 ErrorInfo = null;
42 try
43 {
44 logger.Debug.WriteLine("Reading Exe: {0}", filename);
45
46 using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
47 {
48 try
49 {
50 byte[] data = new byte[] { };
51 GCHandle pinnedPacket = new GCHandle();
52 int size = 0;
53 BinaryReader br = new BinaryReader(fs);
54
55 #region IMAGE_DOS_HEADER
56 size = Marshal.SizeOf(typeof(IMAGE_DOS_HEADER));
57 data = br.ReadBytes(size);
58 pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
59 IMAGE_DOS_HEADER DOS_HEADER = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_DOS_HEADER));
60 pinnedPacket.Free();
61 #endregion
62
63 // skip the old dos stub
64 br.BaseStream.Seek(DOS_HEADER.e_lfanew, SeekOrigin.Begin);
65
66 #region IMAGE_NT_HEADERS
67 size = Marshal.SizeOf(typeof(IMAGE_NT_HEADERS));
68 data = br.ReadBytes(size);
69 pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
70 IMAGE_NT_HEADERS NT_HEADER = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_NT_HEADERS));
71 pinnedPacket.Free();
72 #endregion
73
74 StringBuilder section_header_string_builder = new StringBuilder();
75 List<IMAGE_SECTION_HEADER> section_headers = new List<IMAGE_SECTION_HEADER>();
76 section_header_string_builder.AppendFormat("Section headers:{0}", System.Environment.NewLine);
77 for (int i = 0; i < NT_HEADER.FileHeader.NumberOfSections; i++)
78 {
79 size = Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));
80 data = br.ReadBytes(size);
81 pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
82 IMAGE_SECTION_HEADER SECTION_HEADER = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_SECTION_HEADER));
83 section_headers.Add(SECTION_HEADER);
84 pinnedPacket.Free();
85 section_header_string_builder.AppendFormat("Section Header: {0}{1}", new string(SECTION_HEADER.Name).Replace("\0",""), System.Environment.NewLine);
86
87 }
88 logger.VerboseDebug.WriteLine(section_header_string_builder.ToString());
89 br.Close();
90 }
91 catch (Exception ex)
92 {
93 ErrorInfo = ex;
94 }
95 }
96 }
97 catch (Exception ex)
98 {
99 ErrorInfo = ex;
100 }
101 }
102 #endregion
103
104 #region header support
105 #region IMAGE_DATA_DIRECTORY
106 [StructLayout(LayoutKind.Sequential)]
107 public struct IMAGE_DATA_DIRECTORY
108 {
109 public UInt32 VirtualAddress;
110 public UInt32 Size;
111 public bool HasAddress { get { return (VirtualAddress != 0); } }
112 public bool HasSize { get { return (Size > 0); } }
113 }
114 #endregion
115 #region IMAGE_FILE_HEADER
116 [StructLayout(LayoutKind.Sequential)]
117 public struct IMAGE_FILE_HEADER
118 {
119 public MachineType Machine;
120 public UInt16 NumberOfSections;
121 public UInt32 TimeDateStamp;
122 public UInt32 PointerToSymbolTable;
123 public UInt32 NumberOfSymbols;
124 public UInt16 SizeOfOptionalHeader;
125 public DllCharacteristicsType Characteristics;
126 }
127 #endregion
128 #region IMAGE_DOS_HEADER
129 [StructLayout(LayoutKind.Sequential)]
130 public struct IMAGE_DOS_HEADER
131 {
132 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
133 public char[] e_magic; // Magic number
134 public UInt16 e_cblp; // Bytes on last page of file
135 public UInt16 e_cp; // Pages in file
136 public UInt16 e_crlc; // Relocations
137 public UInt16 e_cparhdr; // Size of header in paragraphs
138 public UInt16 e_minalloc; // Minimum extra paragraphs needed
139 public UInt16 e_maxalloc; // Maximum extra paragraphs needed
140 public UInt16 e_ss; // Initial (relative) SS value
141 public UInt16 e_sp; // Initial SP value
142 public UInt16 e_csum; // Checksum
143 public UInt16 e_ip; // Initial IP value
144 public UInt16 e_cs; // Initial (relative) CS value
145 public UInt16 e_lfarlc; // File address of relocation table
146 public UInt16 e_ovno; // Overlay number
147 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
148 public UInt16[] e_res1; // Reserved words
149 public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
150 public UInt16 e_oeminfo; // OEM information; e_oemid specific
151 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
152 public UInt16[] e_res2; // Reserved words
153 public Int32 e_lfanew; // File address of new exe header
154 private string _e_magic
155 {
156 get { return new string(e_magic); }
157 }
158 public bool isValid
159 {
160 get { return _e_magic == "MZ"; }
161 }
162 }
163 #endregion
164 #region IMAGE_NT_HEADERS
165 [StructLayout(LayoutKind.Explicit)]
166 public struct IMAGE_NT_HEADERS
167 {
168 [FieldOffset(0)]
169 public uint Signature;
170 [FieldOffset(4)]
171 public IMAGE_FILE_HEADER FileHeader;
172 [FieldOffset(24)]
173 public IMAGE_OPTIONAL_HEADER OptionalHeader;
174
175 private string _Signature
176 {
177 get { return Encoding.ASCII.GetString(BitConverter.GetBytes(Signature)); }
178 }
179
180 public bool isValid
181 {
182 get { return _Signature == "PE\0\0" && (OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC || OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC); }
183 }
184 }
185 #endregion
186 #region MachineType
187 public enum MachineType : ushort
188 {
189 Native = 0,
190 I386 = 0x014c,
191 Itanium = 0x0200,
192 x64 = 0x8664
193 }
194 #endregion
195 #region MagicType
196 public enum MagicType : ushort
197 {
198 IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
199 IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
200 }
201 #endregion
202 #region SubSystemType
203 public enum SubSystemType : ushort
204 {
205 IMAGE_SUBSYSTEM_UNKNOWN = 0,
206 IMAGE_SUBSYSTEM_NATIVE = 1,
207 IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
208 IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
209 IMAGE_SUBSYSTEM_POSIX_CUI = 7,
210 IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
211 IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
212 IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
213 IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
214 IMAGE_SUBSYSTEM_EFI_ROM = 13,
215 IMAGE_SUBSYSTEM_XBOX = 14
216
217 }
218 #endregion
219 #region DllCharacteristicsType
220 [Flags]
221 public enum DllCharacteristicsType : ushort
222 {
223 RES_0 = 0x0001,
224 RES_1 = 0x0002,
225 RES_2 = 0x0004,
226 RES_3 = 0x0008,
227 IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
228 IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
229 IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
230 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
231 IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
232 IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
233 RES_4 = 0x1000,
234 IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
235 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
236 }
237 #endregion
238 #region IMAGE_OPTIONAL_HEADER
239 [StructLayout(LayoutKind.Explicit)]
240 public struct IMAGE_OPTIONAL_HEADER
241 {
242 [FieldOffset(0)]
243 public MagicType Magic;
244
245 [FieldOffset(2)]
246 public byte MajorLinkerVersion;
247
248 [FieldOffset(3)]
249 public byte MinorLinkerVersion;
250
251 [FieldOffset(4)]
252 public uint SizeOfCode;
253
254 [FieldOffset(8)]
255 public uint SizeOfInitializedData;
256
257 [FieldOffset(12)]
258 public uint SizeOfUninitializedData;
259
260 [FieldOffset(16)]
261 public uint AddressOfEntryPoint;
262
263 [FieldOffset(20)]
264 public uint BaseOfCode;
265
266 // PE32 contains this additional field
267 [FieldOffset(24)]
268 public uint BaseOfData;
269
270 [FieldOffset(28)]
271 public uint ImageBase;
272
273 [FieldOffset(32)]
274 public uint SectionAlignment;
275
276 [FieldOffset(36)]
277 public uint FileAlignment;
278
279 [FieldOffset(40)]
280 public ushort MajorOperatingSystemVersion;
281
282 [FieldOffset(42)]
283 public ushort MinorOperatingSystemVersion;
284
285 [FieldOffset(44)]
286 public ushort MajorImageVersion;
287
288 [FieldOffset(46)]
289 public ushort MinorImageVersion;
290
291 [FieldOffset(48)]
292 public ushort MajorSubsystemVersion;
293
294 [FieldOffset(50)]
295 public ushort MinorSubsystemVersion;
296
297 [FieldOffset(52)]
298 public uint Win32VersionValue;
299
300 [FieldOffset(56)]
301 public uint SizeOfImage;
302
303 [FieldOffset(60)]
304 public uint SizeOfHeaders;
305
306 [FieldOffset(64)]
307 public uint CheckSum;
308
309 [FieldOffset(68)]
310 public SubSystemType Subsystem;
311
312 [FieldOffset(70)]
313 public DllCharacteristicsType DllCharacteristics;
314
315 [FieldOffset(72)]
316 public uint SizeOfStackReserve;
317
318 [FieldOffset(76)]
319 public uint SizeOfStackCommit;
320
321 [FieldOffset(80)]
322 public uint SizeOfHeapReserve;
323
324 [FieldOffset(84)]
325 public uint SizeOfHeapCommit;
326
327 [FieldOffset(88)]
328 public uint LoaderFlags;
329
330 [FieldOffset(92)]
331 public uint NumberOfRvaAndSizes;
332
333 [FieldOffset(96)]
334 public IMAGE_DATA_DIRECTORY ExportTable;
335
336 [FieldOffset(104)]
337 public IMAGE_DATA_DIRECTORY ImportTable;
338
339 [FieldOffset(112)]
340 public IMAGE_DATA_DIRECTORY ResourceTable;
341
342 [FieldOffset(120)]
343 public IMAGE_DATA_DIRECTORY ExceptionTable;
344
345 [FieldOffset(128)]
346 public IMAGE_DATA_DIRECTORY CertificateTable;
347
348 [FieldOffset(136)]
349 public IMAGE_DATA_DIRECTORY BaseRelocationTable;
350
351 [FieldOffset(144)]
352 public IMAGE_DATA_DIRECTORY Debug;
353
354 [FieldOffset(152)]
355 public IMAGE_DATA_DIRECTORY Architecture;
356
357 [FieldOffset(160)]
358 public IMAGE_DATA_DIRECTORY GlobalPtr;
359
360 [FieldOffset(168)]
361 public IMAGE_DATA_DIRECTORY TLSTable;
362
363 [FieldOffset(176)]
364 public IMAGE_DATA_DIRECTORY LoadConfigTable;
365
366 [FieldOffset(184)]
367 public IMAGE_DATA_DIRECTORY BoundImport;
368
369 [FieldOffset(192)]
370 public IMAGE_DATA_DIRECTORY IAT;
371
372 [FieldOffset(200)]
373 public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
374
375 [FieldOffset(208)]
376 public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
377
378 [FieldOffset(216)]
379 public IMAGE_DATA_DIRECTORY Reserved;
380 }
381 #endregion
382 #region IMAGE_EXPORT_DIRECTORY
383 [StructLayout(LayoutKind.Sequential)]
384 public struct IMAGE_EXPORT_DIRECTORY
385 {
386 public UInt32 Characteristics;
387 public UInt32 TimeDateStamp;
388 public UInt16 MajorVersion;
389 public UInt16 MinorVersion;
390 public UInt32 Name;
391 public UInt32 Base;
392 public UInt32 NumberOfFunctions;
393 public UInt32 NumberOfNames;
394 public UInt32 AddressOfFunctions; // RVA from base of image
395 public UInt32 AddressOfNames; // RVA from base of image
396 public UInt32 AddressOfNameOrdinals; // RVA from base of image
397 }
398 #endregion
399 #endregion
400 #region IMAGE_SECTION_HEADER
401 [StructLayout(LayoutKind.Explicit)]
402 public struct IMAGE_SECTION_HEADER
403 {
404 [FieldOffset(0)]
405 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
406 public char[] Name;
407
408 [FieldOffset(8)]
409 public UInt32 VirtualSize;
410
411 [FieldOffset(12)]
412 public UInt32 VirtualAddress;
413
414 [FieldOffset(16)]
415 public UInt32 SizeOfRawData;
416
417 [FieldOffset(20)]
418 public UInt32 PointerToRawData;
419
420 [FieldOffset(24)]
421 public UInt32 PointerToRelocations;
422
423 [FieldOffset(28)]
424 public UInt32 PointerToLinenumbers;
425
426 [FieldOffset(32)]
427 public UInt16 NumberOfRelocations;
428
429 [FieldOffset(34)]
430 public UInt16 NumberOfLinenumbers;
431
432 [FieldOffset(36)]
433 public DataSectionFlags Characteristics;
434
435 public string Section
436 {
437 get { return new string(Name); }
438 }
439 }
440 #endregion
441 #region DataSectionFlags
442 [Flags]
443 public enum DataSectionFlags : uint
444 {
445 /// <summary>
446 /// Reserved for future use.
447 /// </summary>
448 TypeReg = 0x00000000,
449 /// <summary>
450 /// Reserved for future use.
451 /// </summary>
452 TypeDsect = 0x00000001,
453 /// <summary>
454 /// Reserved for future use.
455 /// </summary>
456 TypeNoLoad = 0x00000002,
457 /// <summary>
458 /// Reserved for future use.
459 /// </summary>
460 TypeGroup = 0x00000004,
461 /// <summary>
462 /// 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.
463 /// </summary>
464 TypeNoPadded = 0x00000008,
465 /// <summary>
466 /// Reserved for future use.
467 /// </summary>
468 TypeCopy = 0x00000010,
469 /// <summary>
470 /// The section contains executable code.
471 /// </summary>
472 ContentCode = 0x00000020,
473 /// <summary>
474 /// The section contains initialized data.
475 /// </summary>
476 ContentInitializedData = 0x00000040,
477 /// <summary>
478 /// The section contains uninitialized data.
479 /// </summary>
480 ContentUninitializedData = 0x00000080,
481 /// <summary>
482 /// Reserved for future use.
483 /// </summary>
484 LinkOther = 0x00000100,
485 /// <summary>
486 /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
487 /// </summary>
488 LinkInfo = 0x00000200,
489 /// <summary>
490 /// Reserved for future use.
491 /// </summary>
492 TypeOver = 0x00000400,
493 /// <summary>
494 /// The section will not become part of the image. This is valid only for object files.
495 /// </summary>
496 LinkRemove = 0x00000800,
497 /// <summary>
498 /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
499 /// </summary>
500 LinkComDat = 0x00001000,
501 /// <summary>
502 /// Reset speculative exceptions handling bits in the TLB entries for this section.
503 /// </summary>
504 NoDeferSpecExceptions = 0x00004000,
505 /// <summary>
506 /// The section contains data referenced through the global pointer (GP).
507 /// </summary>
508 RelativeGP = 0x00008000,
509 /// <summary>
510 /// Reserved for future use.
511 /// </summary>
512 MemPurgeable = 0x00020000,
513 /// <summary>
514 /// Reserved for future use.
515 /// </summary>
516 Memory16Bit = 0x00020000,
517 /// <summary>
518 /// Reserved for future use.
519 /// </summary>
520 MemoryLocked = 0x00040000,
521 /// <summary>
522 /// Reserved for future use.
523 /// </summary>
524 MemoryPreload = 0x00080000,
525 /// <summary>
526 /// Align data on a 1-byte boundary. Valid only for object files.
527 /// </summary>
528 Align1Bytes = 0x00100000,
529 /// <summary>
530 /// Align data on a 2-byte boundary. Valid only for object files.
531 /// </summary>
532 Align2Bytes = 0x00200000,
533 /// <summary>
534 /// Align data on a 4-byte boundary. Valid only for object files.
535 /// </summary>
536 Align4Bytes = 0x00300000,
537 /// <summary>
538 /// Align data on an 8-byte boundary. Valid only for object files.
539 /// </summary>
540 Align8Bytes = 0x00400000,
541 /// <summary>
542 /// Align data on a 16-byte boundary. Valid only for object files.
543 /// </summary>
544 Align16Bytes = 0x00500000,
545 /// <summary>
546 /// Align data on a 32-byte boundary. Valid only for object files.
547 /// </summary>
548 Align32Bytes = 0x00600000,
549 /// <summary>
550 /// Align data on a 64-byte boundary. Valid only for object files.
551 /// </summary>
552 Align64Bytes = 0x00700000,
553 /// <summary>
554 /// Align data on a 128-byte boundary. Valid only for object files.
555 /// </summary>
556 Align128Bytes = 0x00800000,
557 /// <summary>
558 /// Align data on a 256-byte boundary. Valid only for object files.
559 /// </summary>
560 Align256Bytes = 0x00900000,
561 /// <summary>
562 /// Align data on a 512-byte boundary. Valid only for object files.
563 /// </summary>
564 Align512Bytes = 0x00A00000,
565 /// <summary>
566 /// Align data on a 1024-byte boundary. Valid only for object files.
567 /// </summary>
568 Align1024Bytes = 0x00B00000,
569 /// <summary>
570 /// Align data on a 2048-byte boundary. Valid only for object files.
571 /// </summary>
572 Align2048Bytes = 0x00C00000,
573 /// <summary>
574 /// Align data on a 4096-byte boundary. Valid only for object files.
575 /// </summary>
576 Align4096Bytes = 0x00D00000,
577 /// <summary>
578 /// Align data on an 8192-byte boundary. Valid only for object files.
579 /// </summary>
580 Align8192Bytes = 0x00E00000,
581 /// <summary>
582 /// The section contains extended relocations.
583 /// </summary>
584 LinkExtendedRelocationOverflow = 0x01000000,
585 /// <summary>
586 /// The section can be discarded as needed.
587 /// </summary>
588 MemoryDiscardable = 0x02000000,
589 /// <summary>
590 /// The section cannot be cached.
591 /// </summary>
592 MemoryNotCached = 0x04000000,
593 /// <summary>
594 /// The section is not pageable.
595 /// </summary>
596 MemoryNotPaged = 0x08000000,
597 /// <summary>
598 /// The section can be shared in memory.
599 /// </summary>
600 MemoryShared = 0x10000000,
601 /// <summary>
602 /// The section can be executed as code.
603 /// </summary>
604 MemoryExecute = 0x20000000,
605 /// <summary>
606 /// The section can be read.
607 /// </summary>
608 MemoryRead = 0x40000000,
609 /// <summary>
610 /// The section can be written to.
611 /// </summary>
612 MemoryWrite = 0x80000000
613 }
614 #endregion
615 }
616 }

  ViewVC Help
Powered by ViewVC 1.1.22