android加固系列—6.仿爱加密等第三方加固平台之动态加载dex防止apk被反编译
【版权所有,转载请注明出处。出处:http://www.cnblogs.com/joey-hua/p/5402599.html 】
此方案的目的是隐藏源码防止直接性的反编译查看源码,原理是加密编译好的最终源码文件(dex),然后在一个新项目中用新项目的application启动来解密原项目代码并加载到内存中,然后再把当前进程替换为解密后的代码,art模式下也没问题。好了,废话不多说,来看代码,下面是最终想运行的项目,也称为原项目:

这是原项目的目录,项目名叫Hello,就两个activity,第一个activity的布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="我是Hello项目的FirstActivity"
android:textSize="20sp"
/>
<Button
android:id="@+id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="跳转"
/>
</LinearLayout>
非常简单,没什么好说的,运行效果如下:

接下来介绍dex加密工具,名字叫DexJiami,关键代码如下:
private static final String root = "C:";
private static final String path = root + "/Users/lenovo/Documents/mygithub/android-protection/LoadDex/dexFileTmp";
private static final String path_encrypt_source = path + "/mycode.jar";
private static final String path_encrypt = path+"/mycode.dat";
private static String cmd_dex2jar = "cmd /c "+root+" && cd "+path+ " && jar cvf "
+ path_encrypt_source + " classes.dex"; private static String key="GiEhjghmZIO7RTWyycQ9PQ==";
/*
* 需要生成新的秘钥时使用
*/
// static {
// try {
// key = AESUtils.getSecretKey();
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
这个path就是你准备把dex放置的一个临时文件夹,生成加密文件用;key的值就是加密和解密用的秘钥,咱们用的AES对称加解密,这里的key值是通过这个静态块来生成的,生成一次就行了,直接copy到引号,如果想生成新的秘钥就去掉注释行。
public static void main(String[] args) throws Exception {
dex2Jar(); //给dex打成jar包
encrypt(); //对jar加密并生成为.dat文件
}
如上,这是从我公司项目的自动化打包工具上裁剪了的,现在整个工具就两个方法,第一个是把原项目的源码dex文件打成jar包,然后再对jar包用key值加密并生成dat文件。
加密工具使用方法,先从原项目的/bin目录下找到classes.dex,这个文件就是原项目所有的java源码生成的最终的字节码文件,android系统运行你写的程序就是加载这个dex文件。把它拷贝到你自定义的dexFileTmp文件夹,然后run这个加密工具,最终生成的文件如下:

最终要用的就是mycode.dat这个文件,怎么用待会再说,得先介绍第二个android项目DexLoader,这里称为启动项目,先介绍java版的,后面再介绍jni版,先看下java版的目录结构:

