/[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/06/05 10:48:07	294
+++ 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,6 +7,7 @@
 using RomCheater.Logging;
 using System.Runtime.InteropServices;
 using System.Diagnostics;
+using System.ComponentModel;
 
 namespace Sojaner.MemoryScanner
 {
@@ -13,53 +15,147 @@
     {
         // Code (C) Sergey utilized from: http://www.sergeyakopov.com/2010/11/03/reading-pe-format-using-data-marshalling-in-net/
         #region Structs
+
+        [Flags]
+        public enum MachineTypeFlags
+        {
+            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,
+        }
+
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Sequential)]
         public struct IMAGE_DOS_HEADER
         {
-            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;
+            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;
-            public UInt16 e_oemid;
-            public UInt16 e_oeminfo;
+            public UInt16[] _e_res1;
+            public UInt16 _e_oemid;
+            public UInt16 _e_oeminfo;
             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
-            public UInt16[] e_res2;
-            public UInt32 e_lfanew;
-        }
+            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()
+            {
+                return Encoding.UTF8.GetString(BitConverter.GetBytes(_e_magic));
+            }
+        }
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Sequential)]
         public struct IMAGE_NT_HEADERS
         {
-            public UInt32 Signature;
-            public IMAGE_FILE_HEADER FileHeader;
-            public IMAGE_OPTIONAL_HEADER32 OptionalHeader32;
-            public IMAGE_OPTIONAL_HEADER64 OptionalHeader64;
-        }
+            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;} }
 
+            public override string ToString()
+            {
+                return Encoding.UTF8.GetString(BitConverter.GetBytes(_Signature));
+            }
+        }
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [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;
-        }
+            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;
+            }
 
+            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)
+            {
+                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);
+
+            }
+
+        }
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Sequential)]
         public struct IMAGE_OPTIONAL_HEADER32
         {
@@ -96,7 +192,7 @@
             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
             public IMAGE_DATA_DIRECTORY[] DataDirectory;
         }
-
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Sequential)]
         public struct IMAGE_OPTIONAL_HEADER64
         {
@@ -132,37 +228,56 @@
             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
             public IMAGE_DATA_DIRECTORY[] DataDirectory;
         }
-
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Sequential)]
         public struct IMAGE_DATA_DIRECTORY
         {
             public UInt32 VirtualAddress;
             public UInt32 Size;
         }
-
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Sequential)]
         public struct IMAGE_SECTION_HEADER
         {
             [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;
+            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;
+            }
         }
-
+        [TypeConverter(typeof(ExpandableObjectConverter))]
         [StructLayout(LayoutKind.Explicit)]
         public struct Misc
         {
             [FieldOffset(0)]
-            public UInt32 PhysicalAddress;
+            public UInt32 _PhysicalAddress;
             [FieldOffset(0)]
-            public UInt32 VirtualSize;
+            public UInt32 _VirtualSize;
+
+            public string PhysicalAddress { get { return string.Format("0x{0:x8}", _PhysicalAddress); } }
+            public string VirtualSize { get { return string.Format("0x{0:x8}", _VirtualSize); } }
+
         }
 
         #endregion
@@ -172,18 +287,82 @@
         private readonly IMAGE_DOS_HEADER _dosHeader;
         private IMAGE_NT_HEADERS _ntHeaders;
         private readonly IList<IMAGE_SECTION_HEADER> _sectionHeaders = new List<IMAGE_SECTION_HEADER>();
+        #endregion
+
+        #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
+
+
+        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; }
+        }
 
         #endregion
 
         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
                 {
-                    logger.VerboseDebug.WriteLine("Reading PE Format from: {0}", filename);
+                    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);
@@ -191,54 +370,54 @@
                     // Read MS-DOS header section
                     _dosHeader = MarshalBytesTo<IMAGE_DOS_HEADER>(reader);
                     // MS-DOS magic number should read 'MZ'
-                    if (_dosHeader.e_magic != 0x5a4d)
+                    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);
+                    reader.BaseStream.Seek(_dosHeader._e_lfanew, SeekOrigin.Begin);
 
                     // Read NT Headers
-                    _ntHeaders.Signature = MarshalBytesTo<UInt32>(reader);
+                    _ntHeaders._Signature = MarshalBytesTo<UInt32>(reader);
 
                     // Make sure we have 'PE' in the pe signature
