/[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

--- trunk/Win32/Sojaner.MemoryScanner/PEReader.cs	2012/05/28 05:22:28	159
+++ trunk/Win32/Sojaner.MemoryScanner/PEReader.cs	2012/06/05 18:39:06	319
@@ -1,4 +1,5 @@
-´╗┐using System;
+´╗┐#define ENABLE_LOGGING
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -6,347 +7,523 @@
 using RomCheater.Logging;
 using System.Runtime.InteropServices;
 using System.Diagnostics;
+using System.ComponentModel;
 
 namespace Sojaner.MemoryScanner
 {
     public class PEReader
     {
-        public PEReader(FileInfo fi) : this(fi.FullName) { }
-        public PEReader(string filename) { this.Read(filename); }
+        // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
+        #region Structs
 
-        #region marshalling
-        private void Read(string filename)
+        [Flags]
+        public enum MachineTypeFlags
         {
-            logger.Debug.WriteLine("Reading Exe: {0}", filename);
-
-            using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
-            {
-                byte[] data = new byte[] { };
-                GCHandle pinnedPacket = new GCHandle();
-                int size = 0;
-                BinaryReader br = new BinaryReader(fs);
-
-                #region IMAGE_DOS_HEADER
-                size = Marshal.SizeOf(typeof(IMAGE_DOS_HEADER));
-                data = br.ReadBytes(size);
-                pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
-                IMAGE_DOS_HEADER IMAGE_DOS_HEADER = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_DOS_HEADER));
-                pinnedPacket.Free();
-                #endregion
-
-                // skip the old dos stub
-                br.BaseStream.Seek(IMAGE_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 IMAGE_NT_HEADERS = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(IMAGE_NT_HEADERS));
-                pinnedPacket.Free();
-                #endregion
-
-                br.Close();
-            }
-
- 
+            x86 = 0x14C,
+            Alpha = 0x184,
+            ARM = 0x1C0,
+            MIPS16R3000 = 0x162,
+            MIPS16R4000 = 0x166,
+            MIPS16R10000 = 0x168,
+            PowerPCLE = 0x1F0,
+            PowerPCBE = 0x1F2,
+            Itanium = 0x200,
+            MIPS16 = 0x266,
+            Alpha64 = 0x284,
+            MIPSFPU = 0x366,
+            MIPSFPU16 = 0x466,
+            x64 = 0x8664,
         }
-        #endregion
 
-        #region header support
-        #region IMAGE_DATA_DIRECTORY
-        [StructLayout(LayoutKind.Sequential)]
-        public struct IMAGE_DATA_DIRECTORY
-        {
-            public UInt32 VirtualAddress;
-            public UInt32 Size;
-        }
-        #endregion
-        #region IMAGE_FILE_HEADER
-        [StructLayout(LayoutKind.Sequential)]
-        public struct IMAGE_FILE_HEADER
-        {
-            public UInt16 Machine;
-            public UInt16 NumberOfSections;
-            public UInt32 TimeDateStamp;
-            public UInt32 PointerToSymbolTable;
-            public UInt32 NumberOfSymbols;
-            public UInt16 SizeOfOptionalHeader;
-            public UInt16 Characteristics;
-        }
-        #endregion
-        #region IMAGE_DOS_HEADER
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Sequential)]
         public struct IMAGE_DOS_HEADER
         {
-            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
-            public char[] e_magic;       // Magic number
-            public UInt16 e_cblp;    // Bytes on last page of file
-            public UInt16 e_cp;      // Pages in file
-            public UInt16 e_crlc;    // Relocations
-            public UInt16 e_cparhdr;     // Size of header in paragraphs
-            public UInt16 e_minalloc;    // Minimum extra paragraphs needed
-            public UInt16 e_maxalloc;    // Maximum extra paragraphs needed
-            public UInt16 e_ss;      // Initial (relative) SS value
-            public UInt16 e_sp;      // Initial SP value
-            public UInt16 e_csum;    // Checksum
-            public UInt16 e_ip;      // Initial IP value
-            public UInt16 e_cs;      // Initial (relative) CS value
-            public UInt16 e_lfarlc;      // File address of relocation table
-            public UInt16 e_ovno;    // Overlay number
+            public UInt16 _e_magic;
+            public UInt16 _e_cblp;
+            public UInt16 _e_cp;
+            public UInt16 _e_crlc;
+            public UInt16 _e_cparhdr;
+            public UInt16 _e_minalloc;
+            public UInt16 _e_maxalloc;
+            public UInt16 _e_ss;
+            public UInt16 _e_sp;
+            public UInt16 _e_csum;
+            public UInt16 _e_ip;
+            public UInt16 _e_cs;
+            public UInt16 _e_lfarlc;
+            public UInt16 _e_ovno;
             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
-            public UInt16[] e_res1;    // Reserved words
-            public UInt16 e_oemid;       // OEM identifier (for e_oeminfo)
-            public UInt16 e_oeminfo;     // OEM information; e_oemid specific
+            public UInt16[] _e_res1;
+            public UInt16 _e_oemid;
+            public UInt16 _e_oeminfo;
             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
-            public UInt16[] e_res2;    // Reserved words
-            public Int32 e_lfanew;      // File address of new exe header
-            private string _e_magic
-            {
-                get { return new string(e_magic); }
-            }
-            public bool isValid
+            public UInt16[] _e_res2;
+            public UInt32 _e_lfanew;
+
+            public string e_magic { get { return string.Format("0x{0:x4}", _e_magic); } }
+            public string e_cblp { get { return string.Format("0x{0:x4}", _e_cblp); } }
+            public string e_cp { get { return string.Format("0x{0:x4}", _e_cp); } }
+            public string e_crlc { get { return string.Format("0x{0:x4}", _e_crlc); } }
+            public string e_cparhdr { get { return string.Format("0x{0:x4}", _e_cparhdr); } }
+            public string e_minalloc { get { return string.Format("0x{0:x4}", _e_minalloc); } }
+            public string e_maxalloc { get { return string.Format("0x{0:x4}", _e_maxalloc); } }
+            public string e_ss { get { return string.Format("0x{0:x4}", _e_ss); } }
+            public string e_sp { get { return string.Format("0x{0:x4}", _e_sp); } }
+            public string e_csum { get { return string.Format("0x{0:x4}", _e_csum); } }
+            public string e_ip { get { return string.Format("0x{0:x4}", _e_ip); } }
+            public string e_cs { get { return string.Format("0x{0:x4}", _e_cs); } }
+            public string e_lfarlc { get { return string.Format("0x{0:x4}", _e_lfarlc); } }
+            public string e_ovno { get { return string.Format("0x{0:x4}", _e_ovno); } }
+            public ushort[] e_res1 { get { return _e_res1; } }
+            public string e_oemid { get { return string.Format("0x{0:x4}", _e_oemid); } }
+            public string e_oeminfo { get { return string.Format("0x{0:x4}", _e_oeminfo); } }
+            public ushort[] e_res2 { get { return _e_res2; } }
+            public string e_lfanew { get { return string.Format("0x{0:x8}", _e_lfanew); } }
+
+            public override string ToString()
             {
-                get { return _e_magic == "MZ"; }
+                return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic));
             }
         }
