[TOC]
- 将
java
代码转换为Dalvik
字节码; - 将
res
资源文件、AndroidManifest.xml
等配置文件编译为二进制文件。
- 将
DEX
文件转换为jar
包或者Smali
文件; - 将二进制资源文件还原为资源源码文件。
Apktool
dex2jar
jd-gui
作用:反编译DEX
为smali
文件,反编译资源文件,支持重打包。
# 解包apk
java -jar apktool.jar d demo.apk -o out
# 重新打包
java -jar apktool.jar b out # out 为上面的输出目录
# 把DEX转换为jar包
d2j-dex2jar.bat demo.apk
jar
包的图形化阅读工具:
- 逆向分析:漏洞挖掘、协议分析;
- 二次打包:盗版、破解。
- 代码混淆:
Java
代码、C/C++
代码、JS/HTML
代码; - 应用加固:
DEX
文件、SO
文件、资源文件。
动态加载 --> DEX
内存加载 --> DEX
指令抽取 --> 虚拟机加固 --> JAVA2C
Android
加壳框架原理为Proxy/Delegate Application
,即使用自定义的代理Application
类作为程序入口(修改AndroidManifest.xml
),在代理Application
中完成壳的解密操作,最后启动原来的Application
。
ProxyApplication
:框架会提供一个ProxyApplication
抽象基类(abstract class
),使用者需要继承这个类,并重载其initProxyApplication()
方法,在其中改变surrounding
,如替换ClassLoader
等;DelegateApplication
:即应用原有的Application
,应用从getApplicationContext()
等方法中取到的都是DelegateApplication
。
修改AndroidManifext.xml
入口:
<!-- old AndroidManifest.xml -->
<Application
android:name=".MyApplication"
android:icon="@drawable/icon"
android:label="@string/app_name"></Application>
<!-- new AndroidManifest.xml -->
<Application
android:name=".MyProxyApplication"
android:icon="@drawable/icon"
android:label="@string/app_name"></Application>
代理Application
:
public abatract class ProxyApplication extends Application {
protected abstract void initProxyApplication();
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
initProxyApplication();
}
//...
}
initProxyApplication
实现内容:
- 内存加载
DEX
:加载原Application
;ClassLoader
设置;Application
引用替换。
- 内存加载
DEX
文件:通过Dalvik
、ART
虚拟机JNI
接口内存加载被加密隐藏的DEX
文件; - 设置
ClassLoader
:将DEX
文件内存加载产生的mCookie
放入到ClassLoader
中(MutiDex
); - 加载
Application
:基于替换后的ClassLoader
查找原始Application
类并生成实例; Application
还原:将换API
层的所有Application
引用替换为原始Application
.