APK加壳原理简述

先把核心原理记录一下,代码随后再补。

PRE、dex文件结构知识和加壳原理
先看下dex文件的基本结构
这里写图片描述
对于加壳主要关注3个关键字:
1)checksum
文件校验码,使用alder32算法,校验文件除了maigc和checksum外余下的所有文件区域,用于检查文件错误。
2)signature
使用SHA-1算法hash除了magic ,checksum和signature外余下的所有文件区域,用于唯一识别本文件 。
3)file_size
dex文件的大小。
为什么说只需要关注这三个字段呢?
因为我们需要将一个文件(加密之后的源Apk)写入到Dex中,那么我们肯定需要修改文件校验码(checksum).因为他是检查文件是否有错误。那么signature也是一样,也是唯一识别文件的算法。还有就是需要修改dex文件的大小。
不过这里还需要一个操作,就是标注一下我们加密的Apk的大小,因为我们在脱壳的时候,需要知道Apk的大小,才能正确的得到Apk。那么这个值放到哪呢?这个值直接放到文件的末尾就可以了。
所以总结一下我们需要做:修改Dex的三个文件头,将源Apk的大小追加到壳dex的末尾就可以了。
我们修改之后得到新的dex文件样式如下:
这里写图片描述

下面是代码和项目流程,有兴趣的同学可以以此为需求自己研究coding:
1、制作原始项目的apk,这里称作original.apk;
2、制作一个壳项目(具体功能见ps),编译通过后得到它的classes.dex文件,这里称作shell.dex,而壳项目的apk称作shell.apk(需要签名);
3、制作一个加壳工具(java工程就可以),按照以下流程工作:
1)读取original.apk的byte流,并加密;
2)读取shell.dex的byte流;
3)new一个新的byte数组,长度为1)和2)的长度之和+4,因为我们要在shell.dex中保存original.apk的长度;
4)在new byte数组中写入2),写入1),写入1)的长度;
5)根据dex文件的结构,修改checksum文件头、Signature文件头和file_size文件头,最终生成一个新的classes.dex;
4、替换掉2中的shell.apk中的classes.dex,并使用工具重新签名;
5、生成的新签名apk就是我们加壳过的apk了。

PS、壳项目的功能
1)获取shell.dex中的original.apk,解密后在指定的内部文件夹中重新生成original.apk
2)hook ActivityThread中的currentActivityThread,拿到主线程实例;
3)换掉1)中的mClassLoader,使其可以加载外部的apk(参考插件化原理),这里要的是加载就是1)中的original.apk;
(上面三个流程在shell.apk的application中的attachBaseContext方法中执行)
4)动态加载original.apk中的Application,替换掉系统组件中所有的application信息;

PS、以上壳项目是在java层实现的,更深入的可以考虑在jni层来实现。该方法同样适用于jar包加壳~
动态加载技术真的是很重要,我们已经看过很多安卓核心技术的本质都是基于动态加载的。而这些创意的源泉,都来自熟读安卓源码,了解系统核心组件的实现流程。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值