Windows内核编程基础(一)
来记录一下自己学习驱动开发的过程,便于复习回忆。
环境:Windows10 Visual Studio 2019 WDK1803 VMware16 Windows1804
工具:DebugView 数字签名工具(signtools-v3.2)
VMware安装1804的系统,使用签名工具避免开启免签,个人感觉安全些。
类似Windows应用程序有统一的WinMain入口函数,内核驱动也有一个统一的入口函数,DriverEntry
NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath )
第一个参数代表驱动对象指针,操作系统在内存中为当前驱动分配了一个类型为DRIVER_OBJECT的数据结构,用于记录该驱动的详细信息。
第二个参数代表当前驱动对应的注册表位置,类型为UNICODE_STRING
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING;
其中Buffer为一个指针,指向一个UNICODE类型的字符串缓冲区;
MaximumLength表示Buffer所指向缓冲区的总空间大小,一般等于Buffer被分配时的内存大小,单位为字节;
Length表示Buffer所指向缓冲区中字符串的长度,单位也是字节。
驱动SYS文件需要运行,首先需要把这个驱动文件创建成一个服务(第三方服务,区别于系统服务),
注册成功后,系统会把该服务信息写入到注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Service 下,以服务名作为一个注册表的键名。
如下图所示:
下面展示一个最简单的驱动程序:
#include "ntddk.h" //这个是内核开发所需的头文件ntddk.h VOID DriverUnload( PDRIVER_OBJECT DriverObject )//这个函数很重要,但不一定需要,没有运行后就无法停止 { if ( DriverObject != NULL ) { DbgPrint("[%ws] Driver Upload,Driver Object Address:%p", __FUNCTIONW__,DriverObject); } return; } NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject , PUNICODE_STRING RegistryPath ) //驱动入口函数 { //KdBreakPoint();//断点,调试时使用 DbgPrint("[%ws] Hello Kernel World\n",__FUNCTIONW__); //打印日志,WDK提供的API,与其类似的是KdPrint函数(只对DeBug版本的驱动有效)
// %ws 表示打印一个以'\0'结束的UNICODE字符串 , FUNCTIONW表示当前函数名字,对应 %ws if ( RegistryPath != NULL )// 判断是否为NULL ,注册表路径是否存在 { DbgPrint("[%ws] Driver Object Address:%p\n", __FUNCTIONW__,DriverObject); DriverObject->DriverUnload = DriverUnload;//调用DriverUnload函数,内核驱动停止
// A B C
// B为A的一个函数指针 , } return STATUS_SUCCESS;//返回STATUS_SUCCESS表示成功,否则失败 }
UNICODE %ws
UNICODE_STRING %wZ
编译上述驱动
方式多种,直接使用VS编译,
期间存在一些问题,记录一下:
生成空驱动项目后,需要把自动生成的sys移除(不是删除),再重新编译
驱动的运行与调试
生成的sys都通过驱动签名软件进行签名避免关闭系统的驱动校验,
注册驱动的命令
.\sc.exe create driver1 binPath="C:\driver\driver1.sys" type= kernel start= demand
这个稍微记一下,类型为内核,启动方式为手动
其他命令如运行、停止、删除都是sc + start\stop\delete + DriverName
驱动运行时可以管理员运行Dbgview查看DbfPrint的日志
内核驱动不支持暂停操作
一下程序可以注册驱动:
aaa
驱动的调试在虚拟机上进行,
bcdedit /debug on 开启调试模式
bcdedit /dbgsetting net hostip:xxx.xxx.xxx.xxx port:50001 通过网络进行调试
KdBreakPoint与DbgBreakPoint的区别与DbgPrint和KdPrint一样
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?