Hardwarebreakpoint WINAPI

Chr*_*ris 12 c++ winapi breakpoints

我目前正在实现一个小调试框架的最后一个任务,即HW Breakpoints.到目前为止我提到了这篇文章:http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx和一本关于编写调试器的书.

到目前为止,我有两个函数用于设置HW断点:

void debuglib::breakpoints::hw_bp() {
    HANDLE helper = 0;

    CONTEXT co;
    CURRENTCONTEXT(co);

    helper = ::CreateThread(0,0,threadfunc,reinterpret_cast<void*>(co.Eip),0,0);

    DWORD status = ::WaitForSingleObject(helper,INFINITE);


    if (status != WAIT_OBJECT_0) { 
            ::MessageBoxA(0, "Helper thread didn't exit cleanly", "HWBreakpoint", MB_OK);
    }

    ::CloseHandle(helper);
}
Run Code Online (Sandbox Code Playgroud)
static DWORD WINAPI debuglib::breakpoints::threadfunc(void* param) {

    DWORD suspendcnt = ::SuspendThread(debuglib::process::thread());
    if(suspendcnt) {
        return 0;
    }

    CONTEXT co;
    ::ZeroMemory(&co,sizeof(co));
    co.ContextFlags = CONTEXT_DEBUG_REGISTERS;

    BOOL ok = ::GetThreadContext(debuglib::process::thread(),&co);

    if(!ok) {
        return 0;
    }

    DWORD freeDr = 0;
    DWORD condition = debuglib::breakpoints::TRIGGER::CODE;
    DWORD length = debuglib::breakpoints::SIZE::SIZE_1;

    co.Dr0 = reinterpret_cast<DWORD>(param);

    co.Dr7 = co.Dr7 | 1 << (freeDr*2);
    co.Dr7 = co.Dr7 | condition << ((freeDr*4)+16);
    co.Dr7 = co.Dr7 | length << ((freeDr*4)+18);

    co.ContextFlags = CONTEXT_DEBUG_REGISTERS;
    ok = ::SetThreadContext(debuglib::process::thread(), &co);

    co.ContextFlags = CONTEXT_DEBUG_REGISTERS;
    ::GetThreadContext(debuglib::process::thread(),&co);

    suspendcnt = ::ResumeThread(debuglib::process::thread());
    if(suspendcnt == 0xFFFFFFFF) {
        return 0;
    }

    return 1;
 }
Run Code Online (Sandbox Code Playgroud)

所以首先我要创建一个辅助线程,因为我正在调试当前线程.在辅助线程的回调函数中,我挂起了主线程.之后我读取了主线程的当前DR值(此时这是不相关的,因为我总是使用DR0,在此工作之后,我将检查哪些寄存器是空闲的并且最多使用4个BP).之后,我使用调用函数(EIP)的返回地址作为DR0中断的地址,并在DR7中设置所有的标志.

最后,我正在恢复主线程并关闭辅助线程的句柄,因为它已完成.

使用此代码我遇到以下问题:

如果我在调试模式下执行程序,程序会在正确的地址停止,但我不能再做任何事了,因为设置了INT1标志,我想VS调试器不能单步执行?

如果我执行程序而不调试它简单崩溃.我尝试使用__try,__除了上面提到的项目(http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx),但这也不起作用.

我感谢并帮助或了解我做错了什么以及如何解决这个问题.

dou*_*536 2

我认为尝试让程序自行调试并不是一个好主意。为什么不使用 Windows 内置的调试器开发 API?

开发中心 - 桌面 > 学习 > 参考 > 诊断 > 调试和错误处理 > 基本调试 > 调试参考 > 调试功能: http://msdn.microsoft.com/en-us/library/windows/desktop/ms679303%28v=vs .85%29.aspx

在 x86 硬件上,通过在 eflags 中设置陷阱标志来启用单步执行。CPU 在完成一条指令后将引发调试异常(中断 1)。我认为正在发生的事情是 Visual Studio 调试器正在更改那部分标志,干扰您想要执行的操作。

尝试在 Visual Studio 之外运行您的程序(无调试器)。那么它能按预期工作吗?