Android程序的反编译对抗研究
转自: http://www.freebuf.com/tools/76884.html
一、前言
对抗反编译是指让apk文件或者dex文件无法正常通过反编译工具,而且有可能导致工具异常或者崩溃,如apktool、baksmali、dex2jar、JEB等等工具,如下图dex2jar无法正常工作。

二、Dex文件格式解析
目前大多数android软件的反编译工具都是开源的,比如apktool、Dex2jar、baksamli,大家可以非常方便的从github下载并源阅读代码,然后找到可以利用的点,再在自己的软件中加入干扰代码,让反编译工具出现异常或者无法正常阅读代码。
接下来让我们先来熟悉一下dex文件格式 ,一个dex文件由以下几个部份组成:
1. Dex Header: Dex结构头它指定了dex文件的一些基本属性,并记录了部份数据表在dex文件中的物理偏移。
2. String Table: 字符串表,存储字符串的索引和个数
3. Type Table: 类型表,存储类型的索引和个数
4. Proto Table: 函数元型表,存储函数元型索引和个数
5. Field Table: 字段表,存储字段索引和个数
6. Method Table: 方法表,存储方法索引和个数
7. Class def Table:类定义表,存储类定义索引和个数
8. Data Section: 存储数据,由以上类型的索引查找

有兴趣的可以直接翻看android的源码或者参考以下链接:
http://www.netmite.com/android/mydroid/dalvik/docs/dex-format.html
既然要在代码中添加干扰指令,接下的DexClassDef结构,肯定是要了解的非常清楚。
结构中包含了类的类型偏移、访问标志、父类类型索引、接口偏移、注释、静态类型的偏移信息,整体结构图定义如下:

struct DexClassDef
{
u4 classIdx;
u4 accessFlags;
u4 superclassIdx;
u4 interfacesOff;
u4 sourcefileIdx;
u4 annotationsOff;
u4 classDataOff;
u4 staticValuesOff;
}
DexClassDef结构字段详细说明:
classIdx 字段是一个索引值,类的类型,做为下标索引在DexTypeID结构列表中查找
accessFlags 字段是类的访问标志,以ACC_开头的枚举值
superclassIdx 字段是父类的类型,做为下标索引在DexTypeID结构列表中查找
interfacesOff 字段是接口类型,做为下标索引在DexTypeList结构列表中查找
sourcefileIdx 字段是源文件名,做为下标索引在DexTypeList结构列表中查找
annotationsOff 字段是注释信息的偏移,指向DexAnnotationsDirectoryItem结构
classdataOff 字段是指向了DexClassData结构体的偏移
staticValuesOff 字段是指向DexEncodeArray结构体的偏移,记录静态数据的信息
DexClassData结构说明:
struct DexClassData
{
DexClassDataHeader header;
DexField* staticFields; //静态字段,DexField结构
DexField* instanceFields; //实例字段,DexField结构
DexMethod* directMethods; //直接方法,DexMethod结构
DexMethod* virtualMethods; //虚方法, DexMethod结构
}
DexClassData结构中的DexMethod类型描述了:方法的原型、名称、访问标志以及代码数据块,codeOff字段指向了一个DexCode结构,它描述了方法更详细的信息以及方法中指令的内容。
DexMethod结构声明如下
struct DexMethod
{
u4 methodIdx; //指向DexMethodId的索引
u4 accessFlags;//访问标志
u4 codeOff; //指向dexCode的结构偏移
}
struct DexCode
{
ushort registerSsize;//使用的寄存器的数目
ushort insSize; //传入参数的数目
unshort outsSize; //调用其他方法时使用的寄存器个数
unshort triesSize; //try/catch异常块个数
uint debugInfoOff; //调试信息的偏移
uint insnsSize; //指令集个数
ushort insns[1]; //指令集数组,变长数组
}
DexClassData树型结构图:

三、调试dex2jar工程
1. 将dex2jar源码导入IntelliJ IDEA,导入后IntelliJ IDEA会自动查找对应 Grable并下载,需要比较长的时间等待
源码地址: https://github.com/pxb1988/dex2jar
2. 选中Grable中的dex2jar/dex2jar/Tasks/other/antlr2java进行编译

3. 点击工具栏的 Project Structure, 然后选择Modules -> d2j-smali -> build,然后点击Excluded

4. 选择 build/generated-sources/antlr, 然后点击 Sources

5. 最后打开Excluded Gradle Task弹出对话框,运行clean distZip 命令

执行完Gradl clean distZip命令后会在\dex2jar-2.x\dex-tools\build\distributions目录下生成 dex-tools-2.1-SNAPSHOT.zip,压缩包内是编译完后生成的jar文件和一些配置信息文件。大家请参考dex2jar.sh文件,它向我们说明需要使用lib目录下的所有jar文件和入口函数com.googlecode.dex2jar.tools.Dex2jarCmd 才能将dex文件转换成jar文件

6.将dex文件转换成jar文件需要执行转换命令
格式如下:
java -Xms512m -Xmx1024m -classpath .\lib\*.jar “com.googlecode.dex2jar.tools.Dex2jarCmd” classdex.dex
根据以上的命令,来配置调试参数,设置如下:

7.设置完成后,就可以开始调试

四、dex2jar反编译失败原因分析
1.首先我们从解包失败的错误异常入手,定位崩溃处的代码。

通过错误提示可以定位到dex2jar崩溃处的代码,源码位置如下:
dex-ir\src\main\java\com\googlecode\dex2jar\ir\TypeClass.java
2. 在崩溃的函数处下断点,开始调试。

a)通过抛出的异常的说明“cant not merge I and Z”,以及整个调用堆栈。
我们可以看出造成这个异常的原因是函数调用时,实参的类型和形参类型不匹配引起的。因为在Java语法中,将实参是布尔类型传递给形参是int类型。这样是不合法的,所以导致dex2jar在检查的参数类型的时候失败。
b)知道了崩溃的原因,那我们就需要确定它具体是使用怎样的方法做到的,通过dex2jar生成的error异常信息详细说明文件得知该dex文件中的每一个函数头部都加了一句这样的代码Exit.b(Exit.a())请看Ida,现在大致能猜到混淆者所做的工作:
1.首先解析dex文件格式,定位到DexCode结构中的insns成员
2.向代码中添加一个类成员对象名字叫Exit,然后添加代码Exit.b(Exit.a())

3.明白了怎么添加干扰代码,接下来分析一下dex2jar的工作流程,dex2jar转换成jar文件这个过程中会验证,函数调用时的形参和实参的合法性,请看下图,解析到INVOKE_开头的指令时,会开始解析返回值,供给参数,和实参等信息,具体逻辑和代码大家有兴趣可以详细地研究一下dex2jar源码。

4.merge负责的工作是参数类型的验证,如果两个类型相同,返回形参的类型,形参为UNKONW返回实参,实参为UNKONW返回形参,两个类型都不相同,则匹配异常

5.最后在dex2jar里添加代码,使dex文件能正确的被反编译成功。这里给出一段可以成功让dex2jar反编译的出jar文件的代码(其实方法有很多)

下图是成功反编译的jar文件

