Windows x64隐藏可执行内存

news2024/9/20 14:53:48

文章目录

      • 实现效果
      • 实现原理
      • VAD内存
        • 什么是VAD内存
        • 查看VAD内存
        • VAD属性
        • VAD内存可利用的点
      • x64分页机制
        • W7 x64下任意地址PDT PTE算法
        • W10 x64定位随机化页表基址
      • 实现隐藏可执行内存
      • 隐藏内存对抗

实现效果

在这里插入图片描述

驱动程序在Test进程中申请一块内存地址并打印,然后控制台程序在接收到输入的地址后开始跳转执行。申请的内存必须具有可执行属性,否则三环程序会抛异常。
在这里插入图片描述

打开CE查看0x1F0000的内存,属性仅显示可读可写,再查看内存区域,1F0000的地址处也只显示读写属性,说明我们成功的隐藏了一块可执行内存。

实现原理

实现的原理其实很简单,就是在申请一块不可执行的内存后,通过修改PDE和PTE的属性位,将这块连续的内存区域设置为可执行,从而达到隐藏可执行内存的目的。

所需要的前置知识有两块,一个是VAD内存管理,一个是x64的分页机制。

实际上病毒木马也会用到这个操作,在申请内存的时候先申请一块不可执行的内存,然后再通过VirtualProtetc的方式来修改内存属性,这样可以躲避掉一部分的杀软查杀。尽管隐藏的方式比较low,但好过直接申请可执行的内存。

VAD内存

什么是VAD内存

0: kd> dt _EPROCESS ffffaa0daaa3f080
ntdll!_EPROCESS
+0x628 VadRoot          : _RTL_AVL_TREE

在EPROCESS进程结构体+0x628的位置有一个成员叫VadRoot,这是一个二叉树结构,里面保存了这个进程所有内存的信息。

查看VAD内存

再来查看一下当前这块进程的vad内存,用!vad命令

在这里插入图片描述

其中:

  • Level表示层级
  • start表示起始地址,这个是页号,真正的虚拟地址要乘以0x1000
  • end是结束地址 也是页号
  • Commit表示提交属性
  • Mapped表示映射内存
  • Private表示私有内存
  • 倒数第二列是内存属性

在这里插入图片描述

  • 如果commit属性为Mapoed Exe,说明这是一个私有PE文件的映射,在最后一列会出现PE文件的路径

可以看到VAD树把当前进程所有的内存块都清晰的展现出来了,如果你在进程里开辟了一块内存用来执行shellcode的话,那么只要一遍历,直接就能查出来。

VAD属性

VAD是管理虚拟内存的,每一个进程有自己单独的一个VAD树 , 使用VirtualAllocate函数申请一个内存,则会在VAD树上增加一个结点,是_MMVAD结构体,私有内存一般是MMVAD_SHORT,映射内存一般是MMVAD_LONG’

_MMVAD结构

0: kd> dt _MMVAD
nt!_MMVAD
   +0x000 Core             : _MMVAD_SHORT
   +0x040 u2               : <unnamed-tag>
   +0x048 Subsection       : Ptr64 _SUBSECTION
   +0x050 FirstPrototypePte : Ptr64 _MMPTE
   +0x058 LastContiguousPte : Ptr64 _MMPTE
   +0x060 ViewLinks        : _LIST_ENTRY
   +0x070 VadsProcess      : Ptr64 _EPROCESS
   +0x078 u4               : <unnamed-tag>
   +0x080 FileObject       : Ptr64 _FILE_OBJECT

_MMVAD_SHORT结构

