Andriod资源混淆的一次体验

通常情况下,Android中的混淆有代码混淆和资源混淆。

代码混淆比较简单,只要打开 minifyEnabled开关,并且需要时指定一些混淆规则就可以了;

相比之下,资源混淆没有那么简单,因为不能简单的修改res文件夹下的资源文件的文件名,因为在开发时每一个资源文件都对应了R文件中的id, 打包后会生成resource.asrc文件,每一个资源文件都在resource.asrc文件中有对应记录。如果要修改资源文件名,对应的也需要修改resource.asrc文件中的记录,这样很麻烦,而且容易出错。如果我们了解了resource.asrc文件的格式,完全可以自己手写这样的操作。

resource.asrc文件的格式如下:

但是今天我要介绍的不是从头开始自己实现上面的原理,而是介绍一个已经实现了上面操作的开源库,它就是AndResGuard.

粘上github地址:

https://github.com/shwenzhang/AndResGuard

使用微信AndResGuard优化资源 

过程其实很简单:

1.在project的gradle中添加依赖: 

//微信资源混淆工具,注意版本不要太低,太低的话在解析resource.arsc的时候会报错,是因为使用了低版本的appTool
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.16'

 

 

2.在app的gradle中添加配置:

apply plugin: 'AndResGuard'

andResGuard {
    // mappingFile = file("./resource_mapping.txt")
    mappingFile = null
    use7zip = true
    useSign = true
    // it will keep the origin path of your resources when it's true
    keepRoot = false

    //白名单,不混淆的资源
    whiteList = [
            // your icon
            "R.drawable.icon",
            // for fabric
            "R.string.com.crashlytics.*",
            // for google-services
            "R.string.google_app_id",
            "R.string.gcm_defaultSenderId",
            "R.string.default_web_client_id",
            "R.string.ga_trackingId",
            "R.string.firebase_database_url",
            "R.string.google_api_key",
            "R.string.google_crash_reporting_api_key"
    ]
    compressFilePattern = [
            "*.png",
            "*.jpg",
            "*.jpeg",
            "*.webp",
            "*.gif",
            "resources.arsc"
    ]
    sevenzip {
        artifact = 'com.tencent.mm:SevenZip:1.2.10'
        //path = "/usr/local/bin/7za"
    }
}

 

AndResGuard优化使用了7zzip工具。 

配置好之后在as右侧的gradle选项中会出现andresguard的task:

 

我们可以选择需要打包的apk类型进行优化;这里直接打包release版本的, 双击resguardRelease 

看一下task流程: 

 

Executing tasks: [resguardRelease]

Parallel execution is an incubating feature.

> Configure project :app
normal
useNewCruncher has been deprecated. It will be removed in a future version of the gradle plugin. New cruncher is now always enabled.
WARNING: API 'variant.getJavaCompile()' is obsolete and has been replaced with 'variant.getJavaCompileProvider()'.
It will be removed at the end of 2019.
For more information, see https://d.android.com/r/tools/task-configuration-avoidance.
To determine what is calling variant.getJavaCompile(), use -Pandroid.debug.obsoleteApi=true on the command line to display a stack trace.