Android程序的反编译对抗研究的更多相关文章
- Android开发周报:反编译对抗研究、动手制作智能镜子
新闻 <Android Wear落地中国 谷歌增强安卓生态控制力> :9月8日,由摩托罗拉推出的智能手表Moto 360二代作为国内发售的第一款搭载官方Android Wear的设备,正式 ...
- Android程序apk反编译破解方法
简短不割了,我们直接奔主题吧. 把apktool-install-windows-r05-ibot文件里的两个文件剪切到apktool1.5.1目录. 新建一个文件夹把需要破解的apk应用程序放进去. ...
- android apk 防止反编译技术第四篇-对抗JD-GUI
又到周末一个人侘在家里无事可干,这就是程序员的悲哀啊.好了我们利用周末的时间继续介绍android apk防止反编译技术的另一种方法.前三篇我们讲了加壳技术(http://my.oschina.net ...
- 反编译Android APK及防止APK程序被反编译
怎么逆向工程对Android Apk 进行反编译 google Android开发是开源的,开发过程中有些时候会遇到一些功能,自己不知道该怎么做,然而别的软件里面已经有了,这个时候可以采用反编译的方式 ...
- 转: android apk 防止反编译技术(1~5连载)
转: android apk 防止反编译技术 做android framework方面的工作将近三年的时间了,现在公司让做一下android apk安全方面的研究,于是最近就在网上找大量的资料来学习. ...
- android apk 防止反编译技术第一篇-加壳技术
做android framework方面的工作将近三年的时间了,现在公司让做一下android apk安全方面的研究,于是最近就在网上找大量的资料来学习.现在将最近学习成果做一下整理总结.学习的这些成 ...
- android apk 防止反编译技术第二篇-运行时修改字节码
上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...
- android apk 防止反编译技术第三篇-加密
上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...
- android apk 防止反编译技术第二篇-运行时修改Dalvik指令
上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...
随机推荐
- 路径方案数 [SPFA,拓扑排序]
路径方案数 [题目描述] 给一张无向图,n 个点和 m 条边,cyb 在 1 号点,他要去 2 号点, cyb 可以从 a 走到 b,当且仅当 a 到 2 的最短路,比 b 到 2 的最短路长. 求 ...
- 浅谈MVVM模式和MVP模式——Vue.js向
浅谈MVVM模式和MVP模式--Vue.js向 传统前端开发的MVP模式 MVP开发模式的理解过程 首先代码分为三层: model层(数据层), presenter层(控制层/业务逻辑相关) view ...
- FFTW3学习笔记2:FFTW(快速傅里叶变换)中文参考
据说FFTW(Fastest Fourier Transform in the West)是世界上最快的FFT.为了详细了解FFTW以及为编程方便,特将用户手册看了一下,并结合手册制作了以下FFTW中 ...
- 「WC2018即时战略」
「WC2018即时战略」 题目描述 小 M 在玩一个即时战略 (Real Time Strategy) 游戏.不同于大多数同类游戏,这个游戏的地图是树形的.也就是说,地图可以用一个由 \(n\) 个结 ...
- 「APIO2018选圆圈」
「APIO2018选圆圈」 题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1, c_2, \ldots, c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径 ...
- [P1768]天路(分数规划+SPFA判负环)
题目描述 “那是一条神奇的天路诶~,把第一个神犇送上天堂~”,XDM先生唱着这首“亲切”的歌曲,一道猥琐题目的灵感在脑中出现了. 和C_SUNSHINE大神商量后,这道猥琐的题目终于出现在本次试题上了 ...
- CodeForces - 1009D Relatively Prime Graph
题面在这里! 直接暴力找点对就行了,可以证明gcd=1是比较密集的,所以复杂度略大于 O(N log N) #include<bits/stdc++.h> #define ll long ...
- [HDU5965]扫雷
[HDU5965]扫雷 题目大意: 一个\(3\times n(n\le10000)\)的扫雷,第\(2\)排没有雷.告诉你第\(2\)排上的数,问有几种埋雷的方案? 思路: 动态规划. 将\(1,3 ...
- [转]怎么把一个textview的背景图片设置成圆角的?
在drawable文件夹下新建一个文件设置背景样式代码:在drawable文件夹下面新建text_view_border.xml<?xml version="1.0" ...
- mysqldump导出CSV格式及where导出时间范围问题解决
众所周知,mysqldump不但可以导出sql格式,还可以导出csv格式. 导出CSV格式的具体使用如下命令. mysqldump -uroot -ppassword -S /tmp/mysql999 ...