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枚举和隐藏内核模块的更多相关文章

  1. Win64 驱动内核编程-8.内核里的其他常用

    内核里的其他常用 1.遍历链表.内核里有很多数据结构,但它们并不是孤立的,内核使用双向链表把它们像糖 葫芦一样给串了起来.所以遍历双向链表能获得很多重要的内核数据.举个简单的例子,驱 动对象 Driv ...

  2. Win64 驱动内核编程-3.内核里使用内存

    内核里使用内存 内存使用,无非就是申请.复制.设置.释放.在 C 语言里,它们对应的函数是:malloc.memcpy.memset.free:在内核编程里,他们分别对应 ExAllocatePool ...

  3. Win64 驱动内核编程-7.内核里操作进程

    在内核里操作进程 在内核里操作进程,相信是很多对 WINDOWS 内核编程感兴趣的朋友第一个学习的知识点.但在这里,我要让大家失望了,在内核里操作进程没什么特别的,就标准方法而言,还是调用那几个和进程 ...

  4. Win64 驱动内核编程-2.基本框架(安装.通讯.HelloWorld)

    驱动安装,通讯,Hello World 开发驱动的简单流程是这样,开发驱动安装程序,开发驱动程序,然后安装程序(或者其他程序)通过通讯给驱动传命令,驱动接到之后进行解析并且执行,然后把执行结果返回. ...

  5. Win64 驱动内核编程-18.SSDT

    SSDT 学习资料:http://blog.csdn.net/zfdyq0/article/details/26515019 学习资料:WIN64内核编程基础 胡文亮 SSDT(系统服务描述表),刚开 ...

  6. Win64 驱动内核编程-32.枚举与删除注册表回调

    枚举与删除注册表回调 注册表回调是一个监控注册表读写的回调,它的效果非常明显,一个回调能实现在SSDT 上 HOOK 十几个 API 的效果.部分游戏保护还会在注册表回调上做功夫,监控 service ...

  7. Win64 驱动内核编程-34.对抗与枚举MiniFilter

    对抗与枚举MiniFilter MiniFilter 是目前杀毒软件用来实现"文件系统自我保护"和"文件实时监控"的方法. 由于 MiniFilter 模型简单 ...

  8. Win64 驱动内核编程-28.枚举消息钩子

    枚举消息钩子 简单粘贴点百度的解释,科普下消息钩子: 钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之 ...

  9. Win64 驱动内核编程-31.枚举与删除映像回调

    枚举与删除映像回调 映像回调可以拦截 RING3 和 RING0 的映像加载.某些游戏保护会用此来拦截黑名单中的驱动加载,比如 XUETR.WIN64AST 的驱动.同理,在反游戏保护的过程中,也可以 ...

随机推荐

  1. 爬虫必知必会(4)_异步协程-selenium_模拟登陆

    一.单线程+多任务异步协程(推荐) 协程:对象.可以把协程当做是一个特殊的函数.如果一个函数的定义被async关键字所修饰.该特殊的函数被调用后函数内部的程序语句不会被立即执行,而是会返回一个协程对象 ...

  2. FreeBSD 入门 哲学与玄学

    『哲学与玄学』 FreeBSD 是一种 UNIX 哲学(如模块化,一切皆文件等,见< UNIX 编程艺术>❩的发展,也是学院派的代表作品.她是一套工具集,她存在目的是为了让人们更好的生活. ...

  3. Go ORM框架 - GORM 踩坑指南

    今天聊聊目前业界使用比较多的 ORM 框架:GORM.GORM 相关的文档原作者已经写得非常的详细,具体可以看这里,这一篇主要做一些 GORM 使用过程中关键功能的介绍,GORM 约定的一些配置信息说 ...

  4. ES6学习笔记(1)- 块级作用域

    1. var声明变量和变量提升(Hoisting)机制的问题 在JS中通过var关键字声明的变量,无论在函数作用域中亦或是全局作用域中,都会被当成当前作用域顶部的变量,和就是所谓的提升机制(Hoist ...

  5. Centos7 Firewall 使用笔记

    在 Centos 7 中防火墙由 firewalld 来管理,而不是以前的 iptables. 记录一下常用操作备查 firewall-cmd 操作 firewall-cmd --state 查看防火 ...

  6. 3、Spring教程之IOC创建对象方式

    1.通过无参构造方法来创建 1.User.java public class User { private String name; public User() { System.out.printl ...

  7. 使用 Velero 跨云平台迁移集群资源到 TKE

    概述 Velero 是一个非常强大的开源工具,可以安全地备份和还原,执行灾难恢复以及迁移Kubernetes群集资源和持久卷,可以在 TKE 平台上使用 Velero 备份.还原和迁移集群资源,关于如 ...

  8. 历史性突破:使用 .net core 日处理消息量超过 1.7 万条!

    业余时间用 .net core 写了一个在线客服系统.并在博客园写了一个系列的文章,写介绍这个开发过程: .net core 和 WPF 开发升讯威在线客服系统:目录 https://blog.she ...

  9. PAT (Advanced Level) Practice 1019 General Palindromic Number (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1019 General Palindromic Number (20 分) 凌宸1642 题目描述: A number that will ...

  10. [GDKOI2021] 提高组 Day 1 总结

    [ G D K O I 2021 ]    提 高 组    D a y   1    总 结 [GDKOI2021]~~ 提高组~~ Day~1~~ 总结 [GDKOI2021]  提高组  Day ...