VMPStudio (全称Virtual Machine and Protection Studio ),是一款基于函数虚拟机 的交互式二进制动静态 分析器。它主要包括LightIDA 静态反汇编器、UraniumVM 采样编辑器、UrDecompiler 动态反编译器、PhoneVMP 虚拟机保护操作台这四大部分。
名词解释
UraniumVM采样编辑器(UraniumVM Sampling Editor,简称UVMSE),是函数虚拟机UraniumVM的前端操作台。提供UVM采样数据浏览、编辑、导入、导出等功能。
Textobot主要用于提供脚本化的iPhone手机管理功能,下载地址 。安装完成后,服务就自动处于运行状态。如果手机重启过,那么需要在ssh命令行使用tbsvr手动重启服务,如下:
UVMDbg主要提供函数虚拟机运行时liburaniumvm.dylib,下载地址 。安装完成后,相应的文件就已经存放好了。
UVMFire主要提供UVMSE采样运行时支持,下载地址 。安装完成后,服务自动处于运行状态。如果手机重启过,那么需要在ssh命令行使用uvmserver手动重启服务,如下:
UVMSE采样过程,依赖上述步骤提供的服务或文件,我们可以通过如下方式检测依赖是否正常。
进程hybrage-iserver、frida-server说明Textobot环境正常。进程uvmserver、文件/usr/lib/uvmfire.dylib说明UVMFire环境正常。文件/usr/lib/liburaniumvm.dylib说明UVMDbg环境正常。
将UVMFire相关文件放在/data/local/tmp/目录下面,ARM32位下载地址 ,ARM64位下载地址 。安装好之后,目录结构如下:
根据要采样的进程架构,请保持对应的uvmserver一直处于运行状态,如下:
LaunchAPK的主要作用是优先于目标App获得进程控制权。因为如果目标进程使用Ptrace先于Attach操作Attach自身,那么Attach操作将会失败。目前,UVMSE LaunchAPK的实现基于Magisk/Riru模块,下载地址 。下载后,将uvmzygote和riru模块放至/sdcard/Downloads目录,然后使用Magisk模块管理App依次安装riru、uvmzygote即可。
接下来,非常关键的一步设置:关闭SELinux 。这样才能让沙盒App旁加载UVMFire采样运行时:
当SELinux的状态是Permissive时,LaunchAPK才能正常工作。
如果要采样iOS目标进程,那么将如下iOS的IP地址设置为配置好环境的iPhone WiFI IPv4地址:
如果要采样Android目标进程,那么将如下Android的IP地址设置为127.0.0.1,并点击adb按钮选择Android SDK里面的adb路径:
UVMSE授权模式是,9000元/目标架构/台/年,也即一个授权只支持1台电脑,有效期1年,过期后自动转为免费版。目标架构是指arm、arm64,也即一个授权可以同时支持macOS/iOS/Android的同一种架构。
想好你要绑定的电脑(原则上在授权有效期内不能重新绑定新电脑),下载HWID生成器并在要绑定授权的电脑上运行之,下载地址 。
字符串A1W+yv1z8gvcvEsj即是当前电脑的硬件唯一标识符。
剩余步骤请参见完整pdf 用户手册。
我们使用ollvmdebug这个简单的样例来完整说明UVMSE的使用过程。ollvmdebug是一个控制台程序,它接受字符输入,当输入r字符时就调用do_main函数,当输入q字符时就退出程序。源码如下,下载地址 :
我们使用ollvm的bcf、fla、sub以及hikari的strencrypt混淆do_main函数,分别得到ARM macOS、iOS、Android的三个ollvmdebug控制台程序,三个都一样,只是运行目标平台不一样而已。本文以ARM macOS为例进行下面的流程介绍。
本例子中,我们的采样目标是上述ollvmdebug程序的do_main函数,运行它如下:
如果当前LightIDA加载的模块在目标进程中,那么切换到UraniumVM窗口就会得到如下成功的输出日志,反之会输出找不到当前模块的信息:
切换回LightIDA窗口,在do_main函数右键,执行Sample Function菜单,即可设置无痕软件断点:
在ollvmdebug控制台输入r字符并回车,得到如下信息:
这样就对目标进程的目标函数实现了一次采样。
切换回UraniumVM窗口,我们可以看到如下采样数据和采样日志:
在这里,我们就可以浏览、编辑采样回来的指令等数据了,比如,我们可以对比一下静态CFG、动态CFG、重写CFG。
静态CFG:
动态CFG:
重写CFG:
有了采样数据,我们切换到UrDecompiler窗口,就可以看看动态反编译和静态反编译的区别了。
静态反编译:
动态反编译:
当然,现阶段VMPStudio的静态分析能力远远没有IDA那么优秀,所以,我们可以将简化还原后的二进制文件导出给IDA使用。
对于一些复杂的样本,反复研究运行时数据,是有必要的,所以我们可以将采样数据保存,然后任何时候都可以重新加载它们。
上述图片中的*.sdb文件,即是剥离进程存档的采样数据库文件。
我们将简化还原后的文件继续在IDA里面分析,得到更加优质的反编译代码:
Sample Function:附加目标进程后,设置无痕软件断点;
Sample Stop:撤销无痕软件断点;
Dynamic Decompile:使用采样数据对选择的函数进行动态反编译,反编译结果在UrDecompiler窗口浏览;
Restore Instruction:恢复当前选中的指令到编辑之前的值;
Edit Instruction:编辑当前选中的指令;
BasicBlocks to here:跳转至当前选中指令的基本块;
Jump to BasicBlocks:当前选中指令要跳至的基本块;
Reassemble to file:简化还原采样过的函数并重写至新的二进制文件中;
Reassemble to file with code clear:简化还原采样过的函数、清零未采样的函数并重写至新的二进制文件中;
Dyndecompile to file:简化还原采样过的函数、清零未采样的函数并重写至新的二进制文件中,然后利用该文件生成动态反编译数据库文件供A64Dbg专业版C伪代码级调试使用;
Select sample data:选择采样数据,如果多次或者多个采样函数数据,那么可以通过它切换当前操作的采样数据;
Differ samples data:对两次采样数据进行差分计算,找出差异化的部分;
Combine samples data:对多次采样数据进行合并计算;
CFG for static:基于文件Opcodes静态分析得到的控制流程图,属于基本CFG;
CFG for executed:基于采样数据得到的控制流程图,属于基本CFG;
CFG for combined:基于采样数据得到的合并、简化控制流程图,属于高级CFG;
CFG for rewrited:基于采样数据得到的合并、简化、重写控制流程图,属于高级CFG,如果采样函数不是ollvm混淆的,则与CFG for combined一样;
Dynamic Decompile:使用采样数据对选择的函数进行动态反编译;
Attach:选择要采样的目标进程;
Launch APK:选择安装在手机端要采样的目标APK,自动拉起并控制目标进程;
Detach:停止控制目标进程;
当我们对同一个函数做了多次采样或者我们对同一模块的不同函数进行了采样,那么我们就可以通过这三个采样去选择、差分、合并采样数据。其中差分、合并只能是对同一个函数的采样数据进行计算。
Index:采样序列;
PC Chains:PC执行链,同一地址可能出现多次,比如循环;
Address Hit:函数被执行过的指令地址,这就是我们在UraniumVM窗口看到的反汇编代码地址;
Reassemble to file,除了采样函数重写、data区块用内存数据重写之外,其他部分保持不变。
Reassemble to file with code clear,采样函数重写、data区块用内存数据重写、非采样函数清零,其他部分保持不变。该选项对于一些几十MB,甚至几百MB的文件尤其有用。这样可以大大提高IDA分析新二进制文件的速度。
Dyndecompile to file,采样函数重写、data区块用内存数据重写、非采样函数清零,其他部分保持不变。然后对新二进制文件采样过的函数实施动态反编译,并将结果存储。这样A64Dbg专业版就可以对复杂二进制文件的复杂函数进行C伪代码级的调试了。
上述图片中以-dyndec结尾的文件夹即是动态反编译数据库文件,其中* .c是C伪代码、rva.map是采样函数地址重写前后的映射表(供A64Dbg专业版加载使用)。
版本
日期
内容
V1.0
2021-07-28
UraniumVM采样编辑器初始文档编写;
名称
说明
函数虚拟机
用软件模拟CPU指令集的运算,将进程函数运行在该模拟指令集之下。
二进制
CPU指令集的二进制编码,比如arm、x86、arm64、x64、risc-v二进制代码。
动静态分析
从文件或进程入手,分析程序的代码、数据。
反汇编器
将CPU指令集的二进制编码格式化为指令助记符的形式,提高二进制代码可读性。
反编译器
将汇编函数分析、重构为C伪代码的形式,提高汇编函数可读性。
采样器
记录、保存函数虚拟机运行过程中的指令、地址、内存。
虚拟机保护
用函数虚拟机运行加密后的函数代码,达到隐藏函数逻辑,提高逆向、破解的门槛。
iPhone:~ root
lrwxr
-
xr
-
x
1
mobile staff
15
Jan
11
2021
/
usr
/
bin
/
tbsvr
-
> textobot
-
server
*
iPhone:~ root
iPhone:~ root
lrwxr
-
xr
-
x
1
mobile staff
15
Jan
11
2021
/
usr
/
bin
/
tbsvr
-
> textobot
-
server
*
iPhone:~ root
iPhone:~ root
/
usr
/
bin
/
uvmserver
iPhone:~ root
iPhone:~ root
/
usr
/
bin
/
uvmserver
iPhone:~ root
iPhone:~ root
0
20305
1
0
12Jul21
??
0
:
01.14
/
usr
/
bin
/
uvmserver
0
21721
1
0
12Jul21
??
1
:
26.09
/
usr
/
libexec
/
hybrage
-
iserver
0
21724
21721
0
12Jul21
??
0
:
06.17
/
usr
/
libexec
/
frida
-
server
-
l
0.0
.
0.0
0
23258
23250
0
3
:
20PM
ttys000
0
:
00.01
grep server
iPhone:~ root
-
r
-
xr
-
xr
-
x
1
root wheel
591296
Jul
27
08
:
48
/
usr
/
lib
/
liburaniumvm.dylib
*
iPhone:~ root
-
r
-
xr
-
xr
-
x
1
root wheel
973392
Jul
26
13
:
47
/
usr
/
lib
/
uvmfire.dylib
*
iPhone:~ root
0
20305
1
0
12Jul21
??
0
:
01.14
/
usr
/
bin
/
uvmserver
0
21721
1
0
12Jul21
??
1
:
26.09
/
usr
/
libexec
/
hybrage
-
iserver
0
21724
21721
0
12Jul21
??
0
:
06.17
/
usr
/
libexec
/
frida
-
server
-
l
0.0
.
0.0
0
23258
23250
0
3
:
20PM
ttys000
0
:
00.01
grep server
iPhone:~ root
-
r
-
xr
-
xr
-
x
1
root wheel
591296
Jul
27
08
:
48
/
usr
/
lib
/
liburaniumvm.dylib
*
iPhone:~ root
-
r
-
xr
-
xr
-
x
1
root wheel
973392
Jul
26
13
:
47
/
usr
/
lib
/
uvmfire.dylib
*
angler:
/
data
/
local
/
tmp
total
26900
-
rwxrwxrwx
1
shell shell
17833720
2021
-
03
-
05
10
:
53
frida
-
inject
-
rwxrwxrwx
1
shell shell
824264
2021
-
07
-
26
14
:
09
liburaniumvm.so
-
rwxrwxrwx
1
shell shell
4748136
2021
-
07
-
26
16
:
54
libuvmfire.so
-
rwxrwxrwx
1
shell shell
107596
2021
-
07
-
26
16
:
47
libuvmzygote.so
-
rwxrwxrwx
1
shell shell
140980
2021
-
03
-
21
15
:
33
unzip
-
rwxrwxrwx
1
shell shell
4508072
2021
-
07
-
26
16
:
47
uvmserver
-
rwxrwxrwx
1
shell shell
193168
2021
-
03
-
21
15
:
33
zip
angler:
/
data
/
local
/
tmp
total
51744
-
rwxrwxrwx
1
shell shell
41596296
2021
-
03
-
05
10
:
54
frida
-
inject
-
rwxrwxrwx
1
shell shell
748032
2021
-
07
-
26
14
:
09
liburaniumvm.so
-
rwxrwxrwx
1
shell shell
5375368
2021
-
07
-
26
16
:
54
libuvmfire.so
-
rwxrwxrwx
1
shell shell
20784
2021
-
07
-
26
16
:
47
libuvmzygote.so
-
rwxrwxrwx
1
shell shell
145520
2021
-
03
-
21
15
:
33
unzip
-
rwxrwxrwx
1
shell shell
4829480
2021
-
07
-
26
16
:
47
uvmserver
-
rwxrwxrwx
1
shell shell
199576
2021
-
03
-
21
15
:
33
zip
angler:
/
data
/
local
/
tmp
total
26900
-
rwxrwxrwx
1
shell shell
17833720
2021
-
03
-
05
10
:
53
frida
-
inject
-
rwxrwxrwx
1
shell shell
824264
2021
-
07
-
26
14
:
09
liburaniumvm.so
-
rwxrwxrwx
1
shell shell
4748136
2021
-
07
-
26
16
:
54
libuvmfire.so
-
rwxrwxrwx
1
shell shell
107596
2021
-
07
-
26
16
:
47
libuvmzygote.so
-
rwxrwxrwx
1
shell shell
140980
2021
-
03
-
21
15
:
33
unzip
-
rwxrwxrwx
1
shell shell
4508072
2021
-
07
-
26
16
:
47
uvmserver
-
rwxrwxrwx
1
shell shell
193168
2021
-
03
-
21
15
:
33
zip
angler:
/
data
/
local
/
tmp
total
51744
-
rwxrwxrwx
1
shell shell
41596296
2021
-
03
-
05
10
:
54
frida
-
inject
-
rwxrwxrwx
1
shell shell
748032
2021
-
07
-
26
14
:
09
liburaniumvm.so
-
rwxrwxrwx
1
shell shell
5375368
2021
-
07
-
26
16
:
54
libuvmfire.so
-
rwxrwxrwx
1
shell shell
20784
2021
-
07
-
26
16
:
47
libuvmzygote.so
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)