admin 管理员组文章数量: 1184232
文章目录
- 前言
- 一、下载和使用WDK(Windows Driver Kit)
- 1.1 环境
- 1.2 工具
- 1.2.1 srvinstw.exe
- 1.2.2 DriverMonitor
- 1.2.3 DbgView
- 1.2.4 WinDBG
- 1.3 相关知识
- 1.3.1 NT驱动
- 1.3.2 WDK
- 1.3.3 WDM
- 1.3.4 WDF
- 二、安装与运行
- 2.1 项目模板创建与导入
- 2.2 代码
- 2.2.1编译时需要要选择激活x64为活动配置
- 2.2 打开测试模式
- 2.3 禁用驱动签名
- 三、调试内核模块
- 3.1 配置虚拟机串口
- 3.2 启动windbg连接虚拟机
- 四、练习题
- 五、常见问题
- 5.1 DriverMonitor
- 5.1.1 此驱动程序被阻止加载
- 5.1.2 无法验证此文件的数字签名
- 参考
- 总结
前言
此系列纯学习笔记,看别人一系列博客对windows驱动进行学习,虽然前人种树,资料齐全,但是我觉得学习就是思考,将别人的转为自己的理解并加以实践,最后就会成为自己所掌握的知识。
一、下载和使用WDK(Windows Driver Kit)
1.1 环境
| vs版本 | wdk版本 | sdk版本 | 双击调试虚拟机windows版本 |
|---|---|---|---|
| vs2019 | WDK 19041 (Windows Driver Kit 10 2004 (VB) 19041.685 VS 2019) | win10 19041 | win10 19041 |
| vs2013 | WDK 8.1 (Windows Driver Kit 8.1) | win 8.1 | cn_windows_10_consumer_editions_version_1903_x64_dvd_8f05241d.iso |
虚拟机工具:vmware 16 pro
1.2 工具
1.2.1 srvinstw.exe
安装/卸载服务程序的工具
https://filesblogs/pcjim/srvinstw.rar
1.2.2 DriverMonitor
加载/卸载驱动sys文件工具
使用方法,依次Open Driver->Start Driver
1.2.3 DbgView
查看驱动打印日志工具
使用方法,勾选Capture Kernel合Enable Verbose Kernel Output
即可查看DbgPrint等打印日志
1.2.4 WinDBG
winsdk中包含
https://go.microsoft/fwlink/?linkid=2311805
1.3 相关知识
1.3.1 NT驱动
这是Windows NT时代延续下来的最基础、最原始的驱动模型。它提供了与内核交互的最低级API。
不支持即插即用
1.3.2 WDK
windows driver kit 微软驱动开发工具包
1.3.3 WDM
WDM 模型与操作系统紧密相关。 驱动程序通过调用系统服务例程和操作操作系统结构直接与操作系统交互。 由于 WDM 驱动程序是受信任的内核模式组件,因此系统对驱动程序输入提供有限的检查。
为了应对即插即用和电源管理的需求,微软在Windows 98和Windows 2000中引入了WDM模型。它是NT模型的扩展,增加了一套复杂的约定和回调机制。
1.3.4 WDF
Windows 驱动程序框架 (WDF) 模型侧重于驱动程序的要求,框架库处理与系统的大部分交互。
WDF 模型基于对象,由事件驱动。 对象表示常见的驱动程序构造,例如设备、锁或队列。 Kernel-Mode Driver Framework (KMDF) 或 User-Mode Driver Framework (UMDF) 驱动程序包含 (DriverEntry) 入口点、为设备提供服务和支持 I/O 所需的与事件相关的回调函数,以及实现所依赖的任何其他内部实用工具函数。
WDM 和 WDF 之间的差异
WDF是微软为了彻底解决WDM的复杂性而推出的新一代驱动开发框架。它不是一个全新的模型,而是建立在WDM/NT之上的一个抽象层。
二、安装与运行
2.1 项目模板创建与导入
参考:https://wwwblogs/LyShark/p/17163377.html
也可直接使用我配置好的 https://download.csdn/download/qq1113673178/91611640
直接放压缩包到
C:\Users\Administrator\Documents\Visual Studio 2013\Templates\ProjectTemplates (注意改用户路径) 即可
2.2 代码
代码1 windriver_learn_01.sys
用于测试DriverMonitor载入驱动
#include <ntddk.h>
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint(("Uninstall Driver Is OK \n"));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint(("hello lyshark \n"));
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
代码2 windriver_learn_02.sys
用于测试双机调试windbg断点触发
#include <ntifs.h>
NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint("驱动已卸载 \n");
}
// By: LyShark
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
// 初始化默认派遣函数
NTSTATUS status = STATUS_SUCCESS;
Driver->DriverUnload = UnDriver;
for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
Driver->MajorFunction[i] = DriverDefaultHandle;
}
// 设置断点
DbgBreakPoint();
// KdBreakPoint();
// __debugbreak();
DbgPrint("驱动已加载 \n");
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
代码3 内核测试模式过DSE签名
// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark
#include <ntifs.h>
// 绕过签名检查
BOOLEAN BypassCheckSign(PDRIVER_OBJECT pDriverObject)
{
#ifdef _WIN64
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY listEntry;
ULONG64 __Undefined1;
ULONG64 __Undefined2;
ULONG64 __Undefined3;
ULONG64 NonPagedDebugInfo;
ULONG64 DllBase;
ULONG64 EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING path;
UNICODE_STRING name;
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG64 __Undefined6;
ULONG CheckSum;
ULONG __padding1;
ULONG TimeDateStamp;
ULONG __padding2;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
#else
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY listEntry;
ULONG unknown1;
ULONG unknown2;
ULONG unknown3;
ULONG unknown4;
ULONG unknown5;
ULONG unknown6;
ULONG unknown7;
UNICODE_STRING path;
UNICODE_STRING name;
ULONG Flags;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
#endif
PKLDR_DATA_TABLE_ENTRY pLdrData = (PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
pLdrData->Flags = pLdrData->Flags | 0x20;
return TRUE;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
// 绕过签名检查
// LINKER_FLAGS=/INTEGRITYCHECK
BypassCheckSign(Driver);
DbgPrint("[驱动已加载] hello lyshark \n");
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
2.2.1编译时需要要选择激活x64为活动配置
然后再生成即可
2.2 打开测试模式
bcdedit /set testsigning on // 打开测试模式
bcdedit -debug on
bcdedit /bootdebug on
bcdedit /set "{current}" bootmenupolicy Legacy // 修改启动方式为Legacy
bcdedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 // 设置串口1为调试端口波特率为115200
bcdedit /copy "{current}" /d "Debug" // 将当前配置复制到Debug启动配置
bcdedit /debug "{<新建的启动配置的标识符>}" on // 打开调试开关
2.3 禁用驱动签名
开机之后进入系统前界面按下F8键,进入Windows系统的高级启动项,我们会发现与原有的XP系统多了一些不同的地方,最后一项中为禁用驱动程序签名强制,按照此项进入系统即可使用未有数字签名的驱动程序,当然,使用调试模式同样也可以加载未有签名的驱动,这里不推荐。
注意:重启电脑后,会恢复默认,所以虚拟机的话就一直暂停,而不是关闭。
三、调试内核模块
3.1 配置虚拟机串口
(虚拟机使用前置是已打开测试模式,和禁用驱动签名校验了)
3.2 启动windbg连接虚拟机
基本过程:
- 启动windbg 连接串口
- 重启虚拟机,黑屏,卡在进入系统界面
- windbg开始调试
接下来细讲:
启动windbg连接串口
管理员权限运行cmd 执行命令
"C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64\windbg.exe" -b -k com:port=\\.\pipe\com_1,baud=115200,pipe
刚启动windbg时,一直waitting,
重启虚拟机,黑屏,卡在进入系统界面
windbg开始调试
接着执行加载符号和跳过断点
kd> .sympath SRV*c:\mySymbols*http://msdl.microsoft/download/symbols # 加载系统文件符号
kd> .reload # 重载
kd> g # 下一步直到断点
kd> g # # 下一步直到断点
kd> ed nt!Kd_SXS_Mask 0 # 好像没用上
kd> ed nt!Kd_FUSION_Mask 0 # 好像没用上
kd> u KiSystemServiceUser # 好像没用上
然后用drivermonitor载入windriver_learn_02.sys并start,会发现虚拟机卡住
windbg在代码断点处
然后双机调试算是搭建好了
四、练习题
(1)Windows 内核模块使用什么开发包进行开发?
WDK
(2)有哪些调试工具可以调试 Windows内核?
WinDbg,VS, x86/x64 Debuger
(3)开发 Windows内核模块,Visual Studio 是必要的吗?
必要的
(4)WinDbg应该安装在被调试机上,还是安装在调试机上?
调试机
(5)有时在内核模块代码中插入int3指令,这有什么作用?
花指令,用于标记代码
五、常见问题
5.1 DriverMonitor
5.1.1 此驱动程序被阻止加载
1.检查驱动sys和对应系统位数是否相符合,x86只能在x86系统运行,x64在x64运行
2.是否禁用驱动签名
开机之后在登录等待界面按下F8键,进入Windows系统的高级启动项,我们会发现与原有的XP系统多了一些不同的地方,最后一项中为禁用驱动程序签名强制,按照此项进入系统即可使用未有数字签名的驱动程序,当然,使用调试模式同样也可以加载未有签名的驱动,这里不推荐。
3.bcdedit配置
bcdedit /set testsigning on
bcdedit -debug on
bcdedit /bootdebug on
bcdedit /set “{current}” bootmenupolicy Legacy // 修改启动方式为Legacy
bcdedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 // 设置串口1为调试端口波特率为115200
bcdedit /copy “{current}” /d “Debug” // 将当前配置复制到Debug启动配置
bcdedit /debug “{<新建的启动配置的标识符>}” on // 打开调试开关
5.1.2 无法验证此文件的数字签名
是否禁用驱动签名
开机之后在登录等待界面按下F8键,进入Windows系统的高级启动项,我们会发现与原有的XP系统多了一些不同的地方,最后一项中为禁用驱动程序签名强制,按照此项进入系统即可使用未有数字签名的驱动程序,当然,使用调试模式同样也可以加载未有签名的驱动,这里不推荐。
参考
Windows 内核安全编程技术实践 – 系列文章
Windows 内核安全编程技术实践 – 系列文章 lyshark原创
Tutorial: Write a Hello World Windows Driver (Kernel-Mode Driver Framework)
VS2013+WDK8.1 驱动开发环境配置
驱动开发:WinDBG 配置内核双机调试
总结
版权声明:本文标题:[笔记] Windows内核安全编程《一》内核开发前期准备 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1759885562a3134787.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论