驱动开发:运用VAD隐藏R3内存思路

举报
王瑞专家 发表于 2022/11/02 14:07:31 2022/11/02
1.6k+ 0 0
【摘要】 在进程的`_EPROCESS`中有一个`_RTL_AVL_TREE`类型的`VadRoot`成员,它是一个存放进程内存块的二叉树结构,如果我们找到了这个二叉树中我们想要隐藏的内存,直接将这个内存在二叉树中`抹去`,其实是让上一个节点的`EndingVpn`指向下个节点的`EndingVpn`,类似于摘链隐藏进程,就可以达到隐藏的效果。

在进程的_EPROCESS中有一个_RTL_AVL_TREE类型的VadRoot成员,它是一个存放进程内存块的二叉树结构,如果我们找到了这个二叉树中我们想要隐藏的内存,直接将这个内存在二叉树中抹去,其实是让上一个节点的EndingVpn指向下个节点的EndingVpn,类似于摘链隐藏进程,就可以达到隐藏的效果。

通过dt _EPROCESS得到EProcess结构VadRoot如下:

image.png

例如当调用VirtualAlloc分配内存空间。

#include <iostream>
#include <Windows.h>

int main(int argc, char *argv[])
{
	LPVOID p1 = VirtualAlloc(NULL, 0x10000, MEM_COMMIT, PAGE_READWRITE);
	LPVOID p2 = VirtualAlloc(NULL, 0x10000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

	std::cout << "address = " << p1 << std::endl;
	std::cout << "address2 = " << p2 << std::endl;

	getchar();
	return 0;
}

运行程序得到两个内存地址0xf000000xfe0000

image.png

通过!process 0 0枚举所有进程,并得到我们所需进程的EProcess地址。

image.png

检查进程!process ffffe28fbb451080得到VAD地址ffffe28fbe0b7e40

image.png

此处以0xf00000为例,这里我们看到windbg中的值和进程中分配的内存地址并不完全一样,这是因为x86 cpu默认内存页大小4k也就是0x1000,所以这里还要再乘以0x1000才是真正的内存地址。

image.png

所以计算结果刚好等于0xf00000

image.png

而隐藏进程内特定内存段核心代码在于p1->EndingVpn = p2->EndingVpn;将VAD前后节点连接。

PMMVAD p1 = vad_enum((PMMVAD)VadRoot, 0x3a0); // 遍历第一个结点
PMMVAD p2 = vad_enum((PMMVAD)VadRoot, 0x3b0); // 遍历找到第二个结点
if (p1 && p2)
{
p1->EndingVpn = p2->EndingVpn; // 将第二个结点完全隐藏起来
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。