android tinker热更与AndResGuard混淆适配
导读 随着项目越来越大,APK的包也越来越大,前几天对APK进行减包处理,其中有一个资源混淆的减包手段,作用有两点:一是通过混淆资源ID长度同时利用7z深度压缩,减小了apk包大小;二是混淆后在安全性方面有一点提升,提高了逆向破解难度。但项目原来引进了Tinker热更新,这样就存在以下两个问题:
1、资源混淆对热更的包是否有影响,会不会热更后出现找不到资源的情况
2、如果没有影响,Tinker生成补丁后会产生新的基准包,tinker默认是不进行资源混淆的assemble命令执行,如何自动实现执行资源混淆
问题一:资源混淆对热更的包是否有影响,会不会热更后出现找不到资源的情况
tinker主要对dex文件进行处理,AndResGuard主要对资源文件以及resources.arsc进行混淆,在原理上互不影响,但是热更也是产生一个newAPK后与基准oldAPK进行比较后产生patch文件,oldAPK推出历史,newAPK成为下一个热更的基准包,而且newAPK需要再重新资源混淆后才作为基准包,这就是问题二的由来。
问题二:资源混淆对热更的包是否有影响,会不会热更后出现找不到资源的情况
问题二需要解决三个问题:
(1) 以已经资源混淆的包作为基准包
(2) newAPK需要资源混淆
(3) newAPK作为新的基准包
http://www.cnblogs.com/yyangblog/p/6268818.html
http://w4lle.github.io/2017/01/22/gradle-modules/?utm_source=tuicool&utm_medium=referral
http://blog.csdn.net/maosidiaoxian/article/details/42417779
注意:资源混淆的插件一定要配置在tinker插件前面,应为tinker热更需要依赖资源混淆后的APK
附以上问题脚本源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| ext { bakResguard = file("${buildDir}${File.separator}bakApk${File.separator}resguard") }
android.applicationVariants.all { variant -> String taskBaseName = variant.baseName def taskName = variant.name tasks.all { if (variant.buildType.name == 'release') { boolean hasFlavors = false if (variant.productFlavors.size() > 0) { hasFlavors = true }
def favor if (hasFlavors) { favor = taskBaseName.split('-')[0] } if ("tinkerPatch${taskName.capitalize()}".equalsIgnoreCase(it.name)) { def resguardTask tasks.all { if (it.name.startsWith('resguard')) { resguardTask = it; } }
it.doLast { copyBaseApk(hasFlavors,taskBaseName,favor) } it.dependsOn resguardTask }
if ("resguard${taskName.capitalize()}".equalsIgnoreCase(it.name)) { it.doLast { copyBaseApk(hasFlavors,taskBaseName,favor) } } } } }
def copyBaseApk(def hasFlavors,def taskBaseName,def favor){ def date = new Date().format("MMdd-HH-mm-ss") def outPath = bakResguard.absolutePath + File.separator + "app-${date}" if(hasFlavors){ outPath = outPath + File.separator +favor } File file = new File(outPath); if (!file.exists()) { file.mkdirs() }
copy { def dd = "${buildDir}${File.separator}outputs${File.separator}apk${File.separator}AndResGuard_${project.getName()}-${taskBaseName}${File.separator}${project.getName()}-${taskBaseName}_aligned_signed.apk" print '<<<<<<<<<<<<funccc <<<<<<' + dd + '\n' def aa = outPath print '<<<<<<<<<<<<funccc <<<<<<' + aa + '\n' from dd into aa rename { String fileName -> fileName.replace("${project.getName()}-${taskBaseName}_aligned_signed.apk", "${project.getName()}-${taskBaseName}.apk") }
def mappingPath if(hasFlavors){ mappingPath ="${buildDir}${File.separator}outputs${File.separator}mapping${File.separator}$favor${File.separator}release${File.separator}mapping.txt" }else{ mappingPath ="${buildDir}${File.separator}outputs${File.separator}mapping${File.separator}release${File.separator}mapping.txt" } from mappingPath into outPath rename { String fileName -> fileName.replace("mapping.txt", "${project.getName()}-${taskBaseName}-mapping.txt") }
def RPath if(hasFlavors){ RPath ="${buildDir}${File.separator}intermediates${File.separator}symbols${File.separator}$favor${File.separator}release${File.separator}R.txt" }else{ RPath ="${buildDir}${File.separator}intermediates${File.separator}symbols${File.separator}release${File.separator}R.txt" } from RPath into outPath rename { String fileName -> fileName.replace("R.txt", "${project.getName()}-${taskBaseName}-R.txt") }
from "${buildDir}${File.separator}outputs${File.separator}apk${File.separator}AndResGuard_${project.getName()}-${taskBaseName}${File.separator}resource_mapping_${project.getName()}-${taskBaseName}.txt" into outPath rename { String fileName -> fileName.replace("resource_mapping_${project.getName()}-${taskBaseName}.txt", "${project.getName()}-${taskBaseName}-resource_mapping.txt") } } }
|