驱动的DriverUnload函数

对于一个Windows驱动来说,一般需要提供DriverUnload函数,有了这个函数,驱动对应的服务(service)就能被停止。

驱动是已服务的方式运行的,服务停止的实质是系统把该驱动模块对应在内核地址空间中的代码以及数据移除了。

同时,开发者可以在DriverUnload函数中进行一些清理相关的工作。例如驱动Driver A内部有一个线程B,如果开发者没有在DriverUnload函数中停止线程B,一旦驱动A被停止,则线程B对应与驱动A的代码就被系统删除了,线程B执行就会发生异常,从而引起系统异常。

但DriverUnload函数并不是必须的,因此,有些软件就不提供DriverUnload函数,服务就只能启动而不能停止,这一特性被很多软件(例如安全软件)利用,避免驱动被恶意停止。

参考:《Windows内核编程》- 谭文,陈铭霖

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 Windows 内核模式下,我们可以使用 Zw 拦截函数来获取 NtFlushKey 函数的地址。Zw 拦截函数是 Windows 内核中的一种机制,它可以拦截用户态进程调用的系统调用,并将其转换为内核态下的函数调用。因此,我们可以通过 Zw 拦截函数来获取 NtFlushKey 函数的地址。 以下是一个示例代码,用于在 Windows 内核模式下获取 NtFlushKey 函数的地址: ```cpp #include <ntddk.h> // 定义 NtFlushKey 函数原型 typedef NTSTATUS (__stdcall* PFN_NTFLUSHKEY)(HANDLE); // 定义全局变量保存 NtFlushKey 函数地址 PFN_NTFLUSHKEY g_NtFlushKey = NULL; // Zw 拦截函数,用于获取 NtFlushKey 函数地址 NTSTATUS MyZwFlushKey(HANDLE KeyHandle) { // 获取 NtFlushKey 函数地址 if (g_NtFlushKey == NULL) { UNICODE_STRING functionName; RtlInitUnicodeString(&functionName, L"NtFlushKey"); g_NtFlushKey = (PFN_NTFLUSHKEY)MmGetSystemRoutineAddress(&functionName); if (g_NtFlushKey == NULL) { DbgPrint("Failed to get address of NtFlushKey\n"); return STATUS_UNSUCCESSFUL; } DbgPrint("Address of NtFlushKey: %p\n", g_NtFlushKey); } // 调用 NtFlushKey 函数 return g_NtFlushKey(KeyHandle); } // 驱动入口函数 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { // 注册 ZwFlushKey 拦截函数 UNICODE_STRING functionName; RtlInitUnicodeString(&functionName, L"ZwFlushKey"); DriverObject->MajorFunction[IRP_MJ_CREATE] = NULL; DriverObject->MajorFunction[IRP_MJ_CLOSE] = NULL; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NULL; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = NULL; DriverObject->DriverUnload = NULL; DriverObject->MajorFunction[IRP_MJ_CREATE] = NULL; DriverObject->MajorFunction[IRP_MJ_CLOSE] = NULL; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NULL; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = NULL; DriverObject->MajorFunction[IRP_MJ_PNP] = NULL; DriverObject->MajorFunction[IRP_MJ_POWER] = NULL; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyZwFlushKey; IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, NULL); IoCreateSymbolicLink(RtlInitUnicodeString(&functionName, L"\\??\\MyZwFlushKey"), RtlInitUnicodeString(&functionName, L"\\Device\\MyZwFlushKey")); return STATUS_SUCCESS; } ``` 上面的代码定义了 MyZwFlushKey 函数作为 ZwFlushKey 的拦截函数,在第一次调用该函数时获取 NtFlushKey 函数的地址,并保存到全局变量 g_NtFlushKey 中。在后面的调用中,直接使用 g_NtFlushKey 函数指针调用 NtFlushKey 函数。注意,在驱动入口函数中,我们需要将 ZwFlushKey 拦截函数注册到 IRP_MJ_DEVICE_CONTROL 处理函数中,以便驱动程序能够接收到系统调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鹰信息技术服务部

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值