Я пытаюсь подключить контрольную точку оборудования к игровому процессу, и я добился успеха. Затем я пытаюсь пройти через Исключения и дождаться того, что я там вложил, что тоже отлично работает. Проблема в том, что после этого она переходит в бесконечный цикл, который я не могу тормозить. Вы можете посоветовать? Причина, по которой я это делаю, заключается в том, что я хочу остановить поток в этот момент, прочитать значение EAX с помощью контекста, а затем продолжить процесс.Бесконечный цикл при отладке нити
Header.h включает функции, которые вызывают здесь, и все они работают нормально, поэтому Im не включает его в этот момент.
#include "header.h" #include
INT основной() {
SetDebugPrivilege(TRUE);
DWORD dwProcessID = 0;
DWORD dwGame = 0;
printf("Looking for game process...\n");
while (dwProcessID == 0) {
dwProcessID = GetProcessID(L"PathOfExile.exe");
if (dwProcessID != 0)
dwGame = 1;
Sleep(100);
}
printf("dwProcessID = %p\n", dwProcessID);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
MODULEENTRY32 module;
module.dwSize = sizeof(MODULEENTRY32);
Module32First(snapshot, &module);
printf("PoE base address = %p\n", module.modBaseAddr);
hpChangeBreakpoint = (DWORD*)((char *)module.modBaseAddr + 0x1AAD20);
std::cout << hpChangeBreakpoint << std::endl;
//hpChangeBreakpoint = 0x013FB279;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessID);
BOOL bDebugging = DebugActiveProcess(dwProcessID);
printf("bDebugging = %d\n", bDebugging);
DWORD dwThreadID = GetProcessThreadID(dwProcessID);
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadID);
CONTEXT parentCtx;
parentCtx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
if (GetThreadContext(hThread, &parentCtx))
{
parentCtx.Dr0 = (DWORD)hpChangeBreakpoint;
parentCtx.Dr7 = 0x00000001;
std::cout << "GetThreadContext successful" << std::endl;
SetThreadContext(hThread, &parentCtx);
}
DEBUG_EVENT DebugEvent;
DWORD dbgFlag = DBG_CONTINUE;
DWORD *currentHpPointerAddress = nullptr;
DWORD *maxHpPointerAddress = nullptr;
BOOLEAN bQuit = FALSE;
while (!bQuit && WaitForDebugEvent(&DebugEvent, INFINITE))
{
dbgFlag = DBG_CONTINUE;
switch (DebugEvent.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
switch (DebugEvent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_SINGLE_STEP:
if (DebugEvent.u.Exception.ExceptionRecord.ExceptionAddress == (void*)hpChangeBreakpoint)
{
#define RESUME_FLAG 0x10000
CONTEXT childContext;
childContext.ContextFlags = CONTEXT_FULL;
if (GetThreadContext(hThread, &childContext))
{
childContext.EFlags |= RESUME_FLAG;
SetThreadContext(hThread, &childContext);
std::cout << "current HP: " << childContext.Ecx << std::endl;
currentHpPointerAddress = (DWORD*)((char *)childContext.Edi + 0x8E0);
maxHpPointerAddress = (DWORD*)((char *)childContext.Edi + 0x8E4);
}
if (GetThreadContext(hThread, &parentCtx))
{
parentCtx.Dr0 = 0;
parentCtx.Dr7 = 0x400;
SetThreadContext(hThread, &parentCtx);
bQuit = TRUE;
}
}
else
dbgFlag = DBG_EXCEPTION_NOT_HANDLED;
break;
default:
dbgFlag = DBG_EXCEPTION_NOT_HANDLED;
}
break;
case LOAD_DLL_DEBUG_EVENT:
{
CloseHandle(DebugEvent.u.LoadDll.hFile);
break;
}
case CREATE_PROCESS_DEBUG_EVENT:
{
CloseHandle(DebugEvent.u.CreateProcessInfo.hFile);
break;
}
case EXIT_PROCESS_DEBUG_EVENT:
break;
default:
__nop();
}
if (!ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, dbgFlag))
{
break;
}
if (bQuit)
DebugActiveProcessStop(dwProcessID);
}
while (1)
{
WORD currentHP = 0;
WORD maxHP = 0;
if (
ReadProcessMemory(hProcess, currentHpPointerAddress, ¤tHP, sizeof(currentHP), NULL) == 0
|| ReadProcessMemory(hProcess, maxHpPointerAddress, &maxHP, sizeof(maxHP), NULL) == 0
)
{
printf("Failed to read memory: %u\n", GetLastError());
}
else {
std::cout << "HP: " << currentHP << "/" << maxHP << std::endl;
}
Sleep(1000);
}
system("pause>nul");
return 0;
}
Когда я запускаю его, игра работает отлично, пока точка останова не происходит, когда он делает, я получаю бесконечный спам «breakpoint» cout, и когда я его отлаживаю, эта строка: if (DebugEvent.u.Exception.ExceptionRecord.ExceptionAddress == (void *) hpChangeBreakpoint)
всегда верно, но флаг dwFirstChance равен 1, поэтому его всегда является новым исключением? Единственное, что меняется в этом бесконечном цикле, это hThread, всегда другое. Я чувствую, что я что-то теряю из-за своей нехватки знаний, поэтому буду благодарен за любую помощь или намеки в правильном направлении. Спасибо!
«Возвращаясь к теме, бесконечный цикл до сих пор здесь Ive добавил RF флаг» - но вы не называете «SetThreadContext» !! какой смысл просто инициализировать «КОНТЕКСТ Контекст» - без вызова «SetThreadContext» - исправить это первым, для устранения основной проблемы. если вы не работаете под XP. «что нить приостановлена на этом этапе» - до того, как вы вызове ContinueDebugEvent - весь процесс приостановлен - вам не нужно вызывать 'SuspendThread' /' ResumeThread' «даже если бы я изменил память, нет необходимости в них? " - да, не нужно – RbMm
О, моя собака, такая очевидная :) Позвольте мне поближе познакомиться! Спасибо большое RbMm! – MTM
Похоже, он проходит через помощника! :) Спасибо! Есть еще одна проблема - после прохождения этого исключения есть EXCEPTION_ACCESS_VIOLATION, если я не справляюсь с этим, после второй попытки это приведет к сбою приложения. Может ли это быть связано с тем, что я делаю? – MTM