> Task :app:preBuild UP-TO-DATE
> Task :app:preBeta_AppReleaseBuild UP-TO-DATE
> Task :app:compileBeta_AppReleaseAidl SKIPPED
> Task :app:compileBeta_AppReleaseRenderscript UP-TO-DATE
> Task :app:checkBeta_AppReleaseManifest UP-TO-DATE
> Task :app:generateBeta_AppReleaseBuildConfig UP-TO-DATE
> Task :app:prepareLintJar UP-TO-DATE
> Task :app:generateBeta_AppReleaseSources UP-TO-DATE
> Task :app:javaPreCompileBeta_AppRelease UP-TO-DATE
> Task :app:mainApkListPersistenceBeta_AppRelease
> Task :app:generateBeta_AppReleaseResValues UP-TO-DATE
> Task :app:generateBeta_AppReleaseResources UP-TO-DATE
> Task :app:mergeBeta_AppReleaseResources UP-TO-DATE
> Task :app:createBeta_AppReleaseCompatibleScreenManifests
> Task :app:processBeta_AppReleaseManifest
> Task :app:processBeta_AppReleaseResources
> Task :app:compileBeta_AppReleaseJavaWithJavac UP-TO-DATE
> Task :app:compileBeta_AppReleaseNdk SKIPPED
> Task :app:compileBeta_AppReleaseSources UP-TO-DATE
> Task :app:mergeBeta_AppReleaseShaders UP-TO-DATE
> Task :app:compileBeta_AppReleaseShaders UP-TO-DATE
> Task :app:generateBeta_AppReleaseAssets UP-TO-DATE
> Task :app:mergeBeta_AppReleaseAssets UP-TO-DATE
> Task :app:validateSigningBeta_AppRelease UP-TO-DATE
> Task :app:signingConfigWriterBeta_AppRelease UP-TO-DATE
> Task :app:transformClassesWithDexBuilderForBeta_AppRelease UP-TO-DATE
> Task :app:transformClassesWithMultidexlistForBeta_AppRelease UP-TO-DATE
> Task :app:transformDexArchiveWithDexMergerForBeta_AppRelease UP-TO-DATE
> Task :app:mergeBeta_AppReleaseJniLibFolders UP-TO-DATE
> Task :app:transformNativeLibsWithMergeJniLibsForBeta_AppRelease UP-TO-DATE
> Task :app:transformNativeLibsWithStripDebugSymbolForBeta_AppRelease UP-TO-DATE
> Task :app:processBeta_AppReleaseJavaRes NO-SOURCE
> Task :app:transformResourcesWithMergeJavaResForBeta_AppRelease UP-TO-DATE
> Task :app:packageBeta_AppRelease
> Task :app:assembleBeta_AppRelease
> Task :app:preRelease_AppReleaseBuild UP-TO-DATE
> Task :app:compileRelease_AppReleaseAidl SKIPPED
> Task :app:compileRelease_AppReleaseRenderscript UP-TO-DATE
> Task :app:checkRelease_AppReleaseManifest UP-TO-DATE
> Task :app:generateRelease_AppReleaseBuildConfig UP-TO-DATE
> Task :app:generateRelease_AppReleaseSources UP-TO-DATE
> Task :app:javaPreCompileRelease_AppRelease UP-TO-DATE
> Task :app:mainApkListPersistenceRelease_AppRelease
> Task :app:generateRelease_AppReleaseResValues UP-TO-DATE
> Task :app:generateRelease_AppReleaseResources UP-TO-DATE
> Task :app:mergeRelease_AppReleaseResources UP-TO-DATE
> Task :app:createRelease_AppReleaseCompatibleScreenManifests
> Task :app:processRelease_AppReleaseManifest
> Task :app:processRelease_AppReleaseResources
> Task :app:compileRelease_AppReleaseJavaWithJavac UP-TO-DATE
> Task :app:compileRelease_AppReleaseNdk SKIPPED
> Task :app:compileRelease_AppReleaseSources UP-TO-DATE
> Task :app:mergeRelease_AppReleaseShaders UP-TO-DATE
> Task :app:compileRelease_AppReleaseShaders UP-TO-DATE
> Task :app:generateRelease_AppReleaseAssets UP-TO-DATE
> Task :app:mergeRelease_AppReleaseAssets UP-TO-DATE
> Task :app:validateSigningRelease_AppRelease UP-TO-DATE
> Task :app:signingConfigWriterRelease_AppRelease UP-TO-DATE
> Task :app:transformClassesWithDexBuilderForRelease_AppRelease UP-TO-DATE
> Task :app:transformClassesWithMultidexlistForRelease_AppRelease UP-TO-DATE
> Task :app:transformDexArchiveWithDexMergerForRelease_AppRelease UP-TO-DATE
> Task :app:mergeRelease_AppReleaseJniLibFolders UP-TO-DATE
> Task :app:transformNativeLibsWithMergeJniLibsForRelease_AppRelease UP-TO-DATE
> Task :app:transformNativeLibsWithStripDebugSymbolForRelease_AppRelease UP-TO-DATE
> Task :app:processRelease_AppReleaseJavaRes NO-SOURCE
> Task :app:transformResourcesWithMergeJavaResForRelease_AppRelease UP-TO-DATE
> Task :app:packageRelease_AppRelease
> Task :app:assembleRelease_AppRelease
> Task :app:preTest_AppReleaseBuild UP-TO-DATE
> Task :app:compileTest_AppReleaseAidl SKIPPED
> Task :app:compileTest_AppReleaseRenderscript UP-TO-DATE
> Task :app:checkTest_AppReleaseManifest UP-TO-DATE
> Task :app:generateTest_AppReleaseBuildConfig UP-TO-DATE
> Task :app:generateTest_AppReleaseSources UP-TO-DATE
> Task :app:javaPreCompileTest_AppRelease UP-TO-DATE
> Task :app:mainApkListPersistenceTest_AppRelease
> Task :app:generateTest_AppReleaseResValues UP-TO-DATE
> Task :app:generateTest_AppReleaseResources UP-TO-DATE
> Task :app:mergeTest_AppReleaseResources UP-TO-DATE
> Task :app:createTest_AppReleaseCompatibleScreenManifests
> Task :app:processTest_AppReleaseManifest
> Task :app:processTest_AppReleaseResources
> Task :app:compileTest_AppReleaseJavaWithJavac UP-TO-DATE
> Task :app:compileTest_AppReleaseNdk SKIPPED
> Task :app:compileTest_AppReleaseSources UP-TO-DATE
> Task :app:mergeTest_AppReleaseShaders UP-TO-DATE
> Task :app:compileTest_AppReleaseShaders UP-TO-DATE
> Task :app:generateTest_AppReleaseAssets UP-TO-DATE
> Task :app:mergeTest_AppReleaseAssets UP-TO-DATE
> Task :app:validateSigningTest_AppRelease UP-TO-DATE
> Task :app:signingConfigWriterTest_AppRelease UP-TO-DATE
> Task :app:transformClassesWithDexBuilderForTest_AppRelease UP-TO-DATE
> Task :app:transformClassesWithMultidexlistForTest_AppRelease UP-TO-DATE
> Task :app:transformDexArchiveWithDexMergerForTest_AppRelease UP-TO-DATE
> Task :app:mergeTest_AppReleaseJniLibFolders UP-TO-DATE
> Task :app:transformNativeLibsWithMergeJniLibsForTest_AppRelease UP-TO-DATE
> Task :app:transformNativeLibsWithStripDebugSymbolForTest_AppRelease UP-TO-DATE
> Task :app:processTest_AppReleaseJavaRes NO-SOURCE
> Task :app:transformResourcesWithMergeJavaResForTest_AppRelease UP-TO-DATE
> Task :app:packageTest_AppRelease
> Task :app:assembleTest_AppRelease
> Task :app:assembleRelease