-        #endregion
-        #region IMAGE_NT_HEADERS
-        [StructLayout(LayoutKind.Explicit)]
+        [TypeConverter(typeof(ExpandableObjectConverter))]
+        [StructLayout(LayoutKind.Sequential)]
         public struct IMAGE_NT_HEADERS
         {
-            [FieldOffset(0)]
-            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
-            public char[] Signature;
-
-            [FieldOffset(4)]
-            public IMAGE_FILE_HEADER FileHeader;
-
-            [FieldOffset(24)]
-            public IMAGE_OPTIONAL_HEADER OptionalHeader;
+            public UInt32 _Signature;
+            public IMAGE_FILE_HEADER _FileHeader;
+            public IMAGE_OPTIONAL_HEADER32 _OptionalHeader32;
+            public IMAGE_OPTIONAL_HEADER64 _OptionalHeader64;
+
+            public string Signature { get { return string.Format("0x{0:x8}", _Signature); } }
+            public IMAGE_FILE_HEADER FileHeader { get { return _FileHeader; } }
+            public IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get { return _OptionalHeader32;} }
+            public IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get { return _OptionalHeader64;} }
 
-            private string _Signature
+            public override string ToString()
             {
-                get { return new string(Signature); }
+                return Encoding.UTF8.GetString(BitConverter.GetBytes(_Signature));
+            }
+        }
+        [TypeConverter(typeof(ExpandableObjectConverter))]
+        [StructLayout(LayoutKind.Sequential)]
+        public struct IMAGE_FILE_HEADER
+        {
+            public UInt16 _MachineType;
+            public UInt16 _NumberOfSections;
+            public UInt32 _TimeDateStamp;
+            public UInt32 _PointerToSymbolTable;
+            public UInt32 _NumberOfSymbols;
+            public UInt16 _SizeOfOptionalHeader;
+            public UInt16 _Characteristics;
+
+
+            public string MachineType { get { return ((MachineTypeFlags)_MachineType).ToString(); } }
+            public string NumberOfSections { get { return string.Format("0x{0:x4}", _NumberOfSections); } }
+            public string TimeDateStamp { get { return string.Format("{0} (0x{1:x8})", GetDateTimeFromDosDateTime(_TimeDateStamp).ToString(), _TimeDateStamp); } }
+            public string PointerToSymbolTable { get { return string.Format("0x{0:x8}", _PointerToSymbolTable); } }
+            public string NumberOfSymbols { get { return string.Format("0x{0:x8}", _NumberOfSymbols); } }
+            public string SizeOfOptionalHeader { get { return string.Format("0x{0:x4}", _SizeOfOptionalHeader); } }
+            public string Characteristics { get { return string.Format("0x{0:x4}", _Characteristics); } }
+            public override string ToString()
+            {
+                return MachineType;
             }
 
-            public bool isValid
+            private DateTime GetDateTimeFromDosDateTime(UInt32 i32TimeDate)
+            {
+                UInt16 i16Time = (UInt16)(i32TimeDate & 0xFFFF);
+                UInt16 i16Date = (UInt16)((i32TimeDate & 0xFFFF0000) >> 16);
+                return GetDateTimeFromDosDateTime(i16Time, i16Date);
+            }
+            private DateTime GetDateTimeFromDosDateTime(UInt16 i16Time, UInt16 i16Date)
             {
-                get { return _Signature == "PE\0\0" && (OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC || OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC); }
+                int iYear = 0;
+                int iMonth = 1;
+                int iDay = 1;
+                int iHour = 0;
+                int iMinute = 0;
+                int iSecond = 0;
+                iDay = (i16Date & 0x1F);
+                iMonth = ((i16Date & 0x01E0) >> 5);
+                iYear = 1980 + ((i16Date & 0xFE00) >> 9);
+                iSecond = (i16Time & 0x1F) * 2;
+                iMinute = ((i16Time & 0x07E0) >> 5);
+                iHour = ((i16Time & 0x0F800) >> 11);
+                return new DateTime(iYear, iMonth, iDay, iHour, iMinute, iSecond);
+
             }
+
         }
