5.1 Windows驱动开发:判断驱动加载状态

news2024/9/23 15:32:05

在驱动开发中我们有时需要得到驱动自身是否被加载成功的状态,这个功能看似没啥用实际上在某些特殊场景中还是需要的,如下代码实现了判断当前驱动是否加载成功,如果加载成功, 则输出该驱动的详细路径信息。

该功能实现的核心函数是NtQuerySystemInformation这是一个微软未公开的函数,也没有文档化,不过我们仍然可以通过动态指针的方式调用到它,该函数可以查询到很多系统信息状态,首先需要定义一个指针。

typedef NTSTATUS(*NTQUERYSYSTEMINFORMATION)(
IN ULONG SystemInformationClass,
OUT PVOID   SystemInformation,
IN ULONG_PTR    SystemInformationLength,
OUT PULONG_PTR  ReturnLength OPTIONAL);

其次还需要一个SYSTEM_MODULE_INFORMATION该结构内可以得到模块入口信息模块名称等,调用NtQuerySystemInformation数据会被格式化为SYSTEM_MODULE_INFORMATION方便调用。

typedef struct _SYSTEM_MODULE_INFORMATION {
    HANDLE Section;
    PVOID MappedBase;
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT LoadOrderIndex;
    USHORT InitOrderIndex;
    USHORT LoadCount;
    USHORT PathLength;
    CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

最后是SYSTEM_INFORMATION_CLASS该结构同样是一个未文档化的结构体,本此代码中需要用到的枚举类型是SystemModuleInformation其他类型也放这里后期做参考用。

typedef enum _SYSTEM_INFORMATION_CLASS
{
    SystemBasicInformation = 0x0,
    SystemProcessorInformation = 0x1,
    SystemPerformanceInformation = 0x2,
    SystemTimeOfDayInformation = 0x3,
    SystemPathInformation = 0x4,
    SystemProcessInformation = 0x5,
    SystemCallCountInformation = 0x6,
    SystemDeviceInformation = 0x7,
    SystemProcessorPerformanceInformation = 0x8,
    SystemFlagsInformation = 0x9,
    SystemCallTimeInformation = 0xa,
    SystemModuleInformation = 0xb,
    SystemLocksInformation = 0xc,
    SystemStackTraceInformation = 0xd,
    SystemPagedPoolInformation = 0xe,
    SystemNonPagedPoolInformation = 0xf,
    SystemHandleInformation = 0x10,
    SystemObjectInformation = 0x11,
    SystemPageFileInformation = 0x12,
    SystemVdmInstemulInformation = 0x13,
    SystemVdmBopInformation = 0x14,
    SystemFileCacheInformation = 0x15,
    SystemPoolTagInformation = 0x16,
    SystemInterruptInformation = 0x17,
    SystemDpcBehaviorInformation = 0x18,
    SystemFullMemoryInformation = 0x19,
    SystemLoadGdiDriverInformation = 0x1a,
    SystemUnloadGdiDriverInformation = 0x1b,
    SystemTimeAdjustmentInformation = 0x1c,
    SystemSummaryMemoryInformation = 0x1d,
    SystemMirrorMemoryInformation = 0x1e,
    SystemPerformanceTraceInformation = 0x1f,
    SystemObsolete0 = 0x20,
    SystemExceptionInformation = 0x21,
    SystemCrashDumpStateInformation = 0x22,
    SystemKernelDebuggerInformation = 0x23,
    SystemContextSwitchInformation = 0x24,
    SystemRegistryQuotaInformation = 0x25,
    SystemExtendServiceTableInformation = 0x26,
    SystemPrioritySeperation = 0x27,
    SystemVerifierAddDriverInformation = 0x28,
    SystemVerifierRemoveDriverInformation = 0x29,
    SystemProcessorIdleInformation = 0x2a,
    SystemLegacyDriverInformation = 0x2b,
    SystemCurrentTimeZoneInformation = 0x2c,
    SystemLookasideInformation = 0x2d,
    SystemTimeSlipNotification = 0x2e,
    SystemSessionCreate = 0x2f,
    SystemSessionDetach = 0x30,
    SystemSessionInformation = 0x31,
    SystemRangeStartInformation = 0x32,
    SystemVerifierInformation = 0x33,
    SystemVerifierThunkExtend = 0x34,
    SystemSessionProcessInformation = 0x35,
    SystemLoadGdiDriverInSystemSpace = 0x36,
    SystemNumaProcessorMap = 0x37,
    SystemPrefetcherInformation = 0x38,
    SystemExtendedProcessInformation = 0x39,
    SystemRecommendedSharedDataAlignment = 0x3a,
    SystemComPlusPackage = 0x3b,
    SystemNumaAvailableMemory = 0x3c,
    SystemProcessorPowerInformation = 0x3d,
    SystemEmulationBasicInformation = 0x3e,
    SystemEmulationProcessorInformation = 0x3f,
    SystemExtendedHandleInformation = 0x40,
    SystemLostDelayedWriteInformation = 0x41,
    SystemBigPoolInformation = 0x42,
    SystemSessionPoolTagInformation = 0x43,
    SystemSessionMappedViewInformation = 0x44,
    SystemHotpatchInformation = 0x45,
    SystemObjectSecurityMode = 0x46,
    SystemWatchdogTimerHandler = 0x47,
    SystemWatchdogTimerInformation = 0x48,
    SystemLogicalProcessorInformation = 0x49,
    SystemWow64SharedInformationObsolete = 0x4a,
    SystemRegisterFirmwareTableInformationHandler = 0x4b,
    SystemFirmwareTableInformation = 0x4c,
    SystemModuleInformationEx = 0x4d,
    SystemVerifierTriageInformation = 0x4e,
    SystemSuperfetchInformation = 0x4f,
    SystemMemoryListInformation = 0x50,
    SystemFileCacheInformationEx = 0x51,
    SystemThreadPriorityClientIdInformation = 0x52,
    SystemProcessorIdleCycleTimeInformation = 0x53,
    SystemVerifierCancellationInformation = 0x54,
    SystemProcessorPowerInformationEx = 0x55,
    SystemRefTraceInformation = 0x56,
    SystemSpecialPoolInformation = 0x57,
    SystemProcessIdInformation = 0x58,
    SystemErrorPortInformation = 0x59,
    SystemBootEnvironmentInformation = 0x5a,
    SystemHypervisorInformation = 0x5b,
    SystemVerifierInformationEx = 0x5c,
    SystemTimeZoneInformation = 0x5d,
    SystemImageFileExecutionOptionsInformation = 0x5e,
    SystemCoverageInformation = 0x5f,
    SystemPrefetchPatchInformation = 0x60,
    SystemVerifierFaultsInformation = 0x61,
    SystemSystemPartitionInformation = 0x62,
    SystemSystemDiskInformation = 0x63,
    SystemProcessorPerformanceDistribution = 0x64,
    SystemNumaProximityNodeInformation = 0x65,
    SystemDynamicTimeZoneInformation = 0x66,
    SystemCodeIntegrityInformation = 0x67,
    SystemProcessorMicrocodeUpdateInformation = 0x68,
    SystemProcessorBrandString = 0x69,
    SystemVirtualAddressInformation = 0x6a,
    SystemLogicalProcessorAndGroupInformation = 0x6b,
    SystemProcessorCycleTimeInformation = 0x6c,
    SystemStoreInformation = 0x6d,
    SystemRegistryAppendString = 0x6e,
    SystemAitSamplingValue = 0x6f,
    SystemVhdBootInformation = 0x70,
    SystemCpuQuotaInformation = 0x71,
    SystemNativeBasicInformation = 0x72,
    SystemErrorPortTimeouts = 0x73,
    SystemLowPriorityIoInformation = 0x74,
    SystemBootEntropyInformation = 0x75,
    SystemVerifierCountersInformation = 0x76,
    SystemPagedPoolInformationEx = 0x77,
    SystemSystemPtesInformationEx = 0x78,
    SystemNodeDistanceInformation = 0x79,
    SystemAcpiAuditInformation = 0x7a,
    SystemBasicPerformanceInformation = 0x7b,
    SystemQueryPerformanceCounterInformation = 0x7c,
    SystemSessionBigPoolInformation = 0x7d,
    SystemBootGraphicsInformation = 0x7e,
    SystemScrubPhysicalMemoryInformation = 0x7f,
    SystemBadPageInformation = 0x80,
    SystemProcessorProfileControlArea = 0x81,
    SystemCombinePhysicalMemoryInformation = 0x82,
    SystemEntropyInterruptTimingInformation = 0x83,
    SystemConsoleInformation = 0x84,
    SystemPlatformBinaryInformation = 0x85,
    SystemThrottleNotificationInformation = 0x86,
    SystemHypervisorProcessorCountInformation = 0x87,
    SystemDeviceDataInformation = 0x88,
    SystemDeviceDataEnumerationInformation = 0x89,
    SystemMemoryTopologyInformation = 0x8a,
    SystemMemoryChannelInformation = 0x8b,
    SystemBootLogoInformation = 0x8c,
    SystemProcessorPerformanceInformationEx = 0x8d,
    SystemSpare0 = 0x8e,
    SystemSecureBootPolicyInformation = 0x8f,
    SystemPageFileInformationEx = 0x90,
    SystemSecureBootInformation = 0x91,
    SystemEntropyInterruptTimingRawInformation = 0x92,
    SystemPortableWorkspaceEfiLauncherInformation = 0x93,
    SystemFullProcessInformation = 0x94,
    SystemKernelDebuggerInformationEx = 0x95,
    SystemBootMetadataInformation = 0x96,
    SystemSoftRebootInformation = 0x97,
    SystemElamCertificateInformation = 0x98,
    SystemOfflineDumpConfigInformation = 0x99,
    SystemProcessorFeaturesInformation = 0x9a,
    SystemRegistryReconciliationInformation = 0x9b,
    MaxSystemInfoClass = 0x9c,
} SYSTEM_INFORMATION_CLASS;

最后的JudgeLoadDriver()是用于判断驱动是否加载的核心函数,我们看下该函数具体是如何实现的,原理很简单,下面是对代码的详细解释:

  • 1.首先定义了一个函数指针NTQUERYSYSTEMINFORMATION m_NtQuerySystemInformation,并初始化一个UNICODE_STRING类型的变量NtQuerySystemInformation_Name,用于存放要获取的函数名NtQuerySystemInformation
  • 2.调用MmGetSystemRoutineAddress函数获取NtQuerySystemInformation函数的地址,并将其赋值给m_NtQuerySystemInformation函数指针。如果获取失败,则返回1。
  • 3.调用m_NtQuerySystemInformation函数,并传入SystemModuleInformation作为参数,获取系统中所有模块的信息。如果获取失败,则返回1。
  • 4.分配内存,并将获取到的模块信息复制到分配的内存中。如果内存分配失败,则返回1。
  • 5.解析获取到的模块信息,检查是否有名为JudgeLoadDriver的模块被加载。如果有,则打印该模块的名称,并返回2。如果没有,则继续检查下一个模块。
  • 6.最后释放分配的内存,并返回0表示成功执行。
#include <ntifs.h>
#include <windef.h>
#include <stdlib.h>

typedef NTSTATUS(*NTQUERYSYSTEMINFORMATION)(
IN ULONG SystemInformationClass,
OUT PVOID   SystemInformation,
IN ULONG_PTR    SystemInformationLength,
OUT PULONG_PTR  ReturnLength OPTIONAL);

typedef struct _SYSTEM_MODULE_INFORMATION {
    HANDLE Section;
    PVOID MappedBase;
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT LoadOrderIndex;
    USHORT InitOrderIndex;
    USHORT LoadCount;
    USHORT PathLength;
    CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef enum _SYSTEM_INFORMATION_CLASS
{
    SystemBasicInformation = 0x0,
    SystemProcessorInformation = 0x1,
    SystemPerformanceInformation = 0x2,
    SystemTimeOfDayInformation = 0x3,
    SystemPathInformation = 0x4,
    SystemProcessInformation = 0x5,
    SystemCallCountInformation = 0x6,
    SystemDeviceInformation = 0x7,
    SystemProcessorPerformanceInformation = 0x8,
    SystemFlagsInformation = 0x9,
    SystemCallTimeInformation = 0xa,
    SystemModuleInformation = 0xb,
    SystemLocksInformation = 0xc,
} SYSTEM_INFORMATION_CLASS;

// 判断当前Driver是否加载成功
ULONG JudgeLoadDriver()
{
    NTQUERYSYSTEMINFORMATION m_NtQuerySystemInformation = NULL;
    UNICODE_STRING NtQuerySystemInformation_Name;
    PSYSTEM_MODULE_INFORMATION ModuleEntry;
    ULONG_PTR RetLength, BaseAddr, EndAddr;
    ULONG ModuleNumbers, Index;
    NTSTATUS Status;
    PVOID Buffer;
    RtlInitUnicodeString(&NtQuerySystemInformation_Name, L"NtQuerySystemInformation");
    m_NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress(&NtQuerySystemInformation_Name);
    if (m_NtQuerySystemInformation == NULL)
    {
        DbgPrint("获取NtQuerySystemInformation函数失败!\n");
        return 1;
    }

    RetLength = 0;
    Status = m_NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &RetLength);
    if (Status < 0 && Status != STATUS_INFO_LENGTH_MISMATCH)
    {
        DbgPrint("NtQuerySystemInformation调用失败!错误码是:%x\n", Status);
        return 1;
    }

    Buffer = ExAllocatePoolWithTag(NonPagedPool, RetLength, 'lysh');
    if (Buffer == NULL)
    {
        DbgPrint("分配内存失败!\n");
        return 1;
    }

    Status = m_NtQuerySystemInformation(SystemModuleInformation, Buffer, RetLength, &RetLength);
    if (Status < 0)
    {
        DbgPrint("NtQuerySystemInformation调用失败 %x\n", Status);
        return 1;
    }

    ModuleNumbers = *(ULONG*)Buffer;
    ModuleEntry = (PSYSTEM_MODULE_INFORMATION)((ULONG_PTR)Buffer + 8);
    for (Index = 0; Index < ModuleNumbers; ++Index)
    {
        BaseAddr = (ULONG_PTR)ModuleEntry->Base;
        EndAddr = BaseAddr + ModuleEntry->Size;
        if (BaseAddr <= (ULONG_PTR)JudgeLoadDriver && (ULONG_PTR)JudgeLoadDriver <= EndAddr)
        {
            DbgPrint("模块名称是:%s\n", ModuleEntry->ImageName);
            return 2;
        }
        ++ModuleEntry;
    }

    return 0;
}

VOID UnDriver(PDRIVER_OBJECT driver)
{
    DbgPrint("驱动卸载成功 \n");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
    DbgPrint("hello lyshark \n");

    ULONG ul = JudgeLoadDriver();

    DbgPrint("驱动状态: %d \n", ul);

    Driver->DriverUnload = UnDriver;
    return STATUS_SUCCESS;
}

代码运行效果如下所示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1248846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【matlab版本的ggplot2】

gramm (complete data visualization toolbox, ggplot2/R-like) 来源&#xff1a;Morel, Pierre. “Gramm: Grammar of Graphics Plotting in Matlab.” The Journal of Open Source Software, vol. 3, no. 23, The Open Journal, Mar. 2018, p. 568, doi:10.21105/joss.00568…

五种多目标优化算法(NSDBO、NSGA3、MOGWO、NSWOA、MOPSO)求解微电网多目标优化调度(MATLAB代码)

一、多目标优化算法简介 &#xff08;1&#xff09;非支配排序的蜣螂优化算法NSDBO 多目标应用&#xff1a;基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度&#xff08;MATLAB&#xff09;-CSDN博客 &#xff08;2&#xff09;NSGA3 NSGA-III求解微电网多目标…

医院预约管理系统开发 代码展示 九价疫苗接种预约功能(含小程序源代码)

基于微信小程序的疫苗预约系统让疫苗信息&#xff0c;疫苗预约信息等相关信息集中在后台让管理员管理&#xff0c;让用户在小程序端预约疫苗&#xff0c;查看疫苗预约信息&#xff0c;该系统让信息管理变得高效&#xff0c;也让用户预约疫苗&#xff0c;查看疫苗预约等信息变得…

力扣刷题篇之排序算法

系列文章目录 前言 本系列是个人力扣刷题汇总&#xff0c;本文是排序算法。刷题顺序按照[力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 - 力扣&#xff08;LeetCode&#xff09; 这个之前写的左神的课程笔记里也有&#xff1a; 左程云算法与数据结构代码汇总之排序&am…

网络安全工程师就业前景怎么样?

网络安全工程师的就业前景整体来看是不错的&#xff0c;近些年的岗位需求总体呈现上升的趋势&#xff0c;可以说只要有互联网的存在&#xff0c;就会有网络安全工程师的一席之地。不过现在企业更缺乏资深技术人才&#xff0c;如果只学会了皮毛&#xff0c;可能不会很好就业。 网…

推荐几款优秀的Chrome插件,值得收藏!

文章目录 1、Tampermonkey2、WeTab3、Chrono下载管理器4、AdBlock5、Cookie-Editor 1、Tampermonkey 使用用户脚本自由地改变网络&#xff0c;提升您的浏览体验&#xff0c;使用篡改猴&#xff01;&#x1f310;&#x1f680; 篡改猴是一款功能强大的浏览器扩展功能&#xff0c…

python与C++与TensorRT的绑定

绑定的起因 Jetpack中的TensorRT不能直接在python3.8环境中使用,所以我们需要对TensorRT利用pybind11对python相进性绑定。 绑定的官方链接如下:点击这里 这个是8.2版本的,你可以使用其他版本也是可以的。 整个过程可以在虚拟环境中完成,主要是想最后的whl文件 在Jetson…

【快速解决】使用IDEA快速搭建SpringBoot项目(超详细)

前言 Spring Boot是Spring Framework的一款脚手架式框架&#xff0c;可以帮助开发者快速构建基于Spring的企业级应用程序。本篇博客将介绍如何使用IntelliJ IDEA&#xff08;以下简称IDEA&#xff09;来快速搭建一个Spring Boot项目。 目录 ​编辑 前言 使用IDEA快速搭建Spri…

react的开发中关于图片的知识

React是一个流行的JavaScript库&#xff0c;用于构建用户界面。在React开发中&#xff0c;图片是一个非常重要的元素&#xff0c;可以用于美化界面和展示内容。本篇博客将详细讲解React中关于图片的知识。 1. React中使用图片 在React中使用图片非常简单&#xff0c;只需要使…

链表经典面试题

1 回文链表 1.1 判断方法 第一种&#xff08;笔试&#xff09;&#xff1a; 链表从中间分开&#xff0c;把后半部分的节点放到栈中从链表的头结点开始&#xff0c;依次和弹出的节点比较 第二种&#xff08;面试&#xff09;&#xff1a; 反转链表的后半部分&#xff0c;中间节…

用户隐私与游戏体验如何平衡?第二周 Web3 开发者集结精华回顾

由 TinTinLand 联合 Dataverse 、Web3Go 、Subquery 、Cregis 、Litentry、Aspecta、SpaceID、ANOME、VARA&Gear、Moonbeam、Mantle、Obelisk 等 10 余家 Web3 项目共同举办的 Web3 开发者赢积分活动已举办至第三周。精彩线上主题活动分享、近距离交流体验互动&#xff0c;…

PostgreSQL Patroni 3.0 新功能规划 2023年 纽约PG 大会 (音译)

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;&#xff08;…

AlDente Pro v1.22.2(mac电池最大充电限制工具)

AlDente Pro是一款适用于Mac操作系统的小工具&#xff0c;可以帮助您限制电池充电量以延长电池寿命。通常情况下&#xff0c;电池在充满的状态下会继续接受电源充电&#xff0c;这可能会导致电池寿命缩短。使用AlDente Pro&#xff0c;您可以设置电池只充到特定的充电水平&…

TYPE-C、PD原理

一、Type-C简介以及历史 自1998年以来&#xff0c;USB发布至今&#xff0c;USB已经走过20个年头有余了。在这20年间&#xff0c;USB-IF组织发布N种接口状态&#xff0c;包括A口、B口、MINI-A、MINI-B、Micro-A、Micro-B等等接口形态&#xff0c;由于各家产品的喜好不同&#x…

Azkaban极简使用文档

登录 地址: http://服务器ip:8081/, 用户名密码默认都是azkaban 构建项目流程 添加Project 编写工作流文件 在本机新建文件夹如test, 创建一个flow20.project 文件, 内容 azkaban-flow-version: 2.0(固定步骤)编写flow文件, 例如一个最基础的实例 test1.flow nodes:- name…

C语言剔除相关数(ZZULIOJ1204:剔除相关数)

题目描述 一个数与另一个数如果含有相同数字和个数的字符&#xff0c;则称两数相关。现有一堆乱七八糟的整数&#xff0c;里面可能充满了彼此相关的数&#xff0c;请你用一下手段&#xff0c;自动地将其剔除。 输入&#xff1a;多实例测试。每组数据包含一个n(n<1000)&#…

Pbootcms商城插件,支持购物车、订单、支付管理等

pbootcms商城插件上线&#xff0c;可以实现简单的商品管理、商品购买、加入购物车、购物车批量购买、以及后台的订单管理&#xff0c;发货管理、改价功能&#xff0c;支付信息管理等功能&#xff0c;满足商城基本功能后台效果截图&#xff1a; 前端效果截图&#xff1a; 演示网…

【Golang】解决使用interface{}解析json数字会变成科学计数法的问题

在使用解析json结构体的时候&#xff0c;使用interface{}接数字会发现变成了科学计数法格式的数字&#xff0c;不符合实际场景的使用要求。 举例代码如下&#xff1a; type JsonUnmStruct struct {Id interface{} json:"id"Name string json:"name"…

基于Vue+SpringBoot的天沐瑜伽馆管理系统

项目编号&#xff1a; S 039 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S039&#xff0c;文末获取源码。} 项目编号&#xff1a;S039&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 瑜伽课程模块2.3 课…

C语言—指针和数组

写在前 一个指针变量指向某个普通变量&#xff0c;则指针变量就等于普通变量。 指针变量存放的是地址&#xff0c;普通变量存放的是数据。 int * p; int i5,j; p &i;此程序&#xff0c;*pi5&#xff0c;在所有出现 *p 或 i 的位置&#xff0c;两者都可以互相替换。 通过…