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开发之三(内核启动后不正常)的描述,内核无法启动是选择了平板内存模式后 ...
随机推荐
- 为什么catch了异常,但事务还是回滚了?
前几天我发了这篇文章<我来出个题:这个事务会不会回滚?>得到了很多不错的反馈,也有不少读者通过微信.群或者邮件的方式,给了我一些关于test4的回复.其中还有直接发给我测试案例,来证明我的 ...
- excel打印出现多余空白页
问题: 解决方法一:设置打印区域 步骤:选择需要打印的内容--页面布局--打印区域--设置打印区域即可 解决方法二:删除多余的打印空白页 步骤:视图--分页预览--选中多余的空白页删除即可
- kubernetes的存活探针和就绪探针
1.存活探针 使用Kubernetes的一个主要好处是,可以给Kubernetes-个容器列表来由其保持容器在集群中的运行.可以通过让Kubernetes创建pod资源,为其选择一个工作节点并在该节点 ...
- 试着给VuePress添加登录授权支持,基于v-dialogs
背景介绍 VuePress是个不错的能基于Markdown快速构建静态网站的框架,初步来说,对外访问都是透明的. 但是可能因为一些保密需要,有些站点的文档,我们希望控制一下访问,所以我们借着别人的轮子 ...
- POJ 3984 迷宫(BFS)
入门BFS,第一次做,部分借鉴了大牛的 #include <iostream> #include <cstdio> #include <queue> using n ...
- Hadoop:Hadoop的安装
CentOS7安装Hadoop需要有JDK,所以先下载安装JDK后,在进行安装Hadoop 下载Hadoop #联网状态下使用wget命令 wget http://archive.apache.org ...
- 按键控制LED灯-ESP32中断处理
#include <driver/gpio.h> #include <esp_task_wdt.h> #include <freertos/FreeRTOS.h> ...
- ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: NO)解决办法
问题:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) 很久没用这台电脑的mysql ...
- 团队开发day01
进行了项目的划分,负责开发android端的登录注册,网页端的登录注册, 以及服务器端的数据处理,请求响应 第一天任务:编写登录和注册的UI 遇到问题:对android的布局存在不了解,放置的图片lo ...
- DWA局部路径规划算法论文阅读:The Dynamic Window Approach to Collision Avoidance。
DWA(动态窗口)算法是用于局部路径规划的算法,已经在ROS中实现,在move_base堆栈中:http://wiki.ros.org/dwa_local_planner DWA算法第一次提出应该是1 ...
