当前位置: 首页 > news >正文

驱动断链的研究

准备

source insight

从现在开始我们正式进入内核编程,但是很多内核里面的结构和类型是需要我们额外声明的,我们就需要一个工具来快速的阅读WIn内核源码。这里我贴出我所参考的博客

羽夏看Win系统内核——SourceInsight 配置 WRK - 寂静的羽夏 - 博客园

就怕以后文章挂了,我还是走一遍流程

首先安装好sourceinsight之后,新建项目

在这里插入图片描述

WRK

WRK(windows Research Kernel ) 是微软公开的一部分 windows 内核源码,用来供给开发人员学习。
下载地址:http://www.awarenetwork.org/home/iqlord/other/wrk.rar

在上面的步骤后一路ok,直到下面,选择add Tree

在这里插入图片描述

然后关掉这个窗口,按f7导入符号表,这就完成了

理论准备

关于断链,我之前已经写过了文章

R3隐藏导入表_loader函数导入表隐藏-CSDN博客

在R3中有这么一个结构

3: kd> dt _PEB_LDR_DATA
nt!_PEB_LDR_DATA+0x000 Length           : Uint4B+0x004 Initialized      : UChar+0x008 SsHandle         : Ptr64 Void+0x010 InLoadOrderModuleList : _LIST_ENTRY+0x020 InMemoryOrderModuleList : _LIST_ENTRY+0x030 InInitializationOrderModuleList : _LIST_ENTRY+0x040 EntryInProgress  : Ptr64 Void+0x048 ShutdownInProgress : UChar+0x050 ShutdownThreadId : Ptr64 Void

我们复习一下,这个结构中的InLoadOrderModuleList,InMemoryOrderModuleList,InInitializationOrderModuleList都指向了一个双向链表,这个链表里面存储了我们模块信息,如果我们给链表里面的节点断链,那么就可以让其他软件在遍历链表的时候找不到我们的模块

现在在R0里面也是同理的,只是结构变成了,在WRK的ntldr.h这个头文件中,且由于没有PNON_PAGED_DEBUG_INFO的定义,所以还要补上一个。

typedef struct _KLDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;PVOID ExceptionTable;ULONG ExceptionTableSize;// ULONG padding on IA64PVOID GpValue;PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT __Unused5;PVOID SectionPointer;ULONG CheckSum;// ULONG padding on IA64PVOID LoadedImports;PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
typedef struct _NON_PAGED_DEBUG_INFO {USHORT      Signature;USHORT      Flags;ULONG       Size;USHORT      Machine;USHORT      Characteristics;ULONG       TimeDateStamp;ULONG       CheckSum;ULONG       SizeOfImage;ULONGLONG   ImageBase;
} NON_PAGED_DEBUG_INFO, *PNON_PAGED_DEBUG_INFO;

可以从上面的结构中看见R0中只保留了一个InLoadOrderLinks,但是思路也是一样的

代码实现

在知道了上面所提到的内核中的两个结构之后,我们首先要看下系统中的这个双向链表长什么样,这里用一个DbgBreakPoint来断下

