Ejemplo n.º 1
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;

            // Read in the Image Dos Header
            importTable = new List <IMPORT_FUNCTION>(0);
            byte[] headerData = MemoryFunctions.ReadMemory(process, (IntPtr)address, (uint)Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)));
            dosHeader = (IMAGE_DOS_HEADER)MemoryFunctions.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 = MemoryFunctions.ReadMemory(process, (IntPtr)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 = MemoryFunctions.ReadMemory(process, (IntPtr)(PE_header + 4), (uint)Marshal.SizeOf(typeof(COFFHeader)));
            coffHeader = (COFFHeader)MemoryFunctions.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 = MemoryFunctions.ReadMemory(process, (IntPtr)(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;
                }

                // Load the sections
                UInt64         sectionAddress = PE_header + 4 + (UInt64)Marshal.SizeOf(typeof(COFFHeader)) + coffHeader.SizeOfOptionalHeader;
                List <section> 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));
                }


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

                // Read in the first import descriptor structure

                /*
                 * byte[] image_import_descriptor_rawData = oMemoryFunctions.readMemory(process, importTableAddress, (uint)Marshal.SizeOf(typeof(image_import_descriptor)));
                 * image_import_descriptor descriptor = (image_import_descriptor)oMemoryFunctions.RawDataToObject(ref image_import_descriptor_rawData, typeof(image_import_descriptor));
                 * List<image_import_by_name> imports = new List<image_import_by_name>(0);
                 * while (descriptor.FirstThunk != 0 || descriptor.OriginalFirstThunk != 0 || descriptor.Name != 0)
                 * {
                 * // Process this descriptor
                 * imports.Add(new image_import_by_name(process, descriptor, address));
                 *
                 * // Read next descriptor
                 * image_import_descriptor_rawData = oMemoryFunctions.readMemory(process, importTableAddress + (long)(imports.Count * Marshal.SizeOf(typeof(image_import_descriptor))), (uint)Marshal.SizeOf(typeof(image_import_descriptor)));
                 * descriptor = (image_import_descriptor)oMemoryFunctions.RawDataToObject(ref image_import_descriptor_rawData, typeof(image_import_descriptor));
                 * }
                 *
                 * // Now lets process the array of descriptors
                 * foreach (image_import_by_name dllDescriptor in imports)
                 * {
                 * for (int i = 0; i < dllDescriptor.ImportTableAddresses.Count; i++)
                 * {
                 *  // Process this function import
                 *  IMPORT_FUNCTION newImport = new IMPORT_FUNCTION();
                 *  newImport.name = dllDescriptor.Names[i];
                 *  newImport.memoryAddress = dllDescriptor.ImportTableAddresses[i];
                 *  newImport.targetAddress = oMemoryFunctions.readMemoryDword(process, newImport.memoryAddress);
                 *  importTable.Add(newImport);
                 * }
                 * }
                 */

                // 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          = MemoryFunctions.ReadMemory(process, exportTableAddress, (uint)Marshal.SizeOf(typeof(_IMAGE_EXPORT_DIRECTORY)));
                _IMAGE_EXPORT_DIRECTORY export_directory = (_IMAGE_EXPORT_DIRECTORY)MemoryFunctions.RawDataToObject(ref export_directory_rawData, typeof(_IMAGE_EXPORT_DIRECTORY));
                exports = new Hashtable(20);

                UInt64 functionNameArray    = (UInt64)export_directory.AddressOfNames + address;
                string exportName           = MemoryFunctions.ReadString(process, (UInt64)export_directory.Name + address, MemoryFunctions.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)MemoryFunctions.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 = MemoryFunctions.ReadString(process, (UInt64)MemoryFunctions.ReadMemoryDword(process, functionNameArray + (UInt64)i * 4) + address, MemoryFunctions.STRING_TYPE.ascii);
                        }
                        else
                        {
                            name = "oridinal" + ordinal.ToString();
                        }



                        // Lookup the function rva now
                        try
                        {
                            UInt64 offset = (UInt64)MemoryFunctions.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);

                                            exports.Add(name.ToLower(), new_export);
                                        }
                                        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;
            }
        }
Ejemplo n.º 2
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 = MemoryFunctions.ReadMemory(process, (IntPtr)address,
                                                           (uint)Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)));
            IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)MemoryFunctions.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 = MemoryFunctions.ReadMemory(process, (IntPtr)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 = MemoryFunctions.ReadMemory(process, (IntPtr)(PE_header + 4), (uint)Marshal.SizeOf(typeof(COFFHeader)));
                COFFHeader coffHeader         = (COFFHeader)MemoryFunctions.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 = MemoryFunctions.ReadMemory(process, (IntPtr)(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);
            }
        }