/[RomCheater]/trunk/Win32/Sojaner.MemoryScanner/PEReader.cs
ViewVC logotype

Annotation of /trunk/Win32/Sojaner.MemoryScanner/PEReader.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 293 - (hide annotations) (download)
Tue Jun 5 10:27:16 2012 UTC (8 years, 7 months ago) by william
File size: 22837 byte(s)
fix format of IMAGE_NT_HEADERS

1 william 159 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 william 290 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 william 159
38     #region marshalling
39 william 290 private void Read(string filename, out Exception ErrorInfo)
40 william 159 {
41 william 290 ErrorInfo = null;
42     try
43 william 159 {
44 william 290 logger.Debug.WriteLine("Reading Exe: {0}", filename);
45 william 159
46 william 290 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 william 159
55 william 290 #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 william 159
63 william 290 // skip the old dos stub
64     br.BaseStream.Seek(DOS_HEADER.e_lfanew, SeekOrigin.Begin);
65 william 159
66 william 290 #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 william 160
74 william 293 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 william 290
87 william 293 }
88     logger.VerboseDebug.WriteLine(section_header_string_builder.ToString());
89 william 290 br.Close();
90     }
91     catch (Exception ex)
92     {
93     ErrorInfo = ex;
94     }
95     }
96 william 159 }
97 william 290 catch (Exception ex)
98     {
99     ErrorInfo = ex;
100     }
101 william 159 }
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 william 161 public bool HasAddress { get { return (VirtualAddress != 0); } }
112     public bool HasSize { get { return (Size > 0); } }
113 william 159 }
114     #endregion
115     #region IMAGE_FILE_HEADER
116     [StructLayout(LayoutKind.Sequential)]
117     public struct IMAGE_FILE_HEADER
118     {
119 william 160 public MachineType Machine;
120 william 159 public UInt16 NumberOfSections;
121     public UInt32 TimeDateStamp;
122     public UInt32 PointerToSymbolTable;
123     public UInt32 NumberOfSymbols;
124     public UInt16 SizeOfOptionalHeader;
125 william 160 public DllCharacteristicsType Characteristics;
126 william 159 }
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 william 293 public uint Signature;
170     [FieldOffset(4)]
171 william 159 public IMAGE_FILE_HEADER FileHeader;
172     [FieldOffset(24)]
173     public IMAGE_OPTIONAL_HEADER OptionalHeader;
174    
175     private string _Signature
176     {
177 william 293 get { return Encoding.ASCII.GetString(BitConverter.GetBytes(Signature)); }
178 william 159 }
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 william 160 [Flags]
221 william 159 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 william 293 #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 william 159 }
616     }

  ViewVC Help
Powered by ViewVC 1.1.22