2
#include <Windows.h>

int handle_exception (EXCEPTION_POINTERS *exception_pointers) {
    exception_pointers->ContextRecord->Rip += 4;
    return EXCEPTION_CONTINUE_EXECUTION;
}

int main () {
    __try {
        int number = 0;

        number = 1 / number; // generate EXCEPTION_INT_DIVIDE_BY_ZERO
    }
    __except (handle_exception(GetExceptionInformation())) { }
    return 0;
}

I built the source code, and I open it by x64dbg. And set hardware breakpoints.

enter image description here

An exception occurs on IDIV instruction, and run the debuggee. It always stops on a instruction after next.

enter image description here

enter image description here

I expected it to stop at 0x0000000140001056 address because it's where 4bytes away from RIP. But it isn't.

I think there's something I don't know under the hood. Just out of curiosity, why does it work like that? If you have a chance, please let me know. thanks. :D

Additional Attachments

When RIP is modified in handle_exception()

new RIP of NtContinue()'s ThreadContext parameter is 0x0000000140001056.

enter image description here

When RIP isn't modified in handle_exception()

RIP of NtContinue()'s ThreadContext parameter is 0x0000000140001032. (overall, addresses have been changed, because a sourc code has been changed too. That's IDIV instruction's address.)

enter image description here

  • Are you sure about the value of instruction pointer in your exception handler? Maybe, you should have to get first the current RIP after the IDIV instruction. – ismael_akez Mar 21 at 10:09
  • What happens if you simply return EXEPTION_CONITNUE_EXECUTION without changing RIP? – Yotamz Mar 21 at 17:00
  • @ismael_akez As I went over it from NtContinue()'s first parameter, RIP is been changed properly to RIP + 4 address. (pointer to MOV instrction) – left click Mar 21 at 19:41
  • @Yotamz When I changed it as you said, exception occurs again on IDIV instruction. And hardware breakpoint on IDIV instruction doesn't work also, and not counted. even though I set it on IDIV instruction. – left click Mar 21 at 19:46
  • I wonder if other people have the same experience as me on the source code and hardware breakpoint on the MOV instruction isn't working. – left click Mar 21 at 20:00
2

just modified your source a bit to print Rip prior and post in handler
added another exception and eliminated a warning (empty handler block)
and tested with +1,+2,+3 +4 +5 on the handler Hardware breaks doesn't get hit I haven't checked by single stepping inside RtlpExecuteHandlerForxxx calls

here is a modified src

#include <windows.h>
#include <stdio.h>
#include <intrin.h>
int handle_exception(ULONG ExceptionCode,EXCEPTION_POINTERS *exception_pointers)
{
    printf("%x\n",ExceptionCode);
    printf("%I64x\n",exception_pointers->ContextRecord->Rip);
    exception_pointers->ContextRecord->Rip += 4; 
    printf("%I64x\n",exception_pointers->ContextRecord->Rip);
    return EXCEPTION_CONTINUE_EXECUTION;
}
int main(void)
{
    __try
    {
        int number = 0;
        number = 1 / number; // generate EXCEPTION_INT_DIVIDE_BY_ZERO
        __debugbreak();
    }
    __except (handle_exception(GetExceptionCode(),GetExceptionInformation()))
    {
        __nop();
    }
    return 0;
}

results for Rip =Rip+ {1,2,3,4} _CONTEXT->Rip Changed and properly Executed

but hw Bp doesn't get hit so its time to single step inside ntdll/nt/xxxx

:\>grep -i += hwbp.cpp
    exception_pointers->ContextRecord->Rip += 1;

:\>cl /Zi /W4 /Od /analyze /nologo /EHsc hwbp.cpp /link /release
hwbp.cpp

:\>hwbp.exe
c0000094
7ff7adf910a2
7ff7adf910a3
c0000005
7ff7adf910a5
7ff7adf910a6
80000003
7ff7adf910aa
7ff7adf910ab

:\>grep -i += hwbp.cpp
    exception_pointers->ContextRecord->Rip += 2;

:\>cl /Zi /W4 /Od /analyze /nologo /EHsc hwbp.cpp /link /release
hwbp.cpp

:\>hwbp.exe
c0000094
7ff6696d10a2
7ff6696d10a4
80000003
7ff6696d10aa
7ff6696d10ac
c0000005
7ff6696d10ac
7ff6696d10ae

:\>grep -i += hwbp.cpp
    exception_pointers->ContextRecord->Rip += 3;

:\>cl /Zi /W4 /Od /analyze /nologo /EHsc hwbp.cpp /link /release
hwbp.cpp

:\>hwbp.exe
c0000094
7ff788c510a2
7ff788c510a5
c0000005
7ff788c510a5
7ff788c510a8
80000003
7ff788c510aa
7ff788c510ad

:\>grep -i += hwbp.cpp
    exception_pointers->ContextRecord->Rip += 4;

:\>cl /Zi /W4 /Od /analyze /nologo /EHsc hwbp.cpp /link /release
hwbp.cpp

:\>hwbp.exe
c0000094
7ff6f2be10a2
7ff6f2be10a6
80000003
7ff6f2be10aa
7ff6f2be10ae

:\>
| improve this answer | |
  • Thank you for the test. :) I'm so sorry I'm bad at English.. You mean.. when a context switch occurs, hardware breakpoint on new RIP doesn't work, right? – left click Mar 22 at 2:07
  • 1
    no I haven't checked what's the puzzle I just confirmed your observation hw bps on instruction next to the Address of Instruction that caused the exception doesn't get hit and posted an observation that Software breakpoints do gets hit I didn't open a windbg in a full session I ran it in a script in cmdline so I cant actually set a hw breakpoint without doing some circus (The System Does a ContextSwitch During Process Initialization and will clear the Debug Registers during that period ) – blabb Mar 22 at 7:11
  • Ahh now I unserstand what you said for me. I am grateful for your kind explanation. – left click Mar 22 at 7:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.