Reputation: 1
I want to set a breakpoint on my variable, when i do the read access, i have this code:
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);
//..
}
I always get 0 from int status = WaitForDebugEvent(&dbgEvent, INFINITE);
it doesnt perfrorm any waiting just returns 0 immediatly, i placed MessageBoxA
to test, basically i don't get any notifications and waiting that the read has performed on lpBuffer
. I think i have done something wrong, maybe it has to do with dr7 flags? 0x30002 is 00110000000000000010, so it should be hardware read/write bp.
Upvotes: 0
Views: 2929
Reputation: 33754
about debugging. for debug need create special DebugObject and associate process (which you want to debug) with this debug object. after this, when some events occur in process associated with debug object, system suspend all threads in process, insert debug event to debug object and set it to signal state. in debugger, thread which wait on debug object, say via WaitForDebugEvent
(but possible direct pass handle of debug object to say MsgWaitForMultipleObjectsEx
) awakened and handle this debug event. but if thread will be from debugged process - it will be suspended, as all threads in process and never handle this event. process hang in this case. so - process can not debug itself because system suspend all threads in process when debug event (exception for example) occur.
about WaitForDebugEvent
doesnt perfrorm any waiting. WaitForDebugEvent
internally call ZwWaitForDebugEvent
and from where is HANDLE hDebugObject
is geted ? from thread TEB (here exist special field for save it). when you call CreateProcess
with flag DEBUG_PROCESS
or DebugActiveProcess
system internally call DbgUiConnectToDbg
- this api check - are thread already have accosiated debug object (in TEB) and if yet no - create new with ZwCreateDebugObject
and store it in TEB (it can be accessed via DbgUiGetThreadDebugObject
and changed via DbgUiSetThreadDebugObject
). only after this you can call WaitForDebugEvent
. because you not direct create debug object via ZwCreateDebugObject
, and not call CreateProcess
with flag DEBUG_PROCESS
or DebugActiveProcess
- no debug objects assosiated with your thread, and call WaitForDebugEvent
of course fail
only one option catch hardware breakpoint in own process - use VEX. for example:
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);
}
}
Upvotes: 0