Пример #1
0
        /// <summary>
        /// Given a process, this function generates a basic memory map of the entire process. All the extra details are skipped.
        /// </summary>
        /// <param name="process"></param>
        /// <returns></returns>
        public static List<HEAP_INFO> GenerateMemoryMapFast(Process process)
        {
            try
            {
                // Initialize the return structure
                List<HEAP_INFO> result = new List<HEAP_INFO>(200);

                // Walk the process heaps
                uint address = 0;
                uint addressLast = uint.MaxValue;
                MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
                while (address != addressLast && address < 0x7fffffff)
                {
                    // Load this heap information
                    uint blockSize = (uint)VirtualQueryEx(process.Handle, address, ref mbi, Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));

                    addressLast = address;
                    address = (uint)mbi.BaseAddress + (uint)mbi.RegionSize + 1;

                    // Add this heap information
                    result.Add(new HEAP_INFO((ulong)mbi.BaseAddress, (ulong)mbi.RegionSize, mbi.Protect.ToString(), "", null));
                }
                return result;
            }
            catch (Exception ex)
            {
                oConsole.printException(ex);
                return new List<HEAP_INFO>();
            }
        }
Пример #2
0
 static extern Int32 VirtualQueryEx(IntPtr hProcess, uint lpAddress, ref MEMORY_BASIC_INFORMATION buffer, Int32 dwLength);
