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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 293 by william, Tue Jun 5 10:27:16 2012 UTC revision 294 by william, Tue Jun 5 10:48:07 2012 UTC
# Line 11  namespace Sojaner.MemoryScanner Line 11  namespace Sojaner.MemoryScanner
11  {  {
12      public class PEReader      public class PEReader
13      {      {
14          public PEReader(FileInfo fi) : this(fi.FullName) { }          // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
15          public PEReader(string filename)          #region Structs
16          {          [StructLayout(LayoutKind.Sequential)]
17              Exception ErrorInfo = null;          public struct IMAGE_DOS_HEADER
             try  
             {  
                 this.Read(filename, out ErrorInfo);  
             }  
             catch (Exception ex)  
             {  
                 logger.Error.WriteLine("PEReader: Failed to read process: {0}", filename);  
                 if (ErrorInfo != null)  
                 {  
                     //logger.Error.WriteLine(ErrorInfo.GetBaseException().ToString());  
                     throw ErrorInfo;  
                 }  
                 else  
                 {  
                     //logger.Error.WriteLine(ex.GetBaseException().ToString());  
                     throw ex;  
                 }            
             }  
         }  
   
         #region marshalling  
         private void Read(string filename, out Exception ErrorInfo)  
18          {          {
19              ErrorInfo = null;              public UInt16 e_magic;
20              try              public UInt16 e_cblp;
21              {              public UInt16 e_cp;
22                  logger.Debug.WriteLine("Reading Exe: {0}", filename);              public UInt16 e_crlc;
23                public UInt16 e_cparhdr;
24                  using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))              public UInt16 e_minalloc;
25                  {              public UInt16 e_maxalloc;
26                      try              public UInt16 e_ss;
27                      {              public UInt16 e_sp;
28                          byte[] data = new byte[] { };              public UInt16 e_csum;
29                          GCHandle pinnedPacket = new GCHandle();              public UInt16 e_ip;
30                          int size = 0;              public UInt16 e_cs;
31                          BinaryReader br = new BinaryReader(fs);              public UInt16 e_lfarlc;
32                public UInt16 e_ovno;
33                          #region IMAGE_DOS_HEADER              [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
34                          size = Marshal.SizeOf(typeof(IMAGE_DOS_HEADER));              public UInt16[] e_res1;
35                          data = br.ReadBytes(size);              public UInt16 e_oemid;
36                          pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);              public UInt16 e_oeminfo;
37                          IMAGE_DOS_HEADER DOS_HEADER = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_DOS_HEADER));              [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
38                          pinnedPacket.Free();              public UInt16[] e_res2;
39                          #endregion              public UInt32 e_lfanew;
   
                         // skip the old dos stub  
                         br.BaseStream.Seek(DOS_HEADER.e_lfanew, SeekOrigin.Begin);  
   
                         #region IMAGE_NT_HEADERS  
                         size = Marshal.SizeOf(typeof(IMAGE_NT_HEADERS));  
                         data = br.ReadBytes(size);  
                         pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);  
                         IMAGE_NT_HEADERS NT_HEADER = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_NT_HEADERS));  
                         pinnedPacket.Free();  
                         #endregion  
   
                         StringBuilder section_header_string_builder = new StringBuilder();  
                         List<IMAGE_SECTION_HEADER> section_headers = new List<IMAGE_SECTION_HEADER>();  
                         section_header_string_builder.AppendFormat("Section headers:{0}", System.Environment.NewLine);  
                         for (int i = 0; i < NT_HEADER.FileHeader.NumberOfSections; i++)  
                         {  
                             size = Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));  
                             data = br.ReadBytes(size);  
                             pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);  
                             IMAGE_SECTION_HEADER SECTION_HEADER = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_SECTION_HEADER));  
                             section_headers.Add(SECTION_HEADER);  
                             pinnedPacket.Free();  
                             section_header_string_builder.AppendFormat("Section Header: {0}{1}", new string(SECTION_HEADER.Name).Replace("\0",""), System.Environment.NewLine);  
   
                         }  
                         logger.VerboseDebug.WriteLine(section_header_string_builder.ToString());  
                         br.Close();  
                     }  
                     catch (Exception ex)  
                     {  
                         ErrorInfo = ex;  
                     }  
                 }  
             }  
             catch (Exception ex)  
             {  
                 ErrorInfo = ex;  
             }  
