MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Почему buffer при использовании ReadProcessMemory заполняется нулями?"
Answer 926443
Для того, чтобы ReadProcessMemory отработала успешно, нужно следующее:
Дескриптор процесса должен быть открыт с правом PROCESS_VM_READ. У вас он открывается с правом PROCESS_TERMINATE, что явно не то.
Вся запрашиваемая область памяти быть доступна на чтение. Так как вы запрашиваете область, начинающуюся от нулевого байта, у вас всегда будет выбивать ошибку, ведь часть младших адресов памяти зарезервирована для отлова багов с обращением к нулевым указателям и недоступна на чтение. Нужно считывать память блоками меньшего размера.
Также, для адресов лучше использовать тип IntPtr, а не uint, иначе программа не сможет корректно работать при 64-битной целевой архитектуре.
Пример считывания первого доступного блока памяти в 1024 байта:
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Program { public enum DesiredAccessProcess : uint { PROCESS_TERMINATE = 0x0001, PROCESS_CREATE_THREAD = 0x0002, PROCESS_VM_OPERATION = 0x0008, PROCESS_VM_READ = 0x0010, PROCESS_VM_WRITE = 0x0020, PROCESS_DUP_HANDLE = 0x0040, PROCESS_CREATE_PROCESS = 0x0080, PROCESS_SET_QUOTA = 0x0100, PROCESS_SET_INFORMATION = 0x0200, PROCESS_QUERY_INFORMATION = 0x0400, SYNCHRONIZE = 0x00100000, PROCESS_ALL_ACCESS = SYNCHRONIZE | 0xF0FFF } [DllImport("Kernel32.dll", SetLastError = true)] public static extern IntPtr OpenProcess(DesiredAccessProcess dwDesiredAccess, bool bInheritHandle, uint dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] public static extern int ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, IntPtr size, out IntPtr lpNumberOfBytesRead); static void Main(string[] args) { IntPtr m_startAddress = (IntPtr)0; // Адрес, с которого начинается сканирование IntPtr m_scanLength = (IntPtr)1024; // Длина сканируемой области в байтах IntPtr m_bytesRead; // Количество прочитанных байт byte[] buffer = new byte[(int)m_scanLength]; Process m_process = null; Process[] processes = Process.GetProcessesByName("notepad++"); if (processes.Length == 0) throw new Exception("Can't find process!"); m_process = processes[0]; using (m_process) { IntPtr m_intptrProcess = OpenProcess(DesiredAccessProcess.PROCESS_VM_READ, false, (uint)m_process.Id); if (m_intptrProcess == IntPtr.Zero) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); for (UInt64 n = 0; n < UInt64.MaxValue - (UInt64)m_scanLength; n += (UInt64)m_scanLength) { m_startAddress = (IntPtr)n; Console.Write("Address 0x" + n.ToString("X").PadLeft(16, '0') + ": "); int res = ReadProcessMemory(m_intptrProcess, (IntPtr)m_startAddress, buffer, m_scanLength, out m_bytesRead); if (res == 0) { Console.WriteLine("ReadProcessMemory failed. Code: {0}", Marshal.GetLastWin32Error()); } else { Console.WriteLine("Bytes read: {0}", m_bytesRead); for (int i = 0; i < (int)m_scanLength; i++) { Console.Write(buffer[i].ToString("X").PadLeft(2,'0') + " "); } break; } } } Console.ReadKey(); } } }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.