我試圖將一個硬件斷點附加到遊戲進程,並且我成功了。然後我試着循環執行例外,並等待我放入那裏的那個,這也正常工作。問題是,它發生後會進入無限循環,我無法制動。你能建議嗎? 我這樣做的原因是我想在此停止線程,使用上下文讀取EAX值,然後繼續該過程。調試線程時出現無限循環
Header.h包含在這裏被調用的函數,它們都工作正常,因此我沒有包括在這一點上。
的#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;
}
當我運行它,遊戲運行正常,直到斷點發生時,它確實,我得到無限的「斷點」cout的垃圾郵件,當我調試它,這條線: if(DebugEvent.u.Exception.ExceptionRecord.ExceptionAddress ==(void *)hpChangeBreakpoint)
總是如此,但dwFirstChance標誌是1,所以它總是一個新的異常?在這個無限循環中唯一改變的是hThread,總是不同的。我覺得自己因爲缺乏知識而錯過了一些東西,因此會感謝任何幫助或提示正確的方向。謝謝!
「讓我們回到主題,無限循環還在這裏伊夫添加的RF標誌」 - 但你不叫「SetThreadContext」!什麼感覺簡單地初始化'CONTEXT上下文' - 沒有調用「SetThreadContext」 - 首先解決這個問題,以解決主要問題。如果你不在XP下運行。 「這個線程暫時被掛起」 - 在你調用ContinueDebugEvent之前 - 所有進程都被掛起 - 你不需要調用'SuspendThread' /'ResumeThread' 「即使我會修改內存,不需要它們嗎? 「 - 是的,不需要 – RbMm
哦,我的狗,如此明顯:)讓我接受它,會讓你知道!非常感謝RbMm! – MTM
它看起來像穿過隊友! :) 謝謝!還有另一個問題 - 在傳遞這個異常之後,有一個EXCEPTION_ACCESS_VIOLATION,如果我沒有處理它,在第二次嘗試它崩潰應用程序後。它可能與我在做什麼有關? – MTM