2024年4月21日发(作者:)
DbgPrint 函数流程分析 by 小喂 ‐ 1 ‐
DbgPrint 函数流程分析
前言
Windows下编写内核驱动时经常用到DbgPrint函数输出一些调试信息,用来辅助调试。当正在用WinDbg内核调
试时,调试信息会输出到WinDbg中。或者利用一些辅助工具也能看到输出的调试信息,比如Sysinternals公司的
DebugView工具。本文分析了Vista系统上DbgPrint系列函数的执行流程,并揭示了DebugView工具的实现原理。
DbgPrint函数流程
先看一下WDK中DbgPrint函数的原型:
ULONG
DbgPrint (
IN PCHAR Format,
...
);
和printf的参数一样,可以格式化字符串。
.text:0049E123 ; ULONG DbgPrint(PCH Format,...)
.text:0049E123 public _DbgPrint
.text:0049E123 _DbgPrint proc near ; CODE XREF: sub_4046B2+11↑p
.text:0049E123
.text:0049E123 Format = dword ptr 8
.text:0049E123 arglist = byte ptr 0Ch
.text:0049E123
.text:0049E123 mov edi, edi
.text:0049E125 push ebp
.text:0049E126 mov ebp, esp
.text:0049E128 push TRUE
.text:0049E12A lea eax, [ebp+arglist]
.text:0049E12D push eax
.text:0049E12E push [ebp+Format]
.text:0049E131 mov ecx, offset ??_C@_00CNPNBAHC@?$AA@FNODOBFM@
.text:0049E136 push 3 ; DPFLTR_INFO_LEVEL = 3
.text:0049E138 push 65h ; DPFLTR_DEFAULT_ID = 101 = 0x65
.text:0049E13A call vDbgPrintExWithPrefixInternal(x,x,x,x,x,x)
.text:0049E13F pop ebp
.text:0049E140 retn
.text:0049E140 _DbgPrint endp
从反汇编代码来看,DbgPrint函数很简单,传递参数直接调用vDbgPrintExWithPrefixInternal函数。传递的
ComponentId为DPFLTR_DEFAULT_ID,Level为DPFLTR_INFO_LEVEL。查看DbgPrintEx函数的文档可以知道这两个参数的
意义。
DbgPrint 函数流程分析 by 小喂 ‐ 2 ‐
.text:0046EBF4 __stdcall vDbgPrintExWithPrefixInternal(x, x, x, x, x, x) proc near
.text:0046EBF4 ; CODE XREF: _DbgPrintEx+19↑p
.text:0046EC11
.text:0046EC17 push [ebp+ulLevel]
.text:0046EC1A push [ebp+ulComponentId]
.text:0046EC1D call NtQueryDebugFilterState(x,x)
.text:0046EC22 test eax, eax
.text:0046EC24 jnz short loc_46EC2D
.text:0046EC26
.text:0046EC26 loc_46EC26:
.text:0046EC26 xor eax, eax
.text:0046EC28 jmp _exit
vDbgPrintExWithPrefixInternal函数首先调用NtQueryDebugFilterState函数检查ComponentId和Level值判断当前输
出是否需要屏蔽。DbgPrint传入的值分别是65h和3, 65h定为的nt!Kd_DEFAULT_Mask的值和3被移位后的8比较,
从而确定此次输出是否需要屏蔽。所以Vista系统上用WinDbg内核调试时缺省看不到DbgPrint输出的调试字符串,可
以用ed nt!Kd_DEFAULT_Mask 0x8命令或者修改注册表打开DbgPrint调试输出。
.text:0046EBA8 __stdcall NtQueryDebugFilterState(x, x) proc near
.text:0046EBA8
.text:0046EBA8 ulComponentId = dword ptr 8
.text:0046EBA8 ulLevel = dword ptr 0Ch
.text:0046EBA8
.text:0046EBA8 mov edi, edi
.text:0046EBAA push ebp
.text:0046EBAB mov ebp, esp
.text:0046EBC0 mov ecx, [ebp+ulLevel]
.text:0046EBCC xor eax, eax
.text:0046EBCE inc eax
.text:0046EBCF shl eax, cl
.text:0046EBD1 test _Kd_WIN2000_Mask, eax
.text:0046EBD7 jnz short loc_46EBE8
.text:0046EBD9 mov ecx, _KdComponentTable[edx*4]
.text:0046EBE0 test [ecx], eax
.text:0046EBE2 jnz short loc_46EBE8
.text:0046EBE4 xor eax, eax
.text:0046EBE6 jmp short loc_46EBEB


发布评论