首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >硬件断点WINAPI

硬件断点WINAPI
EN

Stack Overflow用户
提问于 2012-01-05 12:18:27
回答 1查看 2.3K关注 0票数 12

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

到目前为止,我获得了设置HW断点的两个函数:

代码语言:javascript
运行
复制
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);
}

代码语言:javascript
运行
复制
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;
 }

因此,首先,我创建了一个帮助线程,因为我正在调试当前线程。在帮助线程的回调函数中,我要挂起主线程。之后,我阅读了主线程当前的DR值(目前这与此无关,因为我总是使用DR0,在此工作之后,我将检查哪些寄存器是免费的,并使用4 BP‘s)。之后,我使用调用函数的返回地址(EIP)作为地址在DR0中中断,并在DR7中设置归属标志。

在结束时,我将恢复主线程并关闭助手线程的句柄。

使用这段代码,我遇到了以下问题:

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

如果我在不调试程序的情况下执行程序,那么它就会简单崩溃。我尝试使用__try,__except,就像在提到的项目(http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx)中一样,但这也不起作用。

我欣赏并帮助或告知我做错了什么,以及如何解决这个问题。

EN

回答 1

Stack Overflow用户

发布于 2012-03-16 12:37:38

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

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

在x86硬件上,通过在e标志中设置陷阱标志来启用单步执行.CPU将在完成一条指令后引发调试异常(中断1)。我认为visual调试器正在改变标志的一部分,干扰了您的尝试。

尝试在visual studio之外运行程序(没有调试器)。它是否如预期的那样起作用?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8742375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档