Esempio n. 1
0
        /// <summary>
        /// This checks whether the specified heap is
        /// a valid pe header.
        /// </summary>
        /// <param name="process"></param>
        /// <param name="address"></param>
        /// <returns></returns>
        public static bool isPeHeader(System.Diagnostics.Process process, UInt64 address)
        {
            // Read in the Image Dos Header
              byte[] headerData = oMemoryFunctions.ReadMemory(process, (ulong)address,
                                                      (uint)Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)));
              IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)oMemoryFunctions.RawDataToObject(ref headerData, typeof(IMAGE_DOS_HEADER));

              // Load the PE Address
              UInt64 PE_header = 0;
              if (dosHeader.e_magic == 0x5A4D)
              {
            // Load the PE header address
            PE_header = dosHeader.e_lfanew + address;
              }
              else
              {
            PE_header = address;
            return false;
              }

              if (PE_header <= 0x7FFFFFFF)
              {
            // Read in the PE token
            byte[] PE_Token = oMemoryFunctions.ReadMemory(process, (ulong)PE_header, 4);
            if (!(PE_Token[0] == 'P' & PE_Token[1] == 'E' & PE_Token[2] == 0 & PE_Token[3] == 0))
            {
              // Problem, we are not pointing at a correct PE header. Abort.
              return false;
            }

            // Input the COFFHeader
            byte[] coffHeader_rawData = oMemoryFunctions.ReadMemory(process, (ulong)(PE_header + 4), (uint)Marshal.SizeOf(typeof(COFFHeader)));
            COFFHeader coffHeader = (COFFHeader)oMemoryFunctions.RawDataToObject(ref coffHeader_rawData, typeof(COFFHeader));

            // Read in the PEOptHeader if it exists
            if (coffHeader.SizeOfOptionalHeader != 0 && coffHeader.SizeOfOptionalHeader < 0x1000)
            {
              // Read in the optHeader
              byte[] optHeader_rawData = oMemoryFunctions.ReadMemory(process, (ulong)(PE_header + 4 + (uint)Marshal.SizeOf(typeof(COFFHeader))), coffHeader.SizeOfOptionalHeader);
              PEOptHeader optHeader = new PEOptHeader(ref optHeader_rawData, 0, optHeader_rawData.Length);

              // Confirm that it loaded correctly
              if ((optHeader.signature & 0xffff) != 0x10b && (optHeader.signature & 0xffff) != 0x20b)
              {
            return false;
              }

              if (optHeader.SizeOfCode == 0)
            return false;
            }
            else
            {
              // No COFFHeader found
              return false;
            }

            return true;
              }
              else
              {
            return false;

              }
        }
