内核调试入门

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

一是使用硬件调试器,它通过特定的接口(如 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 填 "\\.\pipe\com_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:\boot.ini & notepad c:\boot.ini 追加启动文件配置信息如下,再 attrib +a +r +s +h c:\boot.ini 即可。

[boot loader]
timeout=
default=multi()disk()rdisk()partition()\WINDOWS
[operating systems]
multi()disk()rdisk()partition()\WINDOWS="Microsoft Windows XP Professional" /fastdetect
multi()disk()rdisk()partition()\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:\Windows\system32>bcdedit /copy {current} /d "Win7 Debug with Serial port"
The entry was successfully copied to {new_uuid} c:\Windows\system32>bcdedit /debug {new_uuid} on
The operation completed successfully.

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

c:\Windows\system32>bcdedit /dbgsettings
debugtype Serial
debugport
baudrate
The operation completed successfully.

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

c:\Windows\system32>bcdedit /dbgsettings serial DEBUGPORT: BAUDRATE:
The operation completed successfully.

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

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

三,设置 WinDbg 启动参数

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

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

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

-k 也是一个内核模式的选项,-k com:port=\\.\pipe\com_ 1,baud=115200,pipe 表示使用串行通信方式,端口为 \\.\pipe\com_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 等信息,以便错误分析软件对大量的转储文件进行自动分析、统计和归档。

OD: Windows Kernel Debug的更多相关文章

  1. Windows Kernel Security Training Courses

    http://www.codemachine.com/courses.html#kerdbg Windows Kernel Internals for Security Researchers Thi ...

  2. Windows Kernel Way 1:Windows内核调试技术

    掌握Windows内核调试技术是学习与研究Windows内核的基础,调试Windows内核的方式大致分为两种: (1)通过Windbg工具在Windows系统运行之初连接到Windows内核,连接成功 ...

  3. OD: Ring0 & Kernel

    开发技术讲究封装与模块化,安全技术强调底层安全性.安全技术需要打开封装.追根溯源! <0day 安全:软件漏洞分析技术(第2版)> 第21章 探索 Ring0 笔记 Intel x86 系 ...

  4. Linux Kernel - Debug Guide (Linux内核调试指南 )

    http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...

  5. Windows Kernel Way 扉言

    七年寒窗,但求一道. 笔者在学习windows/linux以及各类编程语言.框架之初因摸不到门路而磕磕绊绊,因寻不到明师而步履蹒跚,或不知缘从何起,或不知路在何处,只能尝试.回溯.重来.反反复复,竟也 ...

  6. Windows kernel pool 初探(2014.12)

    Windows kernel pool 1. 简介 Kernel pool类似于Windows用户层所使用Heap,其为内核组件提供系统资源.在系统初始化的时候,内存管理模块就创建了pool. 严格的 ...

  7. 我与 windows kernel 的一段时光

    写在前面 本科毕业设计是实现一个基于 windows 的透明加密过滤系统.由此对 windows kernel development,尤其是 file system 进行过较为深入的探索.对于防终止 ...

  8. /sys/kernel/debug/usb/devices解析

    1.概述 USB设备通过debugfs导出/sys/kernel/debug/usb/devices显示内核已知的每个USB设备及其配置描述符.此文件对于用户模式下的状态查看工具非常方便,可以扫描文本 ...

  9. [微软官网]One Windows Kernel

    One Windows Kernel https://techcommunity.microsoft.com/t5/Windows-Kernel-Internals/One-Windows-Kerne ...

随机推荐

  1. AutoIt3初探(1)

    AutoIt3可实现系统操作,键盘鼠标模拟,是自动化测试的一个好工具. 这个是在线帮助文档,http://www.jb51.net/shouce/autoit/ 需要先下载一个autoIt安装,然后将 ...

  2. java web 学习(1)

    java web 应用的核心技术包括以下几个方面: jsp:进行输入和输出的基本手段 javabean:完成功能的处理 servlet:对应用的流程进行控制 jdbc:是与数据库进行交互不可缺少的技术 ...

  3. exit() die return 的区别

    rutrun 会返回一个值,或不返回值 只是当前函数内return后面的语句将不会执行,后面的其它语句继续执行exit()可以返回值,也可以不返回值直接终止程序 函数输出一条消息,并退出当前脚本. 会 ...

  4. php对mongo操作问题

    最近由于业务需求,需要使用php对mongo做一些操作,关于mongodb,选择的版本是:MongoDB shell version: 2.0.6 MongoDB是一种文档导向数据库管理系统,由C++ ...

  5. 转发:[Python]内存管理

    本文为转发,原地址为:http://chenrudan.github.io/blog/2016/04/23/pythonmemorycontrol.html 本文主要为了解释清楚python的内存管理 ...

  6. PHP之路——PHPExcel使用

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGMAAAJkCAIAAAA6GnvRAAAgAElEQVR4nOzd918bV/ov8Pv33Y2RNC

  7. STM8S学习笔记-时钟控制2

    今天把时钟系统的最后部分,时钟安全系统(CSS)和时钟输出功能(CCO),做一个简答的说明. 1.时钟安全系统(以下简称CSS) CSS功能很简单,就是监控HSE是否实效(如果系统使用HSE作为主时钟 ...

  8. 转:Git_Windows 系统下Git安装图解

    原文地址:http://blog.csdn.net/jiguanghoverli/article/details/7902791 Windows 系统下Git安装图解 简单来说Git是一个免费的.开源 ...

  9. SCALA当的trait

    不是特别懂,但感觉和RUBY当中的MIX-IN功能有几分相似,这又扯到了多重继承及JAVA当中的接口虚拟类了.. package com.hengheng.scala class UseTrait { ...

  10. 多备份CEO胡茂华:创业路上的五道坎

    本文由多备份CEO胡茂华记述,授权南七道发表,未做删改.胡茂华:腾讯第116号员工,历任腾讯总监.盛大CTO (旅游).1号店技术副总裁.现担任云服务提供商多备份联合创始人&CEO. 2014 ...