callstack и ReadProcessMemory
Я пытаюсь прочитать адрес возврата метода, но из другой памяти. поэтому я получаю указатель кадра и читаю значение возвращаемого значения. Насколько я понимаю, я должен получить значение, равное m_stackframe. AddrReturn.Offset, но:
- Если я добавлю Esp к адресу указателя кадра - ReadProcessMemory вернет false.
- Если я просто использую смещение кадра адреса - я получаю неправильное значение.
// Чтение верхнего метода в стеке. bool ok = StackWalk64 (IMAGE_FILE_MACHINE_I386, m_processInfo.Handle, m_threadInfo.Handle, & m_stackframe, & m_threadContext, 0, SymFunctionTableAccess64, SymGetModuleBase64,0); // регистр Esp является базовым адресом стека, верно? DWORD baseAddressOfCallstack = m_threadContext.Esp; // Получение абсолютного адреса путем добавления ESP к адресу стекового фрейма. DWORD absoluteAddressInCallstack = m_stackframe.AddrFrame.Offset + baseAddressOfCallstack; // Преобразование его в указатель. DWORD* addressInCallStack = (DWORD*)absoluteAddressInCallstack; DWORD val = 0; SIZE_T bytesRead = 0; // и пытаемся прочитать это из процесса... ok = ReadProcessMemory(m_processInfo.Handle, addressInCallStack, (void*)&val, sizeof(DWORD) и &bytesRead);
Я использую C++ на Windows. Кто-нибудь может сказать мне, что с ним не так? Спасибо:)
1 ответ
Адрес возврата равен EBP + 4 в текущем кадре стека.
Всякий раз, когда вызывается новая функция, устанавливается новый кадр стека, а старый ESP (указатель стека) перемещается в EBP (базовый указатель). Локальные переменные создаются в стеке путем вычитания нового указателя стека. Переданные аргументы передаются в обратном порядке до вызова. Из базового указателя вы можете получить обратный адрес.