Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hardware breakpoints EXCEPTION_SINGLE_STEP all the time

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?

like image 374
Ryan Fold Avatar asked Nov 15 '25 21:11

Ryan Fold


1 Answers

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.

like image 105
kappa Avatar answered Nov 17 '25 12:11

kappa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!