kd> dt _MMVAD_SHORT 876f4f50  -r1
nt!_MMVAD_SHORT
   +0x000 u1               : <unnamed-tag>
      +0x000 Balance          : 0y00
      +0x000 Parent           : 0x8757afc0 _MMVAD //有无父节点
   +0x004 LeftChild        : (null) 
   +0x008 RightChild       : (null) //有无左子树与右子树
   +0x00c StartingVpn      : 0xd0
   +0x010 EndingVpn        : 0xd0//起始页与结束页
   +0x014 u                : <unnamed-tag>//锁页
      +0x000 LongFlags        : 0x98000001
      +0x000 VadFlags         : _MMVAD_FLAGS
   +0x018 PushLock         : _EX_PUSH_LOCK
      +0x000 Locked           : 0y0
      +0x000 Waiting          : 0y0
      +0x000 Waking           : 0y0
      +0x000 MultipleShared   : 0y0
      +0x000 Shared           : 0y0000000000000000000000000000 (0)
      +0x000 Value            : 0
      +0x000 Ptr              : (null) 
   +0x01c u5               : <unnamed-tag>
      +0x000 LongFlags3       : 0
      +0x000 VadFlags3        : _MMVAD_FLAGS3
kd> dt _MMVAD_FLAGS 876f4f50+14
nt!_MMVAD_FLAGS
   +0x000 CommitCharge     : 0y0000000000000000001 (0x1)
   +0x000 NoChange         : 0y0//如果为1则不可改属性
   +0x000 VadType          : 0y000//类型
   +0x000 MemCommit        : 0y0
   +0x000 Protection       : 0y11000 (0x18)//保护
   +0x000 Spare            : 0y00
   +0x000 PrivateMemory    : 0y1

VAD内存可利用的点

之前我们说了句柄的对抗,实际上游戏和杀软在内存上也会做很多手脚,来达到保护自身的目的。这里有几个可以操作的点。

保护内存属性不被修改

一个是修改_MMVAD_FLAGS结构里面的NoChange字段,这个字段被置为1之后,表示这块内存属性不能被修改,即使你调用VirtualProtect这样的API也是没用的。可以保护自己的内存属性不被修改。

TP一字节保护

bool ProtectMemory(void* memory)
{
    auto vad = GetMemoryVad(memory);
    if(vad) {
        vad->Core.u.LongFlags &= 0x10000;
    }
}

TP的一字节保护也是修改了其中的一个标志位,这个标志位被修改后,你就不能再修改内存属性了

隐藏私有内存

还有一个可以玩的地方是可以利用VAD来隐藏私有内存

+0x00c StartingVpn      : 0xd0
+0x010 EndingVpn        : 0xd0//起始页与结束页

这种方法需要找到隐藏的VAD节点,让StartingVpn等于EndingVpn,就可以达到隐藏效果了。跟断链的套路一样,只不过这里断的是二叉树。

这种方式仅限于隐藏一小块不频繁使用的私有内存,而且有蓝屏的几率,不稳定。

x64分页机制

说完了VAD的内存管理,再来说x64的分页机制。这里只说如何在x64下通过任意一个虚拟地址获取PDE和PTE的方法。其他的分页知识各位需要自行补充。

#### x86 PDE PTE基址

PTEBase=0xC0000000 
PDEBase=0xC0300000

这个是XP下的PTE和PTE的基地址

访问页目录表的公式:0xC0300000+PDI*4
访问页表的公式:0xC0000000+PDI*4096+PTI*4

再通过这个公式,我们就可以修改任意一个地址的PDE和PTE属性。

W7 x64下任意地址PDT PTE算法

在这里插入图片描述

在IDA中找到MiIsAddressValid这个函数,这个函数的原理就是通过查看PDE和PTE的P位是否为零的方式,来判断当前的内存地址是否有效。

从下往上,分别是PTE,PDE,PPE和PXE的算法,在w7x64PDE和PTE的基地址都是固定的,直接拿过来用就可以了。这个没什么可说的。

W10 x64定位随机化页表基址

到了W10 x64下,情况就不一样了, windows 10 14316开始实现了页表随机化 ,PTE的基地址变成了随机的。但是我们只要把PTE的基地址拿到了,剩下的三个基地址就可以推算出来。

获取PTE基地址