-        #endregion
-        #region MachineType
-        public enum MachineType : ushort
+        [TypeConverter(typeof(ExpandableObjectConverter))]
+        [StructLayout(LayoutKind.Sequential)]
+        public struct IMAGE_OPTIONAL_HEADER32
         {
-            Native = 0,
-            I386 = 0x014c,
-            Itanium = 0x0200,
-            x64 = 0x8664
+            public UInt16 Magic;
+            public Byte MajorLinkerVersion;
+            public Byte MinorLinkerVersion;
+            public UInt32 SizeOfCode;
+            public UInt32 SizeOfInitializedData;
+            public UInt32 SizeOfUninitializedData;
+            public UInt32 AddressOfEntryPoint;
+            public UInt32 BaseOfCode;
+            public UInt32 BaseOfData;
+            public UInt32 ImageBase;
+            public UInt32 SectionAlignment;
+            public UInt32 FileAlignment;
+            public UInt16 MajorOperatingSystemVersion;
+            public UInt16 MinorOperatingSystemVersion;
+            public UInt16 MajorImageVersion;
+            public UInt16 MinorImageVersion;
+            public UInt16 MajorSubsystemVersion;
+            public UInt16 MinorSubsystemVersion;
+            public UInt32 Win32VersionValue;
+            public UInt32 SizeOfImage;
+            public UInt32 SizeOfHeaders;
+            public UInt32 CheckSum;
+            public UInt16 Subsystem;
+            public UInt16 DllCharacteristics;
+            public UInt32 SizeOfStackReserve;
+            public UInt32 SizeOfStackCommit;
+            public UInt32 SizeOfHeapReserve;
+            public UInt32 SizeOfHeapCommit;
+            public UInt32 LoaderFlags;
+            public UInt32 NumberOfRvaAndSizes;
+            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+            public IMAGE_DATA_DIRECTORY[] DataDirectory;
         }
