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)-内核模式调试的更多相关文章

  1. Windows内核开发-2-开始内核开发-2-内核开发入门

    Windows内核开发-2-开始内核开发-2- 第一个驱动程序: 直接采用vs2019中的Empty WDM Driver 模块创建: 初始的项目文件夹中有一个Driver Files里面会有一个.i ...

  2. 64位内核开发第二讲.内核编程注意事项,以及UNICODE_STRING

    目录 一丶驱动是如何运行的 1.服务注册驱动 二丶Ring3跟Ring0通讯的几种方式 1.IOCTRL_CODE 控制代码的几种IO 2.非控制 缓冲区的三种方式. 三丶Ring3跟Ring0开发区 ...

  3. 64位内核开发第六讲,Windbg调试ring3跟Ring0.一起调试

    目录 驱动第六讲_Windbg连续调试Ring3.与Ring0 一丶Windbg连调试 驱动第六讲_Windbg连续调试Ring3.与Ring0 一丶Windbg连调试 有时候我们调试一个程序.可以使 ...

  4. Windows内核开发-4-内核编程基础

    Windows内核开发-4-内核编程基础 这里会构建一个简单但是完整的驱动程序和一个客户端,部署内核执行一些平时user下无法执行的操作. 将通过以下内容进行讲解: 1 介绍 2 驱动初始化 3 Cr ...

  5. Bran的内核开发教程(bkerndev)-02 准备工作

    准备工作   内核开发是编写代码以及调试各种系统组件的漫长过程.一开始这似乎是一个让人畏惧的任务,但是并不需要大量的工具集来编写自己的内核.这个内核开发教程主要涉及使用GRUB将内核加载到内存中.GR ...

  6. 内核用户模式调试支持(Dbgk)

    简介 将详细分析Windows调试的内核模式接口.希望读者对C和通用NT内核体系结构和语义有一些基本的了解.此外,这并不是介绍什么是调试或如何编写调试器.它可以作为经验丰富的调试器编写人员或好奇的安全 ...

  7. Windows内核开发-3-内核编程基础

    Windows内核开发-3-内核编程基础 这里会深入讲解kernel内核的API.结构体.和一些定义.考察代码在内核驱动中运行的机制.最后把所有知识合在一起写一个有用的驱动. 本章学习要点: 1:通用 ...

  8. Windows内核开发-6-内核机制 Kernel Mechanisms

    Windows内核开发-6-内核机制 Kernel Mechanisms 一部分Windows的内核机制对于驱动开发很有帮助,还有一部分对于内核理解和调试也很有帮助. Interrupt Reques ...

  9. STM32F103 ucLinux开发之四(内核启动后的调试)

    Stm32-uclinux启动后的调试 1.  修改__pfn_to_page使得能够启动 根据STM32F103 ucLinux开发之三(内核启动后不正常)的描述,内核无法启动是选择了平板内存模式后 ...

随机推荐

  1. 学习Qt Charts - 不使用UI的情况下使用QTCharts

    新建一个Qt Widgets Application项目,不添加UI文件,如下图: 建立工程后,在.pro文件中添加: QT += charts 然后在.h文件中添加: #include " ...

  2. 循序渐进BootstrapVue,开发公司门户网站(5)--- 使用实际数据接口代替本地Mock数据

    在我们开发一些门户网站功能的时候,有时候我们需要快速的创建数据模型来进行数据展示,因为数据结构可能处于不断的修正变化之中,因此服务端的接口我们可以暂时不开发,当我们基本完成数据结构和界面展示的时候,就 ...

  3. Redis6使用指导(完整版)

    一.Nosql与Redis概述 二.Redis6安装 三.常用五大数据类型 四.Redis6配置文件详解 五.Redis6的发布和订阅 六.Redis6新数据类型 七.Jedis操作Redis6(Ma ...

  4. AcWing 1134. 最短路计数

    给出一个n个顶m 条边的无向无权图,顶点编号为 1 到 n.N. 问从顶点 1开始,到其他每个点的最短路有几条. #include<bits/stdc++.h> #define N 100 ...

  5. CentOS-Docker搭建Rancher(单点)

    参考官方安装说明 服务器准备 节点服务器的硬件配置,可根据实际情况依据该表自行选择. 规模集群节点CPU内存 小 最多5个 高达50 2 8 GB 中 最多15个 最多200 4 16 GB 大 高达 ...

  6. hadoop安装前的准备

    1.操作系统安装 2.hostname设定 3.hosts文件设定 4.ssh免密码登录 5.NTP时间同步设定 6.iptables永久关闭 7.selinux永久关闭

  7. Jsp自定义标签,配置tld文件

    Program:Jsp自定义标签,.tld文件的配置 1 <?xml version="1.0" encoding="UTF-8" ?> 2 3 & ...

  8. 题解 AtCoder Beginner Contest 168

    小兔的话 欢迎大家在评论区留言哦~ AtCoder Beginner Contest 168 A - ∴ (Therefore) B - ... (Triple Dots) C - : (Colon) ...

  9. mongodb,redis,mysql的区别和具体应用场景(转)

    一.MySQL 关系型数据库. 在不同的引擎上有不同 的存储方式. 查询语句是使用传统的sql语句,拥有较为成熟的体系,成熟度很高. 开源数据库的份额在不断增加,mysql的份额页在持续增长. 缺点就 ...

  10. celery task异步任务

    业务端后台:通过python manage运行 运行用例时,用python manage运行时会卡,影响效率 celery task 本身自己也是个服务,异步处理case 异步:小明去给我买个东西,我 ...