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. 利用xslt与xml实现具体字段字母的大小写转换

    定义一个全局的变量 <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" ...

  2. frameset、frame和div 、iframe

    框架一般应用于首页的界面排版工作.把一个网页切割成多个页面管理.frame文件一般只包含框架的布局信息,不会包含其他内容,所有的页面效果都是在各个frameset页面内显示.他们都从属于frame文件 ...

  3. List的主要实现类

    //ArrayList:List的主要实现类 /* * List中相对于Collection,新增加的方法 * void add(int index, Object ele):在指定的索引位置inde ...

  4. imagemagick 之 Fred's ImageMagick Scripts 在Ubuntu 下的实践

    Fred's ImageMagick Scripts 官网:http://www.fmwconcepts.com/imagemagick/index.php Windows 10 (64-bit) u ...

  5. 基于阿里云托管kubernetes的版本升级

    前言 因为阿里云的knative对应得k8s版本大于1.15,而我们目前得集群环境是1.14.8,因此需要对预发环境进行版本升级.基于aliyun托管的kubernetes集群版本升级本没有什么可写, ...

  6. Spring IOC 特性有哪些,不会读不懂源码!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 多线程.锁.JVM调优,都背出花啦,怎么一写代码还是乱糟糟? 为什么这些无论从书本. ...

  7. windows认证解读

    0x00 本地认证 本地认证基础知识 在本地登录Windows的情况下,操作系统会使用用户输入的密码作为凭证去与系统中的密码进行验证,但是操作系统中的密码存储在哪里呢? %SystemRoot%\sy ...

  8. C# List常用方法及Dictionary常用方法汇总

    本文主要汇总了在开发过程中,使用List和Dictionary常用的方法,例如增.删.改.查.排序等等各种常用操作. 在平时的开发过程中,List和Dictionary是我们经常使用到的数据结构,而且 ...

  9. java面试-G1垃圾收集器

    一.以前收集器的特点 年轻代和老年代是各自独立且连续的内存块 年轻代收集器使用 eden + S0 + S1 进行复制算法 老年代收集必须扫描整个老年代区域 都是以尽可能的少而快速地执行 GC 为设计 ...

  10. 并发编程-线程池&J.U.C

    8. 共享模型之工具 8.1 线程池 池化技术相比大家已经屡见不鲜了,线程池.数据库连接池.Http 连接池等等都是对这个思想的应用.池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率 ...