首页 > 系统相关 >5.1 Windows驱动开发:判断驱动加载状态

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

时间:2023-11-24 18:44:52浏览次数:42  
标签:Status NtQuerySystemInformation ULONG INFORMATION Windows SYSTEM MODULE 5.1 驱动

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

该功能实现的核心函数是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;
}

代码运行效果如下所示:

标签:Status,NtQuerySystemInformation,ULONG,INFORMATION,Windows,SYSTEM,MODULE,5.1,驱动
From: https://www.cnblogs.com/LyShark/p/17854506.html

相关文章

  • 7.5 Windows驱动开发:监控Register注册表回调
    在笔者前一篇文章《内核枚举Registry注册表回调》中实现了对注册表的枚举,本章将实现对注册表的监控,不同于32位系统在64位系统中,微软为我们提供了两个针对注册表的专用内核监控函数,通过这两个函数可以在不劫持内核API的前提下实现对注册表增加,删除,创建等事件的有效监控,注册表监视通......
  • Windows-Xshell对多个终端同时执行命令(发送命令到多个会话)
    方法1:使用查看中的撰(zhuàn)写栏(1)、查看→撰写→撰写栏。 (2)、底部可以看到“撰写栏”,选择全部会话。 (3)、在撰写栏输入命令,回车后就会发送到所有会话窗口。方法2:使用工具中的发送键输入到所有会话(1)、工具→发送键输入到(K)→所有会话(A)。(2)、当窗口上面出现黄色栏时,......
  • windows ubuntu 安装mysql
    一、介绍二、过程三、问题 一、介绍MySQL是一款开源的关系型数据库管理系统,是目前最流行的数据库之一。关键,免费,好用。二、过程1windows安装1.1下载下载地址:https://downloads.mysql.com/archives/installer/选择下面那......
  • 开源大模型驱动的智能编程与自然语言处理
    随着人工智能技术的不断发展,开源大模型已经成为了一个备受关注的话题。在这些开源大模型中,WizardCoder和WizardLM是两个备受瞩目的项目。本文将重点介绍这两个模型,并突出其中的重点词汇或短语。首先,让我们来了解一下WizardCoder。它是一个基于PyTorch框架的开源代码生成工具,......
  • windows中vscode通过ssh连接linux 保存公钥 运行c程序
    1、首先,vscode下载以下几个扩展,c/c++、remotedevelopment 2、下载完成后编写自己的linux连接配置文件 配置文件包括host、hostname、user和port,以下是我的配置,编辑完成保存,然后直接新建连接即可 3、新建的连接每次重连都需要输入密码,通过ssh公钥来解决首先,打开windo......
  • Windows平台如何实现RTSP流二次编码并添加动态水印后推送RTMP或轻量级RTSP服务
    技术背景我们在对接RTSP播放器相关的技术诉求的时候,遇到这样的需求,客户做特种设备巡检的,需要把摄像头拍到的RTSP流拉下来,然后添加动态水印后,再生成新的RTSPURL,供平台调用。真个流程需要延迟尽可能的低,分辨率要支持到1080p,并需要把添加过动态水印的数据,保存到本地。技术实现在此之......
  • 关键字 开发-02 关键字驱动执行yaml用例
    1.封装request运行方法我们将测试数据写到yaml文件中,通常会使用pytest框架parametrize参数化的方式读取yaml文件数据生成测试用例,于是我们可以根据这个思路来开发。#utils/request_session.pyimportrequestsimportrefromrequestsimportResponseclassParserError(Ex......
  • Windows共享文件夹
    正常共享流程报错解决方案添加完everyone用户即可进入共享盘......
  • MAC与Windows的键盘对应关系
    参考:Mac键盘上的Windows按键-官方Apple支持(中国)Mac键盘上的Windows按键Mac键盘上很多按键的功能与Windows键盘按键的功能相同。以下是其中的一些按键:Windows按键Mac按键用途向前删除键⌦Fn-Delete删除右边的字符。在便携式Mac电脑上,请......
  • 掌握VB.net编程技巧,轻松打造Windows应用
    为了温故而知新,本博客旨在记录我学习VB.net编程的过程,分享基础知识和实用技巧,帮助有需要的朋友轻松入门VB.net编程。无论您是想开发Windows平台上的应用程序,还是想在.NET生态系统中展现创造力和创新精神,本文都将为您提供宝贵的指导。VB.net是一种易学易用的编程语言,它基于Microso......