> Task :app:resguardRelease

看到resguardRelease任务在最后执行,它是依赖于assembleRelease任务的,所以它所做的操作都是基于生成我们原始apk的基础之上的。

 

等待resguardRelease任务执行完成,可能会等待一段时间(7zip压缩耗时),我们看build文件夹的样子:

 

andResGuard生成了一个临时目录,在临时目录里保存过程中生成的临时文件,将最终的apk生成到release目录下。

再来看一下临时目录里究竟有什么:

 

肯定是在做解压原来的apk然后进行一系列的资源混淆,压缩,对齐,签名等操作,里面的后缀为aligned_signed的apk和我们最终的apk是一样的。

 

 

查看一下最终的apk里面是什么样子:

 

看,找不到res文件夹了,有一个r文件夹,应该是它,进去看下:

 

里面的文件都被混淆了,这里可以感叹一下它的强大。这不仅能减少apk的体积,还能增加保密性,让我们的apk更加难以破解。

再对比一下apk大小, 从57M 压缩到 54.7M 单单是通过混淆res和7zip压缩就收到了这样的效果。因为我使用的图片资源都是经过压缩过的,而且一些so库没有压缩(主要大小来自这里),所以这样的效果已经很显著了。

 

过程解析:

那么它的过程原理是什么呢? 我们先看一下run的执行流程:

 