这里注意,除了上面的这几个java文件不一样之外,所有的资源文件和AndroidManifest都是直接从原项目拷贝过来的,还有就是把上面的mycode.dat文件拷贝至启动项目的assets目录下,下面的关键代码为首先在进程的系统文件夹下面创建一个自定义的app_cache文件夹,作为加密文件的中转文件夹,然后解密dat文件并变成jar,变成jar包后系统才能识别并把classes.dex抽取出来。
File odex = this.getDir("cache", MODE_PRIVATE);
String odexPath = odex.getAbsolutePath();
System.out.println("odexPath--->" + odexPath);
try {
Util.decryptFile(this, odexPath+"/mycode.jar");
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
接下来的关键代码如下,把解密后的jar包,也就是原项目的代码加载至内存:
DexClassLoader dLoader = new DexClassLoader(odexPath+"/mycode.jar", odexPath,
"/data/data/" + base.getPackageName() + "/lib/",
base.getClassLoader().getParent());
接下来程序就会走onCreate方法,大量用到了RefInvoke类,这是一个专门调用反射的类,目的是获取系统的private变量和执行private方法,就不多介绍了,最终替换当前进程的代码为刚才加载至内存的代码,最终程序运行如下:

而且还可以跳转至第二个activity。大功告成!
下面介绍一下Jni版,先看下目录结构

对比java版可以看出,解密的代码不见了,其实是被封装到了jni层,下面是java层的关键代码:
static{
System.loadLibrary("load");
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Object currentActivityThread = RefInvoke.invokeStaticMethod(
"android.app.ActivityThread", "currentActivityThread",
new Class[] {}, new Object[] {});
String packageName = getPackageName();
Map mPackages = (Map) RefInvoke.getFieldOjbect(
"android.app.ActivityThread", currentActivityThread,
"mPackages");
WeakReference wr = (WeakReference) mPackages.get(packageName);
run(this, base, "/data/data/"+ base.getPackageName() + "/lib/", base.getClassLoader().getParent(),wr.get());
}
private native String run(Application wrapper, Context context, String libPath,ClassLoader classLoader, Object obj);
可以对比java版的代码,attachBaseContext里的部分关键代码都封装在run函数里,目的就是隐藏解密算法。jni层的代码就不多介绍了,代码原理本身和java版是一样的,只不过多了在jni层获取java层的对象和方法的过程。后续工作还需要对so文件加壳及反调试,本版本中并没有,当然本版本也有一定的安全作用,毕竟可以防止反编译apk直接查看源码。运行结果和上面一致,也可以跳转到第二个activity。
最后我们再来看下爱加密处理后的源码,将爱加密处理后的apk解压,对classes.dex执行反编译查看源码,以及assets目录下的ijiami.dat,如下图:


分析而知爱加密也是运用了动态解密加载dex文件并替换当前进程的方式实现了隐藏原项目源码的行为。

【加密工具】
【原项目】
【jni版启动项目】
android加固系列—6.仿爱加密等第三方加固平台之动态加载dex防止apk被反编译的更多相关文章
- Android应用安全之外部动态加载DEX文件风险
1. 外部动态加载DEX文件风险描述 Android 系统提供了一种类加载器DexClassLoader,其可以在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件.外部动态加载DEX文件 ...
- Android动态加载jar、apk的实现
前段时间到阿里巴巴参加支付宝技术分享沙龙,看到支付宝在Android使用插件化的技术,挺好奇的.正好这几天看到了农民伯伯的相关文章,因此简单整理了下,有什么错误希望大神指正. 核心类 1.1 ...
- 【Android】Android动态加载Jar、APK的实现
本文介绍Android中动态加载Jar.APK的实现.而主要用到的就是DexClassLoader这个类.大家都知道Android和普通的Java虚拟机有差别,它只能加载经过处理的dex文件.而加载这 ...
- Android 插件技术:动态加载dex技术初探
1.Android动态加载dex技术初探 http://blog.csdn.net/u013478336/article/details/50734108 Android使用Dalvik虚拟机加载可执 ...
- [转载] Android动态加载Dex机制解析
本文转载自: http://blog.csdn.net/wy353208214/article/details/50859422 1.什么是类加载器? 类加载器(class loader)是 Java ...
- Unity3D的坑系列:动态加载dll
我现在参与的项目是做MMO手游,目标平台是Android和iOS,iOS平台不能动态加载dll(什么原因找乔布斯去),可以直接忽略,而在Android平台是可以动态加载dll的,有了这个就可以实现代码 ...
- Android Apk的反编译和加密
这几天在上海出差,忙里偷闲学习了一下Apk的反编译工具的基本使用.下面就简单介绍一下如何将我们从网上下载的Apk文件进行反编译得到我们想要获得的资源文件和源码. Android的应用程序APK文件说到 ...
- Android 动态加载(防止逆向编译) jar混淆加密
最近工作中接到了一个研究防止逆向编译的任务.研究了几天资料,最后基本实现了防破解技术,在这个工程中,也略有一些心得体会,现整理下来分享,供大家探讨参考研究.文中如有纰漏.失实之处,请大家及时给与指正. ...
- Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类
前言 近期做换肤功能,由于换肤程度较高,受限于平台本身,实现起来较复杂,暂时搁置了该功能,但也积累了一些经验,将分两篇文章来写这部分的内容,欢迎交流! 关键字:Android动态加载 声明 欢迎转载, ...
随机推荐
- 【转】FastCgi与PHP-fpm关系
刚开始对这个问题我也挺纠结的,看了<HTTP权威指南>后,感觉清晰了不少. 首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者. ...
- 纯Shading Language绘制飞机火焰效果
上篇<纯Shading Language绘制HTML5时钟>体现了GLSL可编程性特点,但没有体现GLSL可编程出各种酷炫效果的特点,今天我们将用纯Shading Language绘制火焰 ...
- 《ASP.NET SignalR系列》第三课 SignalR的支持平台
从现在开始相关文章请到: http://lko2o.com/moon 接着第二课:<ASP.NET SignalR系列>第二课 SignalR的使用说明 一.服务器系统要求 SignalR ...
- C++二维码相关库编译
一.瞎想 坐在地铁上闲来无聊,突然想到了二维码,顺手就百度了下相关的资料,目前C++二维码相关的库不多,也就zbar(开源中国上下了半天也没下载下来).zxing,不过这两个库据说都是解析二维码的,不 ...
- 手机端布局 - rem计算
功能说明:以一个640px的宽度为基准,最小不低于320px,当大于640px时,让其在页面中居中. 如果正处于640 - 320之中的,都按照js进行等比例的缩放. 这里我们规定1rem = 100 ...
- 打开Windows10网络发现或是文件打印共享
新安装的Windows10,已经设置好的目录共享,用户说访问不了.就连管理员的权限使用盘符加"$"也无法访问.原来Windows10默认情况之下,是把网络发现以及文件打印共享关闭的 ...
- Winform开发框架之读卡器和条码扫描枪的数据接收处理
在我们开发一些项目的时候,一般需要一些外围的设备进行数据处理,如ID/IC读卡器获取卡号.激光条码扫描枪.USB摄像头.USB方式的小票据打印机(POS打印机).USB来电录音盒.普通打印机等一系列附 ...
- 基于MVC4+EasyUI的Web开发框架经验总结(5)--使用HTML编辑控件CKEditor和CKFinder
Web开发上有很多HTML的编辑控件,如CKEditor.kindeditor等等,很多都做的很好,本文主要介绍在MVC界面里面,CKEditor的配置和使用.CKEditor的前身是FCKEdito ...
- ASP.NET Core 开发-Logging 使用NLog 写日志文件
ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 .NET Core 和 ASP.NET Core . ASP.NET Core已经内置了日志支持,可以 ...
- iOS 学习笔记二【cocopods安装使用和安装过程中遇到的问题及解决办法】【20160725更新】
在osx 10.11之前cocopods问题不多,但是升级到11之后的版本,之前的cocopods大多用不了,需要重新安装,对于我这种使用测试版系统的技术狂来说,每次都需要重新安装很多东西, 当然,c ...