-        #endregion
-        #region MagicType
-        public enum MagicType : ushort
+        [TypeConverter(typeof(ExpandableObjectConverter))]
+        [StructLayout(LayoutKind.Sequential)]
+        public struct IMAGE_OPTIONAL_HEADER64
         {
-            IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
-            IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
+            public UInt16 Magic;
+            public Byte MajorLinkerVersion;
+            public Byte MinorLinkerVersion;
+            public UInt32 SizeOfCode;
+            public UInt32 SizeOfInitializedData;
+            public UInt32 SizeOfUninitializedData;
+            public UInt32 AddressOfEntryPoint;
+            public UInt32 BaseOfCode;
+            public UInt64 ImageBase;
+            public UInt32 SectionAlignment;
+            public UInt32 FileAlignment;
+            public UInt16 MajorOperatingSystemVersion;
+            public UInt16 MinorOperatingSystemVersion;
+            public UInt16 MajorImageVersion;
+            public UInt16 MinorImageVersion;
+            public UInt16 MajorSubsystemVersion;
+            public UInt16 MinorSubsystemVersion;
+            public UInt32 Win32VersionValue;
+            public UInt32 SizeOfImage;
+            public UInt32 SizeOfHeaders;
+            public UInt32 CheckSum;
+            public UInt16 Subsystem;
+            public UInt16 DllCharacteristics;
+            public UInt64 SizeOfStackReserve;
+            public UInt64 SizeOfStackCommit;
+            public UInt64 SizeOfHeapReserve;
+            public UInt64 SizeOfHeapCommit;
+            public UInt32 LoaderFlags;
+            public UInt32 NumberOfRvaAndSizes;
+            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+            public IMAGE_DATA_DIRECTORY[] DataDirectory;
         }
-        #endregion
-        #region SubSystemType
-        public enum SubSystemType : ushort
+        [TypeConverter(typeof(ExpandableObjectConverter))]
+        [StructLayout(LayoutKind.Sequential)]
+        public struct IMAGE_DATA_DIRECTORY
         {
-            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
-
+            public UInt32 VirtualAddress;
+            public UInt32 Size;
         }