40          }          }
         #endregion  
41    
         #region header support  
         #region IMAGE_DATA_DIRECTORY  
42          [StructLayout(LayoutKind.Sequential)]          [StructLayout(LayoutKind.Sequential)]
43          public struct IMAGE_DATA_DIRECTORY          public struct IMAGE_NT_HEADERS
44          {          {
45              public UInt32 VirtualAddress;              public UInt32 Signature;
46              public UInt32 Size;              public IMAGE_FILE_HEADER FileHeader;
47              public bool HasAddress { get { return (VirtualAddress != 0); } }              public IMAGE_OPTIONAL_HEADER32 OptionalHeader32;
48              public bool HasSize { get { return (Size > 0); } }              public IMAGE_OPTIONAL_HEADER64 OptionalHeader64;
49          }          }
50          #endregion  
         #region IMAGE_FILE_HEADER  
51          [StructLayout(LayoutKind.Sequential)]          [StructLayout(LayoutKind.Sequential)]
52          public struct IMAGE_FILE_HEADER          public struct IMAGE_FILE_HEADER
53          {          {
54              public MachineType Machine;              public UInt16 Machine;
55              public UInt16 NumberOfSections;              public UInt16 NumberOfSections;
56              public UInt32 TimeDateStamp;              public UInt32 TimeDateStamp;
57              public UInt32 PointerToSymbolTable;              public UInt32 PointerToSymbolTable;
58              public UInt32 NumberOfSymbols;              public UInt32 NumberOfSymbols;
59              public UInt16 SizeOfOptionalHeader;              public UInt16 SizeOfOptionalHeader;
60              public DllCharacteristicsType Characteristics;              public UInt16 Characteristics;
61          }          }
62          #endregion  
         #region IMAGE_DOS_HEADER  
63          [StructLayout(LayoutKind.Sequential)]          [StructLayout(LayoutKind.Sequential)]
64          public struct IMAGE_DOS_HEADER          public struct IMAGE_OPTIONAL_HEADER32
65          {          {
66              [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]              public UInt16 Magic;
67              public char[] e_magic;       // Magic number              public Byte MajorLinkerVersion;
68              public UInt16 e_cblp;    // Bytes on last page of file              public Byte MinorLinkerVersion;
69              public UInt16 e_cp;      // Pages in file              public UInt32 SizeOfCode;
70              public UInt16 e_crlc;    // Relocations              public UInt32 SizeOfInitializedData;
71              public UInt16 e_cparhdr;     // Size of header in paragraphs              public UInt32 SizeOfUninitializedData;
72              public UInt16 e_minalloc;    // Minimum extra paragraphs needed              public UInt32 AddressOfEntryPoint;
73              public UInt16 e_maxalloc;    // Maximum extra paragraphs needed              public UInt32 BaseOfCode;
74              public UInt16 e_ss;      // Initial (relative) SS value              public UInt32 BaseOfData;
75              public UInt16 e_sp;      // Initial SP value              public UInt32 ImageBase;
76              public UInt16 e_csum;    // Checksum              public UInt32 SectionAlignment;
77              public UInt16 e_ip;      // Initial IP value              public UInt32 FileAlignment;
78              public UInt16 e_cs;      // Initial (relative) CS value              public UInt16 MajorOperatingSystemVersion;
79              public UInt16 e_lfarlc;      // File address of relocation table              public UInt16 MinorOperatingSystemVersion;
80              public UInt16 e_ovno;    // Overlay number              public UInt16 MajorImageVersion;
81              [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]              public UInt16 MinorImageVersion;
82              public UInt16[] e_res1;    // Reserved words              public UInt16 MajorSubsystemVersion;
83              public UInt16 e_oemid;       // OEM identifier (for e_oeminfo)              public UInt16 MinorSubsystemVersion;
84              public UInt16 e_oeminfo;     // OEM information; e_oemid specific              public UInt32 Win32VersionValue;
85              [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]              public UInt32 SizeOfImage;
86              public UInt16[] e_res2;    // Reserved words              public UInt32 SizeOfHeaders;
87              public Int32 e_lfanew;      // File address of new exe header              public UInt32 CheckSum;
88              private string _e_magic              public UInt16 Subsystem;
89              {              public UInt16 DllCharacteristics;
90                  get { return new string(e_magic); }              public UInt32 SizeOfStackReserve;
91              }              public UInt32 SizeOfStackCommit;
92              public bool isValid              public UInt32 SizeOfHeapReserve;
93              {              public UInt32 SizeOfHeapCommit;
94                  get { return _e_magic == "MZ"; }              public UInt32 LoaderFlags;
95              }              public UInt32 NumberOfRvaAndSizes;
96                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
97                public IMAGE_DATA_DIRECTORY[] DataDirectory;
98          }          }
         #endregion  
         #region IMAGE_NT_HEADERS  
         [StructLayout(LayoutKind.Explicit)]  
         public struct IMAGE_NT_HEADERS  
         {  
             [FieldOffset(0)]  
             public uint Signature;  
             [FieldOffset(4)]  
             public IMAGE_FILE_HEADER FileHeader;  
             [FieldOffset(24)]  
             public IMAGE_OPTIONAL_HEADER OptionalHeader;  
   
             private string _Signature  
             {  
                 get { return Encoding.ASCII.GetString(BitConverter.GetBytes(Signature)); }  
             }  
99    
100              public bool isValid          [StructLayout(LayoutKind.Sequential)]
101              {          public struct IMAGE_OPTIONAL_HEADER64
                 get { return _Signature == "PE\0\0" && (OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC || OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC); }  
             }  
         }  
         #endregion  
         #region MachineType  
         public enum MachineType : ushort  
