├── .gitignore ├── .gitmodules ├── README.md ├── app ├── .gitignore ├── build.gradle ├── debug.keystore ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── me │ │ └── ele │ │ └── mess │ │ ├── ApplicationContext.java │ │ ├── CustomView.java │ │ ├── CustomViewNew.java │ │ ├── MainActivity.java │ │ ├── MyAdapter.java │ │ ├── MyLinearLayoutManager.java │ │ ├── MyVH.java │ │ ├── SecondActivity.java │ │ └── booking │ │ └── ui │ │ └── checkout │ │ └── invoice │ │ └── InvoiceEditActivity.java │ └── res │ ├── layout │ ├── activity_main.xml │ └── simple_item.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── buildSrc ├── build.gradle └── src │ └── main │ ├── groovy │ └── me │ │ └── ele │ │ └── mess │ │ ├── MessExtension.groovy │ │ ├── MessPlugin.groovy │ │ ├── RewriteComponentTask.groovy │ │ └── Util.groovy │ └── resources │ └── META-INF │ └── gradle-plugins │ └── me.ele.mess.properties ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | /buildSrc/gradle.properties 2 | /buildSrc/.gradletasknamecache 3 | *.iml 4 | .gradle 5 | /local.properties 6 | /.idea/workspace.xml 7 | /.idea/libraries 8 | .DS_Store 9 | /build 10 | /captures 11 | /.idea 12 | .idea 13 | /gradlew.bat 14 | /gradlew 15 | /.gradletasknamecache 16 | /buildSrc/build 17 | /buildSrc/.gradle 18 | /app/build 19 | /buildSrc/local.properties 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ButterMess"] 2 | path = ButterMess 3 | url = https://github.com/peacepassion/ButterMess 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mess 2 | 3 | 4 | **mess** is a gradle plugin for obfuscating all code including activity, service, receiver, provider and custom view. It's really very cool to obfuscate all codes, lowers code readability after reverse engineering and ensures code's safety. 5 | 6 | **mess** is super easy to integrate with your app, its implementation is also clear to understand. During android gradle assemble task execution, It has a lot of tasks to do, and can be divided to resource process & code process briefly. 7 | 8 | **process\**Resources** is the last task in resource process, it will generate a merged **AndroidManifest.xml**, **aapt_rules.txt** and a merged **res** directory in project build dir. aapt_rules.txt is the output file after aapt, it contains all classes in xml files, and then this file is delivered to proguard task as a list of keeps. 9 | **transformClassesAndResourcesWithProguardFor\**** is the proguard task which obfuscates code, it generates a **mapping.txt** file which contains all mapping relation between origin and obfuscated classes. 10 | 11 | **mess** hooks two android gradle tasks: **process\**Resources** & **package\****, hook processResources task is to clear aapt_rules.txt, tells proguard not to obfuscate all the classes in xml; package task is the last task before package code & resource into apk, it runs after proguard, mess hooks it just to read the obfuscation mapping relation, then rewrite these into resources again, finally execute processResources task again. If your app sets **shrinkResources** to be true, then execute shrink task one more time. 12 | 13 | 14 | 15 | ## Usage 16 | 17 | ```groovy 18 | dependencies { 19 | ... 20 | classpath 'me.ele:mess-plugin:1.0.1' 21 | } 22 | 23 | apply plugin: 'com.android.library' 24 | apply plugin: 'me.ele.mess' 25 | 26 | ``` 27 | 28 | In some cases, you want to ignore some proguard configuration provided by aar. E.g. latest Butter Knife is an aar which contains proguard.txt, so users do not need to configure its proguard manually. 29 | However, we would like to still obfuscate classes used with Butter Knife. So we provide an extension for such scenario. 30 | 31 | ```groovy 32 | mess { 33 | ignoreProguard 'com.jakewharton:butterknife' 34 | } 35 | ``` 36 | 37 | As a result, the Butter Knife's proguard configuration will be ignored. And those activities, views, fragments will be obfuscated by Mess. 38 | 39 | That's all, just simple as that 40 | 41 | ## Note 42 | As almost every Android project uses [Butter Knife](https://jakewharton.github.io/butterknife/) for view injection. And Butter Knife has its own proguard rules which keeps every class using Butter Knife. As as result, almost every android activity, fragment, custom view would be kept. And out Mess plugin is useless. 43 | 44 | But good news is that we studied Butter Knife source code and figured it out. And the solution is also a gradle plugin [ButterMess](https://github.com/peacepassion/ButterMess) which has been a submodule of this project. 45 | 46 | ## feel free to use, welcome issue and comment 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.neenbedankt.android-apt' 3 | apply plugin: 'me.ele.mess' 4 | 5 | android { 6 | compileSdkVersion 23 7 | buildToolsVersion "23" 8 | 9 | dataBinding { 10 | enabled = true 11 | } 12 | 13 | defaultConfig { 14 | applicationId "me.ele.signdigestfinder" 15 | minSdkVersion 15 16 | targetSdkVersion 23 17 | versionCode 1 18 | versionName "1.0" 19 | } 20 | signingConfigs { 21 | debug { 22 | storeFile file("${project.projectDir}/debug.keystore") 23 | keyAlias 'androiddebugkey' 24 | keyPassword 'android' 25 | storePassword 'android' 26 | } 27 | } 28 | buildTypes { 29 | release { 30 | minifyEnabled true 31 | shrinkResources true 32 | proguardFiles 'proguard-rules.pro' 33 | signingConfig signingConfigs.debug 34 | } 35 | } 36 | } 37 | 38 | dependencies { 39 | compile fileTree(dir: 'libs', include: ['*.jar']) 40 | compile 'com.android.support:appcompat-v7:23.3.0' 41 | compile "com.android.support:recyclerview-v7:23.3.0" 42 | 43 | compile 'com.jakewharton:butterknife:8.2.1' 44 | 45 | apt 'com.jakewharton:butterknife-compiler:8.2.1' 46 | } 47 | 48 | mess { 49 | // ignoreProguard 'com.jakewharton:butterknife' 50 | ignoreProguard 'com.android.support:recyclerview-v7' 51 | } 52 | -------------------------------------------------------------------------------- /app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/Mess/953266f9a7bf045257fe40c7fe1fde7cb77cc409/app/debug.keystore -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | -dontshrink 20 | -optimizationpasses 5 21 | -dontusemixedcaseclassnames#混淆时不会大小写混合类名 22 | -dontskipnonpubliclibraryclasses #指定不去忽略非公共的库类 23 | -dontpreverify #不预校验 24 | -dontwarn #不警告 25 | -verbose 26 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #优化配置 27 | -dontoptimize #不优化 28 | -ignorewarnings #忽略警告 29 | -repackageclasses me.ele 30 | 31 | -keep class !me.ele.**, !retrofit2.**{*;} 32 | 33 | # 保留签名,解决泛型、类型转换的问题 34 | -keepattributes Signature 35 | -keepattributes Exceptions 36 | # 不混淆带有 annotation 的变量 和 函数 37 | -keepattributes *Annotation* 38 | -renamesourcefileattribute SourceFile 39 | -keepattributes SourceFile,LineNumberTable 40 | 41 | -keepclassmembers,allowoptimization enum * { 42 | public static **[] values(); 43 | public static ** valueOf(java.lang.String); 44 | } 45 | 46 | -keepclassmembers class * implements java.io.Serializable { 47 | static final long serialVersionUID; 48 | private static final java.io.ObjectStreamField[] serialPersistentFields; 49 | !static !transient ; 50 | !private ; 51 | !private ; 52 | private void writeObject(java.io.ObjectOutputStream); 53 | private void readObject(java.io.ObjectInputStream); 54 | java.lang.Object writeReplace(); 55 | java.lang.Object readResolve(); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/ApplicationContext.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | public class ApplicationContext extends Application { 7 | 8 | @Override 9 | public void onCreate() { 10 | super.onCreate(); 11 | Log.d("test", "haha"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/CustomView.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.os.Build; 6 | import android.util.AttributeSet; 7 | import android.widget.Button; 8 | 9 | public class CustomView extends Button { 10 | public CustomView(Context context) { 11 | super(context); 12 | } 13 | 14 | public CustomView(Context context, AttributeSet attrs) { 15 | super(context, attrs); 16 | } 17 | 18 | public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { 19 | super(context, attrs, defStyleAttr); 20 | } 21 | 22 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 23 | public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 24 | super(context, attrs, defStyleAttr, defStyleRes); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/CustomViewNew.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import me.ele.mess.CustomView; 6 | 7 | public class CustomViewNew extends CustomView { 8 | public CustomViewNew(Context context) { 9 | super(context); 10 | } 11 | 12 | public CustomViewNew(Context context, AttributeSet attrs) { 13 | super(context, attrs); 14 | } 15 | 16 | public CustomViewNew(Context context, AttributeSet attrs, int defStyleAttr) { 17 | super(context, attrs, defStyleAttr); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/MainActivity.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.view.View; 8 | import android.widget.Toast; 9 | import butterknife.BindView; 10 | import butterknife.ButterKnife; 11 | import butterknife.OnClick; 12 | 13 | public class MainActivity extends AppCompatActivity { 14 | 15 | @BindView(R.id.rv) RecyclerView rv; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_main); 21 | ButterKnife.bind(this); 22 | 23 | CustomView customView = (CustomView) findViewById(R.id.custom_view); 24 | customView.setOnClickListener(new View.OnClickListener() { 25 | @Override 26 | public void onClick(View v) { 27 | Toast.makeText(MainActivity.this, "haha", Toast.LENGTH_SHORT).show(); 28 | } 29 | }); 30 | 31 | rv.setAdapter(new MyAdapter()); 32 | } 33 | 34 | @OnClick(R.id.btn) public void onClickBtn(View v) { 35 | startActivity(new Intent(MainActivity.this, SecondActivity.class)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/MyAdapter.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.LayoutInflater; 5 | import android.view.ViewGroup; 6 | 7 | public class MyAdapter extends RecyclerView.Adapter { 8 | 9 | @Override public MyVH onCreateViewHolder(ViewGroup parent, int viewType) { 10 | return new MyVH( 11 | LayoutInflater.from(parent.getContext()).inflate(R.layout.simple_item, parent, false)); 12 | } 13 | 14 | @Override public void onBindViewHolder(MyVH holder, int position) { 15 | 16 | } 17 | 18 | @Override public int getItemCount() { 19 | return 100; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/MyLinearLayoutManager.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | import android.util.AttributeSet; 6 | 7 | public class MyLinearLayoutManager extends LinearLayoutManager { 8 | public MyLinearLayoutManager(Context context) { 9 | super(context); 10 | } 11 | 12 | public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { 13 | super(context, orientation, reverseLayout); 14 | } 15 | 16 | public MyLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, 17 | int defStyleRes) { 18 | super(context, attrs, defStyleAttr, defStyleRes); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/MyVH.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | 6 | public class MyVH extends RecyclerView.ViewHolder { 7 | 8 | public MyVH(View itemView) { 9 | super(itemView); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/SecondActivity.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | public class SecondActivity extends AppCompatActivity { 8 | 9 | @Override 10 | protected void onCreate(@Nullable Bundle savedInstanceState) { 11 | super.onCreate(savedInstanceState); 12 | setContentView(R.layout.activity_main); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/me/ele/mess/booking/ui/checkout/invoice/InvoiceEditActivity.java: -------------------------------------------------------------------------------- 1 | package me.ele.mess.booking.ui.checkout.invoice; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | import me.ele.mess.R; 8 | 9 | public class InvoiceEditActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(@Nullable Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_main); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 20 | 21 |