ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/PEReader.cs
Revision: 159
Committed: Mon May 28 05:22:28 2012 UTC (11 years, 4 months ago) by william
File size: 11981 byte(s)
Log Message:
+ add support to parse an exe

File Contents

# Content
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) { this.Read(filename); }
16
17 #region marshalling
18 private void Read(string filename)
19 {
20 logger.Debug.WriteLine("Reading Exe: {0}", filename);
21
22 using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
23 {
24 byte[] data = new byte[] { };
25 GCHandle pinnedPacket = new GCHandle();
26 int size = 0;
27 BinaryReader br = new BinaryReader(fs);
28
29 #region IMAGE_DOS_HEADER
30 size = Marshal.SizeOf(typeof(IMAGE_DOS_HEADER));
31 data = br.ReadBytes(size);
32 pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
33 IMAGE_DOS_HEADER IMAGE_DOS_HEADER = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_DOS_HEADER));
34 pinnedPacket.Free();
35 #endregion
36
37 // skip the old dos stub
38 br.BaseStream.Seek(IMAGE_DOS_HEADER.e_lfanew, SeekOrigin.Begin);
39
40 #region IMAGE_NT_HEADERS
41 size = Marshal.SizeOf(typeof(IMAGE_NT_HEADERS));
42 data = br.ReadBytes(size);
43 pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
44 IMAGE_NT_HEADERS IMAGE_NT_HEADERS = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_NT_HEADERS));
45 pinnedPacket.Free();
46 #endregion
47
48 br.Close();
49 }
50
51
52 }
53 #endregion
54
55 #region header support
56 #region IMAGE_DATA_DIRECTORY
57 [StructLayout(LayoutKind.Sequential)]
58 public struct IMAGE_DATA_DIRECTORY
59 {
60 public UInt32 VirtualAddress;
61 public UInt32 Size;
62 }
63 #endregion
64 #region IMAGE_FILE_HEADER
65 [StructLayout(LayoutKind.Sequential)]
66 public struct IMAGE_FILE_HEADER
67 {
68 public UInt16 Machine;
69 public UInt16 NumberOfSections;
70 public UInt32 TimeDateStamp;
71 public UInt32 PointerToSymbolTable;
72 public UInt32 NumberOfSymbols;
73 public UInt16 SizeOfOptionalHeader;
74 public UInt16 Characteristics;
75 }
76 #endregion
77 #region IMAGE_DOS_HEADER
78 [StructLayout(LayoutKind.Sequential)]
79 public struct IMAGE_DOS_HEADER
80 {
81 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
82 public char[] e_magic; // Magic number
83 public UInt16 e_cblp; // Bytes on last page of file
84 public UInt16 e_cp; // Pages in file
85 public UInt16 e_crlc; // Relocations
86 public UInt16 e_cparhdr; // Size of header in paragraphs
87 public UInt16 e_minalloc; // Minimum extra paragraphs needed
88 public UInt16 e_maxalloc; // Maximum extra paragraphs needed
89 public UInt16 e_ss; // Initial (relative) SS value
90 public UInt16 e_sp; // Initial SP value
91 public UInt16 e_csum; // Checksum
92 public UInt16 e_ip; // Initial IP value
93 public UInt16 e_cs; // Initial (relative) CS value
94 public UInt16 e_lfarlc; // File address of relocation table
95 public UInt16 e_ovno; // Overlay number
96 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
97 public UInt16[] e_res1; // Reserved words
98 public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
99 public UInt16 e_oeminfo; // OEM information; e_oemid specific
100 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
101 public UInt16[] e_res2; // Reserved words
102 public Int32 e_lfanew; // File address of new exe header
103 private string _e_magic
104 {
105 get { return new string(e_magic); }
106 }
107 public bool isValid
108 {
109 get { return _e_magic == "MZ"; }
110 }
111 }
112 #endregion
113 #region IMAGE_NT_HEADERS
114 [StructLayout(LayoutKind.Explicit)]
115 public struct IMAGE_NT_HEADERS
116 {
117 [FieldOffset(0)]
118 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
119 public char[] Signature;
120
121 [FieldOffset(4)]
122 public IMAGE_FILE_HEADER FileHeader;
123
124 [FieldOffset(24)]
125 public IMAGE_OPTIONAL_HEADER OptionalHeader;
126
127 private string _Signature
128 {
129 get { return new string(Signature); }
130 }
131
132 public bool isValid
133 {
134 get { return _Signature == "PE\0\0" && (OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC || OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC); }
135 }
136 }
137 #endregion
138 #region MachineType
139 public enum MachineType : ushort
140 {
141 Native = 0,
142 I386 = 0x014c,
143 Itanium = 0x0200,
144 x64 = 0x8664
145 }
146 #endregion
147 #region MagicType
148 public enum MagicType : ushort
149 {
150 IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
151 IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
152 }
153 #endregion
154 #region SubSystemType
155 public enum SubSystemType : ushort
156 {
157 IMAGE_SUBSYSTEM_UNKNOWN = 0,
158 IMAGE_SUBSYSTEM_NATIVE = 1,
159 IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
160 IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
161 IMAGE_SUBSYSTEM_POSIX_CUI = 7,
162 IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
163 IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
164 IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
165 IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
166 IMAGE_SUBSYSTEM_EFI_ROM = 13,
167 IMAGE_SUBSYSTEM_XBOX = 14
168
169 }
170 #endregion
171 #region DllCharacteristicsType
172 public enum DllCharacteristicsType : ushort
173 {
174 RES_0 = 0x0001,
175 RES_1 = 0x0002,
176 RES_2 = 0x0004,
177 RES_3 = 0x0008,
178 IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
179 IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
180 IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
181 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
182 IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
183 IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
184 RES_4 = 0x1000,
185 IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
186 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
187 }
188 #endregion
189 #region IMAGE_OPTIONAL_HEADER
190 [StructLayout(LayoutKind.Explicit)]
191 public struct IMAGE_OPTIONAL_HEADER
192 {
193 [FieldOffset(0)]
194 public MagicType Magic;
195
196 [FieldOffset(2)]
197 public byte MajorLinkerVersion;
198
199 [FieldOffset(3)]
200 public byte MinorLinkerVersion;
201
202 [FieldOffset(4)]
203 public uint SizeOfCode;
204
205 [FieldOffset(8)]
206 public uint SizeOfInitializedData;
207
208 [FieldOffset(12)]
209 public uint SizeOfUninitializedData;
210
211 [FieldOffset(16)]
212 public uint AddressOfEntryPoint;
213
214 [FieldOffset(20)]
215 public uint BaseOfCode;
216
217 // PE32 contains this additional field
218 [FieldOffset(24)]
219 public uint BaseOfData;
220
221 [FieldOffset(28)]
222 public uint ImageBase;
223
224 [FieldOffset(32)]
225 public uint SectionAlignment;
226
227 [FieldOffset(36)]
228 public uint FileAlignment;
229
230 [FieldOffset(40)]
231 public ushort MajorOperatingSystemVersion;
232
233 [FieldOffset(42)]
234 public ushort MinorOperatingSystemVersion;
235
236 [FieldOffset(44)]
237 public ushort MajorImageVersion;
238
239 [FieldOffset(46)]
240 public ushort MinorImageVersion;
241
242 [FieldOffset(48)]
243 public ushort MajorSubsystemVersion;
244
245 [FieldOffset(50)]
246 public ushort MinorSubsystemVersion;
247
248 [FieldOffset(52)]
249 public uint Win32VersionValue;
250
251 [FieldOffset(56)]
252 public uint SizeOfImage;
253
254 [FieldOffset(60)]
255 public uint SizeOfHeaders;
256
257 [FieldOffset(64)]
258 public uint CheckSum;
259
260 [FieldOffset(68)]
261 public SubSystemType Subsystem;
262
263 [FieldOffset(70)]
264 public DllCharacteristicsType DllCharacteristics;
265
266 [FieldOffset(72)]
267 public uint SizeOfStackReserve;
268
269 [FieldOffset(76)]
270 public uint SizeOfStackCommit;
271
272 [FieldOffset(80)]
273 public uint SizeOfHeapReserve;
274
275 [FieldOffset(84)]
276 public uint SizeOfHeapCommit;
277
278 [FieldOffset(88)]
279 public uint LoaderFlags;
280
281 [FieldOffset(92)]
282 public uint NumberOfRvaAndSizes;
283
284 [FieldOffset(96)]
285 public IMAGE_DATA_DIRECTORY ExportTable;
286
287 [FieldOffset(104)]
288 public IMAGE_DATA_DIRECTORY ImportTable;
289
290 [FieldOffset(112)]
291 public IMAGE_DATA_DIRECTORY ResourceTable;
292
293 [FieldOffset(120)]
294 public IMAGE_DATA_DIRECTORY ExceptionTable;
295
296 [FieldOffset(128)]
297 public IMAGE_DATA_DIRECTORY CertificateTable;
298
299 [FieldOffset(136)]
300 public IMAGE_DATA_DIRECTORY BaseRelocationTable;
301
302 [FieldOffset(144)]
303 public IMAGE_DATA_DIRECTORY Debug;
304
305 [FieldOffset(152)]
306 public IMAGE_DATA_DIRECTORY Architecture;
307
308 [FieldOffset(160)]
309 public IMAGE_DATA_DIRECTORY GlobalPtr;
310
311 [FieldOffset(168)]
312 public IMAGE_DATA_DIRECTORY TLSTable;
313
314 [FieldOffset(176)]
315 public IMAGE_DATA_DIRECTORY LoadConfigTable;
316
317 [FieldOffset(184)]
318 public IMAGE_DATA_DIRECTORY BoundImport;
319
320 [FieldOffset(192)]
321 public IMAGE_DATA_DIRECTORY IAT;
322
323 [FieldOffset(200)]
324 public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
325
326 [FieldOffset(208)]
327 public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
328
329 [FieldOffset(216)]
330 public IMAGE_DATA_DIRECTORY Reserved;
331 }
332 #endregion
333 #region IMAGE_EXPORT_DIRECTORY
334 [StructLayout(LayoutKind.Sequential)]
335 public struct IMAGE_EXPORT_DIRECTORY
336 {
337 public UInt32 Characteristics;
338 public UInt32 TimeDateStamp;
339 public UInt16 MajorVersion;
340 public UInt16 MinorVersion;
341 public UInt32 Name;
342 public UInt32 Base;
343 public UInt32 NumberOfFunctions;
344 public UInt32 NumberOfNames;
345 public UInt32 AddressOfFunctions; // RVA from base of image
346 public UInt32 AddressOfNames; // RVA from base of image
347 public UInt32 AddressOfNameOrdinals; // RVA from base of image
348 }
349 #endregion
350 #endregion
351 }
352 }