在这里插入图片描述

W10我们可以用这个函数``MmGetVirtualForPhysical`,其中rdx里面的值是页表基地址,也就是PTE的基地址,拿到了这个基地址,其他的就可以推算出来了。

在这里插入图片描述

MmGetVirtualForPhysical进行反汇编比对PTE,发现地址是一样的。有了PTE的基地址,那么我们就可以拿到任意一个地址的PTE

拿任意一个地址的PTE的公式(这里要取后48位):

(f807`16a90fb0/0x1000)*8

简化一下就成了这个样子

(f807`16a90fb0>>12)<<3+PTEBase

在这里插入图片描述

实际上跟IDA里面的这个pde的算法是一样的,两种都可以,只不过我用的比较方便理解

根据PTE求PDE

把PTE当成一个虚拟地址来求物理地址,求得的物理地址就是PDT,原理就是指向PTE所在物理页面的PTE是PDE。

PDEBase=(B08000000000>>12)<<3+FFFFB08000000000

在这里插入图片描述

0: kd> !pte 0
                                           VA 0000000000000000
PXE at FFFFB0D86C361000    PPE at FFFFB0D86C200000    PDE at FFFFB0D840000000    PTE at FFFFB08000000000
contains 0A000000072D3867  contains 0000000000000000
pfn 72d3      ---DA--UWEV  contains 0000000000000000
not valid

算出来的PDE结果是一样的

根据PDE算PPE

同样把PDE看成是一个普通的虚拟地址

PPEBase=(B0D840000000>>12)<<3+PTEBase

根据PPE算PXE

PXEBase=(B0D86C200000>>12)+PTEBase

实际上,定位随机化页表基址有很种方法,各路神仙好像都有自己的套路,鹅厂的方法是通过CR3里面的字段计算拿到页表基地址,有兴趣可以自行研究一下。用哪个都不重要,理解透一个以后封装拿来用就行了。

那么有了任意地址的PDE和PTE算法之后,我们就实现了修改任意一个地址读写属性的操作了。

实现隐藏可执行内存

最后万事俱备,再来实现隐藏可执行内存的操作。示例代码如下:

PVOID AllocateMemory(HANDLE pid, SIZE_T size)
{
	//获取进程结构体
	PEPROCESS Process=NULL;
	PVOID BaseAddress = 0;
	NTSTATUS status= PsLookupProcessByProcessId(pid, &Process);
	if (!NT_SUCCESS(status))
	{
		return NULL;
	}

	//判断进程是否退出
	if (PsGetProcessExitStatus(Process)!=STATUS_PENDING)
	{
		ObDereferenceObject(Process);
		return NULL;
	}

	//附加进程
	KAPC_STATE kApcState = {0};
	KeStackAttachProcess(Process, &kApcState);

	//附加 
	ZwAllocateVirtualMemory(NtCurrentProcess(), &BaseAddress, 0, &size, MEM_COMMIT, PAGE_READWRITE);
	if (NT_SUCCESS(status))
	{
		RtlZeroMemory(BaseAddress, size);

		memcpy(BaseAddress, shellcode, sizeof(shellcode));

		//修改PDE和PTE 设置可写和可执行属性
		SetExecutePage(BaseAddress, size);
	}

	KeUnstackDetachProcess(&kApcState);

	return BaseAddress;

}

实际上就是申请一块内存,在申请完了之后用修改PDE和PTE属性的方式来修改内存属性。

隐藏内存对抗

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E9osXzn6-1670137929254)(Windows x64隐藏可执行内存.assets/1669908278279.png)]

在CE的设置里面把这几个复选框给勾上,然后重启CE,重新附加进程内存。

在这里插入图片描述

会发现此时我们的内存属性显示成了真正的可读可写可执行的内存方式,这是因为CE在开启这几个选项之后,会利用驱动查PDE PTE属性的方式来查询当前的内存。

在这里插入图片描述

为什么知道是驱动?因为现在CE不仅可以读取三环的地址,也可以读取到零环的内存地址。

不过应该没有哪家公司会用这种方式来进行检测,毕竟这对抗都到物理内存层面了,而且CE上面的选项也提示了,开启之后扫描会变得很慢。

在这里插入图片描述

再来看这个VAD树的遍历,依然还是欺骗过去了。

完整代码:

https://download.csdn.net/download/qq_38474570/87230134?spm=1001.2014.3001.5501

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/60597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web中的Bias(更新中)

目录前言数据偏见对人们的影响衡量偏见活跃偏差或少数人的智慧数据偏见其他参考文献前言 本文参考Ricardo Baeza-Yates 2018年发表在《Communications of the ACM》的论文Bias on the Web&#xff0c;论文旨在提高人们对网络使用和内容中存在的偏见对我们所有人造成的潜在影响…

Methyltetrazine-PEG4-NHS ester,甲基四嗪PEG4琥珀酰亚胺酯

一&#xff1a;产品描述 1、名称 英文&#xff1a;Methyltetrazine-PEG4-NHS ester 中文&#xff1a;甲基四嗪-四聚乙二醇-琥珀酰亚胺酯 2、CAS编号&#xff1a;1802907-92-1 3、所属分类&#xff1a;Tetrazine 4、分子量&#xff1a;533.54 5、分子式&#xff1a;C24H3…

qt单线程实现顺序事件的处理不卡顿技巧(IDE开发)

需求&#xff1a; 我现在是这样的需求&#xff0c;我正在开发一款嵌入式IDE中&#xff0c;编辑器中光标改变&#xff0c;右侧的符号大纲能对应的改变选中项。 这里的过程是这样的&#xff0c;鼠标位置改变事件函数里&#xff0c;通过光标行号&#xff0c;计算得到当前处于的符…

通过私钥连接腾讯云,实现免密远程登录

一、创建 SSH 密钥 系统提示不会保存私钥&#xff0c;要求用户在 10 分钟之内自行下载私钥&#xff0c;要保存在本地电脑和邮箱里面备用。 二、绑定密钥到云服务器 勾选刚才创建的 SSH 密钥&#xff0c;点击上面的绑定云主机&#xff0c;弹窗中要先找到你云主机的地域&#x…

【计算机毕业设计】74.家教平台系统源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐…

CentosLinux 6.5安装教程

、开始安装Centos6.5&#xff1a;我们选择“inistall system with basic video driver” 注意&#xff1a;这是一种精简系统的安装模式&#xff1a; 1.安装或升级现有的系统&#xff1b; 2.安装系统并使用基本的显卡驱动&#xff1b; 3.进入系统修复模式&#xff1b; 4.从硬盘…

[附源码]Python计算机毕业设计SSM竞赛报名管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【计算机毕业设计】基于jsp网上书店(源代码+论文)

网上书店系统 1.需求分析。 参考设计要求&#xff0c;及可行性的分析&#xff0c;我们确定了如下的需求&#xff1a; 1.数据库设计科学合理。 2.网站主页面简洁美观&#xff0c;可以天蓝色为主色调。 3.网站主页显示各个分类的及总的畅销表、新书榜、推荐榜&#xff0c;显…

Allegro如何锁定器件操作指导

Allegro如何锁定器件操作指导 Allegro上可以锁定器件,避免误操作被移动,具体操作如下 选择fix命令 Find选择Symbols 框选需要锁定的器件 可以看到器件被锁住了 除了这个方法之外,还有另外一种方法锁定器件,选择edit-property Find选择Symbols

ADSP-21569/ADSP-21593的开发入门(中)

ADSP-21569/21593的软件准备 安装CCES软件&#xff0c;我装的是2.10.1&#xff0c;官网可以下载&#xff0c;我也可以提供。软件安装没什么可说的&#xff0c;全部下一步&#xff0c;软件的试用跟注册可以单独联系我。 https://www.analog.com/cn/design-center/evaluation-h…

做短视频创业之前必须确定的内容:变现形式,短视频玩法和人设定位

做短视频创业之前必须确定的内容&#xff1a;变现形式&#xff0c;短视频玩法和人设定位。这是短视频的根基&#xff0c;打好基础才能更好的实现盈利目标。 开始做短视频的时候&#xff0c;走了很多弯路&#xff0c;这段时间总结了之前的经验教训&#xff0c;结合在我赢助手上…

【编程题】【Scratch四级】2022.09 班级成绩处理

班级成绩处理 三年级1班有36个小朋友&#xff0c;某次数学考试&#xff0c;同学们的成绩在78-100之间&#xff0c;求出该班学生的平均分和成绩优秀的人数&#xff08;成绩大于85分&#xff09;。 1. 准备工作 &#xff08;1&#xff09;默认小猫角色&#xff0c;默认白色背景…

Python学习基础笔记二十一——迭代器

列表&#xff0c;我们使用for循环来取值&#xff0c;我们把每个值都取到&#xff0c;不需要关心每一个值的位置&#xff0c;因为只能顺序的取值&#xff0c;并不能跳过任何一个去取其他位置的值。那么我们为什么可以使用for循环来取值&#xff0c;for循环内部是怎么工作的呢&am…

【力扣算法简单五十题】17.路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶子节点 是指没有子节点…

模仿Spring注入接口的代理类全过程

前言 在使用mybatis或者openFeign时只定义了一个接口类&#xff0c;并无实现类&#xff0c;可以把接口注入到service中并且能调用方法返回值。一个接口并无实现类&#xff0c;为什么可以实例化并且交给了spring管理。mybatis&#xff0c;OpenFeign又是怎么实现的&#xff1f;接…

生物化学 核磁共振 氢谱 n+1定律 邻碳耦合 同碳耦合

核磁共振氢谱 基础 自旋量子数 自旋为S的粒子&#xff0c;取向的范围为[-S,S],但是需要间隔1。比如质子的自旋为1/2,则有-1/2 &#xff0c;1/2两个取向。取值的个数等于在外加磁场的情况下能够分裂的能级的个数。但是质量数和原子序数都为0的原子(C12,O16C^{12},O^{16}C12,O1…

Java ~ Executor ~ LinkedBlockingQueue【总结】

一 概括 简介 LinkedBlockingQueue&#xff08;链接阻塞队列&#xff09;类是BlockingQueue&#xff08;阻塞队列&#xff09;接口的主要实现类之一&#xff0c;也是Executor&#xff08;执行器&#xff09;框架最常搭配使用的实现之一&#xff0c;采用链表的方式实现。相比基于…

Qt+opencv 鼠标画线实现几何图形识别并动态创建

前言 使用Qt OpenCV实现&#xff0c;通过鼠标画线绘制几何图形&#xff0c;然后通过opencv进行图形轮廓识别&#xff0c;返回图形顶点&#xff0c;然后创建对应的几何图形添加到场景中。绘制使用QGraphics体系完成。 看效果图&#xff1a; 本文demo在这里 点击下载 环境: …

python在centos下安装以及配置

python在centos下安装以及配置 1.背景 centos下默认的都是python2.7下载需要更换为3.x使用&#xff0c;目前大部分应用都是基于pyhton3了 具体步骤&#xff1a; 我下载一个3.8.15的包 https://www.python.org/ftp/python/3.8.15/Python-3.8.15.tgz 小注释&#xff1a;如果…

动手学深度学习(2)—— 线性神经网络

文章目录线性神经网络线性回归线性回归从零开始的实现生成数据集读取数据集初始化模型参数定义模型定义损失函数定义优化算法训练线性回归的简洁实现生成数据集读取数据集定义模型初始化模型参数定义损失函数定义优化算法训练softmax 回归softmax运算交叉熵损失图像分类数据集读…