背景介绍:
每一个app的迭代都会随着功能的增加完善,所需要的资源文件也越来越多,这就导致发到市场上的包也越来越大。
对于用户而言,用户更希望装小的安装包。而资源混淆就是针对资源做的一个优化,从而减小包的大小。
原理概要:
通过对资源文件的重命名以及采用7zip压缩重现打包的方法,从而减少安装包的大小。
备注:本分享主要是解析第三方工具的实现和使用。
https://github.com/shwenzhang/AndResGuard/blob/master/README.zh-cn.md
资源混淆工具的逻辑流:
1.通过命令的形式获取运行时的环境
2.设置运行时路径
3.读取命令行给出的配置参数,一般混淆命令如:
4.进行资源混淆,重新压缩打包
资源混淆工具的核心代码:
用法一:
使用已存在的jar,然后用命令(推荐,简单,成本低)
java -jar andresguard.jar input.apk
若想指定配置文件或输出目录:
java -jar andresguard.jar input.apk -config yourconfig.xml -out output_directory
若想指定签名信息或mapping信息:
java -jar andresguard.jar input.apk -config yourconfig.xml -out
output_directory -signature signature_file_path storepass_value
keypass_value storealias_value -mapping mapping_file_path
若想指定7zip或zipalign的路径(若已设置环境变量,这两项不需要单独设置):
java -jar andresguard.jar input.apk -7zip /shwenzhang/tool/7za -zipalign /shwenzhang/sdk/tools/zipalign
若想用7zip重打包安装包,同时也可指定output路径,指定7zip或zipalign的路径(此模式其他参数都不支持):
java -jar andresguard.jar -repackage input.apk -out output_directory
-7zip /shwenzhang/tool/7za -zipalign /shwenzhang/sdk/tools/zipalign
备注:本地要有混淆工具的jar包。
用法二:
作为第三方工具用在项目中(不推荐使用,配置不小心会出问题,还增加工作量)
运行andresguard/resguard的gradle任务,可以得到资源混淆的安装包 命令行可直接运行./gradlew resguard
备注:这只是在gradle当中一个关键配置。
实例:
结果:
收益:
风险:
潜在风险:
处理不当会crash!!!
备注:尤其是针对大型app,资源文件特别多,三方插件也多,且代码不规范,资源引用写死在代码中的。
原因:
根据前面资源混淆的原理我们知道,减少大小的主要方案就是重命名资源文件,因此就会存在资源文件找不到的问题,一旦找不到,一般来说都会崩溃!
自动化工具背景:
通过资源混淆的原理可以知道,资源混淆最大的风险就是如果白名单不完全,那么任何一个资源的丢失都会让程序直接crash,这种风险是很高的。并且针对于
我们的测试,即便是全功能测试也不能一一覆盖所有的资源。对于这种存在又不可控的风险使资源混淆方案实行起来有点不可行。然后资源混淆的利益则是可观的,
为此便想出了一个方案就是人覆盖不了的case那就让工具去实现。所以就诞生了资源混淆的自动化测试工具。
备注:自己研发的。
开发原理:
1.过滤代码工程里面所有有效的白名单(有效:指的是去重和一些冗余的资源以及config文件通过全匹配已经存在的,因为一些id, color,string, dimen等不是单纯的文件而是某个文件中存在的字段)
2.首先匹配混淆后的apk文件里的所有资源文件,如果存在则pass,如果不存在则fail并且会添加到failed的列表中
3.如1所说有些并非是单纯的文件,所以再去匹配config文件里面的白名单,如果存在就pass,并从failed的列表中移除。(通过实验证实是可行的)。
4.最后输出匹配结果,failed的列表为空则pass,否则failed。并且会输出failed的列表。
技术实现:
1.采用Java开发,eclipse平台。
2.过滤所有的java文件
3.过滤所有的jar文件
4.进行匹配测试
技术难点:
1.如何读取jar文件和apk文件
2.如何判断过滤出来的白名单就是全部的。
3.如何过滤jar文件的白名单,因为jar文件读取后都是class文件,class文件读出来都是乱码。
技术难点攻破:
首先解压:
通过cmd命令调起的方式来实现这个难点。
问题1. 用jad命令进行转换必须是实实在在解压后的class文件。
问题2. 用jad实现必须环境之前得由jad的可运行文件,必须是在jad所在的根目录下才能执行此命令。
解决以上问题,先下载jad的可执行文件,网上有很小,下起来也比较方便。然后代码中写入jad所在的目录,方便cmd的切换。
在RunJADCommand.java类里:
再者,在调起此命令之前我们先得解压jar包,一遍解压一遍转换,然后再读取。读取完后便自动删除解压和转换后的文件。
转换class文件为Java文件:
查找实现:
工具使用:
修改完你自己的指定文件输入输出,直接运行主工程即可:目前是Java工程,这个测试不会流到测试手中,开发人员自己完成测试,分分钟的事。
Java console会详细输出
备注:本地也会以文件形式有输出
附件:如有需要请联系本人要自动化测试的代码。