5.1 Windows驱动开发:判断驱动加载状态
在驱动开发中我们有时需要得到驱动自身是否被加载成功的状态,这个功能看似没啥用实际上在某些特殊场景中还是需要的,如下代码实现了判断当前驱动是否加载成功,如果加载成功, 则输出该驱动的详细路径信息。
该功能实现的核心函数是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;
}
代码运行效果如下所示:

相关文章:
5.1 Windows驱动开发:判断驱动加载状态
在驱动开发中我们有时需要得到驱动自身是否被加载成功的状态,这个功能看似没啥用实际上在某些特殊场景中还是需要的,如下代码实现了判断当前驱动是否加载成功,如果加载成功, 则输出该驱动的详细路径信息。 该功能实现的核心函数是NtQuerySys…...
Linux之高级IO
目录 IO基本概念五种IO模型钓鱼人例子五种IO模型高级IO重要概念同步通信 VS 异步通信阻塞 VS 非阻塞其他高级IO阻塞IO非阻塞IO IO基本概念 I/O(input/output)也就是输入和输出,在著名的冯诺依曼体系结构当中,将数据从输入设备拷贝…...
进程和线程的关系
⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:JavaEE 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 进程&线程 1. 什么是进程PCB 2. 什么是…...
YOLOv5全网独家改进:NanoDet算法动态标签分配策略(附原创改进代码),公开数据集mAP有效涨点,来打造新颖YOLOv5检测器
💡本篇内容:YOLOv5全网独家改进:NanoDet算法动态标签分配策略(附原创改进代码),公开数据集mAP有效涨点,来打造新颖YOLOv5检测器 💡🚀🚀🚀本博客 YOLOv5+ 改进NanoDet模型的动态标签分配策略源代码改进 💡一篇博客集成多种创新点改进:NanoDet 💡:重点:更…...
原生DOM事件、react16、17和Vue合成事件
目录 原生DOM事件 注册/绑定事件 DOM事件级别 DOM0:onclick传统注册: 唯一(同元素的(不)同事件会覆盖) 没有捕获和冒泡的,只有简单的事件绑定 DOM2:addEventListener监听注册:可添加多个…...
基于HTML+CSS+JavaScript的登录注册界面设计
一、界面效果: 二、HTML代码: 登录注册html: 登录成功html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <h1>登录成功!</h1> </body> <…...
BUUCTF [MRCTF2020]Ez_bypass 1
题目环境:F12查看源代码 I put something in F12 for you include flag.php; $flagMRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}; if(isset($_GET[gg])&&isset($_GET[id])) { $id$_GET[id]; $gg$_GET[gg]; if (md5($id) md5($gg) && $id ! $gg) { …...
基于Apache部署虚拟主机网站
文章目录 Apache释义Apache配置关闭防火墙和selinux 更改默认页内容更改默认页存放位置个人用户主页功能基于口令登录网站虚拟主机功能基于ip地址相同ip不同域名相同ip不同端口 学习本章完成目标 1.httpd服务程序的基本部署。 2.个人用户主页功能和口令加密认证方式的实现。 3.…...
大数据平台/大数据技术与原理-实验报告--部署全分布模式HBase集群和实战HBase
实验名称 部署全分布模式HBase集群和实战HBase 实验性质 (必修、选修) 必修 实验类型(验证、设计、创新、综合) 综合 实验课时 2 实验日期 2023.11.07-2023.11.10 实验仪器设备以及实验软硬件要求 专业实验室ÿ…...
手写字符识别神经网络项目总结
1.数据集 手写字符数据集 DIGITS,该数据集的全称为 Pen-Based Recognition of Handwritten Digits Data Set,来源于 UCI 开放数据集网站。 2.加载数据集 import numpy as np from sklearn import datasets digits datasets.load_digits() 3.分割数…...
八、Lua数组和迭代器
一、Lua数组 数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。 在 Lua 中,数组不是一种特定的数据类型,而是一种用来存储一组值的数据结构。 实际上,Lua 中并没有专门的数组类型…...
平凯星辰 TiDB 获评 “2023 中国金融科技守正创新扬帆计划” 十佳优秀实践奖
11 月 10 日,2023 金融街论坛年会同期举办了“第五届成方金融科技论坛——金融科技守正创新论坛”,北京金融产业联盟发布了“扬帆计划——分布式数据库金融应用研究与实践优秀成果”, 平凯星辰提报的实践报告——“国产 HTAP 数据库在金融规模…...
运算符展开、函数,对象,数组,字符串变化 集合
... 展开运算符 用于函数实参或者赋值号右边 console.log(...[1, 2, 3]) // 1,2,3console.log(Math.max(...[1, 2, 3]))//3 console.log(Math.max.apply(null, [1, 2, 3]))//3const o { a: 1, b: 2 }const obj { ...o, c: 3 }console.log(obj)//Object ... 剩余运算符 用于…...
NI自动化测试系统用电必备攻略,电源规划大揭秘
就像使用电脑之前需接通电源一样,自动化测试系统的电源选择也是首当其冲的问题,只不是这个问题更复杂。 比如,应考虑地理位置因素,因为不同国家或地区的公共电网所提供的线路功率有所不同。在电源布局和设备选型方面,有…...
ky10 server arm 在线编译安装openssl3.1.4
在线编译脚本 #!/bin/shOPENSSLVER3.1.4OPENSSL_Vopenssl versionecho "当前OpenSSL 版本 ${OPENSSL_V}" #------------------------------------------------ #wget https://www.openssl.org/source/openssl-3.1.4.tar.gzecho "安装OpenSSL${OPENSSLVER}...&q…...
外网IP和内网IP的区别
首先得先知道什么是ip地址,它就是唯一标识连接网络的设备的,即IP地址充当了设备在网络中的“住址”,使得设备能够相互通信和交换数据。 我们常听开发人员说外网内网,那么它们有什么区别呢? 外网可以理解为互联网&…...
Jquery动画特效
1,Jquery提供的特效方法 2,实例代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…...
Tableau连接到mysql数据库,配置驱动
Tableau想要连接mysql数据库进行数据的可视化,但是没有ODBC驱动,看了几篇文章写的,不是很清楚,顺便写下自己的思路。 1、下载mysql对应的ODBC驱动 首先要知道自己mysql的版本,然后下载对应的ODBC驱动。 MySQL :: Dow…...
HuggingFace学习笔记--AutoModel的使用
1--AutoModel的使用 官方文档 AutoModel 用于加载模型; 1-1--简单Demo 测试代码: from transformers import AutoTokenizer, AutoModelif __name__ "__main__":checkpoint "distilbert-base-uncased-finetuned-sst-2-english"t…...
Kafka常见面试问题
1、Kafka分区设计及主副本如何同步 Apache Kafka是一种分布式流处理平台,它使用分布式复制协议来实现高可用性和容错性。在Kafka中,每个主题(topic)都有一个或多个分区(partition),每个分区都有…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
