How to use the ah series commands of windbg?

60 Views Asked by At

I can't figure out what the Address parameter is for the ah series of commands.


This is the msdn for the ah series of commands.

https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/ah--assertion-handling-

ahb [Address]

ahi [Address]

ahd [Address]

Address

Specifies the address of the instruction whose assertion-handling status is being set. If you omit this parameter, the debugger uses the current program counter.


It says instruction whose assertion-handling status is being set.

Does this mean there is an assembly instruction that sets assertion-handling status?

In fact, the program executes the comparison instruction and decides whether to execute the asserted function based on the comparison result.

So I can't find an assembly instruction that sets assertion-handling statusd.


I wrote a test program.

The program triggers assertions in the main function.

I set every assembly instruction of the main function using the ahb or ahi instruction.

But these instructions did not change the way assertions are handled, the program always pops up the window.

1

There are 1 best solutions below

0
Neitsa On BEST ANSWER

From what I can gather the ah command works only on assertions that generate an int 0x2c.

Here's a very simple example:

#include <Windows.h> // needed for DbgRaiseAssertionFailure
#include <assert.h>  // needed for _ASSERT
#include <stdio.h>

int main(int argc, char** argv)
{
    // generates an int3 (software BP)
    // _ASSERT(argc == 2);

    // generates an int 0x2c
    if (argc != 2)
        DbgRaiseAssertionFailure();


    printf("Ok!\n");

    return 0;
}

Here's the main function, in debug mode (note the interruption at 00007ff6debe2b1c):

0:000> u Test!main L 15
Test!main [G:\CPP\Test\Test.cpp @ 333]:
00007ff6`debe2af0 4889542410      mov     qword ptr [rsp+10h],rdx
00007ff6`debe2af5 894c2408        mov     dword ptr [rsp+8],ecx
00007ff6`debe2af9 55              push    rbp
00007ff6`debe2afa 57              push    rdi
00007ff6`debe2afb 4881ece8000000  sub     rsp,0E8h
00007ff6`debe2b02 488d6c2420      lea     rbp,[rsp+20h]
00007ff6`debe2b07 488d0dace50000  lea     rcx,[Test!_NULL_IMPORT_DESCRIPTOR <PERF> (Test+0x210ba) (00007ff6`debf10ba)]
00007ff6`debe2b0e e853e8ffff      call    Test!ILT+865(__CheckForDebuggerJustMyCode) (00007ff6`debe1366)
00007ff6`debe2b13 83bde000000002  cmp     dword ptr [rbp+0E0h],2
00007ff6`debe2b1a 7402            je      Test!main+0x2e (00007ff6`debe2b1e)
00007ff6`debe2b1c cd2c            int     2Ch
00007ff6`debe2b1e ba80030000      mov     edx,380h
00007ff6`debe2b23 488d0de6700000  lea     rcx,[Test!`string' (00007ff6`debe9c10)]
00007ff6`debe2b2a e861e6ffff      call    Test!ILT+395(printf) (00007ff6`debe1190)
00007ff6`debe2b2f 33c0            xor     eax,eax
00007ff6`debe2b31 488da5c8000000  lea     rsp,[rbp+0C8h]
00007ff6`debe2b38 5f              pop     rdi
00007ff6`debe2b39 5d              pop     rbp
00007ff6`debe2b3a c3              ret
00007ff6`debe2b3b cc              int     3
00007ff6`debe2b3c cc              int     3  

If I run the program normally, the debugger breaks here:

Test!main+0x2c:
00007ff6`debe2b1c cd2c            int     2Ch

If I enter (before running the program):

0:000> ahi 00007ff6`debe2b1c
Test!main+0x2c (00007ff6`debe2b1c) [G:\CPP\Test\Test.cpp @ 336]- ignore

0:000> ah
Test!main+0x2c (00007ff6`debe2b1c) [G:\CPP\Test\Test.cpp @ 336]- ignore

Then the assertion is completely ignored and the program runs normally, without breaking into the debugger.

Note that DbgRaiseAssertionFailure is documented here and its only job is to emit an int 0x2c:

#define DbgRaiseAssertionFailure() __int2c()

The vector for this interruption is as follows:

0: kd> !idt 0x2c

Dumping IDT: fffff8074d3c6000

2c:     fffff80750a16dc0 nt!KiRaiseAssertionShadow

What I really don't know is if there are other macros that are as helpful as the "standard" asserts (which either print or generate a message box with file, line number, and a message), for user mode, but with int 0x2C.

In kernel mode the standard way is to use the NT_ASSERT macro which also generates an int 0x2c. Note that the documentation for this macro also references the ah command, which tends to corroborate the fact that ah works only for int 0x2c.