windwos下想要搞点事,权限当然是越大越好;驱动模块天生在0环,和操作提供平级,大家互相是兄弟,所以很多外挂、木马、病毒都会使用驱动达到自己的目的。那么问题来了:PCHUNTER这种工具能查到系统里面所有驱动模块,外挂\木马\病毒该怎么隐藏了?

  常见隐藏驱动的方式:

  •  驱动模块断链
  • 调用MiProcessLoadEntry删除驱动对象(据说不会触发PG)
  • 清理MmUnloadDriver List 和 PiDDBCacheTable两处
  • driveEntry返回失败
  • 驱动模块加载后立即卸载

  今天介绍一种driveEntry返回失败隐藏驱动的方法 —— DriverEntry返回失败;

  windows会根据DriverEntry的返回值判断驱动是否加载成功。如果返回成功,会在注册表详细记录,并将sys文件复制到System32/drivers目录下;如果失败,会回收执行代码时分配的栈空间,但此时代码已经执行,该方法隐藏驱动最核心的点就在这了:

  •  driverEntry执行的时候操作系统分配的栈内存,执行完毕会被回收,数据和代码都不会留下,只能额外在堆空间分配一块内存,把需要继续执行的代码和数据(本实验是回调函数)都留在堆上
  • 本例中,回调函数需要打印。但call函数后面的操作数都是相对偏移,不是绝对地址。回调函数被复制到堆上,自身位置改变,打印函数的偏移肯定也变了,这里需要重定位,怎么办?

    先自定义一个函数指针,指向打印函数,但地址随便用个Magic Number糊弄; 等回调函数的代码拷贝到堆上后,再调用MmGetSystemRoutineAddress得到打印函数的地址,再写回函数指针;

  完整代码如下(其实不多,也就100行左右):

#include <fltKernel.h>

typedef ULONG (__cdecl * DbgPrintType)(
_In_z_ _Printf_format_string_ PCSTR Format,
...
); #define DBG_PTR_TAG_MAGICNO 0xbabababababababa void MyLoadImageNotifyRoutine(
PUNICODE_STRING FullImageName,
HANDLE ProcessId,
PIMAGE_INFO ImageInfo
)
{
ProcessId = ProcessId;
DbgPrintType MyDbgPrint = (DbgPrintType)DBG_PTR_TAG_MAGICNO;
if (FullImageName != NULL && ImageInfo != NULL)
{
if ((ULONG_PTR)ImageInfo->ImageBase > (ULONG_PTR)0xf000000000000000)
{
MyDbgPrint("MyLoadImageNotifyRoutine: loading a kernel module: %wZ.\r\n",
FullImageName);
}
}
} void DriverUnload(PDRIVER_OBJECT DriverObject)
{
DriverObject = DriverObject;
KdPrint(("Hello, unloaded.\r\n"));
PsRemoveLoadImageNotifyRoutine(MyLoadImageNotifyRoutine);
} #define FUNC_LEN 0x100 NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING dbgprint_str = RTL_CONSTANT_STRING(L"DbgPrint");
//分配堆空间,后续把自己的回调函数(这部分代码还要执行)
PVOID my_func_body = ExAllocatePoolWithTag(NonPagedPool, FUNC_LEN, 'Disp');
DbgPrintType dbgprint_ptr = NULL;
PUCHAR func_body_ptr = NULL;
int i; // 防止警告。
DriverObject = DriverObject;
RegistryPath = RegistryPath;
DbgBreakPoint(); do {
if (my_func_body == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
break;
} // 动态获取DbgPrint函数的地址。
dbgprint_ptr = (DbgPrintType)MmGetSystemRoutineAddress(&dbgprint_str);
if (dbgprint_ptr == NULL)
{
status = STATUS_UNSUCCESSFUL;
break;
}
// 拷贝函数体。
memcpy(my_func_body, (PVOID)MyLoadImageNotifyRoutine, FUNC_LEN); // 替换函数体中的立即数0xbabababababababa,使之变成DbgPrint函数的地址
for (i = ; i < FUNC_LEN; ++i)
{
func_body_ptr = (PUCHAR)my_func_body + i;
if (*(ULONG_PTR*)func_body_ptr == (ULONG_PTR)DBG_PTR_TAG_MAGICNO)
{
*(ULONG_PTR*)func_body_ptr = (ULONG_PTR)dbgprint_ptr;
break;
}
}
if (i == FUNC_LEN)
{
status = STATUS_UNSUCCESSFUL;
break;
} // 将分配的堆函数注册成回调函数。
status = PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)my_func_body);
} while (); if (status != STATUS_SUCCESS && my_func_body != NULL)
{
ExFreePool(my_func_body);
} // 返回失败,确保驱动"不加载"。
status = STATUS_UNSUCCESSFUL;
return status;

  效果如下:

  (1)反正在PCHUNTER的驱动模块页面是找不到了

  (2)加载驱动时看到的提示,给人感觉好像失败了:

  

  但其实驱动的代码已经运行了,这里能正常检测和打印被加载的模块:

  

  (3)内核模块还是能看到,但没有路径,不好找模块在哪,给分析增加难度:

  

  最后总结一下: 目前流行的隐藏驱动方式,都逃不多微软VBS的法眼;一旦开启VT,处于-1环,相当于拥有了上帝视角,通过EPT把操作系统内核的所有操作都能监控到,所以现在的对抗进一步演变成了对系统更底层权限的争夺;谁先获得了更底层的权限,谁就能监控上一层的一举一动。

  