> Task :app:resguardRelease
convertToPatternString typeName drawable format icon
convertToPatternString typeName string format com\.crashlytics\..*
convertToPatternString typeName string format google_app_id
convertToPatternString typeName string format gcm_defaultSenderId
convertToPatternString typeName string format default_web_client_id
convertToPatternString typeName string format ga_trackingId
convertToPatternString typeName string format firebase_database_url
convertToPatternString typeName string format google_api_key
convertToPatternString typeName string format google_crash_reporting_api_key

-->AndResGuard starting! Current thread# id: 149, name: Task worker for ':' Thread 3
unziping apk to D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Test_App\release\AndResGuard_事物链_Test_M.T.1.1.2.13_20190801150220\temp
decoding resources.arsc
parse to get the exist names in the resouces.arsc first
reading packagename com.dayouzc.e2eplatform.thingchain.x5.test
resources mapping file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Test_App\release\AndResGuard_事物链_Test_M.T.1.1.2.13_20190801150220\resource_mapping_事物链_Test_M.T.1.1.2.13_20190801150220.txt done
resources filter mapping file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Test_App\release\AndResGuard_事物链_Test_M.T.1.1.2.13_20190801150220\merge_duplicated_res_mapping_事物链_Test_M.T.1.1.2.13_20190801150220.txt done
writing new resources.arsc 
resources.arsc Character Encoding: utf-8
[AndResGuard] buildApk signatureType: SchemaV2
General unsigned apk: 事物链_Test_M.T.1.1.2.13_20190801150220_unsigned.apk
add meta file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Test_App\release\AndResGuard_事物链_Test_M.T.1.1.2.13_20190801150220\temp\META-INF\services
DestResDir 770 rawResDir 770
use 7zip to repackage: 事物链_Test_M.T.1.1.2.13_20190801150220_7zip_unsigned.apk, will cost much more time
[addStoredFileIn7Zip]rewrite the stored file into the 7zip, file count: 4
zipaligning apk: D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Test_App\release\AndResGuard_事物链_Test_M.T.1.1.2.13_20190801150220\事物链_Test_M.T.1.1.2.13_20190801150220_7zip_unsigned.apk, exists:true
signing apk: 事物链_Test_M.T.1.1.2.13_20190801150220_7zip_aligned_signed.apk
Backup Final APk(V2) to D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Test_App\release\事物链_Test_M.T.1.1.2.13_20190801150220.apk
<--AndResGuard Done! You can find the output in D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Test_App\release\AndResGuard_事物链_Test_M.T.1.1.2.13_20190801150220
convertToPatternString typeName drawable format icon
convertToPatternString typeName string format com\.crashlytics\..*
convertToPatternString typeName string format google_app_id
convertToPatternString typeName string format gcm_defaultSenderId
convertToPatternString typeName string format default_web_client_id
convertToPatternString typeName string format ga_trackingId
convertToPatternString typeName string format firebase_database_url
convertToPatternString typeName string format google_api_key
convertToPatternString typeName string format google_crash_reporting_api_key

-->AndResGuard starting! Current thread# id: 149, name: Task worker for ':' Thread 3
unziping apk to D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Beta_App\release\AndResGuard_事物链_Beta_M.D.1.1.1.1_20190801150220\temp
decoding resources.arsc
parse to get the exist names in the resouces.arsc first
reading packagename com.dayouzc.e2eplatform.thingchain.x5.beta
resources mapping file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Beta_App\release\AndResGuard_事物链_Beta_M.D.1.1.1.1_20190801150220\resource_mapping_事物链_Beta_M.D.1.1.1.1_20190801150220.txt done
resources filter mapping file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Beta_App\release\AndResGuard_事物链_Beta_M.D.1.1.1.1_20190801150220\merge_duplicated_res_mapping_事物链_Beta_M.D.1.1.1.1_20190801150220.txt done
writing new resources.arsc 
resources.arsc Character Encoding: utf-8
[AndResGuard] buildApk signatureType: SchemaV2
General unsigned apk: 事物链_Beta_M.D.1.1.1.1_20190801150220_unsigned.apk
add meta file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Beta_App\release\AndResGuard_事物链_Beta_M.D.1.1.1.1_20190801150220\temp\META-INF\services
DestResDir 770 rawResDir 770
use 7zip to repackage: 事物链_Beta_M.D.1.1.1.1_20190801150220_7zip_unsigned.apk, will cost much more time
[addStoredFileIn7Zip]rewrite the stored file into the 7zip, file count: 4
zipaligning apk: D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Beta_App\release\AndResGuard_事物链_Beta_M.D.1.1.1.1_20190801150220\事物链_Beta_M.D.1.1.1.1_20190801150220_7zip_unsigned.apk, exists:true
signing apk: 事物链_Beta_M.D.1.1.1.1_20190801150220_7zip_aligned_signed.apk
Backup Final APk(V2) to D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Beta_App\release\事物链_Beta_M.D.1.1.1.1_20190801150220.apk
<--AndResGuard Done! You can find the output in D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Beta_App\release\AndResGuard_事物链_Beta_M.D.1.1.1.1_20190801150220
convertToPatternString typeName drawable format icon
convertToPatternString typeName string format com\.crashlytics\..*
convertToPatternString typeName string format google_app_id
convertToPatternString typeName string format gcm_defaultSenderId
convertToPatternString typeName string format default_web_client_id
convertToPatternString typeName string format ga_trackingId
convertToPatternString typeName string format firebase_database_url
convertToPatternString typeName string format google_api_key
convertToPatternString typeName string format google_crash_reporting_api_key

