Windows驱动开发(9)——双机调试
今天具体学习一下双机调试。
前言
肯定主要就是这个调试器怎么去用了,这里我贴一下 VirtualKD 的项目地址——(https://github.com/4d61726b/VirtualKD-Redux)。也由衷地感谢这些开发者给我们开发了这么好用的工具,让我们环境搭建这一步走了很大的捷径,上一篇博客中遇到的问题,当时因为比较急直接去提了 issue,而作者也给出了很耐心的解释,应该是照顾我这个萌新吧。
真的是非常感谢。
Windbg的使用
我是实在用不来那个纯命令行的调试器,因为根本不知道跑起来之后怎么加断点,所以我使用了 Windbg preview,这个据说是要在微软商店下载的,如果停用了 windows 更新的话,好像就直接用不了了,为了这个我重新打开了我 windows 的更新。
初始布局大概是这样:
当提示 Debuggee is running 的时候,是没办法在 KD 命令行输入指令的,断点也打不了。
最开始的情况应该是:这里根本就不知道在哪的,左边的反汇编窗口应该也不是指向了自己想要的位置,此时不知道在哪里断就可以先放着,然后点 break 暂停,这个暂停是无条件的,可以立刻暂停虚拟机的运行,此时KD 命令行可以输入指令了,我们需要找到一个断点使得能在我们想要的地方暂停,这里我们可以直接使用 bp 命令下断点:
比如我们驱动是 xxxxxxx.sys,那么我们想要在这个驱动加载的时候断在 DriverEntry 这个函数就可以输入 bp xxxxxxx!DriverEntry
下断点,或者直接在搜索框输入 xxxxxxx!DriverEntry
然后下断点。
这里可能在加载驱动的时候会蹦出来源码,但是源码调试还是比较坑的,只有汇编是比较精准的结果,所以源码参照就行了,调试主要还是看汇编。
比如之前的 blog 中也有些问题,就是在打印的时候,那个变量总是不对,总是打印出 0xFF 开头的值,于是我就可以找到那个地方,使用 KMDFDriver2!MyProtect
去下断点,然后看看发生了啥。
于是在这里调试的时候,发现问题了,因为 ACCESS_MASK 是定义为 ULONG 的,我以为是 64 位结果就只有 32 位,可能因为这个就输出的一直不对吧,所以后面我选择使用 %x 去打印这个值,看起来也舒服一点。
后面就抄一下网上的其他师傅写的 blog 吧,来介绍下 windbg 的具体操作。
- 步进指令(step in):
t
或者.step
- 步过指令(step over):
p
或者.stepover
- 跳出指令(step out):
gu
或者.stepout
- 继续运行(continue):
g
- 打印寄存器状态:
r
- 打印单个寄存器:
r <%eax>
- 打印所有寄存器:
r*
- 查看内存:
d <memory address> <len>
,如果要字,双字,四字的形式显示,把d
改成db
,dw
,dd
。du
可以查看unicode字符串。参数 len 好像要在前面加上 l 作为修饰符。 - 设置断点:
bp <address>
- 设置条件断点:
bu <address> <addtion>
其中第三个参数可以设置寄存器状态的判断。 - 列出断点列表:
bl
- 删除断点:
bd
,可以跟一个编号删除指定断点,也可以使用通配符*
删除所有断点。 - 禁用断点:
be
- 启用断点:
bc
- 设置硬件断点:
ba <type> <address> [len]
,这里的type可以是以下三种之一:r
:读取断点,当指定地址上的数据被读取时触发断点。w
:写入断点,当指定地址上的数据被写入时触发断点。e
:执行断点,当程序执行到指定地址时触发断点
- 列出当前模块:
lm
- 列出当前模块详细信息:
lml
- 加载模块:
ld <dll-path>
剩余的命令再摸索吧。。