Example #1
0
        public static List<addressRegion> GetValidReadHeaps(Process process)
        {
            List<addressRegion> result = new List<addressRegion>(200);

            // Search the process for heaps
            long address = 0;
            long addressLast = long.MaxValue;
            MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
            while (address != addressLast)
            {
                // Load this heap information
                long blockSize = (long)VirtualQueryEx(process.Handle, (IntPtr)address, ref mbi, (IntPtr)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));
                addressLast = address;
                address = (long)mbi.BaseAddress + (long)mbi.RegionSize + 1;

                // Check if this has READ privilege and does not have a GUARD
                if ((mbi.Protect & (MEMORY_PROTECT.PAGE_GUARD | MEMORY_PROTECT.PAGE_NOACCESS | MEMORY_PROTECT.PAGE_EXECUTE)) == 0 &&
                    mbi.State == StateEnum.MEM_COMMIT)
                {
                    // This is a valid read heap
                    result.Add(new addressRegion((IntPtr)mbi.BaseAddress, (int)mbi.RegionSize));
                }
            }

            return result;
        }
Example #2
0
 static extern Int32 VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, ref MEMORY_BASIC_INFORMATION buffer, IntPtr dwLength);
Example #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>();

                // Search the process for heaps
                long address = 0;
                long addressLast = long.MaxValue;
                MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
                while (address != addressLast)
                {
                    // Load this heap information
                    long blockSize = (long)VirtualQueryEx(process.Handle, (IntPtr)address, ref mbi, (IntPtr)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));

                    if (blockSize == 0)
                    {
                        int error = GetLastError();
                        error++;
                    }

                    // Try to associate a module with this memory block
                    ProcessModule associatedModule = null;
                    foreach (ProcessModule module in process.Modules)
                    {
                        if (((ulong)module.BaseAddress >= (ulong)mbi.BaseAddress) && ((ulong)module.BaseAddress < (ulong)mbi.BaseAddress + (ulong)mbi.RegionSize))
                        {
                            associatedModule = module;
                            break;
                        }
                        else if (associatedModule == null && (ulong)module.BaseAddress < (ulong)mbi.BaseAddress)
                        {
                            associatedModule = module;
                        }
                        else if (associatedModule == null)
                        {

                        }
                        else if (((ulong)module.BaseAddress <= (ulong)mbi.BaseAddress) && ((ulong)module.BaseAddress > (ulong)associatedModule.BaseAddress))
                        {
                            associatedModule = module;
                        }
                    }

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

                    // Decide if this heap is a PE header or not
                    string peHeader = "";
                    if (((mbi.Protect & MEMORY_PROTECT.PAGE_GUARD) == 0) && (mbi.State == StateEnum.MEM_COMMIT))
                    {
                        peHeader = (HeaderReader.isPeHeader(process, (ulong)mbi.BaseAddress, mbi.Protect) ? "PE HEADER" : "");
                    }

                    // Add this heap information
                    result.Add(new HEAP_INFO((ulong)mbi.BaseAddress, (ulong)mbi.RegionSize, mbi.Protect.ToString(), peHeader, associatedModule, mbi.State, mbi.Protect));
                }
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return new List<HEAP_INFO>();
            }
        }
Example #4
0
        public static UInt32 ReadMemoryDword(Process process, IntPtr address)
        {
            // Copy the bytes from this heap
            byte[] buffer = new byte[4];
            int numRead = 0;
            bool result = ReadProcessMemory(process.Handle, (IntPtr)address, buffer, 4, out numRead);

            // Check that all the data was read correctly
            if ((UInt32)numRead != 4 || !result)
            {
                // Retry once incase we caused a page guard stack growth
                MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
                long blockSize = (long)VirtualQueryEx(process.Handle, (IntPtr)address, ref mbi, (IntPtr)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));
                throw new Exception("Failed to read DWORD from address " + address.ToString("X") + ". Read " + numRead.ToString() + " of 4. GetLastError() = " + GetLastError().ToString() + "\n" + mbi.Protect.ToString() + "\n" + mbi.State.ToString());
            }

            return (UInt32)RawDataToObject(ref buffer, typeof(UInt32));
        }