驱动开发:运用VAD隐藏R3内存思路
source link: https://blog.51cto.com/lyshark/5753725
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
驱动开发:运用VAD隐藏R3内存思路
精选 原创在进程的_EPROCESS
中有一个_RTL_AVL_TREE
类型的VadRoot
成员,它是一个存放进程内存块的二叉树结构,如果我们找到了这个二叉树中我们想要隐藏的内存,直接将这个内存在二叉树中抹去
,其实是让上一个节点的EndingVpn
指向下个节点的EndingVpn
,类似于摘链隐藏进程,就可以达到隐藏的效果。
通过dt _EPROCESS
得到EProcess结构VadRoot
如下:
例如当调用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;
}
运行程序得到两个内存地址0xf00000
和0xfe0000
通过!process 0 0
枚举所有进程,并得到我们所需进程的EProcess地址。
检查进程!process ffffe28fbb451080
得到VAD
地址ffffe28fbe0b7e40
此处以0xf00000
为例,这里我们看到windbg
中的值和进程中分配的内存地址并不完全一样,这是因为x86 cpu
默认内存页大小4k
也就是0x1000
,所以这里还要再乘以0x1000
才是真正的内存地址。
所以计算结果刚好等于0xf00000
而隐藏进程内特定内存段核心代码在于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; // 将第二个结点完全隐藏起来
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK