[英]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.