-        #endregion
-        #region DllCharacteristicsType
-        public enum DllCharacteristicsType : ushort
+        [TypeConverter(typeof(ExpandableObjectConverter))]
+        [StructLayout(LayoutKind.Sequential)]
+        public struct IMAGE_SECTION_HEADER
         {
-            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
+            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
+            public string _Name;
+            public Misc _Misc;
+            public UInt32 _VirtualAddress;
+            public UInt32 _SizeOfRawData;
+            public UInt32 _PointerToRawData;
+            public UInt32 _PointerToRelocations;
+            public UInt32 _PointerToLinenumbers;
+            public UInt16 _NumberOfRelocations;
+            public UInt16 _NumberOfLinenumbers;
+            public UInt32 _Characteristics;
+
+            public string Name { get { return _Name; } }
+            public Misc Misc { get { return _Misc; } }
+            public string VirtualAddress { get { return string.Format("0x{0:x8}", _VirtualAddress); } }
+            public string SizeOfRawData { get { return string.Format("0x{0:x8}", _SizeOfRawData); } }
+            public string PointerToRawData { get { return string.Format("0x{0:x8}", _PointerToRawData); } }
+            public string PointerToRelocations { get { return string.Format("0x{0:x8}", _PointerToRelocations); } }
+            public string PointerToLinenumbers { get { return string.Format("0x{0:x8}", _PointerToLinenumbers); } }
+            public string NumberOfRelocations { get { return string.Format("0x{0:x4}", _NumberOfRelocations); } }
+            public string NumberOfLinenumbers { get { return string.Format("0x{0:x4}", _NumberOfLinenumbers); } }
+            public string Characteristics { get { return string.Format("0x{0:x8}", _Characteristics); } }
+            public override string ToString()
+            {
+                return Name;
+            }
         }
-        #endregion
-        #region IMAGE_OPTIONAL_HEADER
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Explicit)]
-        public struct IMAGE_OPTIONAL_HEADER
+        public struct Misc
         {
             [FieldOffset(0)]
-            public MagicType Magic;
-
-            [FieldOffset(2)]
-            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;
+            public UInt32 _PhysicalAddress;
+            [FieldOffset(0)]
+            public UInt32 _VirtualSize;
 
-            [FieldOffset(52)]
-            public uint Win32VersionValue;
+            public string PhysicalAddress { get { return string.Format("0x{0:x8}", _PhysicalAddress); } }
+            public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } }
 
-            [FieldOffset(56)]
-            public uint SizeOfImage;
+        }
 
-            [FieldOffset(60)]
-            public uint SizeOfHeaders;
+        #endregion
 
-            [FieldOffset(64)]
-            public uint CheckSum;
+        #region Fields
 
-            [FieldOffset(68)]
-            public SubSystemType Subsystem;
+        private readonly IMAGE_DOS_HEADER _dosHeader;
+        private IMAGE_NT_HEADERS _ntHeaders;
+        private readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
+        #endregion
 
-            [FieldOffset(70)]
-            public DllCharacteristicsType DllCharacteristics;
+        #region logging implementation
+        private static class log
+        {
+            public static class verbose
+            {
+                public static class debug
+                {
+                    public static void writeline(string format, params object[] args)
+                    {
+#if ENABLE_LOGGING
+                        logger.VerboseDebug.WriteLine(format, args);
+#endif
+                    }
+                    public static void write(string format, params object[] args)
+                    {
+#if ENABLE_LOGGING
+                        logger.VerboseDebug.Write(format, args);
+#endif
+                    }
+                }
+                public static class error
+                {
+                    public static void writeline(string format, params object[] args)
+                    {
+#if ENABLE_LOGGING
+                        logger.VerboseError.WriteLine(format, args);
+#endif
+                    }
+                    public static void write(string format, params object[] args)
+                    {
+#if ENABLE_LOGGING
+                        logger.VerboseError.Write(format, args);
+#endif
+                    }
+                }
+            }
+        }
+        #endregion
 
-            [FieldOffset(72)]
-            public uint SizeOfStackReserve;
 
-            [FieldOffset(76)]
-            public uint SizeOfStackCommit;
+        public PEData GetData
+        {
+            get 
+            {
+                PEData _data = new PEData(_dosHeader, _ntHeaders, _sectionHeaders.ToArray());
+                return _data;
+            }
+        }
+        #region t
+        public class PEData
+        {
+            public PEData() : this(new IMAGE_DOS_HEADER(), new IMAGE_NT_HEADERS(), new IMAGE_SECTION_HEADER[] { }) { }
+            public PEData(IMAGE_DOS_HEADER DosHeader, IMAGE_NT_HEADERS NTHeader, IMAGE_SECTION_HEADER[] SectionHeaders)
+            {
+                this.DosHeader = DosHeader;
+                this.NTHeader = NTHeader;
+                this.SectionHeaders = SectionHeaders;
+            }
+            public IMAGE_DOS_HEADER DosHeader { get; private set; }
+            public IMAGE_NT_HEADERS NTHeader { get; private set; }
+            public IMAGE_SECTION_HEADER[] SectionHeaders { get; private set; }
+        }
 
