检测驱动程序错误(5.1 Windows驱动开发:判断驱动加载状态)

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

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

typedef NTSTATUS(*NTQUERYSYSTEMINFORMATION)( IN ULONG SystemInformationClass, OUT PVOID SystemInformati联通大流量卡on, 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; USHOR联通大流量卡T 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 { SystemBasicInformati联通大流量卡on = 0x0, SystemProcessorInformation = 0x1, SystemPerformanceInformation = 0x2, SystemTimeOfDayInformation = 0x3, SystemPathInformation = 0x4, SystemProcessInformation = 0x5, SystemCallCountInformation = 0x6, SystemDeviceInformation = 0x7, SystemProcessorPerformanceInformation = 0x8, SystemFlagsInformation = 0x9, SystemCallTimeI联通大流量卡nformation = 0xa, SystemModuleInformation = 0xb, SystemLocksInformation = 0xc, SystemStackTraceInformation = 0xd, SystemPagedPoolInformation = 0xe, SystemNonPagedPoolInformation = 0xf, SystemHandleInformation = 0x10, SystemObjectInformation = 0x11, SystemPageFileInformation = 0x12, SystemVdmInstemulInformation = 0x13, SystemVdmB联通大流量卡opInformation = 0x14, SystemFileCacheInformation = 0x15, SystemPoolTagInformation = 0x16, SystemInterruptInformation = 0x17, SystemDpcBehaviorInformation = 0x18, SystemFullMemoryInformation = 0x19, SystemLoadGdiDriverInformation = 0x1a, SystemUnloadGdiDriverInformation = 0x1b, SystemTimeAdjustmentInformation = 0x1c, SystemSum联通大流量卡maryMemoryInformation = 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, Syste联通大流量卡mTimeSlipNotification = 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, SystemExte联通大流量卡ndedHandleInformation = 0x40, SystemLostDelayedWriteInformation = 0x41, SystemBigPoolInformation = 0x42, SystemSessionPoolTagInformation = 0x43, SystemSessionMappedViewInformation = 0x44, SystemHotpatchInformation = 0x45, SystemObjectSecurityMode = 0x46, SystemWatchdogTimerHandler = 0x47, SystemWatchdogTimerInformation = 0x4联通大流量卡8, SystemLogicalProcessorInformation = 0x49, SystemWow64SharedInformationObsolete = 0x4a, SystemRegisterFirmwareTableInformationHandler = 0x4b, SystemFirmwareTableInformation = 0x4c, SystemModuleInformationEx = 0x4d, SystemVerifierTriageInformation = 0x4e, SystemSuperfetchInformation = 0x4f, SystemMemoryListInformation = 0联通大流量卡x50, SystemFileCacheInformationEx = 0x51, SystemThreadPriorityClientIdInformation = 0x52, SystemProcessorIdleCycleTimeInformation = 0x53, SystemVerifierCancellationInformation = 0x54, SystemProcessorPowerInformationEx = 0x55, SystemRefTraceInformation = 0x56, SystemSpecialPoolInformation = 0x57, SystemProcessIdInformatio联通大流量卡n = 0x58, SystemErrorPortInformation = 0x59, SystemBootEnvironmentInformation = 0x5a, SystemHypervisorInformation = 0x5b, SystemVerifierInformationEx = 0x5c, SystemTimeZoneInformation = 0x5d, SystemImageFileExecutionOptionsInformation = 0x5e, SystemCoverageInformation = 0x5f, SystemPrefetchPatchInformation = 0x60, SystemVerif联通大流量卡ierFaultsInformation = 0x61, SystemSystemPartitionInformation = 0x62, SystemSystemDiskInformation = 0x63, SystemProcessorPerformanceDistribution = 0x64, SystemNumaProximityNodeInformation = 0x65, SystemDynamicTimeZoneInformation = 0x66, SystemCodeIntegrityInformation = 0x67, SystemProcessorMicrocodeUpdateInformation = 0x6联通大流量卡8, SystemProcessorBrandString = 0x69, SystemVirtualAddressInformation = 0x6a, SystemLogicalProcessorAndGroupInformation = 0x6b, SystemProcessorCycleTimeInformation = 0x6c, SystemStoreInformation = 0x6d, SystemRegistryAppendString = 0x6e, SystemAitSamplingValue = 0x6f, SystemVhdBootInformation = 0x70, SystemCpuQuotaInformati联通大流量卡on = 0x71, SystemNativeBasicInformation = 0x72, SystemErrorPortTimeouts = 0x73, SystemLowPriorityIoInformation = 0x74, SystemBootEntropyInformation = 0x75, SystemVerifierCountersInformation = 0x76, SystemPagedPoolInformationEx = 0x77, SystemSystemPtesInformationEx = 0x78, SystemNodeDistanceInformation = 0x79, SystemAcpiAuditI联通大流量卡nformation = 0x7a, SystemBasicPerformanceInformation = 0x7b, SystemQueryPerformanceCounterInformation = 0x7c, SystemSessionBigPoolInformation = 0x7d, SystemBootGraphicsInformation = 0x7e, SystemScrubPhysicalMemoryInformation = 0x7f, SystemBadPageInformation = 0x80, SystemProcessorProfileControlArea = 0x81, SystemCombinePhy联通大流量卡sicalMemoryInformation = 0x82, SystemEntropyInterruptTimingInformation = 0x83, SystemConsoleInformation = 0x84, SystemPlatformBinaryInformation = 0x85, SystemThrottleNotificationInformation = 0x86, SystemHypervisorProcessorCountInformation = 0x87, SystemDeviceDataInformation = 0x88, SystemDeviceDataEnumerationInformatio联通大流量卡n = 0x89, SystemMemoryTopologyInformation = 0x8a, SystemMemoryChannelInformation = 0x8b, SystemBootLogoInformation = 0x8c, SystemProcessorPerformanceInformationEx = 0x8d, SystemSpare0 = 0x8e, SystemSecureBootPolicyInformation = 0x8f, SystemPageFileInformationEx = 0x90, SystemSecureBootInformation = 0x91, SystemEntropyInterrup联通大流量卡tTimingRawInformation = 0x92, SystemPortableWorkspaceEfiLauncherInformation = 0x93, SystemFullProcessInformation = 0x94, SystemKernelDebuggerInformationEx = 0x95, SystemBootMetadataInformation = 0x96, SystemSoftRebootInformation = 0x97, SystemElamCertificateInformation = 0x98, SystemOfflineDumpConfigInformation = 0x99, Sys联通大流量卡temProcessorFeaturesInformation = 0x9a, SystemRegistryReconciliationInformation = 0x9b, MaxSystemInfoClass = 0x9c, } SYSTEM_INFORMATION_CLASS;

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

• 1.首先定义了一个函数指针NTQUERYSYSTEMINFORMATION m_NtQuerySystemInformation,并初始化一个UNICODE_STRING类型的变量NtQue联通大流量卡rySystemInformation_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 SystemInformationL联通大流量卡ength, 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; type联通大流量卡def enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0x0, SystemProcessorInformation = 0x1, SystemPerformanceInformation = 0x2, SystemTimeOfDayInformation = 0x3, SystemPathInformation = 0x4, SystemProcessInformation = 0x5, SystemCallCountInformation = 0x6, SystemDeviceInformation = 0x7, SystemProcessorPerformanceInfo联通大流量卡rmation = 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(&NtQuerySystemInfo联通大流量卡rmation_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); Driv联通大流量卡er->DriverUnload = UnDriver; return STATUS_SUCCESS; }

代码运行效果如下所示:


友情提醒: 请添加客服微信进行免费领取流量卡!
QQ交流群:226333560 站长微信:qgzmt2

原创文章,作者:sunyaqun,如若转载,请注明出处:https://www.dallk.cn/52582.html

(0)
sunyaqunsunyaqun
上一篇 2024年6月14日
下一篇 2024年6月14日

相关推荐

发表回复

登录后才能评论