ARM平台指令虚拟化初探
0x00:什么是代码虚拟化?
虚拟机保护是这几年比较流行的软件保护技术。这个词源于俄罗斯的著名软件保护软件“VmProtect”,以此为开端引起了软件保护壳领域的革命,各大软件保护壳都将虚拟机保护这一新颖的技术加入到自己的产品中。
代码虚拟化是将程序代码编译为虚拟机指令即虚拟代码(自己定义的代码集),通过虚拟CPU解释并执行的一种方式,大致流程如下:

我们抛开ARM平台CPU流水线机制不谈,简单来说,其实CPU就是遵循一个简单的模式:循环读取、解码、执行这个过程。
0x01:为什么要指令虚拟化
首先我们来回顾下软件保护壳的发展,大致可分为三个阶段。
第一阶段:当壳完成解密目标代码时,它将不会再次控制程序,被保护程序的明文将在内存中展开。在此之前,壳可以调用一切系统手段来防治黑客的调试与逆向。
第二阶段:可以实现分段式的加解密,壳运行完毕后,并不会消失而仍然会在程序运行到某个点时再次启动。
第三阶段:其实最简单的解释是,将被保护的指令使用一套自定义的字节码(逻辑上等价)来替换掉程序中原有的指令,而字节码在执行的时候又由程序中的解释器来解释执行,自定义的字节码只有自己的解释器才能识别,也是因为这一点,基于虚拟机的保护相对其他保护而言要更加难分析。
0x02:一个简单的虚拟机实现
了解过代码虚拟化的原理之后,就是自定义一套字节码,然后使用一个解释器解释运行字节码。所以,我们要实现定义字节码与实现解释器。
字节码只是一个标识,可以随意定义,以下是自定义的字节码,只定义了几个常用的指令,其中每条指令标识都对应于一个字节码。

在定义好指令对应的字节码之后,就须要一个解释器来解释定义的指令字节码了。其实这里的解释器与物理机CPU很相似。在物理机中的程序执行需要处理器、寄存器、栈、堆等环境才可以运行起来,所以需要虚拟寄存器,栈、堆等,以下是处理器。

有了上面结构之后,就可以来动手写解释器了。解释器的工作其实就是判断当前解释的字节码是否可以解析,如果可以就把相应参数传递给相应的处理函数,让处理函数来解释执行这一条指令。以下是解释器代码。

解释器解释执行过程:
首先可以从上面看到解释器vm_CPU执行时pc会指向Vcode,也就是自定义的字节码第一个字节0xa0(对应指令为MOV),之后会判断pc指向的字节码是否为ret指令,ret指令是0xa3,如果pc指向的不是ret,进入exec_Handle函数进行字节码解释。

0xa0就对应着mov指令,所以当解释器遇到0xa0就会调用vm_mov函数来解释mov指令。

在vm_mov函数中首先把PC + 1处的一个字节和PC + 2处2个字节分别保存在dest和src中,dest是寄存器标识,在后面的switch中判断dest是哪个寄存器,在这个例子中dest是0x10,也就是r1寄存器,在case 0x10分支中就把*src赋值给r1。前4个字节就是第一条mov指令,对应着mov r1, xxxx,xxxx就是这4个字节中的后2个。
上面是一个解释器在解释执行字节码时的过程,其实很简单,就是通过一个字节码和解释函数的关系来调用相应的函数(Handle),或者通过一个很长的switch来判断每个字节码,并调用相应函数(Handle) 。而解释函数则通过执行相应的操作来模拟出一个指令。最后,把这些指令串联在一起就可以执行完一个完整的逻辑。
下面是一个简单的CrackMe完整的Vcode


下面是一个简单的CrackMe完整的源代码

0x03:测试与总结
以android平台上测试如下:

