驱动开发:运用VAD隐藏R3内存思路
2023-06-13 09:16:01 时间
在进程的_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; // 将第二个结点完全隐藏起来
}
相关文章
- 死磕juc(四)Java内存模型之JMM
- 想要在数字经济下驱动业务变革?换内存吧!
- 驱动开发:内核MDL读写进程内存
- Linux性能调优之内存负载调优的一些笔记
- JVM-内存结构篇笔记
- 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 内存复用 | 弱引用 | 引用队列 | 针对不同 Android 版本开发不同的 Bitmap 复用策略 | 工具类代码 )
- 解决MongoDB 排序超过内存限制的问题
- Redis:一款基于内存的高性能数据库(redis的底层实现)
- 用Redis强化系统内存库(内存库redis)
- Linux系统内存分配算法的研究(linux内存分配算法)
- 内存分段机制详解
- 驱动程序:牢记Linux系统的内存调度(linux驱动内存)
- 解析Linux swap文件:优化内存管理和提升系统性能(linuxswap文件)
- 怎样控制Oracle内存占用(oracle内存占多大)
- 深入浅出Redis极速内存数据库的解析(深度解读redis)
- CDB内存与Oracle新型存储优化策略(cdb内存 oracle)
- 1G内存足以运行Mysql的最新版本(1G内存mysql版本)
- GitHub Codespaces现已支持团队和企业云计划 配置最高32核心64GB内存