windows:驱动模块隐藏的更多相关文章

  1. C#使用Windows API 隐藏/显示 任务栏 (FindWindowEx, ShowWindow)

    原文 C#使用Windows API 隐藏/显示 任务栏 (FindWindowEx, ShowWindow) 今天,有网友询问,如何显示和隐藏任务栏? 我这里,发布一下使用Windows API 显 ...

  2. windows服务隐藏后门之克隆帐号

    windows服务隐藏后门之克隆帐号 1.CMD命令行下,建立了一个用户名为“test$”,密码为“abc123!”的简单隐藏账户,并且把该隐藏账户提升为了管理员权限. PS:CMD命令行使用&quo ...

  3. 删除Windows中隐藏的物理网卡和网络虚拟化失败后的虚拟网卡

    Windows环境下,在更换硬件服务器主板和网卡等硬件.恢复操作系统或者网络虚拟化失败后,可能会出现网卡方面的问题.例如,设备管理器中多了不应该存在的网卡:因命名冲突无法重命名当前网络连接:IP地址冲 ...

  4. 在Windows中隐藏用户的方法

    这两天新建了一个用户用于共享文件,由于我的电脑只有我一个人用,多了一个用户后在登录界面上觉得挺碍事的,便想把它隐藏起来.找了一下,可以通过如下方式实现: 在注册表编辑器新建项值: HKEY_LOCAL ...

  5. windows 10隐藏各种文件夹

    1.windows键+R打开运行,或者Ctrl+Alt+Del键调出任务管理器--文件--运行新的任务,然后出入"regedit"打开注册表: 2.按目录找到:[-HKEY_CLA ...

  6. windows下隐藏磁盘分区

    在一定情况下有的人会想隐藏掉部分分区,比如双系统的情况 有两种方式 方法1: 删除盘符,适合在双系统的情况下隐藏掉另外一个系统相关的分区 请注意是删除盘符 不是删除分区 此电脑右键管理 点击磁盘管理 ...

  7. windows下隐藏磁盘分区(转)

    在一定情况下有的人会想隐藏掉部分分区,比如双系统的情况 有两种方式 方法1: 删除盘符,适合在双系统的情况下隐藏掉另外一个系统相关的分区 请注意是删除盘符 不是删除分区 此电脑右键管理 点击磁盘管理 ...

  8. windows创建隐藏用户的powershell脚本

    通过保存并重新注册已删除用户的注册表的方式来隐藏用户,未登录时登陆界面不可见,登陆后可见 方法详情见: https://www.k0rz3n.com/2018/06/26/windows%E6%B8% ...

  9. windows环境隐藏命令行窗口运行Flask项目

    Linux下可以使用nohub来使Flask项目在后台运行,而windows环境下没有nohub命令,如何让Flask项目在windows中在后台运行而不显示命令行窗口呢? 1.写一个.bat脚本来启 ...

随机推荐

  1. 【线型DP】【LCS】洛谷P4303 [AHOI2006]基因匹配

    P4303 [AHOI2006]基因匹配 标签(空格分隔): 考试题 nt题 LCS优化 [题目] 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球 ...

  2. centos7----创建虚拟环境

    优点 使不同的应用开发环境独立 环境升级不影响其他应用,也不会影响全局的python环境 它可以防止系统出现包管理混乱和版本的冲突 安装 pip install virtualenv 创建虚拟环境 v ...

  3. PE文件格式详解(四)

    0x00 前言 上一篇介绍了区块表的信息,以及如何在hexwrokshop找到区块表.接下来,我们继续深入了解区块,并且学会文件偏移和虚拟地址转换的知识. 0x01 区块对齐值 首先我们要知道啥事区块 ...

  4. testNG jar包启动找不到org.testng.TestNG

    主要是因为打包时依赖的jar包没有打入,网上有很多需要将对应的jar单独拷贝出来然后通过classpath引用启动,但是感觉这个就是个无底洞.拷贝了这么多个包最后还是说找不到ObjectId 启动命令 ...

  5. java 面向对象(一):类与对象

    1.面向对象学习的三条主线: * 1.Java类及类的成员:属性.方法.构造器:代码块.内部类 * * 2.面向对象的大特征:封装性.继承性.多态性.(抽象性) * * 3.其它关键字:this.su ...

  6. python网络编程05 /TCP阻塞机制

    python网络编程05 /TCP阻塞机制 目录 python网络编程05 /TCP阻塞机制 1.什么是拥塞控制 2.拥塞控制要考虑的因素 3.拥塞控制的方法: 1.慢开始和拥塞避免 2.快重传和快恢 ...

  7. Django框架02 /Django下载安装、url路由分发

    Django框架02 /Django下载安装.url路由分发 目录 Django框架02 /Django下载安装.url路由分发 1. django下载安装 2. pycharm创建项目 3. 基于D ...

  8. 【五学x红小豆xRS】两边三地大联动-句型

    <第五共和国> Tohara LY Sara'm, Sabang Chua Setuk KS Kareh Moh Induree Junchi Chueh? 阁下!和这样的虫豸在一起,怎么 ...

  9. Hello!GitHub 好用好玩值得收藏的开源项目集合~

    这是我许久以来从各处发现的极佳开源项目,希望分享给大家~ 如果帮到你了,给我个赞好嘛 编程语言类 ️learn-go-with-tests(通过单元测试学Go) GitHub地址:https://gi ...

  10. Java常用API(Math类)

    Java常用API(Math类) Math类的作用 java.lang.Math 类包含用于执行基本数学运算的方法,如初等指数.对数.平方根和三角函数.类似这样的工具 类,其所有方法均为静态方法,并且 ...