-                    if (_ntHeaders.Signature != 0x4550)
+                    if (_ntHeaders._Signature != 0x4550)
                     {
                         throw new InvalidOperationException("Invalid portable executable signature in NT header.");
                     }
 
-                    _ntHeaders.FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);                    
+                    _ntHeaders._FileHeader = MarshalBytesTo<IMAGE_FILE_HEADER>(reader);                    
                     // Read optional headers
                     if (Is32bitAssembly())
                     {
-                        logger.VerboseDebug.WriteLine("Detected a 32Bit PE Executable");
+                        log.verbose.debug.writeline("\tDetected a 32Bit PE Executable");
                         Load32bitOptionalHeaders(reader);
                     }
                     else
                     {
-                        logger.VerboseDebug.WriteLine("Detected a 64Bit PE Executable");
+                        log.verbose.debug.writeline("\tDetected a 64Bit PE Executable");
                         Load64bitOptionalHeaders(reader);
                     }
 
                     // Read section data
-                    logger.VerboseDebug.WriteLine("Total Section Headers: {0}", _sectionHeaders.Count);
+                    log.verbose.debug.writeline("\tTotal Section Headers: {0}", _sectionHeaders.Count);
                     foreach (IMAGE_SECTION_HEADER header in _sectionHeaders)
                     {
                         int section_index = _sectionHeaders.IndexOf(header) + 1;
-                        logger.VerboseDebug.WriteLine("Section Header: {0} of {1}", section_index, _sectionHeaders.Count);
-                        logger.VerboseDebug.WriteLine("\tName: {0}", header.Name);
-                        logger.VerboseDebug.WriteLine("\tVirtual Address: 0x{0:x8}", header.VirtualAddress);
-                        logger.VerboseDebug.WriteLine("\tPhysical Address: 0x{0:x8}", header.Misc.PhysicalAddress);
-                        logger.VerboseDebug.WriteLine("\tVirtual Size: 0x{0:x8}", header.Misc.VirtualSize);
-                        logger.VerboseDebug.WriteLine("\tRaw Data Size: 0x{0:x8}", header.SizeOfRawData);
-                        logger.VerboseDebug.WriteLine("\tPointer To Raw Data: 0x{0:x8}", header.PointerToRawData);
+                        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);
+                        reader.BaseStream.Seek(header._PointerToRawData, SeekOrigin.Begin);
 
                         // Read section data... and do something with it
-                        byte[] sectiondata = reader.ReadBytes((int)header.SizeOfRawData);
+                        byte[] sectiondata = reader.ReadBytes((int)header._SizeOfRawData);
                     }
                     reader.Close();
                 }
@@ -250,8 +429,8 @@
             }
             if (ErrorInfo != null)
             {
-                logger.VerboseError.WriteLine("Error Reading PE Format from: {0}",filename);
-                logger.VerboseError.WriteLine(ErrorInfo.ToString());
+                log.verbose.error.writeline("Error Reading PE Format from: {0}", filename);
+                log.verbose.error.writeline(ErrorInfo.ToString());
             }
         }
 
@@ -262,7 +441,7 @@
 
         public UInt32 GetPESignature()
         {
-            return _ntHeaders.Signature;
+            return _ntHeaders._Signature;
         }
 
         public IMAGE_FILE_HEADER GetFileHeader()
@@ -287,12 +466,12 @@
 
         public bool Is32bitAssembly()
         {
-            return ((_ntHeaders.FileHeader.Characteristics & 0x0100) == 0x0100);
+            return ((_ntHeaders.FileHeader._Characteristics & 0x0100) == 0x0100);
         }
 
         private void Load64bitOptionalHeaders(BinaryReader reader)
         {
-            _ntHeaders.OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
+            _ntHeaders._OptionalHeader64 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER64>(reader);
 
             // Should have 10 data directories
             if (_ntHeaders.OptionalHeader64.NumberOfRvaAndSizes != 0x10)
@@ -312,7 +491,7 @@
 
         private void Load32bitOptionalHeaders(BinaryReader reader)
         {
-            _ntHeaders.OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
+            _ntHeaders._OptionalHeader32 = MarshalBytesTo<IMAGE_OPTIONAL_HEADER32>(reader);
 
             // Should have 10 data directories
             if (_ntHeaders.OptionalHeader32.NumberOfRvaAndSizes != 0x10)

 

  ViewVC Help
Powered by ViewVC 1.1.22