102          {          {
103              Native = 0,              public UInt16 Magic;
104              I386 = 0x014c,              public Byte MajorLinkerVersion;
105              Itanium = 0x0200,              public Byte MinorLinkerVersion;
106              x64 = 0x8664              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          [StructLayout(LayoutKind.Sequential)]
137          public enum MagicType : ushort          public struct IMAGE_DATA_DIRECTORY
138          {          {
139              IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,              public UInt32 VirtualAddress;
140              IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b              public UInt32 Size;
141          }          }
         #endregion  
         #region SubSystemType  
         public enum SubSystemType : ushort  
         {  
             IMAGE_SUBSYSTEM_UNKNOWN = 0,  
             IMAGE_SUBSYSTEM_NATIVE = 1,  
             IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,  
             IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,  
             IMAGE_SUBSYSTEM_POSIX_CUI = 7,  
             IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,  
             IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,  
             IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,  
             IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,  
             IMAGE_SUBSYSTEM_EFI_ROM = 13,  
             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  
         #region DllCharacteristicsType  
         [Flags]  
         public enum DllCharacteristicsType : ushort  
         {  
             RES_0 = 0x0001,  
             RES_1 = 0x0002,  
             RES_2 = 0x0004,  
             RES_3 = 0x0008,  
             IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,  
             IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,  
             IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,  
             IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,  
             IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,  
             IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,  
             RES_4 = 0x1000,  
             IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,  
             IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000  
         }  
         #endregion  
         #region IMAGE_OPTIONAL_HEADER  
159          [StructLayout(LayoutKind.Explicit)]          [StructLayout(LayoutKind.Explicit)]
160          public struct IMAGE_OPTIONAL_HEADER          public struct Misc
161          {          {
162              [FieldOffset(0)]              [FieldOffset(0)]
163              public MagicType Magic;              public UInt32 PhysicalAddress;
164                [FieldOffset(0)]
165              [FieldOffset(2)]              public UInt32 VirtualSize;
166              public byte MajorLinkerVersion;          }
   
             [FieldOffset(3)]  
             public byte MinorLinkerVersion;  
   
             [FieldOffset(4)]  
             public uint SizeOfCode;  
   
             [FieldOffset(8)]  
             public uint SizeOfInitializedData;  
   
             [FieldOffset(12)]  
             public uint SizeOfUninitializedData;  
   
             [FieldOffset(16)]  
             public uint AddressOfEntryPoint;  
   
             [FieldOffset(20)]  
             public uint BaseOfCode;  
   
             // PE32 contains this additional field  
             [FieldOffset(24)]  
             public uint BaseOfData;  
   
             [FieldOffset(28)]  
             public uint ImageBase;  
   
             [FieldOffset(32)]  
             public uint SectionAlignment;  
   
             [FieldOffset(36)]  
             public uint FileAlignment;  
   
             [FieldOffset(40)]  
             public ushort MajorOperatingSystemVersion;  
   
             [FieldOffset(42)]  
             public ushort MinorOperatingSystemVersion;  
   
             [FieldOffset(44)]  
             public ushort MajorImageVersion;  
   
             [FieldOffset(46)]  
             public ushort MinorImageVersion;  
   
             [FieldOffset(48)]  
             public ushort MajorSubsystemVersion;  
   
             [FieldOffset(50)]  
             public ushort MinorSubsystemVersion;  
   
             [FieldOffset(52)]  
             public uint Win32VersionValue;  
   
             [FieldOffset(56)]  
             public uint SizeOfImage;  
   
             [FieldOffset(60)]  
             public uint SizeOfHeaders;  
   
             [FieldOffset(64)]  
             public uint CheckSum;  
   
             [FieldOffset(68)]  
             public SubSystemType Subsystem;  
   
             [FieldOffset(70)]  
             public DllCharacteristicsType DllCharacteristics;  
   
             [FieldOffset(72)]  
             public uint SizeOfStackReserve;  
   
             [FieldOffset(76)]  
             public uint SizeOfStackCommit;  
   
             [FieldOffset(80)]  
             public uint SizeOfHeapReserve;  
   
             [FieldOffset(84)]  
             public uint SizeOfHeapCommit;  
167    
168              [FieldOffset(88)]          #endregion
             public uint LoaderFlags;  
169    
170              [FieldOffset(92)]          #region Fields
             public uint NumberOfRvaAndSizes;  
171    
172              [FieldOffset(96)]          private readonly IMAGE_DOS_HEADER _dosHeader;
173              public IMAGE_DATA_DIRECTORY ExportTable;          private IMAGE_NT_HEADERS _ntHeaders;
174            private readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
175    
176              [FieldOffset(104)]          #endregion
             public IMAGE_DATA_DIRECTORY ImportTable;  
177    
178              [FieldOffset(112)]          public PEReader(FileInfo fi) : this(fi.FullName) { }
179              public IMAGE_DATA_DIRECTORY ResourceTable;          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)]                      // Skip MS-DOS stub and seek reader to NT Headers
200              public IMAGE_DATA_DIRECTORY ExceptionTable;                      reader.BaseStream.Seek(_dosHeader.e_lfanew, SeekOrigin.Begin);
201    
202              [FieldOffset(128)]                      // Read NT Headers
203              public IMAGE_DATA_DIRECTORY CertificateTable;                      _ntHeaders.Signature = MarshalBytesTo<UInt32>(reader);
204    
205              [FieldOffset(136)]                      // Make sure we have 'PE' in the pe signature
206              public IMAGE_DATA_DIRECTORY BaseRelocationTable;                      if (_ntHeaders.Signature != 0x4550)
207                        {
208                            throw new InvalidOperationException("Invalid portable executable signature in NT header.");
209                        }
210    
211              [FieldOffset(144)]                      _ntHeaders.FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);                    
212              public IMAGE_DATA_DIRECTORY Debug;                      // 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)]                      // Read section data
225              public IMAGE_DATA_DIRECTORY Architecture;                      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)]                          // Skip to beginning of a section
238              public IMAGE_DATA_DIRECTORY GlobalPtr;                          reader.BaseStream.Seek(header.PointerToRawData, SeekOrigin.Begin);
239    
240              [FieldOffset(168)]                          // Read section data... and do something with it
241              public IMAGE_DATA_DIRECTORY TLSTable;                          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)]          public IMAGE_DOS_HEADER GetDOSHeader()
259              public IMAGE_DATA_DIRECTORY LoadConfigTable;          {
260                return _dosHeader;
261            }
262    
263              [FieldOffset(184)]          public UInt32 GetPESignature()
264              public IMAGE_DATA_DIRECTORY BoundImport;          {
265                return _ntHeaders.Signature;
266            }
267    
268              [FieldOffset(192)]          public IMAGE_FILE_HEADER GetFileHeader()
269              public IMAGE_DATA_DIRECTORY IAT;          {
270                return _ntHeaders.FileHeader;
271            }
272    
273              [FieldOffset(200)]          public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
274              public IMAGE_DATA_DIRECTORY DelayImportDescriptor;          {
275                return _ntHeaders.OptionalHeader32;
276            }
277    
278              [FieldOffset(208)]          public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
279              public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;          {
280                return _ntHeaders.OptionalHeader64;
281            }
282    
283              [FieldOffset(216)]          public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
284              public IMAGE_DATA_DIRECTORY Reserved;          {
285                return _sectionHeaders;
286          }          }
287          #endregion  
288          #region IMAGE_EXPORT_DIRECTORY          public bool Is32bitAssembly()
         [StructLayout(LayoutKind.Sequential)]  
         public struct IMAGE_EXPORT_DIRECTORY  
