/// <summary> /// Creates a new <see cref="MemoryBufferHelper"/> for the specified process. /// </summary> /// <param name="process">The process.</param> public MemoryBufferHelper(Process process) { Process = process; _bufferSearcher = new MemoryBufferSearcher(process); _virtualQueryFunction = VirtualQueryUtility.GetVirtualQueryFunction(process); _allocateMemoryMutex = MutexObtainer.MakeMutex(CreateBufferMutexName()); }
/// <summary> /// Returns a list of pages that exist within a set process' memory. /// </summary> /// <returns></returns> public static List <MEMORY_BASIC_INFORMATION> GetPages(Process process) { // Is this Windows on Windows 64? (x86 app running on x64 Windows) IsWow64Process(process.Handle, out bool isWow64); GetSystemInfo(out SYSTEM_INFO systemInfo); // This should work. nuint currentAddress = 0; nuint maxAddress = 0x7FFFFFFF; // 32bit (with Address Range Extension) // Check if 64bit. if (systemInfo.wProcessorArchitecture == ProcessorArchitecture.PROCESSOR_ARCHITECTURE_AMD64 && !isWow64) { maxAddress = systemInfo.lpMaximumApplicationAddress; } // Support Large Address Aware if (IntPtr.Size == 4 && (nuint)systemInfo.lpMaximumApplicationAddress > maxAddress) { maxAddress = (nuint)systemInfo.lpMaximumApplicationAddress; } // Get the VirtualQuery function implementation to use. // Local is faster and works for current process; Remote is for another process. VirtualQueryUtility.VirtualQueryFunction virtualQueryFunction = VirtualQueryUtility.GetVirtualQueryFunction(process); // Shorthand for convenience. List <MEMORY_BASIC_INFORMATION> memoryPages = new List <MEMORY_BASIC_INFORMATION>(8192); // Until we get all of the pages. while (currentAddress <= maxAddress) { // Get our info from VirtualQueryEx. var memoryInformation = new MEMORY_BASIC_INFORMATION(); var result = virtualQueryFunction(process.Handle, (nuint)currentAddress, ref memoryInformation); if (result == (UIntPtr)0) { break; } // Add the page and increment address iterator to go to next page. memoryPages.Add(memoryInformation); currentAddress += memoryInformation.RegionSize; } return(memoryPages); }
/// <summary> /// Attempts to find an existing <see cref="MemoryBuffer"/> at the specified address and returns an instance of it. /// If the operation fails; the function returns null. /// </summary> internal static unsafe MemoryBuffer FromAddress(Process process, IntPtr bufferMagicAddress) { // Query the region we are going to create a buffer in. var virtualQueryFunction = VirtualQueryUtility.GetVirtualQueryFunction(process); var memoryInformation = new Kernel32.Kernel32.MEMORY_BASIC_INFORMATION(); virtualQueryFunction(process.Handle, bufferMagicAddress, ref memoryInformation); if (memoryInformation.State != (uint)Memory.Kernel32.Kernel32.MEM_ALLOCATION_TYPE.MEM_FREE) { if (IsBuffer(process, bufferMagicAddress)) { var buffer = new MemoryBuffer(GetMemorySource(process), bufferMagicAddress + sizeof(MemoryBufferMagic)); buffer.SetupMutex(process); return(buffer); } } return(null); }
/// <summary> /// Creates a new <see cref="MemoryBufferHelper"/> for the specified process. /// </summary> /// <param name="process">The process.</param> public MemoryBufferHelper(Process process) { Process = process; _bufferSearcher = new MemoryBufferSearcher(process); _virtualQueryFunction = VirtualQueryUtility.GetVirtualQueryFunction(process); }