[英]Setting hardware breakpoint using winapi for current process
我想在變量上設置一個斷點,當我進行讀取訪問時,我有以下代碼:
char * lpBuffer = NULL;
void proc(PVOID)
{
for (int i = 0; i < 10; i++) {
Sleep(100);
MessageBoxA(0, 0, 0, 0);
char * h = lpBuffer;
h[0x4] = 0x88;
}
}
int main()
{
lpBuffer = malloc(20);
SetDebugPrivilege(TRUE);
HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)proc, 0, CREATE_SUSPENDED, 0);
CONTEXT ctx = {};
BOOL st = GetThreadContext(hThread, &ctx);
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
ctx.Dr0 = (DWORD)&lpBuffer;
ctx.Dr7 = 0x30002;
st = SetThreadContext(hThread, &ctx);
ResumeThread(hThread);
DEBUG_EVENT dbgEvent;
int status = WaitForDebugEvent(&dbgEvent, INFINITE);
//..
}
我總是從int status = WaitForDebugEvent(&dbgEvent, INFINITE);
得到0 int status = WaitForDebugEvent(&dbgEvent, INFINITE);
它不會完美地等待,只是立即返回0,我將MessageBoxA
放置到測試中,基本上我沒有收到任何通知,並等待對lpBuffer
執行的讀取。 我認為我做錯了什么,也許與dr7標志有關? 0x30002是00110000000000000010,因此應為硬件讀/寫bp。
關於調試。 對於調試,需要創建特殊的DebugObject並將該進程(您要調試的)與此調試對象相關聯。 此后,當與調試對象相關聯的進程中發生某些事件時,系統掛起進程中的所有線程 ,將調試事件插入調試對象並將其設置為信號狀態。 在調試器中,等待對象的線程,例如,通過WaitForDebugEvent
(但可以通過調試對象的直接傳遞句柄說MsgWaitForMultipleObjectsEx
)喚醒,並處理此調試事件。 但是如果線程將來自已調試的進程,則它將被掛起,因為所有進程中的線程都不會處理此事件。 在這種情況下進程掛起。 因此-進程無法調試自身,因為在發生調試事件(例如,異常)時,系統會掛起進程中的所有線程 。
關於WaitForDebugEvent
不會造成任何等待。 WaitForDebugEvent
內部調用ZwWaitForDebugEvent
,從何處HANDLE hDebugObject
? 從線程TEB (此處存在用於保存它的特殊字段)。 當您使用標志DEBUG_PROCESS
調用CreateProcess
或DebugActiveProcess
系統在內部調用DbgUiConnectToDbg
-此api檢查-線程是否已附帶調試對象(在TEB中 ),如果還沒有,請使用ZwCreateDebugObject
創建新對象並將其存儲在TEB中 (可以通過DbgUiGetThreadDebugObject
訪問並通過DbgUiSetThreadDebugObject
更改)。 只有在此之后,您才能調用WaitForDebugEvent
。 因為您沒有通過ZwCreateDebugObject
直接創建調試對象,並且沒有用標志DEBUG_PROCESS
或DebugActiveProcess
調用CreateProcess
沒有調試對象與您的線程DEBUG_PROCESS
,所以調用WaitForDebugEvent
當然會失敗
只有一個選項可以在自己的過程中捕獲硬件斷點-使用VEX 。 例如:
LONG NTAPI OnVex(PEXCEPTION_POINTERS ExceptionInfo)
{
WCHAR buf[1024], *sz = buf, wz[64];
PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
swprintf(wz, L"%x> %x at %p", GetCurrentThreadId(), ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionAddress);
*buf = 0;
if (ULONG NumberParameters = ExceptionRecord->NumberParameters)
{
sz += swprintf(sz, L"[ ");
PULONG_PTR ExceptionInformation = ExceptionRecord->ExceptionInformation;
do
{
sz += swprintf(sz, L"%p, ", *ExceptionInformation++);
} while (--NumberParameters);
sz += swprintf(sz - 2, L" ]");
}
MessageBoxW(0, buf, wz, 0);
return ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
}
DWORD HardwareTest(PVOID pv)
{
WCHAR sz[64];
swprintf(sz, L"hThread = %p\n", *(void**)pv);
return MessageBoxW(0, 0, sz, MB_ICONINFORMATION);
}
void ep()
{
if (PVOID handler = AddVectoredExceptionHandler(TRUE, OnVex))
{
if (HANDLE hThread = CreateThread(0, 0, HardwareTest, &hThread, CREATE_SUSPENDED, 0))
{
CONTEXT ctx = {};
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
ctx.Dr3 = (ULONG_PTR)&hThread;
ctx.Dr7 = 0xF0000040;
SetThreadContext(hThread, &ctx);
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
RemoveVectoredExceptionHandler(handler);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.