• OD: Windows Kernel Debug


    内核调试入门

    内核程序运行在内核态,因此不能像对用户态应用程序那样来调试。关于内核调试方面的知识请参考《软件调试》这本书。目前内核调试主要有以下三种方法。

    一是使用硬件调试器,它通过特定的接口(如 JTAG)与 CPU 建立连接并读取它的状态,例如 ITP 调试器。

    二是在内核中插入专门用于调试的中断处理函数和驱动程序。当操作系统内核被中断时,这些中断处理函数和驱动程序接管系统的硬件,营造一个可以供调试器运行的简单环境,并用自己的驱动程序来处理用户输入、输出,例如 SoftICE 和 Syser 等调试器。

    三是在系统内核中加入调试支持,当需要中断到调试器中时,只保留这部分支持调试的代码还在运行,因为正常的内核服务都已经停止,所以调试器程序是不可能运行在同一个系统中的,因此这种方法需要调试器运行在另一个系统中,二者通过通信电缆交流信息。

    Windows操作系统推荐的内核调试方式是第三种,这种方法需要在被调试系统和调试系统之间建立连接,迄今为止共有三种连接方式:串行口、1394 和 USB2.0。

    起初,内核调试大多通过双机调试进行。随着虚拟机技术的广泛使用,双机调试逐渐被虚拟机调试所取代。本节介绍一种非常方便的虚拟机内核调试方法—— "利用命名管道(Named Pipe)模拟串行端口"。具体地说,就是在虚拟机中虚拟一个串行端口,并且把这个串口映射到宿主机的命名管道上。这样一来,虚拟机中所有对该串口的读写操作都会被虚拟机管理软件转换为对宿主系统中的命名管道的读写,运行在宿主系统中的调试器便可以通过这个命名管道来与虚拟机中的内核调试引擎进行通信。

    这种虚拟机调试内核的方法实现了单机调试,其优点是简单方便,但也存在一些缺点,一是难以调试硬件相关的驱动程序;二是当对某些涉及底层操作(中断、异常或者 I/O)的函数或指令设置断点时,可能导致虚拟机意外重启;三是当将目标系统中断到调试器中时,目前的虚拟机管理软件会占用非常高的 CPU,超过 90%。不过总的来说,这种调试方法足以调试目前公布的内核漏洞了。

    下面介绍如何使用 WinDbg 和 VMware 来实现这种方法的调试(VMware Support 中提到,自 4.0.18.0 版本之后的 WinDbg 都支持通过 pipe 进行调试)。

    创建内核调试环境

    一,设置 VMware 虚拟机硬件:关闭虚拟机,编辑虚拟机属性,添加串行商品,选择“Output to named pipe”后,在接下来的设置中,

    named pipe 填 "\.pipecom_1"
    第二个输入框中选择“This end is the server.”
    第三个输入框中选择“The other end is an application.”,并选中“Connect at power on

    添加完毕之后,勾选面板右侧"I/O mode"中的"Yield CPU on poll"选项。

    二,修改虚拟机 Guest OS 中的启动配置文件。

    对于 Windows XP,用 attrib -a -r -s -h c:oot.ini & notepad c:oot.ini 追加启动文件配置信息如下,再 attrib +a +r +s +h c:oot.ini 即可。

    [boot loader]
    timeout=30
    default=multi(0)disk(0)rdisk(0)partition(1)WINDOWS
    [operating systems]
    multi(0)disk(0)rdisk(0)partition(1)WINDOWS="Microsoft Windows XP Professional" /fastdetect
    multi(0)disk(0)rdisk(0)partition(1)WINDOWS="Microsoft Windows XP Professional -Debug" /fastdetect /debug /debugport=com1 /baudrate=115200

    /baudrate=115200,表示串行通信的速率 bps,115200 是串行通信的最大速率,因此使用串行通信进行内核调试时,如果进行频繁的单步跟踪和要传递较大的文件(如 .kdfiles 和 .dump 命令),那么会感觉到速度有些慢。

    从 Windows Vista 开始,考虑到 boot.ini 文件很容易被恶意软件所修改,因此不再使用 boot.ini 文件,而是使用 Boot Configuration Data—BCD。修改 BCD,需要启动一个管理员权限(Run As Administrator)的命令行窗口。然后使用 bcdedit 命令来编辑 BCD(建议首先将当前启动入口复制一份):

    c:Windowssystem32>bcdedit /copy {current} /d "Win7 Debug with Serial port"
    The entry was successfully copied to {new_uuid}
    
    c:Windowssystem32>bcdedit /debug {new_uuid} on
    The operation completed successfully.

    BCD 中有一套全局的调试设置,使用 bcdedit /dbgsettings 可以观察和修改这套全局设置:

    c:Windowssystem32>bcdedit /dbgsettings
    debugtype Serial
    debugport 1
    baudrate 115200
    The operation completed successfully.

    可以看到默认的全局调试设置中,调试类型为 Serial,调试端口为 1,波特率为 115200,这已经是我们需要的设置了。当然也可以通过如下命令再次设置为串口调试:

    c:Windowssystem32>bcdedit /dbgsettings serial DEBUGPORT:1 BAUDRATE:115200
    The operation completed successfully.

    如果希望为某个自启动项设置单独的调试选项,那么可以使用 bcdedit /set:

    bcdedit /set {new_uuid} debugtype serial
    bcdedit /set {new_uuid} debugport 1
    bcdedit /set {new_uuid} baudrate 115200

    三,设置 WinDbg 启动参数

    在 WinDbg 快捷方式中的“目标”项中添加如下参数:

    -b -k com:port=\.pipecom_1,baud=115200,pipe 

    -b 是一个内核模式选项,表示在连接上被调试的计算机后,或被调试计算机重启且内核初始化后,立即 break。

    -k 也是一个内核模式的选项,-k com:port=\.pipecom_ 1,baud=115200,pipe 表示使用串行通信方式,端口为 \.pipecom_1,波特率为 115200。

    设置好后,重启 VM Guest OS 并选择 Debug 项启动,之后会发现系统貌似卡住一样,这其实是系统在等待串口另一端的调试程序与其建立连接。

    启动刚才设置好的WinDbg快捷方式,发现很快WinDbg就连上虚拟机中的Guest OS了,如果很长时间没有连接上的话,可以单击 WinDbg 菜单中的"Debug"->"Kernel Connection"-> "Resynchronize" 重新连接,连接成功后显示如下(Guest OS 为 XP):

    由于调试内核程序经常会死机或蓝屏,而频繁的系统重启又需要很多时间,为了节约部分时间,可灵活使用 VMware 的快照功能,在配置好测试环境后,不要急于测试,而是先建立该测试环境的快照,这样当出现死机或蓝屏后,再次测试时可以直接回滚到之前的快照状态下的 Guest OS 中,这样能够大大节省等待时间。

    蓝屏分析

    蓝屏(Blue Screen)是 Windows 用于提示严重的系统级报错的一种方式。蓝屏一旦出现,Windows 系统便宣告终止,只有重新启动才能恢复到桌面环境,所以蓝屏又被称为蓝屏终止(Blue Screen Of Death),简称为 BSOD

    通过系统的"启动和故障恢复"设置,可以在系统发生错误或崩溃时自动将系统的状态从内存转储到磁盘文件中。Windows 系统定义了 3 种不同的系统转储文件。

    完整转储 Complete memory dump)

    包含产生转储时物理内存中的所有数据,其文件大小通常比物理内存的容量还要大,默认位置为 %SystemRoot%MEMORY.DMP。

    内核转储 Kernel memory dump

    去除了用户进程所使用的内存页,因此文件大小要比完整转储小得多,对于典型的 Windows XP 系统,其大小为200MB左右,默认位置为 %SystemRoot%MEMORY.DMP。

    小型内存转储 Small memory dump

    默认为 64KB,默认位置为 %SystemRoot%MiniDump 下,系统会按照日期加序号的方式来命名该 dump 文件,因此系统可以保存多个小型内存转储文件。

    系统转储文件的格式是不公开的,目前需要使用 WinDbg 调试器来分析系统转储文件。在 WinDbg 中打开 dump 文件,最简单的分析方法是使用 WinDbg 中的 !analyze -v 命令,可以自动地完成很多分析工作。一般使用 !analyze -v 命令,足以分析出蓝屏的原因:

    蓝屏停止码描述和参数:包含了停止码及停止码对应的常量、详细描述和每个参数的含义。

    错误指令位置:包含了导致错误的程序地址、机器码和对应的汇编指令。

    崩溃分类号:是指赋予这次崩溃的一个分类代码,通常是蓝屏的停止码或停止码加上一个子类号。

    陷阱帧信息:描述了导致这次蓝屏异常发生时的状态,主要包括当时的寄存器值和异常的错误代码。

    栈回溯:显示了可疑线程栈上所记录的执行记录,包括函数调用及因为中断或异常而发生的转移,这部分信息对于深入了解导致蓝屏的原因非常重要。例如,本例中从栈回溯结果中可以看出,最终是在 win32k!SfnINSTRING 函数发生了错误,并发生了转移,转移到了 nt!KiTrap0E+0xcc。

    蓝屏的基本信息:包括导致错误发生所在的模块名称、镜像名称、进一步追查名称和错误 ID 等信息,以便错误分析软件对大量的转储文件进行自动分析、统计和归档。

  • 相关阅读:
    ucore lab4 内核线程管理 学习笔记
    谈谈博客三迁的经历
    ucore lab3 虚拟内存管理 学习笔记
    ucore lab2 物理内存管理 学习笔记
    ucore lab1 操作系统启动过程 学习笔记
    【VMware】在移动硬盘或U盘中安装便携linux系统
    借助ADB冻结与卸载Android系统应用(免ROOT)
    Windows下查找各类游戏存档路径
    QMetaObject::connectSlotsByName: No matching signal for XXX 原理探究
    将VScode添加至右键菜单
  • 原文地址:https://www.cnblogs.com/exclm/p/4097576.html
Copyright © 2020-2023  润新知