-->AndResGuard starting! Current thread# id: 149, name: Task worker for ':' Thread 3
unziping apk to D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Release_App\release\AndResGuard_事物链-app-V1.1.2_20190801150220\temp
decoding resources.arsc
parse to get the exist names in the resouces.arsc first
reading packagename com.dayouzc.e2eplatform.thingchain.x5
resources mapping file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Release_App\release\AndResGuard_事物链-app-V1.1.2_20190801150220\resource_mapping_事物链-app-V1.1.2_20190801150220.txt done
resources filter mapping file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Release_App\release\AndResGuard_事物链-app-V1.1.2_20190801150220\merge_duplicated_res_mapping_事物链-app-V1.1.2_20190801150220.txt done
writing new resources.arsc 
resources.arsc Character Encoding: utf-8
[AndResGuard] buildApk signatureType: SchemaV2
General unsigned apk: 事物链-app-V1.1.2_20190801150220_unsigned.apk
add meta file D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Release_App\release\AndResGuard_事物链-app-V1.1.2_20190801150220\temp\META-INF\services
DestResDir 770 rawResDir 770
use 7zip to repackage: 事物链-app-V1.1.2_20190801150220_7zip_unsigned.apk, will cost much more time
[addStoredFileIn7Zip]rewrite the stored file into the 7zip, file count: 4
zipaligning apk: D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Release_App\release\AndResGuard_事物链-app-V1.1.2_20190801150220\事物链-app-V1.1.2_20190801150220_7zip_unsigned.apk, exists:true
signing apk: 事物链-app-V1.1.2_20190801150220_7zip_aligned_signed.apk
Backup Final APk(V2) to D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Release_App\release\事物链-app-V1.1.2_20190801150220.apk
<--AndResGuard Done! You can find the output in D:\projects\test\x5-e2e-platform-thingchain\x5-e2e-platform-thingchain\app\build\outputs\apk\Release_App\release\AndResGuard_事物链-app-V1.1.2_20190801150220

很晕,而且里面有重复打印,我们整理一下它的执行流程:

 

1. 将apk解压到temp目录下;

2. 解析resources.arsc文件;

        a). 获取resources中的已存在的文件名

        b). 获取包名

        c). 建立resource文件名映射,这里需要用到上面两步获取的res文件名和包名,映射关系保存进merge_duplicated_res_mapping_事物链_Test_M.T.1.1.2.13_20190801150220.txt

        d). 使用映射关系创建新的resource.arsc文件

3. 生成未签名apk;

4. 使用7zip重新打包未签名的apk;

5. 使用zipalign生成对齐未签名的apk

6. 对apk进行签名,并生成签名apk

7. 备份最终的apk,即将签名apk从temp文件夹复制到release文件下,并重命名为自己项目中指定的apk名字。

 

至此资源混淆完成,如果项目中想使用资源混淆,AndResGuard这个插件还是值得一用的。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龍林1102

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值