freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Windows 驱动开发入门
2023-04-23 16:17:40
所属地 湖北省

0x00 前言

随着 windows 系统的更新迭代,windows 驱动开发技术也是不断的升级:从最早期的 VXD(Virtual X Driver)(已废弃)到 windows 2000 上推出的 WDM(Windows Driver Model)驱动模型,随后从 windows vista 推出的 WDF(Windows Driver Foudation)驱动模型,沿用至今;WDF 是 WDM 的升级版,并且在一定程度上兼容,WDF 是微软目前推荐的驱动开发模型。

WDF 还可以细分为内核模式 KMDF(Kernel-Mode Driver Framework) 和用户模式 UMDF(User-Mode Driver Framework),顾名思义 UMDF 将受到更多的限制从而换来更高的操作系统稳定性,其二进制扩展名为*.dll;UMDF 和 KMDF 开发基本相同,本文这里仅介绍使用更广泛的 KMDF 开发。

本文实验环境

windows 10 专业版 x64 1909
Visual Studio 2019
SDK 10.0.19041.685
WDK 10.0.19041.685

0x01 搭建驱动开发环境

首先配置Visual Studio 2019的 C/C++ 开发环境(https://visualstudio.microsoft.com/),按 Visual Studio 官方教程,自动下载安装「使用C++的桌面开发」,其中 SDK 默认为10.0.19041.0

image

开发软件需要 SDK(Software Development Kit),而开发 windows 驱动则需要 WDK(Windows Driver Kit);现在我们来配置 WDK 环境,从官网(https://learn.microsoft.com/zh-cn/windows-hardware/drivers/download-the-wdk)下载 WDK 在线安装包(版本必须和 SDK 一致),按如下进行安装:

对于 WDF 驱动模型其开发环境叫 WDK(Windows Driver Kit)
对于 WDM 驱动模型其开发环境叫 DDK(Driver Development Kit)

image

安装完毕后,其窗口会默认勾选为Visual Studio安装 WDK 扩展插件,按照指导进行安装即可,随后我们可以在Visual Studio的创建项目页面,就看到 KMDF/UMDF 等选项,表示 windows 驱动开发环境配置成功。

image

windows 驱动开发环境可能会受操作系统、Visual Studio、SDK、WDK 的版本影响,配置过程需要多留心这些环节,如遇见问题可以参考如下版本信息 https://learn.microsoft.com/en-us/windows-hardware/drivers/other-wdk-downloads。

0x02 HelloWorld开发

根据官方教程,我们在Visual Studio中创建空的KMDF项目,并在其中创建Driver.c文件,编写代码如下:

#include <ntddk.h>
#include <wdf.h>
DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;

NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT     DriverObject,
    _In_ PUNICODE_STRING    RegistryPath
)
{
    // NTSTATUS variable to record success or failure
    NTSTATUS status = STATUS_SUCCESS;

    // Allocate the driver configuration object
    WDF_DRIVER_CONFIG config;

    // Print "Hello World" for DriverEntry
    KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n"));

    // Initialize the driver configuration object to register the
    // entry point for the EvtDeviceAdd callback, KmdfHelloWorldEvtDeviceAdd
    WDF_DRIVER_CONFIG_INIT(&config,
        KmdfHelloWorldEvtDeviceAdd
    );

    // Finally, create the driver object
    status = WdfDriverCreate(DriverObject,
        RegistryPath,
        WDF_NO_OBJECT_ATTRIBUTES,
        &config,
        WDF_NO_HANDLE
    );
    return status;
}

NTSTATUS
KmdfHelloWorldEvtDeviceAdd(
    _In_    WDFDRIVER       Driver,
    _Inout_ PWDFDEVICE_INIT DeviceInit
)
{
    // We're not using the driver object,
    // so we need to mark it as unreferenced
    UNREFERENCED_PARAMETER(Driver);

    NTSTATUS status;

    // Allocate the device object
    WDFDEVICE hDevice;

    // Print "Hello World"
    KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: KmdfHelloWorldEvtDeviceAdd\n"));

    // Create the device object
    status = WdfDeviceCreate(&DeviceInit,
        WDF_NO_OBJECT_ATTRIBUTES,
        &hDevice
    );
    return status;
}

在「配置管理器」中设置为Debug/x64,编译生成项目发现如下错误:

image

Visual Studio默认开启了缓解 Spectre 攻击的机制,可在 VS 安装器中选择安装指定的支持库,我们实验环境下可以直接关闭该功能,在项目属性-C/C++-代码生成-Spectre Mitigation设置为Disable

image

随后便可以成功编译,在[src]/x64/Debug/下,可以看到生成的二进制文件KmdfHelloWorld.sys

0x03 部署和测试

驱动程序一般以服务(service)或设备(device)的方式运行工作,这点和普通应用程序不同,所以不能像应用程序那样进行调试和测试。官方指导中提供一种基于双机调试环境的驱动调试方法,这种方式较为繁琐,我们这里进行简要介绍;想了解更方便的本机调试驱动程序的小伙伴,可跳转至「0x04 本机调试驱动程序」。

按照官方指导,我们将驱动程序作为设备进行运行调试,在此之前需要再提供一台主机作为被调试机(debugee),驱动程序将在被调试机上(debugee)进行部署和测试,而本台主机即作为开发主机同时作为调试机(debugger),如下:

image

首先在被调试机(debugee)上也安装上 WDK 环境,随后在 WDK 的安装目录下运行该工具WDK Test Target Setup,默认路径:C:\Program Files (x86)\Windows Kits\10\Remote\x64\WDK Test Target Setup x64-x64_en-us.msi;在之后调试机(debugger)中的Visual Studio将连接被调试机(debugee)的WDK Test Target Setup的工具,自动完成双机调试环境的配置。

在开发主机上(debugger)初始化被调试机的相关信息,在项目属性-Driver Install-Deployment中添加新设备,我们这里使用网络双机调试的方式,默认参数即可:

image

随后将自动完成配置,如下:

image

Visual Studio中将被调试机(debugee)添加完毕后,在如下窗口选择该主机并设置驱动的硬件 ID 为Root\KmdfHelloWorld,如下:

image

配置完成后,我们在Visual Studio菜单中生成-部署解决方案,驱动程序将自动部署在被调试机上(debugee)并进行测试运行:

image

在被调试机(debugee)上我们在设备管理器中可以看到KmdfHelloWorld已经成功部署了:

image

如果想调试驱动程序,则可以使用 WinDBG 依据以上的双机调试环境对驱动程序进行调试。

image

0x04 本机调试驱动程序

官方提供的驱动程序部署和测试方法,虽然有效的隔离开发环境和调试环境,但实在是过于繁琐了,更不用说其中双机调试环境下的各种问题。而驱动程序还可以以服务的方式进行运行,我们通过这种方式可以更加方便的在本机调试驱动程序。

在日常安全工作中,我更喜欢使用这种方式,因为大多数情况我只需要工作在内核层的驱动代码,而不关心其是否是完整的 windows 驱动设备,这种方式能帮助我快速进行安全验证工作。

创建 KMDF 项目并编写代码如下:

#include <ntddk.h>
#include <wdf.h>

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
    UNREFERENCED_PARAMETER(DriverObject);
    KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "test: unload driver\n"));
}

NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT     DriverObject,
    _In_ PUNICODE_STRING    RegistryPath
)
{
    UNREFERENCED_PARAMETER(DriverObject);
    UNREFERENCED_PARAMETER(RegistryPath);

    KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "test: driver entry\n"));

    DriverObject->DriverUnload = OnUnload;

    return STATUS_SUCCESS;
}

在「配置管理器」中设置为Debug/x64,编译生成项目。

在运行测试前,我们需要在本机(即开发主机)上打开测试模式(重启生效),使得操作系统可以加载我们编译的驱动程序,使用管理员权限打开 powershell:

# 打开测试模式
bcdedit /set testsigning on

重启主机后,使用管理员权限打开 powershell,通过sc.exe命令为驱动程序创建服务(命令详解请参考:https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/sc-create):

# 创建服务名为 test,类型为 kernel,启动方式为 demand 的服务,并指定驱动程序路径
# (注意参数等号后必须有一个空格)
sc.exe create test type= kernel start= demand binPath= C:\Users\john\Desktop\workspace\kmdf_test\x64\Debug\kmdf_test\kmdf_test.sys

# 使用 queryex 查看创建的服务信息
sc.exe queryex test

创建服务如下:

image

随后便可以使用sc.exe命令启动驱动程序运行,并使用DebugView查看调试输出(需要勾选Capture KernelEnable Verbose Kernel Output才能看到输出):

# 启动运行驱动程序
sc.exe start test
# 停止运行驱动程序
sc.exe stop test

运行如下:

image

当我们更新了驱动代码、编译项目后,可以再次start/stop这个服务,便可以快捷的进行驱动程序代码的测试和调试。

0x05 References

https://learn.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/
https://github.com/microsoft/Windows-driver-samples</https://github.com/microsoft/Windows-driver-samples>
https://visualstudio.microsoft.com/
https://learn.microsoft.com/zh-cn/windows-hardware/drivers/download-the-wdk</https://learn.microsoft.com/zh-cn/windows-hardware/drivers/download-the-wdk>
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/sc-create</https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/sc-create>

# windows
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录