Windows内核开发-5-(2)-内核模式调试
Windows内核开发-5-(2)-内核模式调试
普通用户模式的调试,采取的是给进程添加一个线程来挂起断点,作为一个调试器的线程在进程中使用。照这样来类推,对操作系统调试相当于添加一个进程来限制操作系统,所以操作系统是会被冻结的。这样的话就不能直接在本机电脑上进行调试了,不然电脑就卡住了。而且还容易出现问题。最好的办法是创建一个虚拟机,用一台主力机给一台专门用来测试的计算机调试。

测试机和主力机必须通过一种方式来连接,选择有很多,最好的选择是通过网络连接,但是网络连接要求target和host至少是Win8以上,Win7就很尴尬了,但是由于这个很多搞安全的要求兼容,就会很麻烦。以至于很多采用串口连接,这里我们将如何建立串口连接。
还有需要注意的就是这个操作系统的版本和位数。你要开发什么样子的就用什么样子的操作系统。比如说:你要开发一个在Win10 64位计算机上用的东西,你就装一个Win10 64位虚拟机。虽然大部分都有兼容的效果,比如在64位上能跑32位的程序,但是还是建议采用对应的操作系统版本。
搭建内核模式调试环境
这里我采用的是Win10 32位虚拟机,和Win10 64位本机,采用串口连接。
下载操作系统
这个在msdn上下载你需要的对应版本的操作系统就好:
https://msdn.itellyou.cn/,安装虚拟机如果不清楚就自行百度一下。
添加启动引导
给测试机添加启动引导,需要使用管理员模式启动命令行:
cmd管理员身份运行bcdedit
bcdedit /copy {current} /d Sna1lGo//这里的Sna1lGo是引导名称,自己随意设置。
bcdedit /displayorder {xxxxx-xxxx-xxx} /addlast //这里的xxx是你在设置了引导名称后的一长条字符串
//这里的addlast是引导的位置,last表示是最后
bcdedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 //设置调试端口波特率
bcdedit /debug {xxxxx-xxxx-xxx} ON//对新加的启动项增加调试功能
bcdedit /timeout 20//选择等待时长