#include<ntifs.h>
#include<ntstrsafe.h>//要用RtlStringCbPrintfA就别忘了这个库typedef struct _NON_PAGED_DEBUG_INFO {USHORT      Signature;USHORT      Flags;ULONG       Size;USHORT      Machine;USHORT      Characteristics;ULONG       TimeDateStamp;ULONG       CheckSum;ULONG       SizeOfImage;ULONGLONG   ImageBase;
} NON_PAGED_DEBUG_INFO, *PNON_PAGED_DEBUG_INFO;typedef struct _KLDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;PVOID ExceptionTable;ULONG ExceptionTableSize;// ULONG padding on IA64PVOID GpValue;PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT __Unused5;PVOID SectionPointer;ULONG CheckSum;// ULONG padding on IA64PVOID LoadedImports;PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;VOID DriverUnload(PDRIVER_OBJECT DriverObject) {DbgPrint("Driver has benn Unloaded");}
int count = 0;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) {//DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;DbgBreakPoint();pDriver->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}

同时在windbg中指定新的符号路径,并使用.reload /f 命令重载符号表,这样我们的调试就方便多了

如果没有符号表,有些结构我们是没有办法展现出来的

首先来看看我们的pDriver这个结构

0: kd> dt pDriver
Local var @ 0x903289e0 Type _DRIVER_OBJECT*
0x8be44160 +0x000 Type             : 0n4+0x002 Size             : 0n168+0x004 DeviceObject     : (null) +0x008 Flags            : 2+0x00c DriverStart      : 0x9709c000 Void+0x010 DriverSize       : 0x6000+0x014 DriverSection    : 0x8898b7b8 Void+0x018 DriverExtension  : 0x8be44208 _DRIVER_EXTENSION+0x01c DriverName       : _UNICODE_STRING "\Driver\MyDriver2"+0x024 HardwareDatabase : 0x841ab250 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"+0x028 FastIoDispatch   : (null) +0x02c DriverInit       : 0x970a0000     long  MyDriver2!GsDriverEntry+0+0x030 DriverStartIo    : (null) +0x034 DriverUnload     : (null) +0x038 MajorFunction    : [28] 0x83ef4da3     long  nt!IopInvalidDeviceRequest+0

着重关注两个值,DriverStart和DriverInit,分别是我们的模块基址和模块入口

之后我们根据之前得到的知识,pDriver中的DriverSection就是我们的_KLDR_DATA_TABLE_ENTRY结构存放的地址,我们在代码中把它转进变量ldr中,dt看一下,这里就可以看见DllBase和EntryPoint和我们的DriverStart和DriverInit相互对应

0: kd> dt ldr
Local var @ 0x903289d4 Type _KLDR_DATA_TABLE_ENTRY*
0x8898b7b8 +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x83f89850 - 0x889a4e98 ]//Flink和Blink+0x008 ExceptionTable   : 0xffffffff Void+0x00c ExceptionTableSize : 0xffffffff+0x010 GpValue          : 0x00000005 Void+0x014 NonPagedDebugInfo : (null) +0x018 DllBase          : 0x9709c000 Void+0x01c EntryPoint       : 0x970a0000 Void+0x020 SizeOfImage      : 0x6000+0x024 FullDllName      : _UNICODE_STRING "\??\C:\Users\su\Desktop\MyDriver2.sys"+0x02c BaseDllName      : _UNICODE_STRING "MyDriver2.sys"+0x034 Flags            : 0x49104000+0x038 LoadCount        : 1+0x03a __Unused5        : 0+0x03c SectionPointer   : (null) +0x040 CheckSum         : 0xab05+0x044 LoadedImports    : 0x0034f110 Void+0x048 PatchInformation : (null) 

我们看见了第一个InLoadOrderLinks里面的双向链表,所以我们用它给的Flink来访问链表里面的下一个节点,由于我们的MyDriver2是最后一个加载的驱动,所以它的下一个也就是我们的第一个驱动,果不其然,是我们的内核

0: kd> dt PKLDR_DATA_TABLE_ENTRY 0x83f89850
MyDriver2!PKLDR_DATA_TABLE_ENTRY
0x86a4cc98 +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x86a4cc20 - 0x83f89850 ]+0x008 ExceptionTable   : 0x83eb7544 Void+0x00c ExceptionTableSize : 0x12+0x010 GpValue          : (null) +0x014 NonPagedDebugInfo : (null) +0x018 DllBase          : 0x83e3f000 Void+0x01c EntryPoint       : 0x83f5e4d8 Void+0x020 SizeOfImage      : 0x412000+0x024 FullDllName      : _UNICODE_STRING "\SystemRoot\system32\ntkrnlpa.exe"+0x02c BaseDllName      : _UNICODE_STRING "ntoskrnl.exe"+0x034 Flags            : 0x8004000+0x038 LoadCount        : 0x6b+0x03a __Unused5        : 0+0x03c SectionPointer   : (null) +0x040 CheckSum         : 0x3c88ac+0x044 LoadedImports    : (null) +0x048 PatchInformation : (null) 

所以我们稍微修改一下我们的代码

