来记录一下自己学习驱动开发的过程,便于复习回忆。

环境: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 下,以服务名作为一个注册表的键名。

如下图所示:

7 android windows 内核 编译 windows内核编程_内核驱动

 

下面展示一个最简单的驱动程序:

#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一样

 

 

7 android windows 内核 编译 windows内核编程_字符串_02

 

 

 

7 android windows 内核 编译 windows内核编程_bc_03