VMP分析之VM解码循环与基本架构(一)
文章目录
- 示例代码
- VMP区段概览
- VM基本流程跟踪
- 步入虚拟机
- 解密操作码
- 取handler
- VMP解码循环
- 保存寄存器环境
- 总结->VM寄存器的基本架构
示例代码
接下来通过一个简单的Demo来大概了解下VMP代码的整体流程,示例代码如下
#include <windows.h>int Calc(int a, int b)
{return a + b;
}int main()
{Calc(2, 3);system("pause");
}
这里只对Calc函数中的两条汇编指令进行VM加壳处理
右键新增节点,填入需要VM处理的地址0x401088
接着设置结束位置,只对两条指令进行保护
然后在Options中选择最强保护,按F9编译程序
OD加载VM后的程序,跳转到VM的开始地址0x401088。
VMP区段概览
VMP1.09加壳后的程序,会增加两个区段,这两个区段的具体作用如图:
其中VMP0用于保存虚拟机引擎代码,VMP1用于保存VMP的寄存器环境。
VM基本流程跟踪
我们在JMP的位置下断点,让程序执行到这个位置,然后F7单步。
第一条指令中的push的地址,是一个密钥,密钥指向的内存就是VM的指令流。
然后跳转到0x42B3E7的位置。这里就是步入虚拟机的开始
从这里开始就进入到了虚拟机的代码。
步入虚拟机
首先将寄存器环境压入到栈中,接着压入第二个密钥并将先前的第一个密钥保存到esi中。
接着将edi赋值为0x42B000
这个0x42B000就是vmp1区段的起始地址,用于保存VM_Context,VM的线程上下文,里面保存的是VM的寄存器环境。
然后将esi和ebx赋值为当前的密钥
而密钥指向的内存数据,就是VMP的指令流,相当于VM_EIP。接着开始解密指令流
解密操作码
接着VMP开始解密自己的指令集
首先取出esi的第一个字节放到al,并且将esi+1指向下一个操作码,当前al的值为0x27
再经过几步位运算以后,al操作码从0x27更新为了0xA7。后面的add bl,al,是为了更新解密key。
add bl,al;
al=当前VM的操作码
ebx=解密Key
ebx=解密Key+当前操作码
al在这里也起到一个校验码的作用,更新Key的作用是为了防止逆向人员暴力破解,如果强行改变EIP的指向,那么必然会导致下一个VM指令解密失败,整个程序就无法正常运行。
然后将eax的高位清0,令eax=0xA7,此时的eax就是VM解密后的操作码。
这里的eax已经解码完了,eax只是作为一个索引,在指令表里查找指令,真正有效的数据只有AL,因此VM最多只有256个指令。
取handler
这里的0x42B4AF指向的内存地址,就是VMP的handler,handler就是VM指令实现的具体过程。根据解密出来的指令跳转到对应的handler,执行handler代码
接着取出VM指令流中的0xC0,此时指令流EAX=0xC0
经过一系列解密过程后,eax为真实的指令0x2,然后再次更新EBX解密KEY
VMP解码循环
edi指向的地址是之前保存进来的VM_Context,这里将第二个解密Key保存到VM_Conetxt+8的位置
接着又跳转到之前解密指令流的位置
这就是最著名的VMP解码循环,如图:
其中
- 伪码地址对应密钥内存中的指令流
- 跳转表对应Handler
- 最下面的Handler是具体的实现过程
保存寄存器环境
当操作数为A7时的Handler作用的保存当前寄存器环境到VM_Context,A7这个handler会执行多次,保存前的堆栈如下:
当前堆栈
$ ==> > 00000000--->第二个密钥
$+4 > 0019FED0--->EDI
$+8 > 00401520--->ESI
$+C > 0019FED0--->EBP
$+10 > 0019FE7C--->ESP
$+14 > 00309000--->EBX
$+18 > 021E0FC0--->EDX
$+1C > 00000000--->ECX
$+20 > CCCCCCCC--->EAX
$+24 > 00000206--->EFlags
保存后的VM_Context如下:
VM_Context
$ ==> >CCCCCCCC--->EAX
$+4 >00000206--->EFlags
$+8 >0019FED0--->EDI
$+C >00000000--->第二个密钥
$+10 >00000000--->ECX
$+14 >02210FC0--->EDX
$+18 >000B8FA5--->
$+1C >F609851D--->
$+20 >E654F2EE--->
$+24 >0019FED0--->EBP
$+28 >003CA000--->EBX
$+2C >00401520--->ESI
保存现场,ESP为什么不用保存呢?因为在VMP的架构里,ESP是直接使用的,在任何时候都可以获得真正的ESP
总结->VM寄存器的基本架构
80x86的寄存器中,每一个寄存器都有特定的作用,例如eax用于保存返回值,ESI用于保存源操作数,而VM的寄存器也不例外。
- ESI:保存VM_EIP
- EDI:指向虚拟机通用寄存器的地址
- EBP:等于VM_ESP,指向虚拟机堆栈的栈顶
- EAX:计算将要执行的指令流和选择虚拟机通用寄存器,指令执行时用作中间变量,其他时候用作花指令
- EDX:执行时通常用作中间变量,其他时候用作花指令
- EBX:bl用来保存校验码,更新密钥
- ECX:shld,shrd时用作中间变量,其他大部分时间用来做花指令
- ESP:指向垃圾指令,这个寄存器在虚拟机中用于迷惑分析者
VMP分析之VM解码循环与基本架构(一)相关推荐
- VMP分析之VMP2.13流程分析(三)
文章目录 VMP2.X版本特点 VMP2.13加壳 VMP2.13代码分析 进入VM虚拟机 保存堆栈 保存eflags和edx 保存ecx和edi 保存ebx 保存eax 保存ebx ebp和esi ...
- VMP分析之VMP1.09虚拟化架构分析(二)
文章目录 示例代码 VM完整流程分析 VM解码循环 保存寄存器环境 压入EBP和偏移 执行函数 恢复寄存器环境 总结 示例代码 示例代码如下: #include "stdafx.h" ...
- VMP分析之VMP2.13插件化分析(四)
文章目录 Zeus插件 相关介绍 初始化Key并解密 加载操作码 解密操作码 取handler 解密handler 进入handler 保存堆栈 指令流解密Key VMP分析插件 相关介绍 VM分析插 ...
- FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧内宏块(Intra)
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 2:解码数据
注:分析Tiny Jpeg Decoder源代码的文章: Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头 Tiny Jpeg Decoder (JPEG解码程序) ...
- FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)...
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧内宏块(Intra)...
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头
注:分析Tiny Jpeg Decoder源代码的文章: Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头 Tiny Jpeg Decoder (JPEG解码程序) ...
最新文章
- 同等学力计算机综合难吗,报考2018年同等学力申硕计算机在职研究生毕业很困难吗...
- mysql 正则 java 区别_MySQL中的正则表达式
- vue --- 使用vue-router获取带参数的路由
- ad网络标号怎么批量设置_网络打印机怎么设置 网络打印机安装方法【详细步骤】...
- 解决Conda install tensorflow弹窗Python.exe已经停止工作的问题
- php mysql社工库_社工库源码 PHP ASP,持续更新
- 禅道的下载与安装教程
- win10计算机桌面天气,win10电脑桌面显示时间和天气日期怎么设置
- 互联网下一个风口 国务院印发《促进大数据发展行动纲要》
- 铁矿石再次冲高回落,豆粕认购大涨,纯碱09-01季节性反套?2022.4.21
- 遇到问题---linux--crontab输出重定向不生效最全可能原因收集和解决
- python battleship_一个python初学者的作业,battleship
- 日常使用计算机如何进行病毒防范,电脑日常生活中怎么防范电脑病毒
- 苹果公司:苹果商店App价格将调整 多个国家地区受影响
- C++语法学习笔记十四:派生类-调用顺序-访问等级-函数遮蔽
- Android 模拟器 连接局域网
- NodeBB – 基于 Node.js 的开源论坛系统
- QCustomPlot 示例实践--sinc离散序列
- 2021年如何选购华强北AirPods(一次翻车到下车的经历总结的经验)
- ArcGIS中WGS84转为西安80(无自带转换参数的坐标系转换)
热门文章
- DL之LSTM:基于tensorflow框架利用LSTM算法对气温数据集训练并回归预测
- 成功解决 ValueError: feature_names mismatch training data did not have the following fields
- ML之SVM:调用(sklearn的lfw_people函数在线下载55个外国人图片文件夹数据集)来精确实现人脸识别并提取人脸特征向量
- TF之DCGAN:基于TF利用DCGAN测试自己的数据集并进行生成过程全记录
- DL之Keras:基于Keras框架建立模型实现【预测】功能的简介、设计思路、案例分析、代码实现之详细攻略(经典,建议收藏)
- Linux常用命令 积累
- 集成学习-Boosting集成学习算法AdaBoost
- rcmd: socket: Permission denied
- mysql主从复制同步
- c#FileStream文件读写(转)