设置完成后,再开机就有系统启动引导了。
虚拟机设置:
添加串行端口:(如果你的虚拟机里面有打印机,打印机默认会占用一个名为//./pipe/com_1的串行端口)

命名随意,只要是//./pipe/xxx就行,这里我采用的是把打印机移除掉,然后命名为//./pipe/com_1。
WinDbg配置
给WinDbg配置当启动的时候自动连接到测试机。首先根据测试机的位数选择同样的WinDbg,这里我选择32位的WinDbg,然后弄了一个快捷方式在桌面。

快捷方式这里有一个目标,在这个目标的后面添加参数:
-k com:port=//./pipe/com_1,baud=115200,pipe
这里的参数是和前面一一对应的,如果有问题就自己找找前面的定义。然后就可以直接运行WinDbg来调试Windows了。
给WinDbg配置符号
符号就是说函数名称的配置,如果不配置函数名称不完整,大概可以先这样理解。
在WinDbg中选择Symbol Search Path(快捷键Ctrl+S):
然后输入:
srv*D:\symbol*;srv*D:\symbol*http://msdl.microsoft.com/download/symbols
这段指令的意思是,会在D:\symbol中存储符号表,如果没有就到后面那个http:地址下载,然后存放到前面那个地址,这个存放的地址可以自己选择。然后就完美了,大功告成。
开始内核调试:
这里采用之前在第四章写的简单完整驱动来调试。
Windows内核驱动--实现修改线程优先级demo - Sna1lGo - 博客园 (cnblogs.com)这里下载例子。
然后将生成的sys和pdb文件一起复制到虚拟机里面,然后安装驱动但是不加载驱动。参考该博客来安装驱动:Windows内核开发-2-开始内核开发-2-内核开发入门 - Sna1lGo - 博客园 (cnblogs.com)
进入WinDbg后,给我们自己写的入口函数打一个断点:
bu prioritybooster!driverentry
这里采用的是bu断点:bu 命令是针对某个符号下断点。 比如 bu MyApp!SomeFunction 。 在代码被修改之后, 该断点可以随着函数地址改变而自动更新到最新位置。 而且bu 断点会保存在WinDbg工作空间中, 下次启动 Windbg 的时候该断点会自动设置上去。另外,在模块没有被加载的时候,bp 断点会失败(因为函数地址不存在),而bu 断点则可以成功。 新版的WinDBG中 bp失败后会自动被转成bu 。
打下断点后,我们在WinDbg命令行中输入g,让系统跑起来,然后再在系统中去加载该驱动。
如果一切顺利的话会出现下面这样:


就可以像一些平常的调试器一样来调试东西了。
输入k指令来查看堆栈:
1: kd> k
# ChildEBP RetAddr
00 8985fad8 81dac709 PriorityBooster!DriverEntry [D:\ProjectSum\Driver\PriorityBooster\PriorityBooster.cpp @ 14]
01 8985fbc8 81e3552c nt!IopLoadDriver+0x443
02 8985fbe8 81aefa6a nt!IopLoadUnloadDriver+0x42
03 8985fc38 81abe0f0 nt!ExpWorkerThread+0xea
04 8985fc70 81b9a18d nt!PspSystemThreadStartup+0x4a
05 8985fc7c 00000000 nt!KiThreadStartup+0x15
如果断点似乎无法设置,则可能是符号问题。 执行 .reload 命令重新加载符号来查看问题是否已解决。 在用户空间设置断点也是可能的,但首先执行 .reload /user 来解决这个问题。
还可以在命令中添加-p来限制给某某进程打断点,总之WinDbg非常强大,好好学习吧。
总结:
WinDbg其实就是一个调试器,只不过可以调试内核。对于调试用户层的代码来说和别的没什么区别只是可能更强大官方一点。而内核模式就最好还是双机调试。搭建内核调试环境是非常重要的,因为调试可以让我们更加深入的,一步一步的看完所有代码非常好用。至于WinDbg的使用方法,大家多尝试,熟练了就好了。可以看看这本书来熟悉WinDbg:http://www.windbg.info/download/doc/pdf/WinDbg_A_to_Z_bw2.pdf
Windows内核开发-5-(2)-内核模式调试的更多相关文章
- Windows内核开发-2-开始内核开发-2-内核开发入门
Windows内核开发-2-开始内核开发-2- 第一个驱动程序: 直接采用vs2019中的Empty WDM Driver 模块创建: 初始的项目文件夹中有一个Driver Files里面会有一个.i ...
- 64位内核开发第二讲.内核编程注意事项,以及UNICODE_STRING
目录 一丶驱动是如何运行的 1.服务注册驱动 二丶Ring3跟Ring0通讯的几种方式 1.IOCTRL_CODE 控制代码的几种IO 2.非控制 缓冲区的三种方式. 三丶Ring3跟Ring0开发区 ...
- 64位内核开发第六讲,Windbg调试ring3跟Ring0.一起调试
目录 驱动第六讲_Windbg连续调试Ring3.与Ring0 一丶Windbg连调试 驱动第六讲_Windbg连续调试Ring3.与Ring0 一丶Windbg连调试 有时候我们调试一个程序.可以使 ...
- Windows内核开发-4-内核编程基础
Windows内核开发-4-内核编程基础 这里会构建一个简单但是完整的驱动程序和一个客户端,部署内核执行一些平时user下无法执行的操作. 将通过以下内容进行讲解: 1 介绍 2 驱动初始化 3 Cr ...
- Bran的内核开发教程(bkerndev)-02 准备工作
准备工作 内核开发是编写代码以及调试各种系统组件的漫长过程.一开始这似乎是一个让人畏惧的任务,但是并不需要大量的工具集来编写自己的内核.这个内核开发教程主要涉及使用GRUB将内核加载到内存中.GR ...
- 内核用户模式调试支持(Dbgk)
简介 将详细分析Windows调试的内核模式接口.希望读者对C和通用NT内核体系结构和语义有一些基本的了解.此外,这并不是介绍什么是调试或如何编写调试器.它可以作为经验丰富的调试器编写人员或好奇的安全 ...
- Windows内核开发-3-内核编程基础
Windows内核开发-3-内核编程基础 这里会深入讲解kernel内核的API.结构体.和一些定义.考察代码在内核驱动中运行的机制.最后把所有知识合在一起写一个有用的驱动. 本章学习要点: 1:通用 ...
- Windows内核开发-6-内核机制 Kernel Mechanisms
Windows内核开发-6-内核机制 Kernel Mechanisms 一部分Windows的内核机制对于驱动开发很有帮助,还有一部分对于内核理解和调试也很有帮助. Interrupt Reques ...
- STM32F103 ucLinux开发之四(内核启动后的调试)
Stm32-uclinux启动后的调试 1. 修改__pfn_to_page使得能够启动 根据STM32F103 ucLinux开发之三(内核启动后不正常)的描述,内核无法启动是选择了平板内存模式后 ...
随机推荐
- Vue(8)列表渲染v-for
循环 在模板中可以用v-for指令来循环数组,对象等. 循环数组 我们可以用 v-for 指令基于一个数组来渲染一个列表.v-for 指令需要使用 item in items形式的特殊语法,其中 it ...
- Spring学习日记01_IOC_xml的三种注入方式
什么是IOC 控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理 使用IOC目的:为了耦合度降低 做入门案例就是IOC实现 IOC底层原理 xml解析 工厂模式 反射 原始方式 cla ...
- MySQL数据库复制技术应用实战(阶段二)
MySQL数据库复制技术应用实战(阶段二)文档 作者 刘畅 时间 2020-9-27 服务器版本:CentOS Linux release 7.5.1804 主机名 ip地址 服务器配置 安装软件 密 ...
- ssh-正向与反向代理
常用参数 栗子 实战 常用参数 -N 告诉SSH客户端,这个连接不需要执行任何命令.仅仅做端口转发 -C 表示压缩数据传输 -f 告诉SSH客户端在后台运行 -q Quiet mode. 安静模式,忽 ...
- vsftpd配置文件详解(转)
vsftpd配置文件详解 1.默认配置: 1>允许匿名用户和本地用户登陆. anonymous_enable=YES local_enable=YES 2> ...
- Jquery Validate动态添加和删除校验规则
以下面文本框为例, <input type="text"name="username" id="username"/> 我们要让 ...
- 第13次抽考(IO流)
1.将文本文件a.txt 复制成 b.txt.要求: a. 用逐个字符复制方式: b. 用逐行读写方式: c. 用字符数组方式 2.将压缩包a.rar复制成b.rar. 注意:复制前后手工打开文件,若 ...
- 计算机网络体系结构整理-第二单元IP技术
IP技术 1.IPV4 Ipv4的报头格式 Ipv4地址分为ABCDE类, 类别 IP地址范围 私有IP地址范围 A 0.0.0.0-127.255.255.255 10.0.0.0-10.255.2 ...
- C++11运算符重载详解与向量类重载实例(<<,>>,+,-,*等)
1. C++运算符重载介绍 C ++ 中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作.这时就必须在C ++ 中重新定义这些运算符,赋予已 ...
- 二进制方式搭建Kubernetes集群
环境准备: 演练暂时用单节点一台master和一台node节点来进行部署搭建(kubernetes 1.19版本) 角色 IP 组件 master 10.129.246.114 kube-apiser ...
