DbgPrint 函数流程分析

Similar documents
,768 32,767 32K JMP Jnnn (386+) LOOP CALL [Label:] JMP short/near/far address L10: jmp jmp L20: L10 L20

今天刚发现的, 比较简单, 于是就来简单分析下吧 该感染样本很简单, 新加了个区段放病毒执行代码, 执行病毒代码, 最后跳回原入口点来执行原文件 下面就是感染后的代码的简单分析 : ; =============== S U B R O U T I N E =====================

漏 洞 攻 防 EXPLOIT ATTACK & DEFENCE 栏 目 编 辑 脚 本 小 子 scriptsboy@hacker.com.cn HEAD 部 分 大 小 当 然 也 就 是 固 定 的 18200H 如 果 要 提 取 出 HEAD, 我 们 可 以 选 中 前 18200H 字


windbg

1 2 / 3 1 A (2-1) (2-2) A4 6 A4 7 A4 8 A4 9 A ( () 4 A4, A4 7 ) 1 (2-1) (2-2) ()

4 / ( / / 5 / / ( / 6 ( / / / 3 ( 4 ( ( 2

<4D F736F F D20CEC4BCFEBCB6B6F1D2E2B4FAC2EBC9A8C3E8D2FDC7E6D6D0B5C4BCD3BFC7CAB6B1F0BCBCCAF52E646F6378>

1

Microsoft PowerPoint - 03_ADVDBG_RAYMOND_OS.ppt

1 CPU interrupt INT trap CPU exception

学习MSP430单片机推荐参考书

untitled

99710a72ZW.PDF

ROP_bamboofox.key

5( " &$"" & & #! # # # # # # # # # # $ % & &( )( # # # *+,-,.. /012 # # "" # 3 % # # # # # ) &$"4 # # # # # # # # # # # # &$"! # & # ""!

(2) Function 0BH: Function 0CH: (pixel, picture element) Function 0DH: Function 0FH: Function 13H:

Microsoft PowerPoint - XCon2010_win7_cn.ppt [兼容模式]

untitled

Ps22Pdf

untitled

Linux kernel exploit研究和探索


:;< =;< >!?%(, (-+ *$5(1 *$%* *#%0$#34 65&# *--.20$ $-.#+-317 A$#, 4%, 5* 54! >! B-3 0$5)/3#( * %* $-.# 5( *$#53 B3## *5.#7

標準 BIG 中文字型碼表 A 0 9 B C D E F 一 乙 丁 七 乃 九 了 二 人 儿 入 八 几 刀 刁 力 匕 十 卜 又 三 下 丈 上 丫 丸 凡 久 么 也 乞 于 亡 兀 刃 勺 千 叉 口 土 士 夕 大 女 子 孑 孓 寸 小 尢 尸 山 川 工 己 已 巳 巾 干 廾

> u eip l 3 002f2aa9 90 nop 002f2aaa 90 nop >!chkimg -d -lo 1 ping // 检查文件是否被篡改? 002f2aa7-002f2aaa 4 bytes - ping!maincrtstartup [ e :f0 cc 9

C = C + C C = + + C C C C 1 2 3


!!!!"#$ " " %& ( " # " " " " " "$%%& " $%% " "!!

!! "#$% & ()*+,-. &/ 00 " %0#0 % 00 " %0#0 %1% 2 %1$ 2 % )869:;.,*8656<,*= 9*>? *> A6)5, B,55, C,*D, B6 E)*)7)55) " F9D,

<4D F736F F D20C7B6C8EBCABDCFB5CDB3C9E8BCC6CAA6B0B8C0FDB5BCD1A75FD1F9D5C22E646F63>

06721 main() lock pick proc() restart() [2][4] MINIX minix2.0 GDT, IDT irq table[] CPU CPU CPU CPU (IDTR) idt[] CPU _hwint00:! Interrupt


易语言逆向分析

$""$!# # )*+,*-.+/ / 812.9/ : ;2364<+ =5<+3/ $""$ $!( $"""!# %% $! $%"" $%""!& (!#!& & $""" $""$!""""#

(E). (A) (B) (C) (D) (E). (A) (B) (C) (D) (E) (A) (B) (C) (D) (E) (A) (B) (C) (D). ( ) ( ) ( ) ( ) ( ) ( ) (A) (B) (C) (D) (E). (A) (B) (C) (D) (E). (

目 前 言... 1 一 发 展 背 景... 2 ( 一 ) 发 展 优 势...2 ( 二 ) 机 遇 挑 战...6 ( 三 ) 战 略 意 义...8 二 总 体 要 求... 9 ( 一 ) 指 导 思 想...9 ( 二 ) 基 本 原 则...10 ( 三 ) 战 略 定 位... 1

Visualize CMap

新 竹 市 政 府 潮 舖 商 行 陳 祈 玲 新 竹 市 東 區 成 功 里 大 同 路 二 五 號 500, /07/20 F 布 疋 衣 著 鞋 帽 傘 服 飾 品 批 發 業 F 家 具 寢 具 廚 房 器 具 裝 設 品 批 發 業

D/A DAC ( 1us) (10~20 ) DAC0832 1

<453A5CC2EDC0F6C5C5B0E6CEC4BCFE5CC3F1B7A8A1A4C9CCB7A8A1A4C3F1CAC2CBDFCBCFB7A8D3EBD6D9B2C3D6C6B6C8D5AACEC4BCFE574F52445CB9D9B7BDD0DEB6A9B5E7D7D3B7FECEF1A3A8A1B6C3F1CBDFBDE2CACDA1B7BACDA1B6C1A2B7A8B7A8A1B7A3A92E646F63>

! " # $ % & (( %) "*+,- &.(/-) & ( 0 & 1! % " % # % & & $ % "/()%!"# (( (02-03 /(((.1/.2( 4 //). /$0 3)0%. /1/%-2 (( ) / ((0 // "*+,- &.(/-) & ( 0 & 1

: : :ISBN : : : : 20 :,,, :,,, 1

zt

栏目:前沿

Microsoft Word - “调戏”反遭“反调戏”—记Visual Toolbar 的破解过程.doc

(Microsoft Word - 103\300\347\267~\266\265\245\330\245N\275X)

且编写我们的利用程序, 到最后, 会简单讲一下, 这个漏洞的修补. 首先我们来了解下溢出产生的原因. 打开 windbg, 附加到 msue 进程上, 然后在 kernel!readfile 处下断点, 再用 muse 打开我们之前做好的 test.m3u( 注 : 在这个过程中, 会多次断在 Re

消 费 特 征 贸 易 对 象 客 户 群 体 跨 境 电 商 出 口 占 据 绝 对 比 重, 进 口 增 长 迅 速 出 口 端, 美 国 和 欧 盟 市 场 较 为 稳 定, 东 盟 等 群 体 增 长 迅 速 ; 进 口 端 以 日 本 韩 国 新 西 兰 等 发 达 国 家 为 主 主 要

流基地领导小组

银川一职服装设计与工艺专业教学计划

一 学 校 基 本 情 况 目 录 二 部 门 预 算 报 表 ( 一 ) 收 支 总 表 ( 二 ) 收 入 总 表 ( 三 ) 支 出 总 表 ( 四 ) 财 政 拨 款 支 出 表 三 部 门 预 算 报 表 说 明 ( 一 ) 收 支 总 表 说 明 ( 二 ) 收 入 总 表 说 明 (

目 录 一 学 校 基 本 情 况 二 2016 年 预 算 报 表 ( 一 ) 中 南 大 学 收 支 预 算 总 表 ( 二 ) 中 南 大 学 收 入 预 算 表 ( 三 ) 中 南 大 学 支 出 预 算 表 ( 四 ) 中 南 大 学 财 政 拨 款 支 出 预 算 表 三 2016 年

信息参考

Microsoft Word - 15dbtb007

CC213

试卷

!" #$%#&#! () *+, -.!" #$%#/# $!" /$12 0!" 3 4 $$255 % 67 8 $ %% #! " # $9&$

2

!"#$!"%&!"$!""( )( )( #( "#*!&#) %&*!(+,- %.!/( )( #( ,-2 89 /

!!""# $ %#" & $$ % $()! *% $!*% +,-. / 0 %%"#" 0 $%1 0 * $! $#)2 "


〖BT1〗高考通关卷

但 洋 糖 最 终 乘 船 溯 江 而 上, 再 加 上 民 国 初 年 至 抗 战 前 夕 二 十 余 年 间, 四 川 接 连 不 断 遭 受 水 灾 旱 灾 地 震, 平 均 每 月 爆 发 两 次 军 阀 混 战, 乡 村 遭 受 极 大 破 坏,( 赵 泉 民,2007) 农 村 经 济

前沿技术 全面绕过执行流保护 安全研究部张云海 执行流保护 (CFG,Control Flow Guard) 是微软在 Windows 10 技术预览版与 Windows 8.1 update 3 中, 默认启用的一项缓解技术 在分析 CFG 的实现机制的过程中, 我们发现了一种全面绕过 CFG 的

内 蒙 古 自 治 区 煤 情 况 ( 截 至 2015 年 6 月 底 ) 煤 名 称 19 内 蒙 古 大 雁 业 集 团 有 限 责 任 公 司 第 三 煤 300 ( 蒙 )MK 安 许 证 字 [2014 EG003] 20 陈 巴 尔 虎 旗 天 顺 业 有 限 责 任 公 司 天 顺

幻灯片 1

2. 下 列 理 解 和 分 析, 不 符 合 原 文 意 思 的 一 项 是 ( ) A. 水 手 在 伦 敦 讲 东 印 度 群 岛 的 所 见 所 闻, 匠 人 在 火 炉 边 讲 自 己 的 人 生 经 历, 他 们 讲 的 故 事 各 有 特 点, 但 同 属 于 传 统 故 事 模 式

: ( ) : : / : ISBN / F5112 : : CIP (2006)

種 類 左 淋 巴 總 管 ( 胸 管 ) 右 淋 巴 總 管 血 管 連 接 連 接 左 鎖 骨 下 靜 脈 連 接 右 鎖 骨 下 靜 脈 淋 巴 收 集 範 圍 左 上 半 身 及 下 半 身 淋 巴 液 右 上 半 身 淋 巴 液 長 度 很 長 很 短 (3) 循 環 路 徑 : (4)

Ctpu

工 序 的 是 ( ) A. 卷 筒 切 筒 装 药 造 粒 B. 搬 运 造 粒 切 引 装 药 C. 造 粒 切 引 包 装 检 验 D. 切 引 包 装 检 验 运 输 7. 甲 公 司 将 其 实 施 工 项 目 发 包 给 乙 公 司, 乙 公 司 将 其 中 部 分 业 务 分 包 给


zt

Guava学习之Resources

民 國 105 年 大 專 程 度 義 務 役 預 備 軍 官 預 備 士 官 考 選 簡 章 目 錄 壹 考 選 依 據 1 貳 考 ( 甄 ) 選 對 象 1 參 資 格 規 定 1 肆 員 額 及 專 長 類 別 2 伍 報 名 及 選 填 志 願 日 期 方 式 3 陸 選 填 官 科 (

数 学 高 分 的 展 望 一 管 理 类 联 考 分 析 第 一 篇 大 纲 解 析 篇 编 写 : 孙 华 明 1 综 合 能 力 考 试 时 间 :014 年 1 月 4 日 上 午 8:30~11:30 分 值 分 配 : 数 学 :75 分 逻 辑 :60 分 作 文 :65 分 ; 总

!!"#$ " # " " " " " "$%%& " $%% " "!!

《米开朗琪罗传》

思明区现代朊务业发展规划

《民国演义》第一册

!""# $!""%!"&" #

SIK) 者, 需 實 施 1 年 以 上, 經 體 格 檢 查 無 後 遺 症 者 5. 身 體 任 何 部 分 有 刺 青 紋 身 穿 耳 洞 者, 不 得 報 考, 各 項 檢 查 結 果 須 符 合 體 位 區 分 標 準 常 備 役 體 位 二 在 校 軍 訓 成 績 總 平 均 70 分

Ps22Pdf

untitled

(8) 沟 通 谈 判 能 力 (9) 客 户 服 务 能 力. 知 识 目 标 () 掌 握 跨 境 电 子 商 务 的 基 本 理 论 与 知 识 () 掌 握 国 际 市 场 营 销 的 基 本 知 识 (3) 掌 握 国 际 结 算 的 基 本 理 论 与 知 识 (4) 掌 握 国 际 电


zt

!! "!!"#! # $ %&& ( "! )*+, " - &. - &/%%&& - 0!!$! "$! #$ - -! $$ 12.3! 4)5 %&& &.3 "3!!!!!!!!!!!! &/& - 0.&3.322!!!.! 2&& - 2/& - &362! /&&&//!!! 78

21,, 1,,, ( ),,,,,,,,,, (CIP). 2. :, ( ; 21 ) ISBN F CIP ( 2003 ) : ( 17, ) : ( ) E


,,,,,,,,,,,,, :,, ;,,,,, ( ),,,, : ( ) ; ( ) ; ( ) ( ) ; ( ) ( A ) ; ( ) ( ),,,,,,, 80

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

民國八十九年台灣地區在校學生性知識、態度與行為研究調查

untitled


2. 过程 这里主要使用 gdb 来拆炸弹 当然, 用其他工具来辅助, 应该可以更高效地完成 (gdb) echo ======================= Defuse Phase_1 ==============================\n\n ==================

《美国名将全传——德怀特·戴维·艾森豪威尔》

untitled

!!! "# $ " %!!

Transcription:

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.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 vdbgprintexwithprefixinternal 函数首先调用 NtQueryDebugFilterState 函数检查 ComponentId 和 Level 值判断当前输 出是否需要屏蔽 DbgPrint 传入的值分别是 65h 和 3, 65h 定为的 nt!kd_default_mask 的值和 3 被移位后的 8 比较, 从而确定此次输出是否需要屏蔽 所以 Vista 系统上用 WinDbg 内核调试时缺省看不到 DbgPrint 输出的调试字符串, 可 以用 ed nt!kd_default_mask 0x8 命令或者修改注册表打开 DbgPrint 调试输出

DbgPrint 函数流程分析 by 小喂 3.text:0046EC5D push [ebp+ntstatus2] ; cbdest.text:0046ec63 push [ebp+pszdest] ; pszdest.text:0046ec69 mov ecx, 512.text:0046EC6E sub ecx, esi.text:0046ec70 lea edi, [ebp+esi+szbuffer].text:0046ec77 call RtlStringCbVPrintfA(x,x,x,x).text:0046ECB2 lea ecx, [ebp+szbuffer].text:0046ecb8 mov [ebp+asbuffer.buffer], ecx.text:0046ecbe mov [ebp+asbuffer.length], ax.text:0046ecc5 cmp _KeBugCheckActive, 0.text:0046ECCC jnz short loc_46ed09.text:0046eccc.text:0046ecce mov esi, _RtlpDebugPrintCallback.text:0046ECD4 test esi, esi.text:0046ecd6 jz short loc_46ed09.text:0046ecd6.text:0046ecd8 call ds:kegetcurrentirql().text:0046ecde mov bl, al.text:0046ece0 cmp bl, PROFILE_LEVEL.text:0046ECE3 jnb short loc_46eced.text:0046ece3.text:0046ece5 mov cl, PROFILE_LEVEL.text:0046ECE7 call ds:kfraiseirql(x).text:0046eced.text:0046eced loc_46eced:.text:0046eced push [ebp+ullevel].text:0046ecf0 push [ebp+ulcomponentid].text:0046ecf3 lea eax, [ebp+asbuffer].text:0046ecf9 push eax.text:0046ecfa call esi ; DbgPrintCallback(PANSI_STRING pasbuffer, ULONG ulcomponentid, ULONG ullevel);.text:0046ecfc cmp bl, PROFILE_LEVEL.text:0046ECFF jnb short loc_46ed09.text:0046ecff.text:0046ed01 mov cl, bl.text:0046ed03 call ds:kflowerirql(x) 如果此次输出不需要屏蔽,vDbgPrintExWithPrefixInternal 继续执行 调用 RtlStringCbVPrintfA 函数格式化字符串, 再判断是否正在蓝屏过程中, 然后提高 IRQL 调用输出回调函数 调试输出回调是 Vista 的新增功能,XP 中没有见到 NTSTATUS DbgSetDebugPrintCallback(PDBGPRINT_CALLBACE pdbgcallback, BOOLEAN bset) 函数用来设置和取消回调函数, 只能设置一个函数, 函数地址保存在 RtlpDebugPrintCallback 内部变量中 回调函数返回后降低 IRQL

DbgPrint 函数流程分析 by 小喂 4.text:0046ED09 movzx eax, [ebp+asbuffer.length].text:0046ed10 mov [ebp+pszdest], eax.text:0046ed16 mov eax, [ebp+asbuffer.buffer].text:0046ed1c mov [ebp+var_234], eax.text:0046ed22 push edi.text:0046ed23 push ebx.text:0046ed24 mov eax, 1 ; eax = BREAKPOINT_PRINT.text:0046ED29 mov ecx, [ebp+var_234] ; ecx = pszbuffer.text:0046ed2f mov edx, [ebp+pszdest] ; edx = ulbuflength.text:0046ed35 mov ebx, [ebp+ulcomponentid].text:0046ed38 mov edi, [ebp+ullevel].text:0046ed3b int 2Dh ; Internal routine for MSDOS (IRET).text:0046ED3D int 3 ; Trap to Debugger vdbgprintexwithprefixinternal 函数接着执行, 通过 int2d 调用调试服务把字符串输出到调试器 int2d 的服务例程为 KiDebugService 函数.text:0044737C _KiDebugService: ; DATA XREF: INIT:0070A35C o.text:004473ea inc dword ptr [ebp+68h].text:004473ea inc dword ptr [ebp+68h] ; [_KTRAP_FRAME].Eip.text:004473ED mov eax, [ebp+44h] ; [_KTRAP_FRAME].Eax.text:004473F0 mov ecx, [ebp+40h] ; [_KTRAP_FRAME].Ecx.text:004473F3 mov edx, [ebp+3ch] ; [_KTRAP_FRAME].Edx.text:004473F6 jmp loc_447527.text:00447527.text:00447527 loc_447527: ; CODE XREF:.text:004473F6 j.text:00447527.text:00447543 mov esi, ecx.text:00447545 mov edi, edx.text:00447547 mov edx, eax.text:00447549 mov ebx, [ebp+68h] ; [_KTRAP_FRAME].Eip.text:0044754C dec ebx.text:0044754d mov ecx, 3.text:00447552 mov eax, STATUS_BREAKPOINT.text:00447557 call CommonDispatchException.text:00446D70 CommonDispatchException proc near.text:00446d70.text:00446d70 stexceptionrecord= EXCEPTION_RECORD ptr -50h.text:00446D70.text:00446D70 sub esp, 50h.text:00446D73 mov [esp+50h+stexceptionrecord.exceptioncode], eax.text:00446d76 xor eax, eax.text:00446d78 mov [esp+50h+stexceptionrecord.exceptionflags], eax.text:00446d7c mov [esp+50h+stexceptionrecord.exceptionrecord], eax.text:00446d80 mov [esp+50h+stexceptionrecord.exceptionaddress], ebx.text:00446d84 mov [esp+50h+stexceptionrecord.numberparameters], ecx.text:00446d88 cmp ecx, 0

DbgPrint 函数流程分析 by 小喂 5.text:00446D8B jz short loc_446d99.text:00446d8d lea ebx, [esp+50h+stexceptionrecord.exceptioninformation].text:00446d91 mov [ebx], edx.text:00446d93 mov [ebx+4], esi.text:00446d96 mov [ebx+8], edi.text:00446d99.text:00446d99.text:00446da8 mov eax, [ebp+6ch] ; [_KTRAP_FRAME].SegCs.text:00446DAB.text:00446DAB loc_446dab: ; CODE XREF: CommonDispatchException+36 j.text:00446dab and eax, 1.text:00446DAE push 1 ; char.text:00446db0 push eax ; int.text:00446db1 push ebp ; BugCheckParameter3.text:00446DB2 push 0 ; int.text:00446db4 push ecx ; void *.text:00446db5 call KiDispatchException(x,x,x,x,x) KiDebugService 先构建一个陷阱帧 (KTRAP_FRAME ), 然后设置参数调用 CommonDispatchException, CommonDispatchException 会构建一个异常纪录 (EXCEPTION_RECORD), 然后调用 KiDispatchException 函数走异常处理 流程, 异常代码为 STATUS_BREAKPOINT 从 int2d >KiDebugService >CommonDispatchException >KiDispatchException 这个 流程一路看下来, 会发现 int2d 时提供的三个参数存放在异常纪录的 ExceptionInformation 数组里面, 分别是 : ExceptionInformation[0] 表示 BREAKPOINT_PRINT 功能号 ExceptionInformation[1] 表示调试信息字符串地址 ExceptionInformation[2] 表示调试信息字符串长度 进入 KiDispatchException 后的代码比较复杂, 当前只是分析 DbgPrint 的流程, 其他代码暂时不管, 只需要知道 KiDispatchException 会调用 KiDebugRoutine 把异常提交给内核调试引擎处理 当处于内核调试时,KiDebugRoutine 指向 KdpTrap 函数, 没有调试时,KiDebugRoutine 指向 KdpStub 函数 先来看看 KdpStub 函数.text:0042A2DC stdcall KdpStub(x, x, x, x, x, x) proc near.text:0042a2dc.text:0042a2dc TrapFrame = dword ptr 8.text:0042A2DC ExceptionFrame = dword ptr 0Ch.text:0042A2DC ExceptionRecord = dword ptr 10h.text:0042A2DC ContextRecord = dword ptr 14h.text:0042A2DC PreviousMode = dword ptr 18h.text:0042A2DC bsecondchance = dword ptr 1Ch.text:0042A2DC.text:0042A2DC mov edi, edi.text:0042a2de push ebp.text:0042a2df mov ebp, esp.text:0042a2e1 push ebx.text:0042a2e2 push esi.text:0042a2e2.text:0042a2e3 mov esi, [ebp+exceptionrecord].text:0042a2e6 xor ebx, ebx.text:0042a2e8 cmp [esi+exception_record.exceptioncode], STATUS_BREAKPOINT

DbgPrint 函数流程分析 by 小喂 6.text:0042A2EE jnz short _elseif.text:0042a2ee.text:0042a2f0 cmp [esi+exception_record.numberparameters], ebx.text:0042a2f3 jbe short _elseif.text:0042a2f3.text:0042a2f5 mov eax, [esi+exception_record.exceptioninformation].text:0042a2f8 cmp eax, BREAKPOINT_LOAD_SYMBOLS.text:0042A2FB jz short loc_42a30c.text:0042a2fd cmp eax, BREAKPOINT_UNLOAD_SYMBOLS.text:0042A300 jz short loc_42a30c.text:0042a302 cmp eax, BREAKPOINT_COMMAND_STRING.text:0042A305 jz short loc_42a30c.text:0042a307 cmp eax, BREAKPOINT_PRINT.text:0042A30A jnz short _elseif.text:0042a30c.text:0042a30c mov eax, [ebp+contextrecord].text:0042a30f inc [eax+context._eip].text:0042a315 mov al, 1 ; return TRUE;.text:0042A317 jmp short _exit KdpStub 先判断异常代码是不是 STATUS_BREAKPOINT(int3 断点异常也是这个异常代码, 但第一个参数是 BREAKPOINT_BREAK), 然后判断参数个数 对于当前支持的四种调试服务, 包括输出调试字符串, 都是把 eip 加一, 跳 过 int2d 后面带的 int3 指令, 然后从异常处理中返回, 继续执行 当正在调试时,KiDispatchException 调用的就是 KdpTrap 函数 PAGEKD:006AB5EB stdcall KdpTrap(x, x, x, x, x, x) proc near PAGEKD:006AB6A1 loc_6ab6a1: ; CODE XREF: KdpTrap(x,x,x,x,x,x)+3A j PAGEKD:006AB6A1 mov edx, [ebx+context._ebx] PAGEKD:006AB6A7 lea ecx, [ebp+breturn] PAGEKD:006AB6AA push ecx PAGEKD:006AB6AB push [ebp+exceptionframe] PAGEKD:006AB6AE movzx ecx, word ptr [eax+1ch] ; ExceptionInformation[2] PAGEKD:006AB6B2 push [ebp+trapframe] PAGEKD:006AB6B5 push dword ptr [ebp+previousmode] PAGEKD:006AB6B8 push ecx PAGEKD:006AB6B9 push dword ptr [eax+18h] ; ExceptionInformation[1] PAGEKD:006AB6BC mov ecx, [ebx+context._edi] PAGEKD:006AB6C2 call KdpPrint(x,x,x,x,x,x,x,x) KdpTrap 也会和 KdpStub 一样判断异常代码和参数个数, 以及调试服务号, 根据调试服务号的不同调用不同的处理 函数 针对 BREAKPOINT_PRINT 输出调试信息的情况, 调用的是 KdpPrint 函数 KdpPrint 也会根据 ComponentId 和 Level 值判断一下是否需要屏蔽此次输出 然后判断特权模式, 如果是用户模式 还需要探测字符串内存, 保证可读

DbgPrint 函数流程分析 by 小喂 7 PAGEKD:006AC921 mov [ebp+asbuffer.buffer], edi PAGEKD:006AC924 mov [ebp+asbuffer.length], bx PAGEKD:006AC928 lea eax, [ebp+asbuffer] PAGEKD:006AC92B push eax PAGEKD:006AC92C call KdpLogDbgPrint(x) PAGEKD:006AC931 cmp _KdDebuggerNotPresent, 0 PAGEKD:006AC938 jnz short loc_6ac984 PAGEKD:006AC93A push [ebp+exceptionframe] PAGEKD:006AC93D push [ebp+trapframe] PAGEKD:006AC940 call KdEnterDebugger(x,x) PAGEKD:006AC945 mov [ebp-20h], al PAGEKD:006AC948 lea eax, [ebp+asbuffer] PAGEKD:006AC94B call KdpPrintString(x) KdpPrint 接着调用 KdpLogDbgPrint 在一个循环缓冲区里记录调试字符串, 然后判断是否挂接了调试器, 调用 KdpPrintString 输出调试字符串 KdpPrintString 构造一个调试包, 通过 KdSendPacket 函数发送给调试器 DebugView 实现原理 上一节详细介绍了 DbgPrint 输出调试字符串的流程, 现在来看看 DebugView 工具的实现原理 在 Vista 系统上,DebugView 设置了调试输出回调函数, 从而截获调试字符串 kd> dps nt!rtlpdebugprintcallback L 1 818f41b8 00000000 kd> g ModLoad: 919ef000 919f2d00 Dbgv.sys kd> dps nt!rtlpdebugprintcallback L 1 818f41b8 919efa86 Dbgv+0xa86 在 Vista 以前的系统, 比如 2003 系统上,DbgPrint 函数调用 vdbgprintexwithprefixinternal 函数, 在 vdbgprintexwithprefixinternal 函数里面不是直接 int2d 调用调试服务, 而是通过 DebugPrint 函数再调用调试服务把字符 串输出 DebugView 通过 Hook 函数 DebugPrint 截获调试字符串 kd> u nt!debugprint nt!debugprint: 808356b6 8bff mov edi,edi 808356b8 55 push ebp 808356b9 8bec mov ebp,esp 808356bb ff7510 push dword ptr [ebp+10h] 808356be 8b4508 mov eax,dword ptr [ebp+8] 808356c1 ff750c push dword ptr [ebp+0ch] 808356c4 0fb708 movzx ecx,word ptr [eax] 808356c7 51 push ecx 808356c8 ff7004 push dword ptr [eax+4] 808356cb 6a01 push 1 808356cd e86f460100 call nt!debugservice (80849d41)

DbgPrint 函数流程分析 by 小喂 8 808356d2 5d pop ebp 808356d3 c20c00 ret 0Ch kd> g ModLoad: f6a46000 f6a49d00 Dbgv.sys kd> u nt!debugprint nt!debugprint: 808356b6 ff258c7da4f6 jmp dword ptr [Dbgv+0x1d8c (f6a47d8c)] 808356bc 7510 jne nt!debugprint+0x18 (808356ce) 808356be 8b4508 mov eax,dword ptr [ebp+8] 808356c1 ff750c push dword ptr [ebp+0ch] 808356c4 0fb708 movzx ecx,word ptr [eax] 808356c7 51 push ecx 808356c8 ff7004 push dword ptr [eax+4] 808356cb 6a01 push 1 kd> dps 0xf6a47d8c L 1 f6a47d8c f6a469ac Dbgv+0x9ac ========== 小喂 2007 12 01