ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/PEReader.cs
(Generate patch)

Comparing trunk/Win32/Sojaner.MemoryScanner/PEReader.cs (file contents):
Revision 293 by william, Tue Jun 5 10:27:16 2012 UTC vs.
Revision 294 by william, Tue Jun 5 10:48:07 2012 UTC

# Line 11 | Line 11 | 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)
14 >        // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
15 >        #region Structs
16 >        [StructLayout(LayoutKind.Sequential)]
17 >        public struct IMAGE_DOS_HEADER
18          {
19 <            ErrorInfo = null;
20 <            try
21 <            {
22 <                logger.Debug.WriteLine("Reading Exe: {0}", filename);
23 <
24 <                using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
25 <                {
26 <                    try
27 <                    {
28 <                        byte[] data = new byte[] { };
29 <                        GCHandle pinnedPacket = new GCHandle();
30 <                        int size = 0;
31 <                        BinaryReader br = new BinaryReader(fs);
32 <
33 <                        #region IMAGE_DOS_HEADER
34 <                        size = Marshal.SizeOf(typeof(IMAGE_DOS_HEADER));
35 <                        data = br.ReadBytes(size);
36 <                        pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
37 <                        IMAGE_DOS_HEADER DOS_HEADER = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_DOS_HEADER));
38 <                        pinnedPacket.Free();
39 <                        #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 <            }
19 >            public UInt16 e_magic;
20 >            public UInt16 e_cblp;
21 >            public UInt16 e_cp;
22 >            public UInt16 e_crlc;
23 >            public UInt16 e_cparhdr;
24 >            public UInt16 e_minalloc;
25 >            public UInt16 e_maxalloc;
26 >            public UInt16 e_ss;
27 >            public UInt16 e_sp;
28 >            public UInt16 e_csum;
29 >            public UInt16 e_ip;
30 >            public UInt16 e_cs;
31 >            public UInt16 e_lfarlc;
32 >            public UInt16 e_ovno;
33 >            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
34 >            public UInt16[] e_res1;
35 >            public UInt16 e_oemid;
36 >            public UInt16 e_oeminfo;
37 >            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
38 >            public UInt16[] e_res2;
39 >            public UInt32 e_lfanew;
40          }
102        #endregion
41  
104        #region header support
105        #region IMAGE_DATA_DIRECTORY
42          [StructLayout(LayoutKind.Sequential)]
43 <        public struct IMAGE_DATA_DIRECTORY
43 >        public struct IMAGE_NT_HEADERS
44          {
45 <            public UInt32 VirtualAddress;
46 <            public UInt32 Size;
47 <            public bool HasAddress { get { return (VirtualAddress != 0); } }
48 <            public bool HasSize { get { return (Size > 0); } }
45 >            public UInt32 Signature;
46 >            public IMAGE_FILE_HEADER FileHeader;
47 >            public IMAGE_OPTIONAL_HEADER32 OptionalHeader32;
48 >            public IMAGE_OPTIONAL_HEADER64 OptionalHeader64;
49          }
50 <        #endregion
115 <        #region IMAGE_FILE_HEADER
50 >
51          [StructLayout(LayoutKind.Sequential)]
52          public struct IMAGE_FILE_HEADER
53          {
54 <            public MachineType Machine;
54 >            public UInt16 Machine;
55              public UInt16 NumberOfSections;
56              public UInt32 TimeDateStamp;
57              public UInt32 PointerToSymbolTable;
58              public UInt32 NumberOfSymbols;
59              public UInt16 SizeOfOptionalHeader;
60 <            public DllCharacteristicsType Characteristics;
60 >            public UInt16 Characteristics;
61          }
62 <        #endregion
128 <        #region IMAGE_DOS_HEADER
62 >
63          [StructLayout(LayoutKind.Sequential)]
64 <        public struct IMAGE_DOS_HEADER
64 >        public struct IMAGE_OPTIONAL_HEADER32
65          {
66 <            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
67 <            public char[] e_magic;       // Magic number
68 <            public UInt16 e_cblp;    // Bytes on last page of file
69 <            public UInt16 e_cp;      // Pages in file
70 <            public UInt16 e_crlc;    // Relocations
71 <            public UInt16 e_cparhdr;     // Size of header in paragraphs
72 <            public UInt16 e_minalloc;    // Minimum extra paragraphs needed
73 <            public UInt16 e_maxalloc;    // Maximum extra paragraphs needed
74 <            public UInt16 e_ss;      // Initial (relative) SS value
75 <            public UInt16 e_sp;      // Initial SP value
76 <            public UInt16 e_csum;    // Checksum
77 <            public UInt16 e_ip;      // Initial IP value
78 <            public UInt16 e_cs;      // Initial (relative) CS value
79 <            public UInt16 e_lfarlc;      // File address of relocation table
80 <            public UInt16 e_ovno;    // Overlay number
81 <            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
82 <            public UInt16[] e_res1;    // Reserved words
83 <            public UInt16 e_oemid;       // OEM identifier (for e_oeminfo)
84 <            public UInt16 e_oeminfo;     // OEM information; e_oemid specific
85 <            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
86 <            public UInt16[] e_res2;    // Reserved words
87 <            public Int32 e_lfanew;      // File address of new exe header
88 <            private string _e_magic
89 <            {
90 <                get { return new string(e_magic); }
91 <            }
92 <            public bool isValid
93 <            {
94 <                get { return _e_magic == "MZ"; }
95 <            }
66 >            public UInt16 Magic;
67 >            public Byte MajorLinkerVersion;
68 >            public Byte MinorLinkerVersion;
69 >            public UInt32 SizeOfCode;
70 >            public UInt32 SizeOfInitializedData;
71 >            public UInt32 SizeOfUninitializedData;
72 >            public UInt32 AddressOfEntryPoint;
73 >            public UInt32 BaseOfCode;
74 >            public UInt32 BaseOfData;
75 >            public UInt32 ImageBase;
76 >            public UInt32 SectionAlignment;
77 >            public UInt32 FileAlignment;
78 >            public UInt16 MajorOperatingSystemVersion;
79 >            public UInt16 MinorOperatingSystemVersion;
80 >            public UInt16 MajorImageVersion;
81 >            public UInt16 MinorImageVersion;
82 >            public UInt16 MajorSubsystemVersion;
83 >            public UInt16 MinorSubsystemVersion;
84 >            public UInt32 Win32VersionValue;
85 >            public UInt32 SizeOfImage;
86 >            public UInt32 SizeOfHeaders;
87 >            public UInt32 CheckSum;
88 >            public UInt16 Subsystem;
89 >            public UInt16 DllCharacteristics;
90 >            public UInt32 SizeOfStackReserve;
91 >            public UInt32 SizeOfStackCommit;
92 >            public UInt32 SizeOfHeapReserve;
93 >            public UInt32 SizeOfHeapCommit;
94 >            public UInt32 LoaderFlags;
95 >            public UInt32 NumberOfRvaAndSizes;
96 >            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
97 >            public IMAGE_DATA_DIRECTORY[] DataDirectory;
98          }
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            }
99  
100 <            public bool isValid
101 <            {
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
100 >        [StructLayout(LayoutKind.Sequential)]
101 >        public struct IMAGE_OPTIONAL_HEADER64
102          {
103 <            Native = 0,
104 <            I386 = 0x014c,
105 <            Itanium = 0x0200,
106 <            x64 = 0x8664
103 >            public UInt16 Magic;
104 >            public Byte MajorLinkerVersion;
105 >            public Byte MinorLinkerVersion;
106 >            public UInt32 SizeOfCode;
107 >            public UInt32 SizeOfInitializedData;
108 >            public UInt32 SizeOfUninitializedData;
109 >            public UInt32 AddressOfEntryPoint;
110 >            public UInt32 BaseOfCode;
111 >            public UInt64 ImageBase;
112 >            public UInt32 SectionAlignment;
113 >            public UInt32 FileAlignment;
114 >            public UInt16 MajorOperatingSystemVersion;
115 >            public UInt16 MinorOperatingSystemVersion;
116 >            public UInt16 MajorImageVersion;
117 >            public UInt16 MinorImageVersion;
118 >            public UInt16 MajorSubsystemVersion;
119 >            public UInt16 MinorSubsystemVersion;
120 >            public UInt32 Win32VersionValue;
121 >            public UInt32 SizeOfImage;
122 >            public UInt32 SizeOfHeaders;
123 >            public UInt32 CheckSum;
124 >            public UInt16 Subsystem;
125 >            public UInt16 DllCharacteristics;
126 >            public UInt64 SizeOfStackReserve;
127 >            public UInt64 SizeOfStackCommit;
128 >            public UInt64 SizeOfHeapReserve;
129 >            public UInt64 SizeOfHeapCommit;
130 >            public UInt32 LoaderFlags;
131 >            public UInt32 NumberOfRvaAndSizes;
132 >            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
133 >            public IMAGE_DATA_DIRECTORY[] DataDirectory;
134          }
135 <        #endregion
136 <        #region MagicType
137 <        public enum MagicType : ushort
135 >
136 >        [StructLayout(LayoutKind.Sequential)]
137 >        public struct IMAGE_DATA_DIRECTORY
138          {
139 <            IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
140 <            IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
139 >            public UInt32 VirtualAddress;
140 >            public UInt32 Size;
141          }
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
142  
143 +        [StructLayout(LayoutKind.Sequential)]
144 +        public struct IMAGE_SECTION_HEADER
145 +        {
146 +            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
147 +            public string Name;
148 +            public Misc Misc;
149 +            public UInt32 VirtualAddress;
150 +            public UInt32 SizeOfRawData;
151 +            public UInt32 PointerToRawData;
152 +            public UInt32 PointerToRelocations;
153 +            public UInt32 PointerToLinenumbers;
154 +            public UInt16 NumberOfRelocations;
155 +            public UInt16 NumberOfLinenumbers;
156 +            public UInt32 Characteristics;
157          }
158 <        #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
158 >
159          [StructLayout(LayoutKind.Explicit)]
160 <        public struct IMAGE_OPTIONAL_HEADER
160 >        public struct Misc
161          {
162              [FieldOffset(0)]
163 <            public MagicType Magic;
164 <
165 <            [FieldOffset(2)]
166 <            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;
163 >            public UInt32 PhysicalAddress;
164 >            [FieldOffset(0)]
165 >            public UInt32 VirtualSize;
166 >        }
167  
168 <            [FieldOffset(88)]
328 <            public uint LoaderFlags;
168 >        #endregion
169  
170 <            [FieldOffset(92)]
331 <            public uint NumberOfRvaAndSizes;
170 >        #region Fields
171  
172 <            [FieldOffset(96)]
173 <            public IMAGE_DATA_DIRECTORY ExportTable;
172 >        private readonly IMAGE_DOS_HEADER _dosHeader;
173 >        private IMAGE_NT_HEADERS _ntHeaders;
174 >        private readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
175  
176 <            [FieldOffset(104)]
337 <            public IMAGE_DATA_DIRECTORY ImportTable;
176 >        #endregion
177  
178 <            [FieldOffset(112)]
179 <            public IMAGE_DATA_DIRECTORY ResourceTable;
178 >        public PEReader(FileInfo fi) : this(fi.FullName) { }
179 >        public PEReader(string filename)
180 >        {
181 >            Exception ErrorInfo = null;
182 >            using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
183 >            {
184 >                try
185 >                {
186 >                    logger.VerboseDebug.WriteLine("Reading PE Format from: {0}", filename);
187 >                    BinaryReader reader = new BinaryReader(fs);
188 >                    // Reset reader position, just in case
189 >                    reader.BaseStream.Seek(0, SeekOrigin.Begin);
190 >
191 >                    // Read MS-DOS header section
192 >                    _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
193 >                    // MS-DOS magic number should read 'MZ'
194 >                    if (_dosHeader.e_magic != 0x5a4d)
195 >                    {
196 >                        throw new InvalidOperationException("File is not a portable executable.");
197 >                    }
198  
199 <            [FieldOffset(120)]
200 <            public IMAGE_DATA_DIRECTORY ExceptionTable;
199 >                    // Skip MS-DOS stub and seek reader to NT Headers
200 >                    reader.BaseStream.Seek(_dosHeader.e_lfanew, SeekOrigin.Begin);
201  
202 <            [FieldOffset(128)]
203 <            public IMAGE_DATA_DIRECTORY CertificateTable;
202 >                    // Read NT Headers
203 >                    _ntHeaders.Signature = MarshalBytesTo<UInt32>(reader);
204  
205 <            [FieldOffset(136)]
206 <            public IMAGE_DATA_DIRECTORY BaseRelocationTable;
205 >                    // Make sure we have 'PE' in the pe signature
206 >                    if (_ntHeaders.Signature != 0x4550)
207 >                    {
208 >                        throw new InvalidOperationException("Invalid portable executable signature in NT header.");
209 >                    }
210  
211 <            [FieldOffset(144)]
212 <            public IMAGE_DATA_DIRECTORY Debug;
211 >                    _ntHeaders.FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);                    
212 >                    // Read optional headers
213 >                    if (Is32bitAssembly())
214 >                    {
215 >                        logger.VerboseDebug.WriteLine("Detected a 32Bit PE Executable");
216 >                        Load32bitOptionalHeaders(reader);
217 >                    }
218 >                    else
219 >                    {
220 >                        logger.VerboseDebug.WriteLine("Detected a 64Bit PE Executable");
221 >                        Load64bitOptionalHeaders(reader);
222 >                    }
223  
224 <            [FieldOffset(152)]
225 <            public IMAGE_DATA_DIRECTORY Architecture;
224 >                    // Read section data
225 >                    logger.VerboseDebug.WriteLine("Total Section Headers: {0}", _sectionHeaders.Count);
226 >                    foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
227 >                    {
228 >                        int section_index = _sectionHeaders.IndexOf(header) + 1;
229 >                        logger.VerboseDebug.WriteLine("Section Header: {0} of {1}", section_index, _sectionHeaders.Count);
230 >                        logger.VerboseDebug.WriteLine("\tName: {0}", header.Name);
231 >                        logger.VerboseDebug.WriteLine("\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
232 >                        logger.VerboseDebug.WriteLine("\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
233 >                        logger.VerboseDebug.WriteLine("\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
234 >                        logger.VerboseDebug.WriteLine("\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
235 >                        logger.VerboseDebug.WriteLine("\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
236  
237 <            [FieldOffset(160)]
238 <            public IMAGE_DATA_DIRECTORY GlobalPtr;
237 >                        // Skip to beginning of a section
238 >                        reader.BaseStream.Seek(header.PointerToRawData, SeekOrigin.Begin);
239  
240 <            [FieldOffset(168)]
241 <            public IMAGE_DATA_DIRECTORY TLSTable;
240 >                        // Read section data... and do something with it
241 >                        byte[] sectiondata = reader.ReadBytes((int)header.SizeOfRawData);
242 >                    }
243 >                    reader.Close();
244 >                }
245 >                catch (Exception ex)
246 >                {
247 >                    ErrorInfo = ex;
248 >                    throw ErrorInfo;
249 >                }
250 >            }
251 >            if (ErrorInfo != null)
252 >            {
253 >                logger.VerboseError.WriteLine("Error Reading PE Format from: {0}",filename);
254 >                logger.VerboseError.WriteLine(ErrorInfo.ToString());
255 >            }
256 >        }
257  
258 <            [FieldOffset(176)]
259 <            public IMAGE_DATA_DIRECTORY LoadConfigTable;
258 >        public IMAGE_DOS_HEADER GetDOSHeader()
259 >        {
260 >            return _dosHeader;
261 >        }
262  
263 <            [FieldOffset(184)]
264 <            public IMAGE_DATA_DIRECTORY BoundImport;
263 >        public UInt32 GetPESignature()
264 >        {
265 >            return _ntHeaders.Signature;
266 >        }
267  
268 <            [FieldOffset(192)]
269 <            public IMAGE_DATA_DIRECTORY IAT;
268 >        public IMAGE_FILE_HEADER GetFileHeader()
269 >        {
270 >            return _ntHeaders.FileHeader;
271 >        }
272  
273 <            [FieldOffset(200)]
274 <            public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
273 >        public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
274 >        {
275 >            return _ntHeaders.OptionalHeader32;
276 >        }
277  
278 <            [FieldOffset(208)]
279 <            public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
278 >        public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
279 >        {
280 >            return _ntHeaders.OptionalHeader64;
281 >        }
282  
283 <            [FieldOffset(216)]
284 <            public IMAGE_DATA_DIRECTORY Reserved;
283 >        public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
284 >        {
285 >            return _sectionHeaders;
286          }
287 <        #endregion
288 <        #region IMAGE_EXPORT_DIRECTORY
383 <        [StructLayout(LayoutKind.Sequential)]
384 <        public struct IMAGE_EXPORT_DIRECTORY
287 >
288 >        public bool Is32bitAssembly()
289          {
290 <            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
290 >            return ((_ntHeaders.FileHeader.Characteristics & 0x0100) == 0x0100);
291          }
292 <        #endregion
293 <        #endregion
400 <        #region IMAGE_SECTION_HEADER
401 <        [StructLayout(LayoutKind.Explicit)]
402 <        public struct IMAGE_SECTION_HEADER
292 >
293 >        private void Load64bitOptionalHeaders(BinaryReader reader)
294          {
295 <            [FieldOffset(0)]
405 <            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
406 <            public char[] Name;
295 >            _ntHeaders.OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
296  
297 <            [FieldOffset(8)]
298 <            public UInt32 VirtualSize;
297 >            // Should have 10 data directories
298 >            if (_ntHeaders.OptionalHeader64.NumberOfRvaAndSizes != 0x10)
299 >            {
300 >                throw new InvalidOperationException("Invalid number of data directories in NT header");
301 >            }
302  
303 <            [FieldOffset(12)]
304 <            public UInt32 VirtualAddress;
303 >            // Scan data directories and load section headers
304 >            for (int i = 0; i < _ntHeaders.OptionalHeader64.NumberOfRvaAndSizes; i++)
305 >            {
306 >                if (_ntHeaders.OptionalHeader64.DataDirectory[i].Size > 0)
307 >                {
308 >                    _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
309 >                }
310 >            }
311 >        }
312  
313 <            [FieldOffset(16)]
314 <            public UInt32 SizeOfRawData;
313 >        private void Load32bitOptionalHeaders(BinaryReader reader)
314 >        {
315 >            _ntHeaders.OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
316  
317 <            [FieldOffset(20)]
318 <            public UInt32 PointerToRawData;
317 >            // Should have 10 data directories
318 >            if (_ntHeaders.OptionalHeader32.NumberOfRvaAndSizes != 0x10)
319 >            {
320 >                throw new InvalidOperationException("Invalid number of data directories in NT header");
321 >            }
322  
323 <            [FieldOffset(24)]
324 <            public UInt32 PointerToRelocations;
323 >            // Scan data directories and load section headers
324 >            for (int i = 0; i < _ntHeaders.OptionalHeader32.NumberOfRvaAndSizes; i++)
325 >            {
326 >                if (_ntHeaders.OptionalHeader32.DataDirectory[i].Size > 0)
327 >                {
328 >                    _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
329 >                }
330 >            }
331 >        }
332  
333 <            [FieldOffset(28)]
334 <            public UInt32 PointerToLinenumbers;
333 >        private static T MarshalBytesTo<T>(BinaryReader reader)
334 >        {
335 >            // Unmanaged data
336 >            byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
337  
338 <            [FieldOffset(32)]
339 <            public UInt16 NumberOfRelocations;
338 >            // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
339 >            GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
340  
341 <            [FieldOffset(34)]
342 <            public UInt16 NumberOfLinenumbers;
341 >            // Use our previously created pointer to unmanaged data and marshal to the specified type
342 >            T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
343  
344 <            [FieldOffset(36)]
345 <            public DataSectionFlags Characteristics;
344 >            // Deallocate pointer
345 >            handle.Free();
346  
347 <            public string Section
436 <            {
437 <                get { return new string(Name); }
438 <            }
347 >            return theStructure;
348          }
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
349      }
350   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines