Debugger里面如何得到DbgPrintEx的输出

WinDbg

Debugger里面如何得到DbgPrintEx的输出


Thomson 2009-04-10, 13:27 下午
我用WinDbg在debuggee里面的ntdll!DbgPrintEx上设置了断点,并且在上面停了下来,不过,step over过后,windbg里面看不到输出,在断点上看ntdll!DbgPrintEx的参数是有内容的, 如何能在user mode debug的情况下拿到输出呢?

我用dbgview同样也没等到输出,DbgPrintEx里面有还filter吗?

Re: Debugger里面如何得到DbgPrintEx的输出


王宇 2009-04-10, 15:34 下午

楼主什么平台? Vista? 不晓得了 很奇怪...

要不试着看看 idt 0x2d 那的信息还有不?

这样:

先找到 idt 0x2d
    2d: 805425fc (nt!KiDebugService)

0: kd> bp 805425fc

0: kd> g
Breakpoint 0 hit
nt!KiDebugService:
805425fc 6a00            push    0

1: kd> kb
ChildEBP RetAddr  Args to Child             
f9c2eaac 80531ecc 00000001 f9c2eb00 0000001b nt!KiDebugService
f9c2eac8 8052b6e3 f9c2eae8 ffffffff 00000000 nt!DebugPrint+0x1c
f9c2ed1c 8052b878 8052b858 ffffffff 00000000 nt!vDbgPrintExWithPrefix+0x101
f9c2ed38 f75edc04 f75edb4c f9c2ed60 f75f3a9d nt!DbgPrint+0x1a
f9c2ed44 f75f3a9d 00000000 80556460 8056475c Basic!SetNetworkMonitor+0x94 [c:\code3\sys\netmon.c @ 243]
f9c2ed60 8058114d 812ac5f0 f7e63a04 8056475c Basic!DriverUnload+0x1d [c:\code3\sys\main.c @ 4108]
f9c2ed7c 80538757 f7e63a04 00000000 8158e8b8 nt!IopLoadUnloadDriver+0x19
f9c2edac 805cf794 f7e63a04 00000000 00000000 nt!ExpWorkerThread+0xef
f9c2eddc 805460ce 80538668 00000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

在 ARG1 == 00000001 的情况下分析 ARG2:

1: kd> db f9c2eb00
f9c2eb00  49 50 46 69 6c 74 65 72-46 75 6e 63 74 69 6f 6e  IPFilterFunction
f9c2eb10  28 29 20 2d 20 46 41 4c-53 45 0a 00 18 c1 4d 80  () - FALSE....M.
f9c2eb20  ff ff ff ff 5f cf 52 80-93 cf 52 80 40 eb c2 f9  ...._.R...R.@...
f9c2eb30  04 00 00 00 40 00 00 00-87 ec c2 f9 70 68 52 81  ....@.......phR.
f9c2eb40  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
f9c2eb50  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
f9c2eb60  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
f9c2eb70  00 00 00 00 06 02 20 00-05 00 50 80 01 00 00 00  ...... ...P.....

中断派遣之后,这个串就打印出来了:

1: kd> g
IPFilterFunction() - FALSE


难道下面还有钩子?

Re: Debugger里面如何得到DbgPrintEx的输出


Thomson 2009-04-10, 18:37 下午
谢谢王宇.
我是在Server 03 R2上面,
你是在Driver里面用的DbgPrintEx,我当时是断在了ntdll!DbgPrintEx里面了,我跟了一下,发现,这个里面确实有一个filter的,就是后面这个,ntdll!NtQueryDebugFilterState,后者是一个SysCall,根据DbgPrintEx的参数ComponentId来做Mask, 貌似设置nt!Kd_WIN2000_Mask成0xffffffff后,所有的component都不会被mask,也就会被show出来了.

Re: Debugger里面如何得到DbgPrintEx的输出


格蠹老雷 2009-04-10, 19:02 下午
使用这种方式打印时,会以参数BREAKPOINT_PRINT(值为1)(参见《软件调试》18.6.6节)来调用调试服务,调试服务发起INT 2D异常后,KiDebugService做了一些预处理工作后,便跳转到KiTrap03。从KiDebugService跳转到KiTrap03后,要传递的调试信息会被当作断点异常的参数信息而传递给异常分发函数,对于没有内核器的情况下,系统会调用KdpTrap这个简易的内核调试器处理函数。KdpTrap内部如果发现是断点异常,且参数1是BREAKPOINT_PRINT,那么就调整EIP后返回了,也就是把要打印的消息抛弃了。
u nt!KdpStub
...
804f6c37 83f901 cmp ecx,1 ;;比较异常的第一个参数是不是BREAKPOINT_PRINT
804f6c3a 750d jne nt!KdpStub+0x35 (804f6c49) ;;不是则另外处理
804f6c3c 8b4514 mov eax,dword ptr [ebp+14h] ;; 取第4个参数的值,即CONTEXT
804f6c3f ff80b8000000 inc dword ptr [eax+0B8h] ;; 调整EIP,跳过INT 2D后的INT 3
804f6c45 b001 mov al,1 ;;返回真,声明已经处理该异常,停止继续分发
804f6c47 eb16 jmp nt!KdpStub+0x4b (804f6c5f) ;; 调转到出口
...
804f6c5f 5d pop ebp
804f6c60 c21800 ret 18h
用户态的消息打印方式就是OutputDebugString,通过发送DBG_PRINTEXCEPTION_C异常(《软件调试》10.7.1)。

Powered by Community Server Powered by CnForums.Net