Hardware breakpoints EXCEPTION_SINGLE_STEP all the time

I have a program that acts like a debugger. I set hw bp to set the dr0 stream to the address that I want to include bp, and dr7 as 1, because I want bp to generate an event every time this address is executed.

This works, but now the problem is that I do not stop getting EXCEPTION_SINGLE_STEP all the time. I created a loop with WaitForDebugEvent as usual:

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 make the exception pass, and only get control the next time the address is executed?

+2
source share
2 answers

Your implementation simply continues the debugging event even after the breakpoint hits, which again disables the breakpoint in an infinite loop.

The correct implementation should be handled differently depending on the environment you are working with. If you are debugging a newer environment than Windows XP, the way to handle a breakpoint is:

  • Set the resume flag (EFLAG).
  • Continue a debugging event (ContinueDebugEvent).

If you are running Windows XP, your implementation should be changed to:

  • Disable breakpoint (Dr7).
  • Set the trap flag (EFLAG).
  • Continue a debugging event (ContinueDebugEvent).
  • Wait for EXCEPTION_SINGLE_STEP caused by the Trap flag (now you will follow the next instruction).
  • Enable breakpoint (Dr7).
  • Continue a debugging event (ContinueDebugEvent).

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

+5
source

I finally found out what was going on: The way hw bp works is different from bp software. With software breakpoints, you can simply call ContinueDebugEvent and wait for the next event (bp is reached).

With HW bp, you first need to reset the registers Dr0-Dr3, Dr6 and Dr7, then call ContinueDebugEvent , and then set the registers again as they were when the event was generated. This is confusing because ContinueDebugEvent does not act like it does at software breakpoints.

Hope this helps someone else with the same issue.

Greetings

+3
source

Source: https://habr.com/ru/post/1480624/


All Articles