1 |
#region Logging Defines |
2 |
// include this any class or method that required logging, and comment-out what is not needed |
3 |
|
4 |
#region Enabled logging levels |
5 |
#define LOGGING_ENABLE_INFO |
6 |
#define LOGGING_ENABLE_WARN |
7 |
#define LOGGING_ENABLE_DEBUG |
8 |
//#define LOGGING_ENABLE_VERBOSEDEBUG |
9 |
#define LOGGING_ENABLE_ERROR |
10 |
#define LOGGING_ENABLE_VERBOSEERROR |
11 |
#define LOGGING_ENABLE_PROFILER |
12 |
#endregion |
13 |
#endregion |
14 |
|
15 |
using System; |
16 |
using System.Collections.Generic; |
17 |
using System.Runtime.InteropServices; |
18 |
using System.IO; |
19 |
using System.Diagnostics; |
20 |
using RomCheater.PluginFramework.Interfaces; |
21 |
using System.ComponentModel; |
22 |
using System.Text; |
23 |
|
24 |
namespace Sojaner.MemoryScanner |
25 |
{ |
26 |
public interface IPEDData |
27 |
{ |
28 |
IMAGE_DOS_HEADER DosHeader { get; } |
29 |
string NTSignature { get; } |
30 |
IMAGE_FILE_HEADER FileHeader { get; } |
31 |
IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get; } |
32 |
IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get; } |
33 |
IMAGE_SECTION_HEADER[] SectionHeaders { get; } |
34 |
bool Is32bitAssembly(); |
35 |
|
36 |
[Browsable(false)] |
37 |
uint _VirtualEntryPoint { get; } |
38 |
string VirtualEntryPoint { get; } |
39 |
|
40 |
[Browsable(false)] |
41 |
uint _VirtualRVA { get; } |
42 |
string VirtualRVA { get; } |
43 |
|
44 |
[Browsable(false)] |
45 |
ulong _VirtualImageBase { get; } |
46 |
string VirtualImageBase { get; } |
47 |
|
48 |
ISECTION_DATA[] SectionData { get; } |
49 |
} |
50 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
51 |
public interface ISECTION_DATA |
52 |
{ |
53 |
string Name { get; } |
54 |
uint _Start { get; } |
55 |
uint _End { get; } |
56 |
uint _Size { get; } |
57 |
|
58 |
string Start { get; } |
59 |
string End { get; } |
60 |
string Size { get; } |
61 |
string ToString(); |
62 |
|
63 |
} |
64 |
|
65 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
66 |
public class SECTION_DATA : ISECTION_DATA |
67 |
{ |
68 |
public SECTION_DATA() : this(string.Empty, 0, 0) { } |
69 |
public SECTION_DATA(string name, uint virtualAddress, uint rva, uint virtualSize) : this(name, virtualAddress + rva, virtualSize) { } |
70 |
public SECTION_DATA(string name, uint virtualAddress, uint virtualSize) |
71 |
{ |
72 |
this._Name = name; |
73 |
this._Start = virtualAddress; |
74 |
this._Size = virtualSize; |
75 |
} |
76 |
|
77 |
#region ISECTION_DATA members |
78 |
private string _Name; |
79 |
private uint __Start; |
80 |
[Browsable(false)] |
81 |
public uint _Start { get { return __Start; } set { __Start = value; } } |
82 |
[Browsable(false)] |
83 |
public uint _End { get { return __Start + __Size; } } |
84 |
private uint __Size; |
85 |
[Browsable(false)] |
86 |
public uint _Size { get { return __Size; } set { __Size = value; } } |
87 |
|
88 |
|
89 |
public string Name { get { return _Name; } } |
90 |
public string Start { get { return string.Format("0x{0:x8}", _Start); } } |
91 |
public string End { get { return string.Format("0x{0:x8}", _End); } } |
92 |
public string Size { get { return string.Format("0x{0:x8}", _Size); } } |
93 |
|
94 |
public override string ToString() |
95 |
{ |
96 |
return this.Name; |
97 |
} |
98 |
#endregion |
99 |
} |
100 |
|
101 |
public class PEData : IPEDData |
102 |
{ |
103 |
#region IPEDData Members |
104 |
public IMAGE_DOS_HEADER DosHeader { get { if (reader == null) { return new IMAGE_DOS_HEADER(); } else { return reader.DosHeader; } } } |
105 |
public string NTSignature { get { if (reader == null) { return "0"; } else { return reader.NTSignature; } } } |
106 |
public IMAGE_FILE_HEADER FileHeader { get { if (reader == null) { return new IMAGE_FILE_HEADER(); } else { return reader.FileHeader; } } } |
107 |
public IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get { if (reader == null) { return new IMAGE_OPTIONAL_HEADER32(); } else { return reader.OptionalHeader32; } } } |
108 |
public IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get { if (reader == null) { return new IMAGE_OPTIONAL_HEADER64(); } else { return reader.OptionalHeader64; } } } |
109 |
|
110 |
public IMAGE_SECTION_HEADER[] SectionHeaders { get { if (reader == null) { return new IMAGE_SECTION_HEADER[0]; } else { return reader.ImageSectionHeaders; } } } |
111 |
|
112 |
private ISECTION_DATA[] _SectionData; |
113 |
public ISECTION_DATA[] SectionData { get { return _SectionData; } private set { _SectionData = value; } } |
114 |
|
115 |
public Boolean Is32bitAssembly() { if (reader == null) { return true; } else { return reader.Is32BitHeader; } } |
116 |
|
117 |
|
118 |
[Browsable(false)] |
119 |
public uint _VirtualEntryPoint { get; private set; } |
120 |
public string VirtualEntryPoint { get { return string.Format("0x{0:x8}", _VirtualEntryPoint); } } |
121 |
|
122 |
[Browsable(false)] |
123 |
public uint _VirtualRVA |
124 |
{ |
125 |
get |
126 |
{ |
127 |
if (this.Is32bitAssembly()) |
128 |
{ |
129 |
return (_VirtualEntryPoint - OptionalHeader32._AddressOfEntryPoint); |
130 |
} |
131 |
else |
132 |
{ |
133 |
return (_VirtualEntryPoint - OptionalHeader64._AddressOfEntryPoint); |
134 |
} |
135 |
} |
136 |
} |
137 |
public string VirtualRVA { get { return string.Format("0x{0:x8}", _VirtualRVA); } } |
138 |
|
139 |
[Browsable(false)] |
140 |
public ulong _VirtualImageBase { get; private set; } |
141 |
public string VirtualImageBase |
142 |
{ |
143 |
get |
144 |
{ |
145 |
if (this.Is32bitAssembly()) |
146 |
{ |
147 |
return string.Format("0x{0:x8}", _VirtualImageBase); |
148 |
} |
149 |
else |
150 |
{ |
151 |
return string.Format("0x{0:x16}", _VirtualImageBase); |
152 |
} |
153 |
} |
154 |
} |
155 |
|
156 |
|
157 |
#endregion |
158 |
|
159 |
private PeHeaderReader reader = null; |
160 |
|
161 |
public static readonly IPEDData Empty = new PEData(); |
162 |
|
163 |
protected PEData() { } |
164 |
public PEData(IAcceptsProcess iap) |
165 |
{ |
166 |
if (iap == null) { throw new ArgumentNullException("iap", "The selected process cannot be null"); } |
167 |
Process p = iap.AcceptedProcess; |
168 |
reader = new PeHeaderReader(p); |
169 |
|
170 |
this._VirtualEntryPoint = (uint)p.MainModule.EntryPointAddress; |
171 |
if (this.Is32bitAssembly()) |
172 |
{ |
173 |
this._VirtualImageBase = (uint)p.MainModule.BaseAddress; |
174 |
} |
175 |
else |
176 |
{ |
177 |
this._VirtualImageBase = (ulong)p.MainModule.BaseAddress; |
178 |
} |
179 |
|
180 |
this.SectionData = new ISECTION_DATA[this.SectionHeaders.Length]; |
181 |
|
182 |
for (int i = 0; i < this.SectionHeaders.Length; i++) |
183 |
{ |
184 |
var t = this.SectionHeaders[i]; |
185 |
SECTION_DATA data = new SECTION_DATA(t.Name, t._VirtualAddress, this._VirtualRVA, t._VirtualSize); |
186 |
this.SectionData[i] = (ISECTION_DATA)data; |
187 |
} |
188 |
} |
189 |
public PEData(IAcceptsProcessAndConfig iapc) : this((IAcceptsProcess)iapc) { } |
190 |
} |
191 |
|
192 |
#region File Header Structures |
193 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
194 |
public struct IMAGE_DOS_HEADER |
195 |
{ // DOS .EXE header |
196 |
public UInt16 _e_magic; // Magic number |
197 |
public UInt16 _e_cblp; // Bytes on last page of file |
198 |
public UInt16 _e_cp; // Pages in file |
199 |
public UInt16 _e_crlc; // Relocations |
200 |
public UInt16 _e_cparhdr; // Size of header in paragraphs |
201 |
public UInt16 _e_minalloc; // Minimum extra paragraphs needed |
202 |
public UInt16 _e_maxalloc; // Maximum extra paragraphs needed |
203 |
public UInt16 _e_ss; // Initial (relative) SS value |
204 |
public UInt16 _e_sp; // Initial SP value |
205 |
public UInt16 _e_csum; // Checksum |
206 |
public UInt16 _e_ip; // Initial IP value |
207 |
public UInt16 _e_cs; // Initial (relative) CS value |
208 |
public UInt16 _e_lfarlc; // File address of relocation table |
209 |
public UInt16 _e_ovno; // Overlay number |
210 |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] |
211 |
public UInt16[] _e_res1; |
212 |
public UInt16 _e_oemid; // OEM identifier (for e_oeminfo) |
213 |
public UInt16 _e_oeminfo; // OEM information; e_oemid specific |
214 |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] |
215 |
public UInt16[] _e_res2; |
216 |
public UInt32 _e_lfanew; // File address of new exe header |
217 |
|
218 |
public string e_magic { get { return string.Format("0x{0:x4}", _e_magic); } } |
219 |
public string e_cblp { get { return string.Format("0x{0:x4}", _e_cblp); } } |
220 |
public string e_cp { get { return string.Format("0x{0:x4}", _e_cp); } } |
221 |
public string e_crlc { get { return string.Format("0x{0:x4}", _e_crlc); } } |
222 |
public string e_cparhdr { get { return string.Format("0x{0:x4}", _e_cparhdr); } } |
223 |
public string e_minalloc { get { return string.Format("0x{0:x4}", _e_minalloc); } } |
224 |
public string e_maxalloc { get { return string.Format("0x{0:x4}", _e_maxalloc); } } |
225 |
public string e_ss { get { return string.Format("0x{0:x4}", _e_ss); } } |
226 |
public string e_sp { get { return string.Format("0x{0:x4}", _e_sp); } } |
227 |
public string e_csum { get { return string.Format("0x{0:x4}", _e_csum); } } |
228 |
public string e_ip { get { return string.Format("0x{0:x4}", _e_ip); } } |
229 |
public string e_cs { get { return string.Format("0x{0:x4}", _e_cs); } } |
230 |
public string e_lfarlc { get { return string.Format("0x{0:x4}", _e_lfarlc); } } |
231 |
public string e_ovno { get { return string.Format("0x{0:x4}", _e_ovno); } } |
232 |
public ushort[] e_res1 { get { return _e_res1; } } |
233 |
public string e_oemid { get { return string.Format("0x{0:x4}", _e_oemid); } } |
234 |
public string e_oeminfo { get { return string.Format("0x{0:x4}", _e_oeminfo); } } |
235 |
public ushort[] e_res2 { get { return _e_res2; } } |
236 |
public string e_lfanew { get { return string.Format("0x{0:x8}", _e_lfanew); } } |
237 |
|
238 |
public override string ToString() |
239 |
{ |
240 |
return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic)); |
241 |
} |
242 |
} |
243 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
244 |
[StructLayout(LayoutKind.Sequential)] |
245 |
public struct IMAGE_DATA_DIRECTORY |
246 |
{ |
247 |
public UInt32 _VirtualAddress; |
248 |
public UInt32 _Size; |
249 |
[Browsable(false)] |
250 |
public UInt32 _VirtualStart { get { return _VirtualAddress; } } |
251 |
public string VirtualStart { get { return string.Format("0x{0:x8}", _VirtualStart); } } |
252 |
[Browsable(false)] |
253 |
public UInt32 _VirtualEnd { get { return (_VirtualStart + _VirtualSize); } } |
254 |
public string VirtualEnd { get { return string.Format("0x{0:x8}", _VirtualEnd); } } |
255 |
[Browsable(false)] |
256 |
public UInt32 _VirtualSize { get { return _Size; } } |
257 |
public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } } |
258 |
|
259 |
public override string ToString() |
260 |
{ |
261 |
return string.Format("{0}-{1} [{2}]", VirtualStart, VirtualEnd, VirtualSize); |
262 |
} |
263 |
} |
264 |
|
265 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
266 |
[StructLayout(LayoutKind.Sequential, Pack = 1)] |
267 |
public struct DATA_DIRECTORIES |
268 |
{ |
269 |
public IMAGE_DATA_DIRECTORY _ExportTable; |
270 |
public IMAGE_DATA_DIRECTORY _ImportTable; |
271 |
public IMAGE_DATA_DIRECTORY _ResourceTable; |
272 |
public IMAGE_DATA_DIRECTORY _ExceptionTable; |
273 |
public IMAGE_DATA_DIRECTORY _CertificateTable; |
274 |
public IMAGE_DATA_DIRECTORY _BaseRelocationTable; |
275 |
public IMAGE_DATA_DIRECTORY _Debug; |
276 |
public IMAGE_DATA_DIRECTORY _Architecture; |
277 |
public IMAGE_DATA_DIRECTORY _GlobalPtr; |
278 |
public IMAGE_DATA_DIRECTORY _TLSTable; |
279 |
public IMAGE_DATA_DIRECTORY _LoadConfigTable; |
280 |
public IMAGE_DATA_DIRECTORY _BoundImport; |
281 |
public IMAGE_DATA_DIRECTORY _IAT; |
282 |
public IMAGE_DATA_DIRECTORY _DelayImportDescriptor; |
283 |
public IMAGE_DATA_DIRECTORY _CLRRuntimeHeader; |
284 |
public IMAGE_DATA_DIRECTORY _Reserved; |
285 |
|
286 |
// data directories |
287 |
public IMAGE_DATA_DIRECTORY ExportTable { get { return _ExportTable; } } |
288 |
public IMAGE_DATA_DIRECTORY ImportTable { get { return _ImportTable; } } |
289 |
public IMAGE_DATA_DIRECTORY ResourceTable { get { return _ResourceTable; } } |
290 |
public IMAGE_DATA_DIRECTORY ExceptionTable { get { return _ExceptionTable; } } |
291 |
public IMAGE_DATA_DIRECTORY CertificateTable { get { return _CertificateTable; } } |
292 |
public IMAGE_DATA_DIRECTORY BaseRelocationTable { get { return _BaseRelocationTable; } } |
293 |
public IMAGE_DATA_DIRECTORY Debug { get { return _Debug; } } |
294 |
public IMAGE_DATA_DIRECTORY Architecture { get { return _Architecture; } } |
295 |
public IMAGE_DATA_DIRECTORY GlobalPtr { get { return _GlobalPtr; } } |
296 |
public IMAGE_DATA_DIRECTORY TLSTable { get { return _TLSTable; } } |
297 |
public IMAGE_DATA_DIRECTORY LoadConfigTable { get { return _LoadConfigTable; } } |
298 |
public IMAGE_DATA_DIRECTORY BoundImport { get { return _BoundImport; } } |
299 |
public IMAGE_DATA_DIRECTORY IAT { get { return _IAT; } } |
300 |
public IMAGE_DATA_DIRECTORY DelayImportDescriptor { get { return _DelayImportDescriptor; } } |
301 |
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader { get { return _CLRRuntimeHeader; } } |
302 |
public IMAGE_DATA_DIRECTORY Reserved { get { return _Reserved; } } |
303 |
|
304 |
private uint DataDirectoryCount { get { return 16; } } |
305 |
|
306 |
public override string ToString() |
307 |
{ |
308 |
return string.Format("Cout: 0x{0}", DataDirectoryCount.ToString("X")); |
309 |
} |
310 |
} |
311 |
|
312 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
313 |
[StructLayout(LayoutKind.Sequential, Pack = 1)] |
314 |
public struct IMAGE_OPTIONAL_HEADER32 |
315 |
{ |
316 |
public UInt16 _Magic; |
317 |
public Byte _MajorLinkerVersion; |
318 |
public Byte _MinorLinkerVersion; |
319 |
public UInt32 _SizeOfCode; |
320 |
public UInt32 _SizeOfInitializedData; |
321 |
public UInt32 _SizeOfUninitializedData; |
322 |
public UInt32 _AddressOfEntryPoint; |
323 |
public UInt32 _BaseOfCode; |
324 |
public UInt32 _BaseOfData; |
325 |
public UInt32 _ImageBase; |
326 |
public UInt32 _SectionAlignment; |
327 |
public UInt32 _FileAlignment; |
328 |
public UInt16 _MajorOperatingSystemVersion; |
329 |
public UInt16 _MinorOperatingSystemVersion; |
330 |
public UInt16 _MajorImageVersion; |
331 |
public UInt16 _MinorImageVersion; |
332 |
public UInt16 _MajorSubsystemVersion; |
333 |
public UInt16 _MinorSubsystemVersion; |
334 |
public UInt32 _Win32VersionValue; |
335 |
public UInt32 _SizeOfImage; |
336 |
public UInt32 _SizeOfHeaders; |
337 |
public UInt32 _CheckSum; |
338 |
public SubSystemType _Subsystem; |
339 |
public DllCharacteristicsType _DllCharacteristics; |
340 |
public UInt32 _SizeOfStackReserve; |
341 |
public UInt32 _SizeOfStackCommit; |
342 |
public UInt32 _SizeOfHeapReserve; |
343 |
public UInt32 _SizeOfHeapCommit; |
344 |
public UInt32 _LoaderFlags; |
345 |
public UInt32 _NumberOfRvaAndSizes; |
346 |
|
347 |
|
348 |
public DATA_DIRECTORIES _DATA_DIRECTORIES; |
349 |
|
350 |
public string Magic { get { return ((MagicType)_Magic).ToString(); } } |
351 |
public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } } |
352 |
public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } } |
353 |
|
354 |
public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } } |
355 |
public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } } |
356 |
public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } } |
357 |
public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } } |
358 |
public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } } |
359 |
public string BaseOfData { get { return string.Format("0x{0:x8}", _BaseOfData); } } |
360 |
public string ImageBase { get { return string.Format("0x{0:x8}", _ImageBase); } } |
361 |
public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } } |
362 |
public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } } |
363 |
|
364 |
public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } } |
365 |
public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } } |
366 |
public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } } |
367 |
public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } } |
368 |
public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } } |
369 |
public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } } |
370 |
|
371 |
public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } } |
372 |
public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } } |
373 |
public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } } |
374 |
public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } } |
375 |
|
376 |
public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } } |
377 |
public string DllCharacteristics { get { return string.Format("{0}", _DllCharacteristics); } } |
378 |
|
379 |
public string SizeOfStackReserve { get { return string.Format("0x{0:x8}", _SizeOfStackReserve); } } |
380 |
public string SizeOfStackCommit { get { return string.Format("0x{0:x8}", _SizeOfStackCommit); } } |
381 |
public string SizeOfHeapReserve { get { return string.Format("0x{0:x8}", _SizeOfHeapReserve); } } |
382 |
public string SizeOfHeapCommit { get { return string.Format("0x{0:x8}", _SizeOfHeapCommit); } } |
383 |
|
384 |
public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } } |
385 |
public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } } |
386 |
|
387 |
public DATA_DIRECTORIES DATA_DIRECTORIES { get { return _DATA_DIRECTORIES; } } |
388 |
|
389 |
|
390 |
|
391 |
public override string ToString() |
392 |
{ |
393 |
return Magic; |
394 |
} |
395 |
} |
396 |
|
397 |
[StructLayout(LayoutKind.Sequential, Pack = 1)] |
398 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
399 |
public struct IMAGE_OPTIONAL_HEADER64 |
400 |
{ |
401 |
public UInt16 _Magic; |
402 |
public Byte _MajorLinkerVersion; |
403 |
public Byte _MinorLinkerVersion; |
404 |
public UInt32 _SizeOfCode; |
405 |
public UInt32 _SizeOfInitializedData; |
406 |
public UInt32 _SizeOfUninitializedData; |
407 |
public UInt32 _AddressOfEntryPoint; |
408 |
public UInt32 _BaseOfCode; |
409 |
public UInt64 _ImageBase; |
410 |
public UInt32 _SectionAlignment; |
411 |
public UInt32 _FileAlignment; |
412 |
public UInt16 _MajorOperatingSystemVersion; |
413 |
public UInt16 _MinorOperatingSystemVersion; |
414 |
public UInt16 _MajorImageVersion; |
415 |
public UInt16 _MinorImageVersion; |
416 |
public UInt16 _MajorSubsystemVersion; |
417 |
public UInt16 _MinorSubsystemVersion; |
418 |
public UInt32 _Win32VersionValue; |
419 |
public UInt32 _SizeOfImage; |
420 |
public UInt32 _SizeOfHeaders; |
421 |
public UInt32 _CheckSum; |
422 |
public UInt16 _Subsystem; |
423 |
public DllCharacteristicsType _DllCharacteristics; |
424 |
public UInt64 _SizeOfStackReserve; |
425 |
public UInt64 _SizeOfStackCommit; |
426 |
public UInt64 _SizeOfHeapReserve; |
427 |
public UInt64 _SizeOfHeapCommit; |
428 |
public UInt32 _LoaderFlags; |
429 |
public UInt32 _NumberOfRvaAndSizes; |
430 |
|
431 |
public DATA_DIRECTORIES _DATA_DIRECTORIES; |
432 |
|
433 |
|
434 |
public string Magic { get { return ((MagicType)_Magic).ToString(); } } |
435 |
public string MajorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } } |
436 |
public string MinorLinkerVersion { get { return string.Format("0x{0:x2}", _MajorLinkerVersion); } } |
437 |
|
438 |
public string SizeOfCode { get { return string.Format("0x{0:x2}", _SizeOfCode); } } |
439 |
public string SizeOfInitializedData { get { return string.Format("0x{0:x8}", _SizeOfInitializedData); } } |
440 |
public string SizeOfUninitializedData { get { return string.Format("0x{0:x8}", _SizeOfUninitializedData); } } |
441 |
public string AddressOfEntryPoint { get { return string.Format("0x{0:x8}", _AddressOfEntryPoint); } } |
442 |
public string BaseOfCode { get { return string.Format("0x{0:x8}", _BaseOfCode); } } |
443 |
public string ImageBase { get { return string.Format("0x{0:x16}", _ImageBase); } } |
444 |
public string SectionAlignment { get { return string.Format("0x{0:x8}", _SectionAlignment); } } |
445 |
public string FileAlignment { get { return string.Format("0x{0:x8}", _FileAlignment); } } |
446 |
|
447 |
public string MajorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MajorOperatingSystemVersion); } } |
448 |
public string MinorOperatingSystemVersion { get { return string.Format("0x{0:x4}", _MinorOperatingSystemVersion); } } |
449 |
public string MajorImageVersion { get { return string.Format("0x{0:x4}", _MajorImageVersion); } } |
450 |
public string MinorImageVersion { get { return string.Format("0x{0:x4}", _MinorImageVersion); } } |
451 |
public string MajorSubsystemVersion { get { return string.Format("0x{0:x4}", _MajorSubsystemVersion); } } |
452 |
public string MinorSubsystemVersion { get { return string.Format("0x{0:x4}", _MinorSubsystemVersion); } } |
453 |
|
454 |
public string Win32VersionValue { get { return string.Format("0x{0:x8}", _Win32VersionValue); } } |
455 |
public string SizeOfImage { get { return string.Format("0x{0:x8}", _SizeOfImage); } } |
456 |
public string SizeOfHeaders { get { return string.Format("0x{0:x8}", _SizeOfHeaders); } } |
457 |
public string CheckSum { get { return string.Format("0x{0:x8}", _CheckSum); } } |
458 |
|
459 |
public string Subsystem { get { return ((SubSystemType)_Subsystem).ToString(); } } |
460 |
public string DllCharacteristics { get { return string.Format("{0}", _DllCharacteristics); } } |
461 |
|
462 |
public string SizeOfStackReserve { get { return string.Format("0x{0:x16}", _SizeOfStackReserve); } } |
463 |
public string SizeOfStackCommit { get { return string.Format("0x{0:x16}", _SizeOfStackCommit); } } |
464 |
public string SizeOfHeapReserve { get { return string.Format("0x{0:x16}", _SizeOfHeapReserve); } } |
465 |
public string SizeOfHeapCommit { get { return string.Format("0x{0:x16}", _SizeOfHeapCommit); } } |
466 |
|
467 |
public string LoaderFlags { get { return string.Format("0x{0:x8}", _LoaderFlags); } } |
468 |
public string NumberOfRvaAndSizes { get { return string.Format("0x{0:x8}", _NumberOfRvaAndSizes); } } |
469 |
|
470 |
public DATA_DIRECTORIES DATA_DIRECTORIES { get { return _DATA_DIRECTORIES; } } |
471 |
|
472 |
|
473 |
public override string ToString() |
474 |
{ |
475 |
return Magic; |
476 |
} |
477 |
|
478 |
} |
479 |
|
480 |
[StructLayout(LayoutKind.Sequential, Pack = 1)] |
481 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
482 |
public struct IMAGE_FILE_HEADER |
483 |
{ |
484 |
public MachineTypeFlags _Machine; |
485 |
public UInt16 _NumberOfSections; |
486 |
public UInt32 _TimeDateStamp; |
487 |
public UInt32 _PointerToSymbolTable; |
488 |
public UInt32 _NumberOfSymbols; |
489 |
public UInt16 _SizeOfOptionalHeader; |
490 |
public FileCharacteristicType _Characteristics; |
491 |
|
492 |
public MachineTypeFlags MachineType { get { return _Machine; } } |
493 |
public string NumberOfSections { get { return string.Format("0x{0:x4}", _NumberOfSections); } } |
494 |
public string TimeDateStamp { get { return string.Format("{0} (0x{1:x8})", GetDateTimeFromLinkerTime(_TimeDateStamp).ToString(), _TimeDateStamp); } } |
495 |
public string PointerToSymbolTable { get { return string.Format("0x{0:x8}", _PointerToSymbolTable); } } |
496 |
public string NumberOfSymbols { get { return string.Format("0x{0:x8}", _NumberOfSymbols); } } |
497 |
public string SizeOfOptionalHeader { get { return string.Format("0x{0:x4}", _SizeOfOptionalHeader); } } |
498 |
public FileCharacteristicType Characteristics { get { return _Characteristics; } } |
499 |
public override string ToString() |
500 |
{ |
501 |
return MachineType.ToString(); |
502 |
} |
503 |
|
504 |
private DateTime GetDateTimeFromLinkerTime(UInt32 linker_timer) |
505 |
{ |
506 |
// http://msdn.microsoft.com/en-us/library/ms809762.aspx |
507 |
// This field holds the number of seconds since December 31st, 1969, at 4:00 P.M. |
508 |
DateTime t = new DateTime(1969, 12, 31, 16, 0, 0); |
509 |
t = t.AddSeconds(linker_timer); |
510 |
t += TimeZone.CurrentTimeZone.GetUtcOffset(t); |
511 |
return t; |
512 |
} |
513 |
} |
514 |
|
515 |
// Grabbed the following 2 definitions from http://www.pinvoke.net/default.aspx/Structures/IMAGE_SECTION_HEADER.html |
516 |
|
517 |
[TypeConverter(typeof(ExpandableObjectConverter))] |
518 |
[StructLayout(LayoutKind.Explicit)] |
519 |
public struct IMAGE_SECTION_HEADER |
520 |
{ |
521 |
[FieldOffset(0)] |
522 |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] |
523 |
public string _Name; |
524 |
[FieldOffset(8)] |
525 |
public UInt32 _VirtualSize; |
526 |
[FieldOffset(12)] |
527 |
public UInt32 _VirtualAddress; |
528 |
[FieldOffset(16)] |
529 |
public UInt32 _SizeOfRawData; |
530 |
[FieldOffset(20)] |
531 |
public UInt32 _PointerToRawData; |
532 |
[FieldOffset(24)] |
533 |
public UInt32 _PointerToRelocations; |
534 |
[FieldOffset(28)] |
535 |
public UInt32 _PointerToLinenumbers; |
536 |
[FieldOffset(32)] |
537 |
public UInt16 _NumberOfRelocations; |
538 |
[FieldOffset(34)] |
539 |
public UInt16 _NumberOfLinenumbers; |
540 |
[FieldOffset(36)] |
541 |
public DataSectionFlags _Characteristics; |
542 |
|
543 |
public string Name { get { if (_Name == null || _Name.Length == 0) { return string.Empty; } else { return _Name; } } } |
544 |
//public Misc Misc { get { return _Misc; } } |
545 |
public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } } |
546 |
public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } } |
547 |
[Browsable(false)] |
548 |
public UInt32 _VirtualAddressEnd { get { return _VirtualAddress + _VirtualSize; } } |
549 |
public string VirtualAddressEnd { get { return string.Format("0x{0:x8}", _VirtualAddressEnd); } } |
550 |
|
551 |
public string SizeOfRawData { get { return string.Format("0x{0:x8}", _SizeOfRawData); } } |
552 |
public string PointerToRawData { get { return string.Format("0x{0:x8}", _PointerToRawData); } } |
553 |
public string PointerToRelocations { get { return string.Format("0x{0:x8}", _PointerToRelocations); } } |
554 |
public string PointerToLinenumbers { get { return string.Format("0x{0:x8}", _PointerToLinenumbers); } } |
555 |
public string NumberOfRelocations { get { return string.Format("0x{0:x4}", _NumberOfRelocations); } } |
556 |
public string NumberOfLinenumbers { get { return string.Format("0x{0:x4}", _NumberOfLinenumbers); } } |
557 |
public string Characteristics { get { return _Characteristics.ToString(); } } |
558 |
|
559 |
public override string ToString() |
560 |
{ |
561 |
return Name; |
562 |
} |
563 |
} |
564 |
#endregion File Header Structures |
565 |
|
566 |
|
567 |
#region code |
568 |
#region helpers |
569 |
[Flags] |
570 |
public enum MachineTypeFlags : ushort |
571 |
{ |
572 |
x86 = 0x14C, |
573 |
Alpha = 0x184, |
574 |
ARM = 0x1C0, |
575 |
MIPS16R3000 = 0x162, |
576 |
MIPS16R4000 = 0x166, |
577 |
MIPS16R10000 = 0x168, |
578 |
PowerPCLE = 0x1F0, |
579 |
PowerPCBE = 0x1F2, |
580 |
Itanium = 0x200, |
581 |
MIPS16 = 0x266, |
582 |
Alpha64 = 0x284, |
583 |
MIPSFPU = 0x366, |
584 |
MIPSFPU16 = 0x466, |
585 |
x64 = 0x8664, |
586 |
} |
587 |
public enum MagicType : ushort |
588 |
{ |
589 |
NT_OPTIONAL_HEADER_NOT_PRESENT, // 0 |
590 |
NT_OPTIONAL_HEADER_32 = 0x10b, |
591 |
NT_OPTIONAL_HEADER_64 = 0x20b |
592 |
} |
593 |
public enum SubSystemType : ushort |
594 |
{ |
595 |
IMAGE_SUBSYSTEM_UNKNOWN = 0, |
596 |
IMAGE_SUBSYSTEM_NATIVE = 1, |
597 |
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, |
598 |
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, |
599 |
IMAGE_SUBSYSTEM_POSIX_CUI = 7, |
600 |
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, |
601 |
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, |
602 |
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, |
603 |
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, |
604 |
IMAGE_SUBSYSTEM_EFI_ROM = 13, |
605 |
IMAGE_SUBSYSTEM_XBOX = 14 |
606 |
|
607 |
} |
608 |
[Flags] |
609 |
public enum DllCharacteristicsType : ushort |
610 |
{ |
611 |
RES_0 = 0x0001, |
612 |
RES_1 = 0x0002, |
613 |
RES_2 = 0x0004, |
614 |
RES_3 = 0x0008, |
615 |
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040, |
616 |
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080, |
617 |
IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, |
618 |
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200, |
619 |
IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400, |
620 |
IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800, |
621 |
RES_4 = 0x1000, |
622 |
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000, |
623 |
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 |
624 |
} |
625 |
[Flags] |
626 |
public enum FileCharacteristicType : ushort |
627 |
{ |
628 |
RelocationInformationStrippedFromFile = 0x1, |
629 |
Executable = 0x2, |
630 |
LineNumbersStripped = 0x4, |
631 |
SymbolTableStripped = 0x8, |
632 |
AggresiveTrimWorkingSet = 0x10, |
633 |
LargeAddressAware = 0x20, |
634 |
Supports16Bit = 0x40, |
635 |
ReservedBytesWo = 0x80, |
636 |
Supports32Bit = 0x100, |
637 |
DebugInfoStripped = 0x200, |
638 |
RunFromSwapIfInRemovableMedia = 0x400, |
639 |
RunFromSwapIfInNetworkMedia = 0x800, |
640 |
IsSytemFile = 0x1000, |
641 |
IsDLL = 0x2000, |
642 |
IsOnlyForSingleCoreProcessor = 0x4000, |
643 |
BytesOfWordReserved = 0x8000, |
644 |
} |
645 |
#region DataSectionFlags |
646 |
[Flags] |
647 |
public enum DataSectionFlags : uint |
648 |
{ |
649 |
/// <summary> |
650 |
/// Reserved for future use. |
651 |
/// </summary> |
652 |
TypeReg = 0x00000000, |
653 |
/// <summary> |
654 |
/// Reserved for future use. |
655 |
/// </summary> |
656 |
TypeDsect = 0x00000001, |
657 |
/// <summary> |
658 |
/// Reserved for future use. |
659 |
/// </summary> |
660 |
TypeNoLoad = 0x00000002, |
661 |
/// <summary> |
662 |
/// Reserved for future use. |
663 |
/// </summary> |
664 |
TypeGroup = 0x00000004, |
665 |
/// <summary> |
666 |
/// 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. |
667 |
/// </summary> |
668 |
TypeNoPadded = 0x00000008, |
669 |
/// <summary> |
670 |
/// Reserved for future use. |
671 |
/// </summary> |
672 |
TypeCopy = 0x00000010, |
673 |
/// <summary> |
674 |
/// The section contains executable code. |
675 |
/// </summary> |
676 |
ContentCode = 0x00000020, |
677 |
/// <summary> |
678 |
/// The section contains initialized data. |
679 |
/// </summary> |
680 |
ContentInitializedData = 0x00000040, |
681 |
/// <summary> |
682 |
/// The section contains uninitialized data. |
683 |
/// </summary> |
684 |
ContentUninitializedData = 0x00000080, |
685 |
/// <summary> |
686 |
/// Reserved for future use. |
687 |
/// </summary> |
688 |
LinkOther = 0x00000100, |
689 |
/// <summary> |
690 |
/// The section contains comments or other information. The .drectve section has this type. This is valid for object files only. |
691 |
/// </summary> |
692 |
LinkInfo = 0x00000200, |
693 |
/// <summary> |
694 |
/// Reserved for future use. |
695 |
/// </summary> |
696 |
TypeOver = 0x00000400, |
697 |
/// <summary> |
698 |
/// The section will not become part of the image. This is valid only for object files. |
699 |
/// </summary> |
700 |
LinkRemove = 0x00000800, |
701 |
/// <summary> |
702 |
/// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files. |
703 |
/// </summary> |
704 |
LinkComDat = 0x00001000, |
705 |
/// <summary> |
706 |
/// Reset speculative exceptions handling bits in the TLB entries for this section. |
707 |
/// </summary> |
708 |
NoDeferSpecExceptions = 0x00004000, |
709 |
/// <summary> |
710 |
/// The section contains data referenced through the global pointer (GP). |
711 |
/// </summary> |
712 |
RelativeGP = 0x00008000, |
713 |
/// <summary> |
714 |
/// Reserved for future use. |
715 |
/// </summary> |
716 |
MemPurgeable = 0x00020000, |
717 |
/// <summary> |
718 |
/// Reserved for future use. |
719 |
/// </summary> |
720 |
Memory16Bit = 0x00020000, |
721 |
/// <summary> |
722 |
/// Reserved for future use. |
723 |
/// </summary> |
724 |
MemoryLocked = 0x00040000, |
725 |
/// <summary> |
726 |
/// Reserved for future use. |
727 |
/// </summary> |
728 |
MemoryPreload = 0x00080000, |
729 |
/// <summary> |
730 |
/// Align data on a 1-byte boundary. Valid only for object files. |
731 |
/// </summary> |
732 |
Align1Bytes = 0x00100000, |
733 |
/// <summary> |
734 |
/// Align data on a 2-byte boundary. Valid only for object files. |
735 |
/// </summary> |
736 |
Align2Bytes = 0x00200000, |
737 |
/// <summary> |
738 |
/// Align data on a 4-byte boundary. Valid only for object files. |
739 |
/// </summary> |
740 |
Align4Bytes = 0x00300000, |
741 |
/// <summary> |
742 |
/// Align data on an 8-byte boundary. Valid only for object files. |
743 |
/// </summary> |
744 |
Align8Bytes = 0x00400000, |
745 |
/// <summary> |
746 |
/// Align data on a 16-byte boundary. Valid only for object files. |
747 |
/// </summary> |
748 |
Align16Bytes = 0x00500000, |
749 |
/// <summary> |
750 |
/// Align data on a 32-byte boundary. Valid only for object files. |
751 |
/// </summary> |
752 |
Align32Bytes = 0x00600000, |
753 |
/// <summary> |
754 |
/// Align data on a 64-byte boundary. Valid only for object files. |
755 |
/// </summary> |
756 |
Align64Bytes = 0x00700000, |
757 |
/// <summary> |
758 |
/// Align data on a 128-byte boundary. Valid only for object files. |
759 |
/// </summary> |
760 |
Align128Bytes = 0x00800000, |
761 |
/// <summary> |
762 |
/// Align data on a 256-byte boundary. Valid only for object files. |
763 |
/// </summary> |
764 |
Align256Bytes = 0x00900000, |
765 |
/// <summary> |
766 |
/// Align data on a 512-byte boundary. Valid only for object files. |
767 |
/// </summary> |
768 |
Align512Bytes = 0x00A00000, |
769 |
/// <summary> |
770 |
/// Align data on a 1024-byte boundary. Valid only for object files. |
771 |
/// </summary> |
772 |
Align1024Bytes = 0x00B00000, |
773 |
/// <summary> |
774 |
/// Align data on a 2048-byte boundary. Valid only for object files. |
775 |
/// </summary> |
776 |
Align2048Bytes = 0x00C00000, |
777 |
/// <summary> |
778 |
/// Align data on a 4096-byte boundary. Valid only for object files. |
779 |
/// </summary> |
780 |
Align4096Bytes = 0x00D00000, |
781 |
/// <summary> |
782 |
/// Align data on an 8192-byte boundary. Valid only for object files. |
783 |
/// </summary> |
784 |
Align8192Bytes = 0x00E00000, |
785 |
/// <summary> |
786 |
/// The section contains extended relocations. |
787 |
/// </summary> |
788 |
LinkExtendedRelocationOverflow = 0x01000000, |
789 |
/// <summary> |
790 |
/// The section can be discarded as needed. |
791 |
/// </summary> |
792 |
MemoryDiscardable = 0x02000000, |
793 |
/// <summary> |
794 |
/// The section cannot be cached. |
795 |
/// </summary> |
796 |
MemoryNotCached = 0x04000000, |
797 |
/// <summary> |
798 |
/// The section is not pageable. |
799 |
/// </summary> |
800 |
MemoryNotPaged = 0x08000000, |
801 |
/// <summary> |
802 |
/// The section can be shared in memory. |
803 |
/// </summary> |
804 |
MemoryShared = 0x10000000, |
805 |
/// <summary> |
806 |
/// The section can be executed as code. |
807 |
/// </summary> |
808 |
MemoryExecute = 0x20000000, |
809 |
/// <summary> |
810 |
/// The section can be read. |
811 |
/// </summary> |
812 |
MemoryRead = 0x40000000, |
813 |
/// <summary> |
814 |
/// The section can be written to. |
815 |
/// </summary> |
816 |
MemoryWrite = 0x80000000 |
817 |
} |
818 |
#endregion |
819 |
#endregion |
820 |
/// <summary> |
821 |
/// Reads in the header information of the Portable Executable format. |
822 |
/// Provides information such as the date the assembly was compiled. |
823 |
/// </summary> |
824 |
public class PeHeaderReader |
825 |
{ |
826 |
|
827 |
|
828 |
#region Private Fields |
829 |
|
830 |
private UInt32 ntSignature; |
831 |
/// <summary> |
832 |
/// The DOS header |
833 |
/// </summary> |
834 |
private IMAGE_DOS_HEADER dosHeader; |
835 |
/// <summary> |
836 |
/// The file header |
837 |
/// </summary> |
838 |
private IMAGE_FILE_HEADER fileHeader; |
839 |
/// <summary> |
840 |
/// Optional 32 bit file header |
841 |
/// </summary> |
842 |
private IMAGE_OPTIONAL_HEADER32 optionalHeader32; |
843 |
/// <summary> |
844 |
/// Optional 64 bit file header |
845 |
/// </summary> |
846 |
private IMAGE_OPTIONAL_HEADER64 optionalHeader64; |
847 |
/// <summary> |
848 |
/// Image Section headers. Number of sections is in the file header. |
849 |
/// </summary> |
850 |
private IMAGE_SECTION_HEADER[] imageSectionHeaders; |
851 |
|
852 |
#endregion Private Fields |
853 |
|
854 |
#region Public Methods |
855 |
|
856 |
public PeHeaderReader(Process p) |
857 |
{ |
858 |
string filePath = p.MainModule.FileName; |
859 |
// Read in the DLL or EXE and get the timestamp |
860 |
using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) |
861 |
{ |
862 |
BinaryReader reader = new BinaryReader(stream); |
863 |
dosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(reader); |
864 |
|
865 |
// Add 4 bytes to the offset |
866 |
stream.Seek(dosHeader._e_lfanew, SeekOrigin.Begin); |
867 |
|
868 |
UInt32 ntHeadersSignature = reader.ReadUInt32(); |
869 |
ntSignature = ntHeadersSignature; |
870 |
fileHeader = FromBinaryReader<IMAGE_FILE_HEADER>(reader); |
871 |
if (this.Is32BitHeader) |
872 |
{ |
873 |
optionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(reader); |
874 |
//optionalHeader32._VirtualEntryPoint = (uint)p.MainModule.EntryPointAddress; |
875 |
//optionalHeader32._VirtualImageBase = (uint)p.MainModule.BaseAddress; |
876 |
} |
877 |
else |
878 |
{ |
879 |
optionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(reader); |
880 |
//optionalHeader64._VirtualEntryPoint = (uint)p.MainModule.EntryPointAddress; |
881 |
//optionalHeader64._VirtualImageBase = (ulong)p.MainModule.BaseAddress; |
882 |
} |
883 |
|
884 |
imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader._NumberOfSections]; |
885 |
for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) |
886 |
{ |
887 |
imageSectionHeaders[headerNo] = FromBinaryReader<IMAGE_SECTION_HEADER>(reader); |
888 |
} |
889 |
|
890 |
} |
891 |
} |
892 |
|
893 |
///// <summary> |
894 |
///// Gets the header of the .NET assembly that called this function |
895 |
///// </summary> |
896 |
///// <returns></returns> |
897 |
//public static PeHeaderReader GetCallingAssemblyHeader() |
898 |
//{ |
899 |
// // Get the path to the calling assembly, which is the path to the |
900 |
// // DLL or EXE that we want the time of |
901 |
// string filePath = System.Reflection.Assembly.GetCallingAssembly().Location; |
902 |
|
903 |
// // Get and return the timestamp |
904 |
// return new PeHeaderReader(filePath); |
905 |
//} |
906 |
|
907 |
///// <summary> |
908 |
///// Gets the header of the .NET assembly that called this function |
909 |
///// </summary> |
910 |
///// <returns></returns> |
911 |
//public static PeHeaderReader GetAssemblyHeader() |
912 |
//{ |
913 |
// // Get the path to the calling assembly, which is the path to the |
914 |
// // DLL or EXE that we want the time of |
915 |
// string filePath = System.Reflection.Assembly.GetAssembly(typeof(PeHeaderReader)).Location; |
916 |
|
917 |
// // Get and return the timestamp |
918 |
// return new PeHeaderReader(filePath); |
919 |
//} |
920 |
|
921 |
/// <summary> |
922 |
/// Reads in a block from a file and converts it to the struct |
923 |
/// type specified by the template parameter |
924 |
/// </summary> |
925 |
/// <typeparam name="T"></typeparam> |
926 |
/// <param name="reader"></param> |
927 |
/// <returns></returns> |
928 |
public static T FromBinaryReader<T>(BinaryReader reader) |
929 |
{ |
930 |
// Read in a byte array |
931 |
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T))); |
932 |
|
933 |
// Pin the managed memory while, copy it out the data, then unpin it |
934 |
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); |
935 |
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); |
936 |
handle.Free(); |
937 |
|
938 |
return theStructure; |
939 |
} |
940 |
|
941 |
#endregion Public Methods |
942 |
|
943 |
#region Properties |
944 |
|
945 |
/// <summary> |
946 |
/// Gets if the file header is 32 bit or not |
947 |
/// </summary> |
948 |
public bool Is32BitHeader |
949 |
{ |
950 |
get |
951 |
{ |
952 |
return FileHeader.Characteristics.HasFlag(FileCharacteristicType.Supports32Bit); |
953 |
} |
954 |
} |
955 |
|
956 |
/// <summary> |
957 |
/// Gets the file header |
958 |
/// </summary> |
959 |
public IMAGE_FILE_HEADER FileHeader |
960 |
{ |
961 |
get |
962 |
{ |
963 |
return fileHeader; |
964 |
} |
965 |
} |
966 |
/// <summary> |
967 |
/// Gets the file header |
968 |
/// </summary> |
969 |
public string NTSignature |
970 |
{ |
971 |
get |
972 |
{ |
973 |
ushort sig = (ushort)ntSignature; |
974 |
return string.Format("0x{0:x4} [{1}]", sig, Encoding.ASCII.GetString(BitConverter.GetBytes(sig))); |
975 |
} |
976 |
} |
977 |
/// <summary> |
978 |
/// Gets the file header |
979 |
/// </summary> |
980 |
public IMAGE_DOS_HEADER DosHeader |
981 |
{ |
982 |
get |
983 |
{ |
984 |
return dosHeader; |
985 |
} |
986 |
} |
987 |
/// <summary> |
988 |
/// Gets the optional header |
989 |
/// </summary> |
990 |
public IMAGE_OPTIONAL_HEADER32 OptionalHeader32 |
991 |
{ |
992 |
get |
993 |
{ |
994 |
return optionalHeader32; |
995 |
} |
996 |
} |
997 |
|
998 |
/// <summary> |
999 |
/// Gets the optional header |
1000 |
/// </summary> |
1001 |
public IMAGE_OPTIONAL_HEADER64 OptionalHeader64 |
1002 |
{ |
1003 |
get |
1004 |
{ |
1005 |
return optionalHeader64; |
1006 |
} |
1007 |
} |
1008 |
|
1009 |
public IMAGE_SECTION_HEADER[] ImageSectionHeaders |
1010 |
{ |
1011 |
get |
1012 |
{ |
1013 |
return imageSectionHeaders; |
1014 |
} |
1015 |
} |
1016 |
|
1017 |
///// <summary> |
1018 |
///// Gets the timestamp from the file header |
1019 |
///// </summary> |
1020 |
//public DateTime TimeStamp |
1021 |
//{ |
1022 |
// get |
1023 |
// { |
1024 |
// // Timestamp is a date offset from 1970 |
1025 |
// DateTime returnValue = new DateTime(1970, 1, 1, 0, 0, 0); |
1026 |
|
1027 |
// // Add in the number of seconds since 1970/1/1 |
1028 |
// returnValue = returnValue.AddSeconds(fileHeader.TimeDateStamp); |
1029 |
// // Adjust to local timezone |
1030 |
// returnValue += TimeZone.CurrentTimeZone.GetUtcOffset(returnValue); |
1031 |
|
1032 |
// return returnValue; |
1033 |
// } |
1034 |
//} |
1035 |
|
1036 |
#endregion Properties |
1037 |
} |
1038 |
#endregion |
1039 |
} |