[英]Setting hardware breakpoint using winapi for current process
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);
我总是从int status = WaitForDebugEvent(&dbgEvent, INFINITE);
得到0 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
. 它不会完美地等待,只是立即返回0,我将MessageBoxA
放置到测试中,基本上我没有收到任何通知,并等待对lpBuffer
执行的读取。 I think i have done something wrong, maybe it has to do with dr7 flags? 我认为我做错了什么,也许与dr7标志有关? 0x30002 is 00110000000000000010, so it should be hardware read/write bp. 0x30002是00110000000000000010,因此应为硬件读/写bp。
about debugging. 关于调试。 for debug need create special DebugObject and associate process (which you want to debug) with this debug object. 对于调试,需要创建特殊的DebugObject并将该进程(您要调试的)与此调试对象相关联。 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. 在调试器中,等待对象的线程,例如,通过WaitForDebugEvent
(但可以通过调试对象的直接传递句柄说MsgWaitForMultipleObjectsEx
)唤醒,并处理此调试事件。 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
不会造成任何等待。 WaitForDebugEvent
internally call ZwWaitForDebugEvent
and from where is HANDLE hDebugObject
is geted ? WaitForDebugEvent
内部调用ZwWaitForDebugEvent
,从何处HANDLE hDebugObject
? from thread TEB (here exist special field for save it). 从线程TEB (此处存在用于保存它的特殊字段)。 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
). 当您使用标志DEBUG_PROCESS
调用CreateProcess
或DebugActiveProcess
系统在内部调用DbgUiConnectToDbg
-此api检查-线程是否已附带调试对象(在TEB中 ),如果还没有,请使用ZwCreateDebugObject
创建新对象并将其存储在TEB中 (可以通过DbgUiGetThreadDebugObject
访问并通过DbgUiSetThreadDebugObject
更改)。 only after this you can call WaitForDebugEvent
. 只有在此之后,您才能调用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 因为您没有通过ZwCreateDebugObject
直接创建调试对象,并且没有用标志DEBUG_PROCESS
或DebugActiveProcess
调用CreateProcess
没有调试对象与您的线程DEBUG_PROCESS
,所以调用WaitForDebugEvent
当然会失败
only one option catch hardware breakpoint in own process - use VEX . 只有一个选项可以在自己的过程中捕获硬件断点-使用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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.