289          {          {
290              public UInt32 Characteristics;              return ((_ntHeaders.FileHeader.Characteristics & 0x0100) == 0x0100);
             public UInt32 TimeDateStamp;  
             public UInt16 MajorVersion;  
             public UInt16 MinorVersion;  
             public UInt32 Name;  
             public UInt32 Base;  
             public UInt32 NumberOfFunctions;  
             public UInt32 NumberOfNames;  
             public UInt32 AddressOfFunctions;     // RVA from base of image  
             public UInt32 AddressOfNames;     // RVA from base of image  
             public UInt32 AddressOfNameOrdinals;  // RVA from base of image  
291          }          }
292          #endregion  
293          #endregion          private void Load64bitOptionalHeaders(BinaryReader reader)
         #region IMAGE_SECTION_HEADER  
         [StructLayout(LayoutKind.Explicit)]  
         public struct IMAGE_SECTION_HEADER  
294          {          {
295              [FieldOffset(0)]              _ntHeaders.OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]  
             public char[] Name;  
296    
297              [FieldOffset(8)]              // Should have 10 data directories
298              public UInt32 VirtualSize;              if (_ntHeaders.OptionalHeader64.NumberOfRvaAndSizes != 0x10)
299                {
300                    throw new InvalidOperationException("Invalid number of data directories in NT header");
301                }
302    
303              [FieldOffset(12)]              // Scan data directories and load section headers
304              public UInt32 VirtualAddress;              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)]          private void Load32bitOptionalHeaders(BinaryReader reader)
314              public UInt32 SizeOfRawData;          {
315                _ntHeaders.OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
316    
317              [FieldOffset(20)]              // Should have 10 data directories
318              public UInt32 PointerToRawData;              if (_ntHeaders.OptionalHeader32.NumberOfRvaAndSizes != 0x10)
319                {
320                    throw new InvalidOperationException("Invalid number of data directories in NT header");
321                }
322    
323              [FieldOffset(24)]              // Scan data directories and load section headers
324              public UInt32 PointerToRelocations;              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)]          private static T MarshalBytesTo<T>(BinaryReader reader)
334              public UInt32 PointerToLinenumbers;          {
335                // Unmanaged data
336                byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
337    
338              [FieldOffset(32)]              // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
339              public UInt16 NumberOfRelocations;              GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
340    
341              [FieldOffset(34)]              // Use our previously created pointer to unmanaged data and marshal to the specified type
342              public UInt16 NumberOfLinenumbers;              T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
343    
344              [FieldOffset(36)]              // Deallocate pointer
345              public DataSectionFlags Characteristics;              handle.Free();
346    
347              public string Section              return theStructure;
             {  
                 get { return new string(Name); }  
             }  
348          }          }
         #endregion  
         #region DataSectionFlags  
         [Flags]  
         public enum DataSectionFlags : uint  
         {  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             TypeReg = 0x00000000,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             TypeDsect = 0x00000001,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             TypeNoLoad = 0x00000002,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             TypeGroup = 0x00000004,  
             /// <summary>  
             /// 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.  
             /// </summary>  
             TypeNoPadded = 0x00000008,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             TypeCopy = 0x00000010,  
             /// <summary>  
             /// The section contains executable code.  
             /// </summary>  
             ContentCode = 0x00000020,  
             /// <summary>  
             /// The section contains initialized data.  
             /// </summary>  
             ContentInitializedData = 0x00000040,  
             /// <summary>  
             /// The section contains uninitialized data.  
             /// </summary>  
             ContentUninitializedData = 0x00000080,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             LinkOther = 0x00000100,  
             /// <summary>  
             /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.  
             /// </summary>  
             LinkInfo = 0x00000200,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             TypeOver = 0x00000400,  
             /// <summary>  
             /// The section will not become part of the image. This is valid only for object files.  
             /// </summary>  
             LinkRemove = 0x00000800,  
             /// <summary>  
             /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.  
             /// </summary>  
             LinkComDat = 0x00001000,  
             /// <summary>  
             /// Reset speculative exceptions handling bits in the TLB entries for this section.  
             /// </summary>  
             NoDeferSpecExceptions = 0x00004000,  
             /// <summary>  
             /// The section contains data referenced through the global pointer (GP).  
             /// </summary>  
             RelativeGP = 0x00008000,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             MemPurgeable = 0x00020000,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             Memory16Bit = 0x00020000,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             MemoryLocked = 0x00040000,  
             /// <summary>  
             /// Reserved for future use.  
             /// </summary>  
             MemoryPreload = 0x00080000,  
             /// <summary>  
             /// Align data on a 1-byte boundary. Valid only for object files.  
             /// </summary>  
             Align1Bytes = 0x00100000,  
             /// <summary>  
             /// Align data on a 2-byte boundary. Valid only for object files.  
             /// </summary>  
             Align2Bytes = 0x00200000,  
             /// <summary>  
             /// Align data on a 4-byte boundary. Valid only for object files.  
             /// </summary>  
             Align4Bytes = 0x00300000,  
             /// <summary>  
             /// Align data on an 8-byte boundary. Valid only for object files.  
             /// </summary>  
             Align8Bytes = 0x00400000,  
             /// <summary>  
             /// Align data on a 16-byte boundary. Valid only for object files.  
             /// </summary>  
             Align16Bytes = 0x00500000,  
             /// <summary>  
             /// Align data on a 32-byte boundary. Valid only for object files.  
             /// </summary>  
             Align32Bytes = 0x00600000,  
             /// <summary>  
             /// Align data on a 64-byte boundary. Valid only for object files.  
             /// </summary>  
             Align64Bytes = 0x00700000,  
             /// <summary>  
             /// Align data on a 128-byte boundary. Valid only for object files.  
             /// </summary>  
             Align128Bytes = 0x00800000,  
             /// <summary>  
             /// Align data on a 256-byte boundary. Valid only for object files.  
             /// </summary>  
             Align256Bytes = 0x00900000,  
             /// <summary>  
             /// Align data on a 512-byte boundary. Valid only for object files.  
             /// </summary>  
             Align512Bytes = 0x00A00000,  
             /// <summary>  
             /// Align data on a 1024-byte boundary. Valid only for object files.  
             /// </summary>  
             Align1024Bytes = 0x00B00000,  
             /// <summary>  
             /// Align data on a 2048-byte boundary. Valid only for object files.  
             /// </summary>  
             Align2048Bytes = 0x00C00000,  
             /// <summary>  
             /// Align data on a 4096-byte boundary. Valid only for object files.  
             /// </summary>  
             Align4096Bytes = 0x00D00000,  
             /// <summary>  
             /// Align data on an 8192-byte boundary. Valid only for object files.  
             /// </summary>  
             Align8192Bytes = 0x00E00000,  
             /// <summary>  
             /// The section contains extended relocations.  
             /// </summary>  
             LinkExtendedRelocationOverflow = 0x01000000,  
             /// <summary>  
             /// The section can be discarded as needed.  
             /// </summary>  
             MemoryDiscardable = 0x02000000,  
             /// <summary>  
             /// The section cannot be cached.  
             /// </summary>  
             MemoryNotCached = 0x04000000,  
             /// <summary>  
             /// The section is not pageable.  
             /// </summary>  
             MemoryNotPaged = 0x08000000,  
             /// <summary>  
             /// The section can be shared in memory.  
             /// </summary>  
             MemoryShared = 0x10000000,  
             /// <summary>  
             /// The section can be executed as code.  
             /// </summary>  
             MemoryExecute = 0x20000000,  
             /// <summary>  
             /// The section can be read.  
             /// </summary>  
             MemoryRead = 0x40000000,  
             /// <summary>  
             /// The section can be written to.  
             /// </summary>  
             MemoryWrite = 0x80000000  
         }  
         #endregion  
349      }      }
350  }  }

Legend:
Removed from v.293  
changed lines
  Added in v.294

  ViewVC Help
Powered by ViewVC 1.1.22