Hardware breakpoints EXCEPTION_SINGLE_STEP all the time

时光怂恿深爱的人放手 提交于 2019-12-11 03:35:04

问题


I have a program that acts as a debugger. I set a hw bp for a thread setting dr0 to the address I want to bp to be in and dr7 as 1 because I want the bp to generate an event each time that address is executed.

It works but the problem now is that I don't stop receiving the EXCEPTION_SINGLE_STEP all the time. I created a loop with WaitForDebugEvent as normal:

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);
                }

What is wrong here? What should I do to let the exception go and only get the control the next time that the address is being executed?


回答1:


Your implementation simply continues the debug event even after the break point is hit, which will trip the break point again in an infinite loop.

The correct implementation needs to be handled differently depending on the environment you work with. If you are debugging in a newer environment than Windows XP, the way you handle a break point would be:

  1. Set the Resume Flag (EFLAG).
  2. Continue the debug event (ContinueDebugEvent).

If you do work in a Windows XP environment, your implementation needs to be changed to:

  1. Disable the break point (Dr7).
  2. Set the Trap Flag (EFLAG).
  3. Continue the debug event (ContinueDebugEvent).
  4. Wait for the EXCEPTION_SINGLE_STEP caused by the Trap Flag (you are now at the next instruction).
  5. Enable the break point (Dr7).
  6. Continue the debug event (ContinueDebugEvent).

Sorry to bump this old thread, however, these are the correct implementations.




回答2:


I finally found out what is happening: The way hw bp works is different than software bp. With software breakpoints you can just call ContinueDebugEvent and wait for the next event to happen (bp being reached).

With HW bp you need to first reset the Dr0-Dr3,Dr6 and Dr7 registers then call ContinueDebugEvent and after that set again the registers as they were when the event was generated. It's confusing because ContinueDebugEvent is not acting the same way as in software Breakpoints.

I hope this helps somebody else with the same problem.

Cheers



来源:https://stackoverflow.com/questions/29287507/hardware-breakpoints-exception-single-step-all-the-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!