总结:
其实这只是最简单的实现,仅仅是为了学习和理解,如果想实现一个基于虚拟机的保护壳还是有些复杂,比如:随机VCode与Handle的关系映射、Handle混淆与乱序、代码变形、重定位等。
bin:
链接: https://pan.baidu.com/s/1nvbmcSp 密码: wduy
ARM平台指令虚拟化初探的更多相关文章
- ARM平台的虚拟化介绍
本篇博文主要介绍虚拟化的基本思想以及在arm平台如何做虚拟化,arm提供的硬件feature等等. 虚拟化技术简介 虚拟化技术 虚拟化是一个概念,单从这个概念的角度来看,只要是用某一种物品去模拟另一种 ...
- 【安卓安全】ARM平台代码保护之虚拟化
简介:代码的虚拟化即不直接通过CPU而是通过虚拟机来执行虚拟指令.代码虚拟化能有效防止逆向分析,可大大地增加了代码分析的难度和所需要的时间,若配合混淆等手段,对于动静态分析有着较强的防御能力. 背景: ...
- [转]ARM平台下独占访问指令LDREX和STREX
参考:ARM平台下独占访问指令LDREX和STREX的原理与使用详解 全文转载如下: 为了实现线程间同步,一般都要在执行关键代码段之前加互斥(Mutex)锁,且在执行完关键代码段之后解锁.为了实现所谓 ...
- (二十三)ARM平台NEON指令的编译和优化
ARM平台NEON指令的编译和优化 本文介绍了ARM平台基于ARM v7-A架构的ARM Cortex-A系列处理器(Cortex-A5, Cortex-A7,Cortex-A8, Cortex-A9 ...
- ARM汇编指令调试方法
学习ARM汇编时,少不了对ARM汇编指令的调试.作为支持多语言的调试器,gdb自然是较好的选择.调试器工作时,一般通过修改代码段的内容构造trap软中断指令,实现程序的暂停和程序执行状态的监控.为了在 ...
- 移植mysql到嵌入式ARM平台
移植MySQL到嵌入式ARM平台 MySQL没有专门针对ARM的版本,移植到ARM没有官方文档可参考,因此,暂时参考这样一篇文档: http://blog.chinaunix.net/space.p ...
- arm平台的调用栈回溯(backtrace)
title: arm平台的调用栈回溯(backtrace) date: 2018-09-19 16:07:47 tags: --- 介绍 arm平台的调用栈与x86平台的调用栈大致相同,稍微有些区别, ...
- GNU ARM 汇编指令
第一部分 Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针.设置页表.操作 ARM的协处理器等.初始化完成后就可以跳转到C ...
- QtCreator动态编译jsoncpp完美支持x86和arm平台
如果是做嵌入式开发. 在Qt下支持JSon最好的办法,可能不是采用qjson这个库.QJson这个库的实例只提供了x86环境下的编译方法. Installing QJson-------------- ...
随机推荐
- 用勤哲excel服务器开发设计燃烧器生产行业ERP
J公司是一家专业从事设计.制造.生产及销售各类燃油燃气燃烧设备和各类冶金燃烧装置的专业公司.2011年随着企业的发展,原来手工操作模式已经很难应付日益增长的工作量. J公司希望通过软件管理实现以下几个 ...
- Vuex基础-Module
官方API地址:https://vuex.vuejs.org/zh/guide/modules.html 前面几节课写的user.js就称为一个module,这样做的原因是:由于使用单一状态树,应用的 ...
- Functions that return a function
javascript学习中,经常会遇到闭包的问题,然后闭包的很多例子中又会遇到很多返回函数的闭包的例子程序.因为对闭包的理解还不够透彻,然后对于Functions rerurn a function产 ...
- [Java]如何把Soap Message装成一个String对象
代码片段 // Create transformer TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf ...
- Redis学习笔记(4)—— Jedis入门
一.Jedis介绍 Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如Java.C.C#.C++.php.Node.js.Go等. 在官方网站里列的一些Java客户端,有jedi ...
- 001 开发环境搭建、安卓项目结构、R文件位置、asset目录创建
1.安卓开发平台搭建 (1)下载SDK基础工具包(自己的百度云中) (2)将下载的安装包(android-sdk_r24.4.1-windows.zip)解压后,放到以下路径 C:\SoftAppli ...
- office word使用技巧汇总
1.用MathType编辑的公式放在Word中有时会显示不全,仅显示其中一部分. 以下教程介绍解决Word中MathType公式显示不全的方法. 在Word中粘贴完公式后,选中该公式,在工具栏里选择“ ...
- javscript---Bom 和Dom
JavaScript分为 ECMAScript,DOM,BOM. ECMA javascript标准语法 BOM(Browser Object Model)是指浏览器对象模型,它使 JavaScrip ...
- 2.Servlet(一)
1.Servlet的编写.访问过程: (1)编写部署Servlet程序: 编写源文件->编译类文件->部署程序->运行->Servlet处理请求,返回响应. (2)Eclips ...
- args 、kwargs不定参数通过列表、元组、字典传递
*args .**kwargs是不定参数的表达方法,一般用于函数形参.*args .**kwargs 作为传递参数的函数,在使用过程中,可对*args .**kwargs多个输入,但是效率或者比较麻烦 ...