Пример #3
0
        /// <summary>
        /// Given a process, this function generates a memory map of the entire process.
        /// </summary>
        /// <param name="process"></param>
        /// <returns></returns>
        public static List<HEAP_INFO> GenerateMemoryMap(Process process)
        {
            try
            {
                // Initialize the return structure
                List<HEAP_INFO> result = new List<HEAP_INFO>(100);

                // Create a list of module base addresses
                List<IntInt> moduleBases = new List<IntInt>(process.Modules.Count);
                for( int i = 0; i < process.Modules.Count; i++ )
                {
                    moduleBases.Add( new IntInt((int) process.Modules[i].BaseAddress, i) );
                }
                IntInt.IntIntComparer comparer = new IntInt.IntIntComparer();
                moduleBases.Sort(comparer);

                // Walk the process heaps
                uint address = 0;
                uint addressLast = uint.MaxValue;
                MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
                List<ulong> peHeaderBases = new List<ulong>(20);
                List<IntInt> addressToHeapinfoIndex = new List<IntInt>(100);
                while (address != addressLast && address < 0x7fffffff)
                {
                    // Load this heap information
                    uint blockSize = (uint)VirtualQueryEx(process.Handle, address, ref mbi, Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));

                    addressLast = address;
                    address = (uint)mbi.BaseAddress + (uint)mbi.RegionSize + 1;

                    // If this is a PE header, lets mark it for processing later
                    bool isPeHeader = HeaderReader.isPeHeader(process, (ulong) mbi.BaseAddress, mbi.Protect);
                    ProcessModule associatedModule = null;
                    if( isPeHeader )
                    {
                        // Add this PE header base for later processing
                        peHeaderBases.Add((ulong)mbi.BaseAddress);

                        // Try to associate a module with this peHeader
                        int index = moduleBases.BinarySearch(new IntInt((int)mbi.BaseAddress, 0), comparer);
                        if (index < 0)
                            index = ~index - 1;
                        if (index >= 0 && index < moduleBases.Count)
                            associatedModule = process.Modules[moduleBases[index].int2];
                    }

                    // Add this heap information
                    HEAP_INFO heapInfo = new HEAP_INFO((ulong) mbi.BaseAddress, (ulong) mbi.RegionSize,
                                                       mbi.Protect.ToString(),
                                                       (isPeHeader ? "PE HEADER" : ""), associatedModule);
                    result.Add(heapInfo);
                    addressToHeapinfoIndex.Add(new IntInt((int)mbi.BaseAddress, result.Count - 1));
                }

                // Now add all the header information from the PE headers to the regions
                for (int i = 0; i < peHeaderBases.Count; i++)
                {
                    // Get this header
                    HeaderReader headerReader = new HeaderReader(process, peHeaderBases[i]);

                    // Find the associated module for this pe header
                    int moduleIndex = moduleBases.BinarySearch(new IntInt((int)peHeaderBases[i], 0), comparer);
                    ProcessModule associatedModule = null;
                    if (moduleIndex < 0)
                        moduleIndex = ~moduleIndex - 1;
                    if (moduleIndex >= 0 && moduleIndex < moduleBases.Count)
                        associatedModule = process.Modules[moduleBases[moduleIndex].int2];

                    // Record the highest address, because we know the section from the start of the PE until
                    // the highest section is all part of this module
                    int highestAddress = (int) peHeaderBases[i];

                    // Mark the execution entry point heap
                    int entry = (int) headerReader.optHeader.AddressOfEntryPoint;
                    // Associate this with a heap
                    int index = addressToHeapinfoIndex.BinarySearch(new IntInt(entry + (int)peHeaderBases[i], 0), comparer);
                    if (index < 0)
                        index = ~index - 1;
                    if (index >= 0 && index < addressToHeapinfoIndex.Count)
                    {
                        // We found the heap this section resides in, lets add this section and associate the module.
                        HEAP_INFO newInfo = result[index];
                        newInfo.associatedModule = associatedModule;

                        // Add the section information
                        newInfo.extra = (newInfo.extra + " entry_point").Trim();

                        // Change the heap info
                        result[index] = newInfo;

                        if ( (int) newInfo.heapAddress > highestAddress)
                            highestAddress = (int) newInfo.heapAddress;
                    }

                    // Add the section information to the heaps
                    foreach(section section in headerReader.sections )
                    {
                        // Associate this section with a heap
                        index = addressToHeapinfoIndex.BinarySearch(new IntInt((int)section.SectionHeader.VirtualAddress + (int)peHeaderBases[i], 0), comparer);
                        if (index < 0)
                            index = ~index - 1;
                        if (index >= 0 && index < addressToHeapinfoIndex.Count)
                        {
                            // We found the heap this section resides in, lets add this section and associate the module.
                            HEAP_INFO newInfo = result[index];
                            newInfo.associatedModule = associatedModule;

                            // Add the section information
                            newInfo.extra = section.Name + " " + newInfo.extra;

                            // Change the heap info
                            result[index] = newInfo;

                            if ((int)newInfo.heapAddress > highestAddress)
                                highestAddress = (int)newInfo.heapAddress;
                        }
                    }

                    // Now associate all heaps up until highestAddress with this module
                    int indexStart = addressToHeapinfoIndex.BinarySearch(new IntInt(entry + (int)peHeaderBases[i], 0), comparer);
                    if (indexStart < 0)
                        indexStart = ~indexStart - 1;
                    int indexEnd = addressToHeapinfoIndex.BinarySearch(new IntInt(highestAddress,0), comparer);
                    if (indexEnd < 0)
                        indexEnd = ~indexEnd - 1;
                    for( int n = indexStart; n <= indexEnd; n++ )
                    {
                        // Associate this heap
                        HEAP_INFO newInfo = result[n];
                        newInfo.associatedModule = associatedModule;
                        result[n] = newInfo;
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                oConsole.printException(ex);
                return new List<HEAP_INFO>();
            }
        }
Пример #4
0
        public static bool validExecuteAddress(uint address)
        {
            bool result = false;

            // First make sure this address makes sense
            if (address > 0x0000000000 && address < 0xffffffff)
            {
                // Make sure the destination has access writes execute
                MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
                try
                {
                    int size = VirtualQueryEx(oProcess.activeProcess.Handle, (IntPtr)address, ref mbi, Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));
                    if (mbi.Protect == MEMORY_PROTECT.PAGE_EXECUTE ||
                        mbi.Protect == MEMORY_PROTECT.PAGE_EXECUTE_READ ||
                        mbi.Protect == MEMORY_PROTECT.PAGE_EXECUTE_READWRITE ||
                        mbi.Protect == MEMORY_PROTECT.PAGE_EXECUTE_WRITECOPY)
                    {
                        // This function call is to a execute page.
                        result = true;
                    }
                }
                catch
                {
                }
            }
            return result;
        }