-            [FieldOffset(80)]
-            public uint SizeOfHeapReserve;
+        #endregion
 
-            [FieldOffset(84)]
-            public uint SizeOfHeapCommit;
+        public PEReader(FileInfo fi) : this(fi.FullName) { }
+        public PEReader(string filename)
+        {            
+            Exception ErrorInfo = null;
+            using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
+            {
+                try
+                {
+                    log.verbose.debug.writeline("Reading PE Format from: {0}", filename);
+                    BinaryReader reader = new BinaryReader(fs);
+                    // Reset reader position, just in case
+                    reader.BaseStream.Seek(0, SeekOrigin.Begin);
+
+                    // Read MS-DOS header section
+                    _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
+                    // MS-DOS magic number should read 'MZ'
+                    if (_dosHeader._e_magic != 0x5a4d)
+                    {
+                        throw new InvalidOperationException("File is not a portable executable.");
+                    }
+
+                    // Skip MS-DOS stub and seek reader to NT Headers
+                    reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
+
+                    // Read NT Headers
+                    _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
+
+                    // Make sure we have 'PE' in the pe signature
+                    if (_ntHeaders._Signature != 0x4550)
+                    {
+                        throw new InvalidOperationException("Invalid portable executable signature in NT header.");
+                    }
+
+                    _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);                    
+                    // Read optional headers
+                    if (Is32bitAssembly())
+                    {
+                        log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
+                        Load32bitOptionalHeaders(reader);
+                    }
+                    else
+                    {
+                        log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
+                        Load64bitOptionalHeaders(reader);
+                    }
+
+                    // Read section data
+                    log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
+                    foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
+                    {
+                        int section_index = _sectionHeaders.IndexOf(header) + 1;
+                        log.verbose.debug.writeline("\tSection Header: {0} of {1}", section_index, _sectionHeaders.Count);
+                        log.verbose.debug.writeline("\t\tName: {0}", header.Name);
+                        log.verbose.debug.writeline("\t\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
+                        log.verbose.debug.writeline("\t\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
+                        log.verbose.debug.writeline("\t\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
+                        log.verbose.debug.writeline("\t\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
+                        log.verbose.debug.writeline("\t\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
+
+                        // Skip to beginning of a section
+                        reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
+
+                        // Read section data... and do something with it
+                        byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
+                    }
+                    reader.Close();
+                }
+                catch (Exception ex)
+                {
+                    ErrorInfo = ex;
+                    throw ErrorInfo;
+                }
+            }
+            if (ErrorInfo != null)
+            {
+                log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
+                log.verbose.error.writeline(ErrorInfo.ToString());
+            }
+        }
 
-            [FieldOffset(88)]
-            public uint LoaderFlags;
+        public IMAGE_DOS_HEADER GetDOSHeader()
+        {
+            return _dosHeader;
+        }
 
-            [FieldOffset(92)]
-            public uint NumberOfRvaAndSizes;
+        public UInt32 GetPESignature()
+        {
+            return _ntHeaders._Signature;
+        }
 
-            [FieldOffset(96)]
-            public IMAGE_DATA_DIRECTORY ExportTable;
+        public IMAGE_FILE_HEADER GetFileHeader()
+        {
+            return _ntHeaders.FileHeader;
+        }
 
-            [FieldOffset(104)]
-            public IMAGE_DATA_DIRECTORY ImportTable;
+        public IMAGE_OPTIONAL_HEADER32 GetOptionalHeaders32()
+        {
+            return _ntHeaders.OptionalHeader32;
+        }
 
-            [FieldOffset(112)]
-            public IMAGE_DATA_DIRECTORY ResourceTable;
+        public IMAGE_OPTIONAL_HEADER64 GetOptionalHeaders64()
+        {
+            return _ntHeaders.OptionalHeader64;
+        }
 
-            [FieldOffset(120)]
-            public IMAGE_DATA_DIRECTORY ExceptionTable;
+        public IList<IMAGE_SECTION_HEADER> GetSectionHeaders()
+        {
+            return _sectionHeaders;
+        }
 
-            [FieldOffset(128)]
-            public IMAGE_DATA_DIRECTORY CertificateTable;
+        public bool Is32bitAssembly()
+        {
+            return ((_ntHeaders.FileHeader._Characteristics & 0x0100) == 0x0100);
+        }
 
-            [FieldOffset(136)]
-            public IMAGE_DATA_DIRECTORY BaseRelocationTable;
+        private void Load64bitOptionalHeaders(BinaryReader reader)
+        {
+            _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
 
-            [FieldOffset(144)]
-            public IMAGE_DATA_DIRECTORY Debug;
+            // Should have 10 data directories
+            if (_ntHeaders.OptionalHeader64.NumberOfRvaAndSizes != 0x10)
+            {
+                throw new InvalidOperationException("Invalid number of data directories in NT header");
+            }
 
-            [FieldOffset(152)]
-            public IMAGE_DATA_DIRECTORY Architecture;
+            // Scan data directories and load section headers
+            for (int i = 0; i < _ntHeaders.OptionalHeader64.NumberOfRvaAndSizes; i++)
+            {
+                if (_ntHeaders.OptionalHeader64.DataDirectory[i].Size > 0)
+                {
+                    _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
+                }
+            }
+        }
 
-            [FieldOffset(160)]
-            public IMAGE_DATA_DIRECTORY GlobalPtr;
+        private void Load32bitOptionalHeaders(BinaryReader reader)
+        {
+            _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
 
-            [FieldOffset(168)]
-            public IMAGE_DATA_DIRECTORY TLSTable;
+            // Should have 10 data directories
+            if (_ntHeaders.OptionalHeader32.NumberOfRvaAndSizes != 0x10)
+            {
+                throw new InvalidOperationException("Invalid number of data directories in NT header");
+            }
 
-            [FieldOffset(176)]
-            public IMAGE_DATA_DIRECTORY LoadConfigTable;
+            // Scan data directories and load section headers
+            for (int i = 0; i < _ntHeaders.OptionalHeader32.NumberOfRvaAndSizes; i++)
+            {
+                if (_ntHeaders.OptionalHeader32.DataDirectory[i].Size > 0)
+                {
+                    _sectionHeaders.Add(MarshalBytesTo<IMAGE_SECTION_HEADER>(reader));
+                }
+            }
+        }
 
-            [FieldOffset(184)]
-            public IMAGE_DATA_DIRECTORY BoundImport;
+        private static T MarshalBytesTo<T>(BinaryReader reader)
+        {
+            // Unmanaged data
+            byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
 
-            [FieldOffset(192)]
-            public IMAGE_DATA_DIRECTORY IAT;
+            // Create a pointer to the unmanaged data pinned in memory to be accessed by unmanaged code
+            GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
 
-            [FieldOffset(200)]
-            public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
+            // Use our previously created pointer to unmanaged data and marshal to the specified type
+            T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
 
-            [FieldOffset(208)]
-            public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
+            // Deallocate pointer
+            handle.Free();
 
-            [FieldOffset(216)]
-            public IMAGE_DATA_DIRECTORY Reserved;
-        }
-        #endregion
-        #region IMAGE_EXPORT_DIRECTORY
-        [StructLayout(LayoutKind.Sequential)]
-        public struct IMAGE_EXPORT_DIRECTORY
-        {
-            public UInt32 Characteristics;
-            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
+            return theStructure;
         }
-        #endregion
-        #endregion
     }
 }

 

  ViewVC Help
Powered by ViewVC 1.1.22