频道栏目
首页 > 安全 > 系统安全 > 正文

Android代码混淆技术总结(一)

2017-04-08 09:23:30      个评论      
收藏   我要投稿

Android代码混淆技术总结(一)

一、前言

最近一直在学习Android加固方面的知识,看了不少论文、技术博客以及一些github上的源代码,下面总结一下混淆方面的技术,也算是给想学习加固的同学做一些科普,在文中将到的论文、资料以及源码,我都会给出相应的链接,供大家进一步去深入学习。后面我会弄成一个系列的文章,如有一些混淆技术没讲到,还希望大家指点,当做是交流学习。

二、Android混淆技术介绍

2.1 控制流平坦化

2.1.1 概念和思路

控制流平坦化,就是在不改变源代码的功能前提下,将C或C++代码中的if、while、for、do等控制语句转换成switch分支语句。这样做的好处是可以模糊switch中case代码块之间的关系,从而增加分析难度。

这种技术的思想是,首先将要实现平坦化的方法分成多个基本块(就是case代码块)和一个入口块,为每个基本快编号,并让这些基本块都有共同的前驱模块和后继模块。前驱模块主要是进行基本块的分发,分发通过改变switch变量来实现。后继模块也可用于更新switch变量的值,并跳转到switch开始处。详细的概念可以参考文献[1]。

其模型如下图:

\

下面用代码来说明,左边方法是没有采用控制流平坦化之前的效果,右边是采用了控制流平坦化的效果。

\

2.1.2 开源项目

目前用的最多的是OLLVM(Obfuscator-LLVM)的开源混淆方案,很多国内加固厂商都可以看到使用它的身影。它提供了3中保护方式:控制流平坦化、虚假控制流和指令替换。其项目地址如下:

https://github.com/Fuzion24/AndroidObfuscation-NDK

https://github.com/obfuscator-llvm/obfuscator

2.1.3 对抗

目前,对于ollvm的反混淆思路,多采用基于符号执行的方法来消除控制流平坦化,这里不做详细分析,详细的分析思路,可以参考quarkslab写的文章[3]。

2.2 花指令

2.2.1 概念和思路

花指令也叫垃圾指令,是指在原始程序中插入一组无用的字节,但又不会改变程序的原始逻辑,程序仍然可以正常运行,然而反汇编工具在反汇编这些字节时会出错,由此造成反汇编工具失效,提高破解难度。

花指令的主要思想是,当花指令跟正常指令的开始几个字节被反汇编工具识别成一条指令的时候,才可以使得反汇编工具报错。因此插入的花指令都是一些随机的但是不完整的指令。但是这些花指令必须要满足两个条件:

在程序运行时,花指令是位于一个永远也不会被执行的路径中。

这些花指令也是合法指令的一部分,只不过它们是不完整指令而已。

也就是说,我们只需要在每个要保护的代码块之前插入无条件分支语句和花指令,如下图所示。无条件分枝是保证程序在运行的时候不会运行到花指令的位置。而反汇编工具在再反汇编时由于会执行到花指令,所以就会报错。

\

那么目前的反汇编工具所使用的反汇编算法,主要分为两类:线性扫描算法和递归扫描算法。

线性扫描:依次按顺序逐个地将每一条指令反汇编成汇编指令

例如下面的指令:

\

如果是反汇编工具使用线性扫描算法,就会把花指令错误识别,导致反汇编出错。如下:

\

Dalvik Bytecode Obfuscation on Android[5]这篇文章就利用线性扫描的特点,插入fill-array-data-payload花指令,导致反编译工具失效。

\

递归扫描:按顺序逐个反汇编指令,如果某个地方出现了分支,就会把这个分支地址记录下来,然后对这些反汇编过程中碰到的分支进行反汇编。

可见,递归扫描的算法反汇编能力更强。我们常用的Android逆向工具里面,使用的反汇编算法如下:

\

2.2.2 开源项目

(1) https://github.com/thuxnder/dalvik-obfuscator

可以结合文章[5]一起看。

(2) https://github.com/faber03/AndroidMalwareEvaluatingTools

这个工具是意大利萨尼奥大学的laswatlab团队打造出来的恶意程序免杀工具,其实就是使用各种混淆技术,其中也包括花指令插入,在AndroidMalwareEvaluatingTools/transformations sources/JunkInsertion/目录下。该工具的使用报告可以参考文献[4]。

(3) https://github.com/strazzere/APKfuscator

APKFuscator通过插入下图的垃圾指令使得反汇编器出错。

\

2.2.3 对抗

检测出花指令的位置和长度,然后用NOP指令替换即可。

2.3 标识符混淆

2.3.1 概念和思路

标识符混淆就是对源程序中的包名、类名、方法名和变量名进行重命名,用无意义的标识符来替换,使得破解这分析起来更困难。最常用的就是ProGuard开源工具,其混淆后效果如右图所示。

\

甚至通过定制混淆字典,可以达到下面这种混淆效果,参考开源项目[7]:

\

那么这个标识符混淆的原理是怎样的呢?要了解这个原理,我们得事先对dex文件格式有一定了解,这个资料大家可以在网上找,很多,这里就不详细说了。

我们知道dex文件中的类名、方法名、变量名其实都对应的一个string_id的字符串索引,如下图。每一个类对应着class_def_item结构体,其中class_idx就是指向类名的字符串索引。

\

同样,每个方法也是对应一个method_id_item的结构体,其中name_idx就是指向方法名的字符串索引。

\

字段名也一样,对应着一个field_id_item的结构体,其中name_idx是指向字段名的字符串索引。

\

也就是说,我们只要修改相应的string_id索引表中的字符串,就可以达到标识符混淆的目的。

\

具体的实现可以参考文章[10],它还提供了一个dex混淆器的简单原型:DexConfuse。

上一篇:安卓Hacking Part 23:基于AndBug的Android应用调试技术
下一篇:Linux 内核漏洞利用教程(一):环境配置
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站