#include<ntifs.h>
#include<ntstrsafe.h>//要用RtlStringCbPrintfA就别忘了这个库typedef struct _NON_PAGED_DEBUG_INFO {USHORT      Signature;USHORT      Flags;ULONG       Size;USHORT      Machine;USHORT      Characteristics;ULONG       TimeDateStamp;ULONG       CheckSum;ULONG       SizeOfImage;ULONGLONG   ImageBase;
} NON_PAGED_DEBUG_INFO, *PNON_PAGED_DEBUG_INFO;typedef struct _KLDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;PVOID ExceptionTable;ULONG ExceptionTableSize;// ULONG padding on IA64PVOID GpValue;PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT __Unused5;PVOID SectionPointer;ULONG CheckSum;// ULONG padding on IA64PVOID LoadedImports;PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;VOID DriverUnload(PDRIVER_OBJECT DriverObject) {DbgPrint("Driver has benn Unloaded");}
int count = 0;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) {//DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;PKLDR_DATA_TABLE_ENTRY next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;while (next != pre){DbgPrint("[%d] %wZ", count, &next->BaseDllName);next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;count++;} pDriver->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}

这样重新编译之后,用DbgView可以看见我们确实遍历所有模块

在这里插入图片描述

那既然我们已经正确的找到这个双向链表了,剩下的事情就好办多了,使用我们之前驱动篇基础里面介绍过的API来初始化一个Unicode字符串,然后用这个字符串去对比某个目标模块,如果一致,就按照链表断链的方式将其从双向链表中删除,继续修改我们的代码

#include<ntifs.h>
#include<ntstrsafe.h>//要用RtlStringCbPrintfA就别忘了这个库typedef struct _NON_PAGED_DEBUG_INFO {USHORT      Signature;USHORT      Flags;ULONG       Size;USHORT      Machine;USHORT      Characteristics;ULONG       TimeDateStamp;ULONG       CheckSum;ULONG       SizeOfImage;ULONGLONG   ImageBase;
} NON_PAGED_DEBUG_INFO, *PNON_PAGED_DEBUG_INFO;typedef struct _KLDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;PVOID ExceptionTable;ULONG ExceptionTableSize;// ULONG padding on IA64PVOID GpValue;PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT __Unused5;PVOID SectionPointer;ULONG CheckSum;// ULONG padding on IA64PVOID LoadedImports;PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;VOID DriverUnload(PDRIVER_OBJECT DriverObject) {DbgPrint("Driver has benn Unloaded");}
int count = 0;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) {//DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;PKLDR_DATA_TABLE_ENTRY next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;UNICODE_STRING target = { 0 };RtlInitUnicodeString(&target, L"srv2.sys");while (next != pre){//gPrint("[%d] %wZ", count, &next->BaseDllName);if (!RtlCompareUnicodeString(&target, &next->BaseDllName, TRUE)) {DbgPrint("[db] target has been found,the num is %d\r\n",count);//RemoveEntryList(&next);DbgBreakPoint();RemoveEntryList(&next->InLoadOrderLinks);//这个api和直接操作链表断链是等价的//PKLDR_DATA_TABLE_ENTRY PreNode = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Blink;//PKLDR_DATA_TABLE_ENTRY NextNode = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;//PreNode->InLoadOrderLinks.Flink = next->InLoadOrderLinks.Flink;//NextNode->InLoadOrderLinks.Blink = next->InLoadOrderLinks.Blink;break;}next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;count++;} //DbgBreakPoint();//ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;//第二次遍历内核模块,看看有没有真的断链pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;DbgPrint("%wZ\r\n", &pre->BaseDllName);DbgPrint("%wZ\r\n", &next->BaseDllName);count = 0;while (next != pre){DbgPrint("[+] %d %wZ", count, &next->BaseDllName);next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;count++;}pDriver->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}

可以看见我们的模块在149,在DbgView中向下翻,可以看见149已经不是我们的模块了

在这里插入图片描述

在这里插入图片描述

继续深入的研究

这是真正的断掉了吗?我打开了我的PChunter,这种简单的断链即使已经没有办法被遍历出来,还是没有办法逃过它的检测,换句话说,如果这是一个AV或者那些Anti-Cheat程序,它还是有办法能找到你

在这里插入图片描述

这里我们就可以提到刚刚我们所强调的DriverInit和DriverSection,我们不仅要断掉双向链表,还要保证我们的驱动入口不被找到(这里先暂时不考虑我们的后续怎么找到自己的驱动)

ObReferenceObjectByName

介绍一个新的未导出的内核函数,这里函数后面ByName是我们可以通过名字来查询驱动对象,类似的还有句柄等等,只是我们这里已经定义了字符串

NTKERNELAPI
NTSTATUS
ObReferenceObjectByName(__in PUNICODE_STRING ObjectName,__in ULONG Attributes,__in_opt PACCESS_STATE AccessState,__in_opt ACCESS_MASK DesiredAccess,__in POBJECT_TYPE ObjectType,__in KPROCESSOR_MODE AccessMode,__inout_opt PVOID ParseContext,__out PVOID *Object);

它的作用就是帮助我们去获取驱动对象的指针,方便我们进行操作,由于它未导出,我们得先声明一下

我们修改我们的代码

#include<ntifs.h>
#include<ntstrsafe.h>//要用RtlStringCbPrintfA就别忘了这个库typedef struct _NON_PAGED_DEBUG_INFO {USHORT      Signature;USHORT      Flags;ULONG       Size;USHORT      Machine;USHORT      Characteristics;ULONG       TimeDateStamp;ULONG       CheckSum;ULONG       SizeOfImage;ULONGLONG   ImageBase;
} NON_PAGED_DEBUG_INFO, *PNON_PAGED_DEBUG_INFO;typedef struct _KLDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;PVOID ExceptionTable;ULONG ExceptionTableSize;// ULONG padding on IA64PVOID GpValue;PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT __Unused5;PVOID SectionPointer;ULONG CheckSum;// ULONG padding on IA64PVOID LoadedImports;PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;NTSTATUS ObReferenceObjectByName(__in PUNICODE_STRING ObjectName,__in ULONG Attributes,__in_opt PACCESS_STATE AccessState,__in_opt ACCESS_MASK DesiredAccess,__in POBJECT_TYPE ObjectType,__in KPROCESSOR_MODE AccessMode,__inout_opt PVOID ParseContext,__out PVOID *Object
);extern POBJECT_TYPE *IoDriverObjectType;VOID DriverUnload(PDRIVER_OBJECT DriverObject) {DbgPrint("Driver has benn Unloaded");}
int count = 0;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) {//DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;//DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;PKLDR_DATA_TABLE_ENTRY next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;UNICODE_STRING target = { 0 };RtlInitUnicodeString(&target, L"srv2.sys");UNICODE_STRING ObName = { 0 };RtlInitUnicodeString(&ObName, L"\\FileSystem\\srv2");//这里如果不知道自己的驱动在什么路径可以在windbg中使用!drvobj srv2 1这个命令while (next != pre){//gPrint("[%d] %wZ", count, &next->BaseDllName);if (!RtlCompareUnicodeString(&target, &next->BaseDllName, TRUE)) {PDRIVER_OBJECT TargetDriver = NULL;NTSTATUS status = ObReferenceObjectByName(&ObName, FILE_ALL_ACCESS, 0, 0, *IoDriverObjectType, KernelMode, NULL, &TargetDriver);DbgPrint("[db] target has been found,the num is %d\r\n",count);//RemoveEntryList(&next);DbgBreakPoint();if (NT_SUCCESS(status)) {TargetDriver->DriverSection = NULL;//去除掉我们的驱动入口TargetDriver->DriverInit = NULL;RemoveEntryList(&next->InLoadOrderLinks);}//PKLDR_DATA_TABLE_ENTRY PreNode = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Blink;//PKLDR_DATA_TABLE_ENTRY NextNode = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;//PreNode->InLoadOrderLinks.Flink = next->InLoadOrderLinks.Flink;//NextNode->InLoadOrderLinks.Blink = next->InLoadOrderLinks.Blink;break;}next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;count++;} //DbgBreakPoint();//ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;//第二次遍历内核模块pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;DbgPrint("%wZ\r\n", &pre->BaseDllName);DbgPrint("%wZ\r\n", &next->BaseDllName);count = 0;while (next != pre){DbgPrint("[+] %d %wZ\r\n", count, &next->BaseDllName);next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;count++;}pDriver->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}

按照这个运行之后,再打开PCHunter,这下是彻底被藏住了

1: kd> g
Driver has benn Unloaded[db] target has been found,the num is 149//这次我们在149
Break instruction exception - code 80000003 (first chance)
Unable to load image MyDriver2.sys, Win32 error 0n2
MyDriver2+0x10bf:
9d17c0bf cc              int     3

在这里插入图片描述

我们马上就可以想到,那能不能用这种方法隐藏自己呢?

继续稍微修改我们的代码

#include<ntifs.h>
#include<ntstrsafe.h>//要用RtlStringCbPrintfA就别忘了这个库typedef struct _NON_PAGED_DEBUG_INFO {USHORT      Signature;USHORT      Flags;ULONG       Size;USHORT      Machine;USHORT      Characteristics;ULONG       TimeDateStamp;ULONG       CheckSum;ULONG       SizeOfImage;ULONGLONG   ImageBase;
} NON_PAGED_DEBUG_INFO, *PNON_PAGED_DEBUG_INFO;typedef struct _KLDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;PVOID ExceptionTable;ULONG ExceptionTableSize;// ULONG padding on IA64PVOID GpValue;PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT __Unused5;PVOID SectionPointer;ULONG CheckSum;// ULONG padding on IA64PVOID LoadedImports;PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;NTSTATUS ObReferenceObjectByName(__in PUNICODE_STRING ObjectName,__in ULONG Attributes,__in_opt PACCESS_STATE AccessState,__in_opt ACCESS_MASK DesiredAccess,__in POBJECT_TYPE ObjectType,__in KPROCESSOR_MODE AccessMode,__inout_opt PVOID ParseContext,__out PVOID *Object
);extern POBJECT_TYPE *IoDriverObjectType;VOID DriverUnload(PDRIVER_OBJECT DriverObject) {DbgPrint("Driver has benn Unloaded");}
int count = 0;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) {//DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;//DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;PKLDR_DATA_TABLE_ENTRY next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;UNICODE_STRING target = { 0 };RtlInitUnicodeString(&target, L"MyDriver2.sys");UNICODE_STRING ObName = { 0 };RtlInitUnicodeString(&ObName, L"\\Driver\\MyDriver2");//这里路径改了while (next != pre){//gPrint("[%d] %wZ", count, &next->BaseDllName);if (!RtlCompareUnicodeString(&target, &next->BaseDllName, TRUE)) {PDRIVER_OBJECT TargetDriver = NULL;NTSTATUS status = ObReferenceObjectByName(&ObName, FILE_ALL_ACCESS, 0, 0, *IoDriverObjectType, KernelMode, NULL, &TargetDriver);DbgPrint("[db] target has been found,the num is %d\r\n",count);//RemoveEntryList(&next);DbgBreakPoint();if (NT_SUCCESS(status)) {TargetDriver->DriverSection = NULL;//去除掉我们的驱动入口TargetDriver->DriverInit = NULL;RemoveEntryList(&next->InLoadOrderLinks);}//PKLDR_DATA_TABLE_ENTRY PreNode = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Blink;//PKLDR_DATA_TABLE_ENTRY NextNode = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;//PreNode->InLoadOrderLinks.Flink = next->InLoadOrderLinks.Flink;//NextNode->InLoadOrderLinks.Blink = next->InLoadOrderLinks.Blink;DbgPrint("%d", status);break;}next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;count++;} //DbgBreakPoint();//ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;//第二次遍历内核模块pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;DbgPrint("%wZ\r\n", &pre->BaseDllName);DbgPrint("%wZ\r\n", &next->BaseDllName);count = 0;while (next != pre){DbgPrint("[+] %d %wZ\r\n", count, &next->BaseDllName);next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;count++;}pDriver->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}

一运行,蓝屏了

*** Fatal System Error: 0x0000007e(0xC0000005,0x83FE1943,0x9BF03900,0x9BF03360)Break instruction exception - code 80000003 (first chance)A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.A fatal system error has occurred.For analysis of this file, run !analyze -v
nt!RtlpBreakWithStatusInstruction:
83e99110 cc              int     3

这是为什么呢,因为我们在把驱动的入口给抹掉了,但是还是有一些操作要用到这个驱动入口,所以我们不能加载自己的一瞬间就把自己的入口抹掉,还需要一点延时

线程延时

在内核中,我们一般不使用sleep函数,这其中当然也有sleep函数容易被Hook的原因

我们如果要想达成一个类似延时的效果,可以在自己的驱动模块中起一个内核线程,然后延时启动这个线程,延时是为了保证所有之前用过的驱动入口都正确的运行后释放(不知道怎么说,描述不清楚)

我们要新用到两个函数

NTSTATUS PsCreateSystemThread([out]           PHANDLE            ThreadHandle,[in]            ULONG              DesiredAccess,[in, optional]  POBJECT_ATTRIBUTES ObjectAttributes,[in, optional]  HANDLE             ProcessHandle,[out, optional] PCLIENT_ID         ClientId,[in]            PKSTART_ROUTINE    StartRoutine,[in, optional]  PVOID              StartContext
);
NTSTATUS KeDelayExecutionThread([in] KPROCESSOR_MODE WaitMode,[in] BOOLEAN         Alertable,[in] PLARGE_INTEGER  Interval
);

改进代码如下

#include<ntifs.h>
#include<ntstrsafe.h>//要用RtlStringCbPrintfA就别忘了这个库typedef struct _NON_PAGED_DEBUG_INFO {USHORT      Signature;USHORT      Flags;ULONG       Size;USHORT      Machine;USHORT      Characteristics;ULONG       TimeDateStamp;ULONG       CheckSum;ULONG       SizeOfImage;ULONGLONG   ImageBase;
} NON_PAGED_DEBUG_INFO, *PNON_PAGED_DEBUG_INFO;typedef struct _KLDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;PVOID ExceptionTable;ULONG ExceptionTableSize;// ULONG padding on IA64PVOID GpValue;PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT __Unused5;PVOID SectionPointer;ULONG CheckSum;// ULONG padding on IA64PVOID LoadedImports;PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;NTSTATUS ObReferenceObjectByName(__in PUNICODE_STRING ObjectName,__in ULONG Attributes,__in_opt PACCESS_STATE AccessState,__in_opt ACCESS_MASK DesiredAccess,__in POBJECT_TYPE ObjectType,__in KPROCESSOR_MODE AccessMode,__inout_opt PVOID ParseContext,__out PVOID *Object
);extern POBJECT_TYPE *IoDriverObjectType;void DriverHide(PWCH ObName) {LARGE_INTEGER in = { 0 };in.QuadPart = -10000 * 20000;//规定时间KeDelayExecutionThread(KernelMode, FALSE, &in);//不到时间不启动UNICODE_STRING ObjName = { 0 };RtlInitUnicodeString(&ObjName, ObName);PDRIVER_OBJECT TargetDriver = NULL;NTSTATUS status = ObReferenceObjectByName(&ObjName, FILE_ALL_ACCESS, 0, 0, *IoDriverObjectType, KernelMode, NULL, &TargetDriver);if (NT_SUCCESS(status)) {//DbgBreakPoint();PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)TargetDriver->DriverSection;RemoveEntryList(&ldr->InLoadOrderLinks);TargetDriver->DriverSection = NULL;//去除掉我们的驱动入口TargetDriver->DriverInit = NULL;ObDereferenceObject(TargetDriver);DbgPrint("Success!!\r\n");}return;
}VOID DriverUnload(PDRIVER_OBJECT DriverObject) {DbgPrint("Driver has benn Unloaded");}
int count = 0;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) {HANDLE pThread = NULL;NTSTATUS status = PsCreateSystemThread(&pThread, THREAD_ALL_ACCESS,NULL, NULL, NULL, DriverHide, L"\\Driver\\MyDriver2");DbgBreakPoint();if (NT_SUCCESS(status)) {NtClose(pThread);}pDriver->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}

