繁体   English   中英

硬件断点始终为EXCEPTION_SINGLE_STEP

[英]Hardware breakpoints EXCEPTION_SINGLE_STEP all the time

我有一个充当调试器的程序。 我为线程设置dr0设置了一个hw bp到我想要bp的地址,dr7设置为1,因为我希望每次执行该地址时bp都会生成一个事件。

它的工作原理但现在的问题是我不会一直停止接收EXCEPTION_SINGLE_STEP。 我像往常一样用WaitForDebugEvent创建了一个循环:

DebugActiveProcess(pid);
while (flag == 0)
    {
        WaitForDebugEvent(&DBEvent, INFINITE);
        if (first_time){
            setHWBPInCurrentThreads(pid, breakpoint_address);
            first_time = 0;
        }
        switch (DBEvent.dwDebugEventCode)
        {
            // Here we check if a new thread is created and we set a BP for all of them
            case CREATE_THREAD_DEBUG_EVENT: 
            {
                HANDLE thread_handle = DBEvent.u.CreateProcessInfo.hProcess;
                HANDLE hX3 = SetHardwareBreakpoint(thread_handle, HWBRK_TYPE_CODE, HWBRK_SIZE_1, breakpoint_address);

            }break;

            case EXCEPTION_DEBUG_EVENT:
            {
                switch (DBEvent.u.Exception.ExceptionRecord.ExceptionCode)
                {
                case EXCEPTION_SINGLE_STEP:
                {       
                    printf("%d\n", DBEvent.dwThreadId);
                    ///MessageBoxA(0, "yesssssssss", "", 0);
                }break;

                case EXCEPTION_BREAKPOINT:
                {
                    //MessageBoxA(0, "Found break point", "", 0);

                }break;
                }
            }break;

        }

        ContinueDebugEvent(DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE);
                }

这有什么不对? 我该怎么办才能让异常发生,并且只在下次执行地址时获取控件?

即使在命中断点之后,您的实现也只是继续调试事件,这将在无限循环中再次触发断点。

需要根据您使用的环境以不同方式处理正确的实现。 如果您在比Windows XP更新的环境中进行调试,则处理断点的方式是:

  1. 设置恢复标志(EFLAG)。
  2. 继续调试事件(ContinueDebugEvent)。

如果您在Windows XP环境中工作,则需要将实现更改为:

  1. 禁用断点(Dr7)。
  2. 设置陷阱标志(EFLAG)。
  3. 继续调试事件(ContinueDebugEvent)。
  4. 等待陷阱标志引起的EXCEPTION_SINGLE_STEP(您现在处于下一条指令)。
  5. 启用断点(Dr7)。
  6. 继续调试事件(ContinueDebugEvent)。

很抱歉这个旧线程,这些都是正确的实现。

我终于发现了正在发生的事情:hw bp的工作方式与软件bp不同。 使用软件断点,您只需调用ContinueDebugEvent并等待下一个事件发生(达到bp)。

使用HW bp,您需要首先重置Dr0-Dr3,Dr6和Dr7寄存器,然后调用ContinueDebugEvent ,然后再次设置寄存器,就像生成事件时那样。 这很令人困惑,因为ContinueDebugEvent的行为与软件Breakpoints中的行为不同。

我希望这可以帮助其他人解决同样的问题。

干杯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM