Mess——一个可混淆Activity的项目

目录

    • 一、Mess 介绍及引用
    • 二、Mess 使用注意点
      • 2.1 appt2问题
      • 2.2 gradle 版本问题
      • 2.3 Progurad 参数配置问题
    • 三、Mess 的重大问题
    • 四、建议
    • 五、改进
      • 5.1 改进一——根据 aapt_rules.txt 进行匹配处理
      • 5.2 改进二—— 支持aapt2
      • 5.3 如何使用?

一、Mess 介绍及引用

工程地址为Mess git。

使用方式如下:

dependencies {
   ...
   // 引用该库
   classpath 'me.ele:mess-plugin:1.1.5'
 }
  
apply plugin: 'com.android.library'
// 或 apply plugin: 'com.android.application'
apply plugin: 'me.ele.mess'

// 由于不能兼容 Butter Knife,所以需要加入如下 
mess {
    ignoreProguard 'com.jakewharton:butterknife'
}

注: 有另外一个库,做了兼容,地址为(ButterMess)[https://github.com/peacepassion/ButterMess]

二、Mess 使用注意点

2.1 appt2问题

由于替换写在xml里面的自定义View,而 appt2 编译过程产生的不再是 xml文件,而是flat文件,所以需要在 gradle.properties 文件添加如下代码:

android.enableAapt2=false

2.2 gradle 版本问题

作者编译改工程的时候,使用的 gradle 是 2.* 或 3.* ,所以 AndroidManifest.xml 目录在 RewriteComponentTask 中有如下定义:

String realPath = "${project.buildDir.absolutePath}/intermediates/manifests/full/${getSubResPath()}/AndroidManifest.xml"

而 gradle 4.* 目录将变为

// debug 为
String realPath = "${project.buildDir.absolutePath}/intermediates/merged_manifests/${getSubResPath()}/processDebugManifest/merged/AndroidManifest.xml"
// release为
String realPath = "${project.buildDir.absolutePath}/intermediates/merged_manifests/${getSubResPath()}/processReleaseManifest/merged/AndroidManifest.xml"

2.3 Progurad 参数配置问题

  1. Activity、View等,混淆不成功
    检查 proguard-rules.pro 或 proguard.cfg 等文件中是否配置如下字段:
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Service
-keep public class * extends android.view.View

# 全局:保留所有继承自View的子类名称
-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet, int);
}

如果是,请去除。

2)部分 Activity 混淆成功了,部分没有成功,切应用启动之后,报了 ClassNotFound 的crash,需要在 proguard-rules.pro 或 proguard.cfg 文件中加入,如下

-dontshrink

三、Mess 的重大问题

Mess 的 大致原理可以分为两部分:
1)在 processResourcesTask 之后,删除如下路径的文件。

build/generated/intermediates/proguard-rules/debug[或]release/aapt_rules.txt

使得 proguard 能将View和Activity等进行混淆。

2)在transformClassesAndResourcesWithProguardFor* 之后,根据生成的 mapping.txt 文件,对 AndroidMenifest.xml 文件以及其他 res 文件中的相关字段进行替换。
这里有一个重大的bug: 如:

// mapping.txt 有如下字段
d.c -> someWhat
// 然后
xmlns:android="http://schemas.android.com/apk/res/android"
被替换为
// xmlns:android="http://schemas.androi[d.c]om/apk/res/android"
xmlns:android="http://schemas.androisomewhatom/apk/res/android"

然后就各种布局bug了

四、建议

其实 aapt_rules.txt 里面如下定义:

# view res/layout/layout_1.xml #generated:2
# view res/layout/layout_2.xml #generated:9
-keep class com.lxb.sample.MyView { (...); }

由上面可以看出,其实哪个xml里面有那些 View 等,都已经比较明确,所以只需要替换相应的 xml 里面的 相应的 Class 字段就可以,避免出现(三)中的异常。

五、改进

5.1 改进一——根据 aapt_rules.txt 进行匹配处理

原工程中遍历了所有的资源文件,遍历所有的mapping的内容,进行替换处理,就会出现(三)中的异常,根据(四)的建议,就可以进行改进处理。

5.2 改进二—— 支持aapt2

原工程不支持 aapt2 是因为,aapt2将资源文件压缩为.flat文件,无法直接通过替换字符串的方式进行替换。
那么我们为什么一定要揪住.flat文件不放呢?直接修改源文件,然后执行 aapt2 替换之前的 .flat 不久行了吗?

5.3 如何使用?

改进的项目地址为:https://github.com/linxuebin1990/Mess

和(一)中所说无差,只要自己进行一次编包处理将如下文件拷贝到主工程目录下。

MessProjuecPath/buildSrc/build/libs/buildSrc.jar

然后,

dependencies {
   ...
   // 引用该库,将(一)中的 classpath 'me.ele:mess-plugin:1.1.5' 改为如下方式
   classpath files('./buildSrc.jar')
 }

再之后,将aapt2文件,也同样拷贝到主工程目录下,就可以。
其他参考前面的配置就可以。

你可能感兴趣的:(android)