1

What is the reason behind the byte scission (the next immediate byte following "int 2d" is skipped) behaviour when executing INT 0x2D? I came across this article http://www.drdobbs.com/monitoring-nt-debug-services/184416239 but still cannot understand what is the reason for Windows to skip the byte. Any explanation is welcome. Thanks.

2
  • 2
    The DrDobbs article does not mention 'byte scission' at all, which seems to be a term invented by Dr Fu in relation to a peculiarity/quirk in Windows (see Peter Ferrie's paper which explains it in detail).
    – DarthGizka
    May 31, 2016 at 10:53
  • Thanks! That answer the question. Yeah, I know that the Dr Dobbs article didn't not mention "byte scission". That is the only article I came across after searching for mechanism behind INT 0x2D after reading about it on Dr Fu's blog. The other articles on the net usually only mention that a byte will be skipped without explanation. Hence this question. Thanks for pointing me to Peter Ferrie's paper.
    – xyz
    May 31, 2016 at 23:22

2 Answers 2

2

The full details of the behavior are described here: http://pferrie.epizy.com/papers/antidebug.pdf

Specifically, if the EAX register has the value of 1, 3, or 4 on all versions of Windows, or the value 5 on Windows Vista and later, then Windows will increase by one the exception address. Finally, it issues an EXCEPTION_BREAKPOINT (0x80000003) exception if a debugger is present.

The skipped byte is intended to pass information to the kernel-mode component, but the mechanism is not used by default.

2
  • Thanks. When you say the skipped byte is intended to pass information to kernel-mode component, specifically what information? Is it an undocumented feature of Windows kernel? I am still puzzle why do INT 0x2D need to behave the way it does. Comparatively the behaviour of INT 3 seem more understandable.
    – xyz
    Jun 6, 2016 at 11:50
  • you can pass any single-byte value to the kernel, as a "parameter" to the interrupt, along with register values. This is not possible using int 3 style. Jun 26, 2016 at 15:27
0

From what I can tell, it’s because the int 0x2d instruction is supposed to be immediately followed by a int3 breakpoint opcode, which in turn is presumably a graceful degradation/backwards compatibility feature.

Interrupt 0x2d is a debugger hook, used to pass information from the debugged program to the debugger; presumably the ultimate place where APIs like DbgPrintEx are implemented. A debugger that traps interrupt 0x2d will respond to the hook invocation, skip the int3 opcode that follows, and resume execution normally. A more primitive debugger that ignores interrupt 0x2d will instead trap the int3 opcode, allowing the user to examine register state and respond to the hook call manually; or to patch a nop instruction over the breakpoint opcode to ignore the hook from now on.

If you disassemble BOOTMGR.EXE (the PE executable extracted from BOOTMGR), MEMTEST.EXE, WINLOAD.EXE or NTOSKRNL.EXE, you will see the int 0x2d / int3 sequence appear. Those are boot-time and/or kernel-mode programs which execute in a different environment from normal Windows applications, but the debugger ABI they are subject to is presumably the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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