最后是成功的将我们的自己的驱动MyDriver2.sys给隐藏了

在这里插入图片描述

http://www.lryc.cn/news/500441.html

相关文章:

  • 在 Windows WSL 上部署 Ollama 和大语言模型:从镜像冗余问题看 Docker 最佳实践20241208
  • 做题时HashSet、TreeSet、LinkedHashSet的选择
  • Manus手套动作捕捉AI训练灵巧手
  • 嵌入式驱动开发详解4(内核定时器)
  • Linux:信号的预备和产生
  • 国城杯2024——Curve
  • AI生成不了复杂前端页面?也许有解决方案了
  • 常见矩阵分析法(BCG、GE、IE、SPACE、TOWS、优先、战略优先级、安索夫、风险矩阵):如何通过系统化方法助力战略决策与数据驱动决策
  • JWT 在 SaaS 系统中的作用与分布式 SaaS 系统设计的最佳实践
  • 基于C#和Sql Server的网上书店管理系统
  • 特高频局放装置在现代配电设施中的应用
  • FSC认证是什么?FSC认证费用
  • JAVA数据结构
  • mysql8 主从复制一直失败
  • EDA - Spring Boot构建基于事件驱动的消息系统
  • 使用vue-seamless-scroll实现echarts图表大屏滚动,出现空白间隔的解决方案
  • ios使用UIScrollView和PageControl创建图片轮播
  • 3D 生成重建024-LGM第一个开源的3D生成大模型!
  • linux目录权限
  • 语言模型使用心得
  • ChatGPT客户端安装教程(附下载链接)
  • Electron 基础+传值+引用+安全
  • 手机租赁系统全面解析与开发指南
  • mongoDb的读session和写session权限报错问题
  • Centos在2024年6月30日停止维护后如何换yum源安装组件
  • 阿里云ACP云计算模拟试题(附答案解析)
  • 简单的爬虫脚本编写
  • [MySQL基础](三)SQL--图形化界面+DML
  • 11.23[大数据]
  • C++ 游戏开发进阶:打造更精彩的游戏世界