While using [x64dbg](https://x64dbg.com/) I was experiencing incredibly strange issue - `int3` was swallowed and `KiUserExceptionDispatcher` was never invoked.
Turns out that x64dbg ([TitanEngine](https://github.com/x64dbg/TitanEngine/blob/x64dbg/TitanEngine/TitanEngine.De...)) expects system breakpoint to be first breakpoint that will be triggered and it always swallows it (it's hardcoded no setting to change it's behavior).
That means if you have a DLL with `int3` for example ```c LONG ExceptionHandler(EXCEPTION_POINTERS *ExceptionInfo) { ExceptionInfo->ContextRecord->Rip++; return EXCEPTION_CONTINUE_EXECUTION; }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { AddVectoredExceptionHandler(1, ExceptionHandler); asm("int $0x03; nop; nop;"); } return TRUE; } ```
That `int3` would be swallowed and `ExceptionHandler` never invoked when running under x64dbg. Now with this MR applied it works correctly and as expected (same as on Windows).
Another interesting thing is that without this MR it wouldn't just swallow `int3` but even skip first `nop` aswell and RIP would end up on 2nd `nop`.
From: Dāvis Mosāns davispuh@gmail.com
x64dbg (TitanEngine) expects that system breakpoint is first breakpoint that will be triggered. Before this patch that wasn't the case causing user breakpoint (eg. in some DLL) to be swallowed instead. --- dlls/ntdll/loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 59624bc70f8..f06e657cc45 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -4368,6 +4368,7 @@ void loader_init( CONTEXT *context, void **entry ) NtTerminateProcess( GetCurrentProcess(), status ); }
+ process_breakpoint(); if ((status = walk_node_dependencies( wm->ldr.DdagNode, context, process_attach ))) { if (last_failed_modref) @@ -4380,7 +4381,6 @@ void loader_init( CONTEXT *context, void **entry ) release_address_space(); if (wm->ldr.TlsIndex == -1) call_tls_callbacks( wm->ldr.DllBase, DLL_PROCESS_ATTACH ); if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie ); - process_breakpoint(); } else {