Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

技术学习来源:火哥(QQ:471194425)

内存在0环的两种内存隐藏方式(基于VAD树)

一、通过 _MMVAD.StartingVpn与_MMVAD.EndingVpn等值来隐藏内存。

  这种方法找到需要隐藏的VAD结点,使 _MMVAD.StartingVpn=_MMVAD.EndingVpn,这样就能达到隐藏的效果

  在 》》VAD树的属性及其遍历 《《 中,在遍历每个结点下,直接 pVad.StartingVpn = pVad.EndingVpn即可。

  1)隐藏前的效果

    

  2)隐藏后的效果

    

二、通过将两个VAD结点融合达到隐藏效果

  我们需要找到 宿主结点p1 与 被隐藏结点p2,将p2融合进p1中,此时就会显示p1的段属性从而忽视p2的段属性。

  比如扫描内存时,恶意代码必然可执行 EXECUTE,但是我们隐藏在READ之类段中,往往可以规避掉扫描。

  实现方法 p1.EndingVpn = p2.EndingPvn

1) 实验代码 test.exe

 // test.cpp : Defines the entry point for the console application.
// #include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <stdlib.h>
int main()
{
LPVOID p1 = VirtualAlloc(NULL, 0x10000, MEM_COMMIT, PAGE_READWRITE);
LPVOID p2 = VirtualAlloc(NULL, 0x10000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
printf("p1 = %x / p2 = %x", p1, p2);
system("pause");
}

2) 驱动代码

 #include <ntddk.h>

 //---------------------//
// MMVAD结构体简单定义 //
//---------------------//
typedef struct _MMVAD {
ULONG StartingVpn;
ULONG EndingVpn;
struct _MMVAD * Parent;
struct _MMVAD * LeftChild;
struct _MMVAD * RightChild;
}MMVAD,*PMMVAD; VOID Unload(IN PDRIVER_OBJECT pDriverObject) {
DbgPrint("Driver UnLoad!");
} //-----------//
// 遍历VAD树 //
//-----------//
PMMVAD vad_enum(PMMVAD pVad,ULONG target_StartingVpn) { //---------------------------//
// 遍历目标VAD,并返回其指针 //
//---------------------------//
if (pVad) {
if (target_StartingVpn == pVad->StartingVpn) {
_asm int
return pVad;
}
else {
if (pVad->LeftChild) {
PMMVAD p1 = vad_enum(pVad->LeftChild, target_StartingVpn);
// 如果结点不为空,则直接返回就好。
// 否则继续判断其右子树结点。
if (p1)
return p1;
}
if (pVad->RightChild) {
PMMVAD p2 = vad_enum(pVad->RightChild, target_StartingVpn);
if (p2)
return p2;
}
return NULL;
}
}
return NULL;
} //-------------------------------------------------------------//
// 在内核中进程遍历的原理就是先获取系统进程EPROCESS结构 //
// 然后依照其链表来获取其他的进程 //
// 依次遍历出来 //
//-------------------------------------------------------------//
NTSTATUS process_enum() { PEPROCESS pEprocess = NULL; // 得到系统进程地址
PEPROCESS pFirstEprocess = NULL;
ULONG ulProcessName = ; // 字符串指针,指向进程名称
ULONG ulProcessID = ; // 进程ID
ANSI_STRING target_str; // 带检测进程的名称
ANSI_STRING ansi_string; //
ULONG VadRoot; //----------------------------//
// 得到当前系统进程的EPROCESS //
//----------------------------//
pEprocess = PsGetCurrentProcess();
if (pEprocess == NULL) {
DbgPrint("获取当前系统进程EPROCESS错误..");
return STATUS_SUCCESS;
}
DbgPrint("pEprocess addr is %x0x8\r\n", pEprocess);
pFirstEprocess = pEprocess; while (pEprocess) { ulProcessName = (ULONG)pEprocess + 0x174;
ulProcessID = *(ULONG*)((ULONG)pEprocess + 0x84);
VadRoot = *(ULONG*)((ULONG)pEprocess + 0x11c); //--------------------------------------//
// 将目标进程与当前进程的进程名进行对比 //
//--------------------------------------//
RtlInitAnsiString(&ansi_string, (PCSTR)ulProcessName);
RtlInitAnsiString(&target_str, "test.exe");
if (RtlEqualString(&ansi_string, &target_str, TRUE)) {
DbgPrint("检测到进程字符串,%x", ulProcessID); PMMVAD p1 = vad_enum((PMMVAD)VadRoot,0x3a0); // 遍历第一个结点
PMMVAD p2 = vad_enum((PMMVAD)VadRoot, 0x3b0); // 遍历找到第二个结点
_asm int
if(p1 && p2)
p1->EndingVpn = p2->EndingVpn; // 将第二个结点完全隐藏起来 return STATUS_SUCCESS;
}
pEprocess = (PEPROCESS)(*(ULONG*)((ULONG)pEprocess + 0x88) - 0x88);
if (pEprocess == pFirstEprocess || *(ULONG*)((ULONG)pEprocess + 0x84) <= ) {
DbgPrint("遍历结束!未检测到进程ID!\r\n");
break;
}
}
return STATUS_SUCCESS;
} NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING registeryPat) {
DbgPrint("Driver Loaded!");
pDriverObject->DriverUnload = Unload;
process_enum();
return STATUS_SUCCESS;
}

3)隐藏效果

最新文章

  1. 【Java每日一题】20170106
  2. oracle 锁表问题
  3. BZOJ 1831 &amp; 就是一个DP....
  4. AutoIT 实现Firefox上传文件
  5. linux 2.6.37-3.x.x x86_64
  6. 服务器端spice配置详解
  7. Javascript中while和do-while循环用法详解
  8. Matlab中添加搜索目录
  9. HDU 5698 瞬间移动
  10. this指针与function变量--this究竟指向哪里?
  11. 初探机器学习之使用百度AI服务实现图片识别与相似图片
  12. WIN10解决:失败 – 检测到病毒文件下载失败问题
  13. Unable to launch the IIS Express Web server
  14. js基本类型存放和对象存放的区别(对象遍历)
  15. 07装饰模式Decorator
  16. ie8以下兼容圆角等css3的属性
  17. SAP月末结账年结流程
  18. 邂逅明下 HDU - 2897
  19. POJ 3709 K-Anonymous Sequence - 斜率优化dp
  20. redis 命令clear、set、get、del、rename、keys *、exists、type、expire、expireat、persist、ttl、move、select

热门文章

  1. poj 1270 Following Orders (拓扑排序+回溯)
  2. 清晰明了的javascript版动态规划
  3. C#访问SFTP:Renci.SshNet.Async
  4. Java之缓冲流(字节/字符缓冲流)
  5. JavaEE初学笔记之Servlet与Tomcat
  6. C# Monitor and transfer or copy the changed or created file to a new location
  7. spring4 学习4 spring MVC+mybatis+Mysql
  8. seaborn画出的一些好看的图片
  9. 2019QM大作业2-weyl半金属Landau Level
  10. MS16-072域内中间人攻击