Esempio n. 2
0
        /// <summary>
        /// This function loads the header and PE header at the
        /// specified address in memory.
        /// </summary>
        /// <param name="process"></param>
        /// <param name="address"></param>
        public HeaderReader(System.Diagnostics.Process process, UInt64 address)
        {
            this.BaseAddress = address;
              codeStartAddress = 0;
              codeLength = 0;
              invalidCodeAddresses = new List<ADDRESS_RANGE>(10);
              sections = new List<section>(10);
              exports = new Hashtable(10);

              // Read in the Image Dos Header
              importTable = new List<IMPORT_FUNCTION>(0);
              byte[] headerData = oMemoryFunctions.ReadMemory(process, (ulong)address, (uint)Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)));
              dosHeader = (IMAGE_DOS_HEADER)oMemoryFunctions.RawDataToObject(ref headerData, typeof(IMAGE_DOS_HEADER));

              // Load the PE Address
              UInt64 PE_header = 0;
              if (dosHeader.e_magic == 0x5A4D)
              {
            // Load the PE header address
            PE_header = dosHeader.e_lfanew + address;
              }
              else
              {
            PE_header = address;
              }

              // Read in the PE token
              byte[] PE_Token = oMemoryFunctions.ReadMemory(process, (ulong)PE_header, 4);
              if (!(PE_Token[0] == 'P' & PE_Token[1] == 'E' & PE_Token[2] == 0 & PE_Token[3] == 0))
              {
            // Problem, we are not pointing at a correct PE header. Abort.
            Console.WriteLine("Failed to read PE header from block " + address.ToString("X") + " with PE header located at " + PE_header.ToString() + ".");
            return;
              }

              // Input the COFFHeader
              byte[] coffHeader_rawData = oMemoryFunctions.ReadMemory(process, (ulong)(PE_header + 4), (uint)Marshal.SizeOf(typeof(COFFHeader)));
              coffHeader = (COFFHeader)oMemoryFunctions.RawDataToObject(ref coffHeader_rawData, typeof(COFFHeader));

              // Read in the PEOptHeader if it exists
              if (coffHeader.SizeOfOptionalHeader != 0 && coffHeader.SizeOfOptionalHeader < 0x1000)
              {
            // Read in the optHeader
            byte[] optHeader_rawData = oMemoryFunctions.ReadMemory(process, (ulong)(PE_header + 4 + (uint)Marshal.SizeOf(typeof(COFFHeader))), coffHeader.SizeOfOptionalHeader);
            optHeader = new PEOptHeader(ref optHeader_rawData, 0, coffHeader.SizeOfOptionalHeader);

            // Confirm that it loaded correctly
            if ((optHeader.signature & 0xffff) != 0x10b && (optHeader.signature & 0xffff) != 0x20b)
            {
              Console.WriteLine("Failed to read optHeader; Expected signature does not match read in signature of " + optHeader.signature.ToString() + ".");
              return;
            }

            if (optHeader._is64)
              return; // Do not process 64bit headers

            // Load the sections
            UInt64 sectionAddress = PE_header + 4 + (UInt64)Marshal.SizeOf(typeof(COFFHeader)) + coffHeader.SizeOfOptionalHeader;
            sections = new List<section>(coffHeader.NumberOfSections);
            for (int i = 0; i < coffHeader.NumberOfSections; i++)
            {
              sections.Add(new section(process, sectionAddress));
              sectionAddress += (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));
            }

            // Add all the directories as invalid code ranges
            try
            {
              if (optHeader.DataDirectory1_export.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory1_export.VirtualAddress),
                    optHeader.DataDirectory1_export.Size));
              if (optHeader.DataDirectory2_import.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory2_import.VirtualAddress),
                    optHeader.DataDirectory2_import.Size));
              if (optHeader.DataDirectory3.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory3.VirtualAddress),
                    optHeader.DataDirectory3.Size));
              if (optHeader.DataDirectory4.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory4.VirtualAddress),
                    optHeader.DataDirectory4.Size));
              if (optHeader.DataDirectory5.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory5.VirtualAddress),
                    optHeader.DataDirectory5.Size));
              if (optHeader.DataDirectory6.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory6.VirtualAddress),
                    optHeader.DataDirectory6.Size));
              if (optHeader.DataDirectory7.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory7.VirtualAddress),
                    optHeader.DataDirectory7.Size));
              if (optHeader.DataDirectory8.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory8.VirtualAddress),
                    optHeader.DataDirectory8.Size));
              if (optHeader.DataDirectory9.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory9.VirtualAddress),
                    optHeader.DataDirectory9.Size));
              if (optHeader.DataDirectory10.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory10.VirtualAddress),
                    optHeader.DataDirectory10.Size));
              if (optHeader.DataDirectory11.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory11.VirtualAddress),
                    optHeader.DataDirectory11.Size));
              if (optHeader.DataDirectory12.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory12.VirtualAddress),
                    optHeader.DataDirectory12.Size));
              if (optHeader.DataDirectory13.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory13.VirtualAddress),
                    optHeader.DataDirectory13.Size));
              if (optHeader.DataDirectory14.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory14.VirtualAddress),
                    optHeader.DataDirectory14.Size));
              if (optHeader.DataDirectory15.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory15.VirtualAddress),
                    optHeader.DataDirectory15.Size));
              if (optHeader.DataDirectory16.Size > 0)
            invalidCodeAddresses.Add(
                new ADDRESS_RANGE(
                    oMemoryFunctions.AddressAdd(address, optHeader.DataDirectory16.VirtualAddress),
                    optHeader.DataDirectory16.Size));
            }
            catch
            {
              // Ignore exceptions, this is not cretical.
            }

            // Extract the names of the functions and corresponding table entries
            Int64 importTableAddress = (Int64)optHeader.DataDirectory2_import.VirtualAddress + (Int64)address;
            loadImportTable(process, (uint)importTableAddress, optHeader.DataDirectory2_import.Size, (uint)address);

            // Extract the names of the functions and corresponding table entries
            Int64 exportTableAddress = (Int64)optHeader.DataDirectory1_export.VirtualAddress + (Int64)address;

            // Read in the first _IMAGE_EXPORT_DIRECTORY structure
            byte[] export_directory_rawData = oMemoryFunctions.ReadMemory(process, (ulong)exportTableAddress, (uint)Marshal.SizeOf(typeof(_IMAGE_EXPORT_DIRECTORY)));
            _IMAGE_EXPORT_DIRECTORY export_directory = (_IMAGE_EXPORT_DIRECTORY)oMemoryFunctions.RawDataToObject(ref export_directory_rawData, typeof(_IMAGE_EXPORT_DIRECTORY));
            exports = new Hashtable(20);

            UInt64 functionNameArray = (UInt64)export_directory.AddressOfNames + address;
            string exportName = oMemoryFunctions.ReadString(process, (UInt64)export_directory.Name + address, oMemoryFunctions.STRING_TYPE.ascii);
            UInt64 functionOrdinalArray = (UInt64)export_directory.AddressOfNameOrdinal + address;
            UInt64 functionAddressArray = (UInt64)export_directory.AddressOfFunctions + address;
            for (int i = 0; i < export_directory.NumberOfNames; i++)
            {
              int ordinal_relative = (int)oMemoryFunctions.ReadMemoryUShort(process, functionOrdinalArray + (UInt64)i * 2);
              int ordinal = ordinal_relative + (int)export_directory.Base;

              if (ordinal_relative < export_directory.NumberOfFunctions)
              {
            // Continue with importing this function
            string name = "";
            if (i < export_directory.NumberOfNames)
              name = oMemoryFunctions.ReadString(process, (UInt64)oMemoryFunctions.ReadMemoryDword(process, functionNameArray + (UInt64)i * 4) + address, oMemoryFunctions.STRING_TYPE.ascii);
            else
              name = "oridinal" + ordinal.ToString();

            // Lookup the function rva now
            try
            {
              UInt64 offset = (UInt64)oMemoryFunctions.ReadMemoryDword(process, functionAddressArray + (UInt64)ordinal_relative * 4);

              // Check to see if this is a forwarded export
              if (offset < optHeader.DataDirectory1_export.VirtualAddress ||
                  offset > optHeader.DataDirectory1_export.VirtualAddress + optHeader.DataDirectory1_export.Size)
              {
                // Lookup privilege of heap to confirm it requests execute privileges. We only want to list exported functions, not variables.
                foreach (section exp in sections)
                {
                  if (exp.Contains(offset))
                  {
                    if (exp.IsExecutable())
                    {
                      // Add this exported function
                      export new_export = new export(offset + address,
                                          name,
                                          ordinal);

                      if (!exports.ContainsKey(new_export.Address))
                      {
                        exports.Add(new_export.Address, new_export);
                      }
                      break;
                    }
                    break;
                  }
                }
              }
              else
              {
                // Forwarded export. Ignore it.
              }
            }
            catch (Exception e)
            {
              Console.WriteLine("Warning, failed to parse PE header export directory entry for name '" + name + "'.");
            }
              }
            }
              }
              else
              {
            // No COFFHeader found
            Console.WriteLine("Warning, no COFFHeader found for address " + address.ToString("X") + ".");
            return;
              }
        }