Android代码混淆,就这么简单

前言

在这个乞丐都精通C++的时代,我们的代码安全实在是不敢保证,为了保护我们的代码不被牛逼的乞丐篡改,代码混淆还是必须的。大多数人还是认为代码混淆是很复杂的事情,我自己也这么认为。。。

看完这篇博客,也许就会发现,其实没那么难。

段子

老规矩,在节目开始之前,先来一个搞笑段子:

女孩:你为什么对我这么好啊?

男孩:我希望有朝一日…

女孩:滚!混蛋

男孩:哎,我还没说完呢~

五步搞定

1

打开项目中的proguard-rules.pro,将下面的代码复制进去。我的思路是将混淆分为2个主要部分

定制化区域。这里边的内容是我们主要需要补充的部分,大致分为4个小部分,我们接下来的步骤主要是补充这4个部分的东西。

基本不用动区域。顾名思义,基本不用动。这块的内容我已经写好了,除非有特殊的需求,基本不用改动。

#---------------------------------定制化区域--------------------------------
#---------------------------------1.实体类---------------------------------

#-------------------------------------------------------------------------

#---------------------------------2.第三方包-------------------------------

#-------------------------------------------------------------------------

#---------------------------------3.与js互相调用的类------------------------

#-------------------------------------------------------------------------

#---------------------------------4.反射相关的类和方法-----------------------

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------

#-----------------------------基本不用动区域--------------------------------
#---------------------------------基本指令区--------------------------------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
#-----------------------------------------------------------------------

#---------------------------------默认保留区------------------------------
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}

-keepclasseswithmembernames class * {
    native <methods>;
}
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
-keep class **.R$* {
 *;
}
-keepclassmembers class * {
    void *(**On*Event);
}
#----------------------------------------------------------------------------

#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
    public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.webView, jav.lang.String);
}
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------

2

理解完战略级思想后,我们开始第一部分补充-实体类。实体类由于涉及到与服务端的交互,各种gson的交互如此等等,是要保留的。将你项目中实体类都拎出来,用以下语法进行保留。

-keep class 你的实体类所在的包.** { *; }

如我的项目下类User的完整路径为:com.demo.login.bean.User, 那我的混淆如下

#---------------------------------1.实体类---------------------------------

-keep class com.demo.login.bean.** { *; }

#-------------------------------------------------------------------------

当然你的实体类肯定不止这一个,请用上边的方式一一添加,如果你的实体类都在一个包下,那你就幸福了。

3

第2部分是第三方包。打开你的build.gradle文件,查看你用了哪些第三方的包。

dependencies {
    compile ‘com.github.bumptech.glide:glide:3.7.0‘
    compile ‘org.greenrobot:eventbus:3.0.0‘
}

我这里用了glide,eventbus。我去他们的官网把已经写好的混淆copy下来。

#---------------------------------2.第三方包-------------------------------

#eventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

#glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

#-------------------------------------------------------------------------

一般官网都是有混淆的,没有的话就google,也没有的话自己按照上面的写法自己写,还不会的话。。。。。只能换个包。。。。。如果你是直接包含的jar包的话,你这样写

#---------------------------------2.第三方包-------------------------------

#log4j
-libraryjars log4j-1.2.17.jar
-dontwarn org.apache.log4j.**
-keep class  org.apache.log4j.** { *;}

#-------------------------------------------------------------------------

大致意思就是不混淆,不报warn。如果gradle报错的话,可以考虑注释掉-libraryjars log4j-1.2.17.jar这句。

4

第三部分与js互调的类,工程中没有直接跳过。一般你可以这样写

-keep class 你的类所在的包.** { *; }

如果是内部类的话,你可以这样

-keepclasseswithmembers class 你的类所在的包.父类$子类 { <methods>; }

例如

-keepclasseswithmembers class com.demo.login.bean.ui.MainActivity$JSInterface {
      <methods>;
}

5

第四部分与反射有关的类,工程中没有直接跳过。类的话直接这样

-keep class 你的类所在的包.** { *; }

熟练后不用五分钟就能搞定。大家可以把自己写完混淆所用的时间写在评论里(0,0)

深入了解

先逐条介绍下基本指令区指令的含义

-optimizationpasses 5 //代码混淆的压缩比例,值在0-7之间
-dontusemixedcaseclassnames //混淆后类名都为小写
-dontskipnonpubliclibraryclasses //指定不去忽略非公共的库的类
-dontskipnonpubliclibraryclassmembers //指定不去忽略非公共的库的类的成员
-dontpreverify //不做预校验的操作
-verbose
-printmapping proguardMapping.txt //生成原类名和混淆后的类名的映射文件
-optimizations !code/simplification/cast,!field/*,!class/merging/* //指定混淆是采用的算法
-keepattributes *Annotation*,InnerClasses //不混淆Annotation
-keepattributes Signature //不混淆泛型
-keepattributes SourceFile,LineNumberTable //抛出异常时保留代码行号

基本指令区基本介绍完了,说下2条用的最多的指令

-keep class XXXX //保留类名不变,也就是类名不混淆,而类中的成员名不保证。
-keepclasseswithmembers class XXXX //保留类名和成员名。当然也可以是类中特定方法

附:完整的混淆

#--------------------------------定制化区域---------------------------------
#---------------------------------1.实体类---------------------------------

-keep class com.demo.login.bean.** { *; }
-keep class com.demo.main.bean.** { *; }

#-------------------------------------------------------------------------

#---------------------------------2.第三方包-------------------------------

#eventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

#glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

#log4j
-libraryjars log4j-1.2.17.jar
-dontwarn org.apache.log4j.**
-keep class  org.apache.log4j.** { *;}

#-------------------------------------------------------------------------

#---------------------------------3.与js互相调用的类------------------------

-keepclasseswithmembers class com.demo.login.bean.ui.MainActivity$JSInterface {
      <methods>;
}

#-------------------------------------------------------------------------

#---------------------------------4.反射相关的类和方法-----------------------

#TODO 我的工程里没有。。。

#------------------------------------------------------------------------
#------------------------------------------------------------------------

#--------------------------------基本不用动区域------------------------------
#---------------------------------基本指令区----------------------------------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
#----------------------------------------------------------------------------

#---------------------------------默认保留区---------------------------------
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}

-keepclasseswithmembernames class * {
    native <methods>;
}
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
-keep class **.R$* {
 *;
}
-keepclassmembers class * {
    void *(**On*Event);
}
#----------------------------------------------------------------------------

#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
    public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.webView, jav.lang.String);
}
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------

后言

将build.gradle中minifyEnabled设置为true打个包试试吧

release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
}

更新日志

1.模板中的规则有部分与默认的proguard-android.txt文件中的重复了,可以精简一下

#------------------------------定制化区域-----------------------------------
#---------------------------------1.实体类---------------------------------

#-------------------------------------------------------------------------

#---------------------------------2.第三方包-------------------------------

#-------------------------------------------------------------------------

#---------------------------------3.与js互相调用的类------------------------

#-------------------------------------------------------------------------

#---------------------------------4.反射相关的类和方法-----------------------

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------

#---------------------------------基本不用动区域----------------------------
#---------------------------------基本指令区--------------------------------
-optimizationpasses 5
-dontskipnonpubliclibraryclassmembers
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
#--------------------------------------------------------------------------

#---------------------------------默认保留区---------------------------------
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}

-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
-keep class **.R$* {
 *;
}
-keepclassmembers class * {
    void *(**On*Event);
}
#----------------------------------------------------------------------------

#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
    public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.webView, jav.lang.String);
}
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------

本期节目就到这里,感谢大家的收看,下期再见~

引用地址:http://www.jianshu.com/p/f3455ecaa56e

时间: 2024-10-19 10:32:52

Android代码混淆,就这么简单的相关文章

android 代码混淆

android 代码 混淆- 原来如此简单 一个xxx.apk提交给测试. ok,去倒杯水,看看网页~~~~~ 呃,忽然觉得 是不是应该 给我的代码 提高点安全性, 记得看过 apk直接可以 解压,然后很容易的就可以 反编译出 .java 找了找,果然,这一切 只不过是 一分钟的事儿, 1.得到 classes.dex文件:直接用你机器上的  解压软件 打开 .apk 文件 解压出 classes.dex 文件,(这个就是 .jar 的前生--- 其实应该说 后世) 2.还原.jar文件:这一步

Android代码混淆防反编译解决方案研究

做Android开发的都知道要做混淆去防apk被反编译.破解,通过proguard进行Java代码混淆.但是,Android代码混淆真的能起到实质性的作用吗?看下面分析 1.Android代码混淆 如上图,对Android 代码进行混淆后混淆器将代码中的所有变量.函数.类的名称加密为简短的英文字母代号,在APP被破解后增加破解者对代码的阅读难度. 但是混淆的功效只能运作在APP已经被破解后,而且只是增加破解者的难度时间,对其防止破解的作用意义不是很大. 那么,Android代码混淆不能从根本上防

Proguard android代码混淆 防止反编译

Proguard android代码混淆 防止反编译 http://www.360doc.com/content/13/1030/13/9171956_325290258.shtml

Android代码混淆(新版本ADT)

说明: 看网上说的很多Android代码混淆的方法都是旧版本ADT的方法,今天用到代码混淆,记下来分享一下,有需要的可以看看. 实践: 我就不写东西了,还是直接给大家看我项目中用到的文件就好了.注释我写在图片上了. 第二个文件的代码我还是写出来吧,可能有朋友用的和我的差不多.(注意不要把注释写进去) 这两个文件都是项目生成的时候由ADT自动生成的,不用自己加. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -keep public class * extend

【转】Android代码混淆指南

请尊重他人的劳动成果,转载请注明出处:<Android代码混淆指南> 本文将和大家分享使用Eclipse+ADT与使用Android Studio进行代码混淆打包的方法. 使用Eclipse+ADT进行代码混淆打包的方法 新版本SDK下进行打包混淆 如果使用新版本的SDK创建的Android项目会在项目的根目录下生成一个proguard-project.txt文件,该文件是默认的混淆规则文件. 混淆打包的步骤: 1.在proguard-project.txt文件中添加混淆的项目规则,大家可参考

Android代码混淆之混淆规则

请尊重他人的劳动成果,转载请注明出处:<Android代码混淆技巧> 因为Android是使用Java开发的,所以开发者可以使用ProGuard对代码进行混淆.SDK已经集成了ProGuard工具,开发者可以从SDK目录下的\tools\proguard目录中进行查看. ProGuard是一个免费的Java类文件收缩,优化,混淆和预校验器.它可以检测并删除未使用的类,字段,方法和属性.它可以优化字节码,并删除未使用的指令.它可以将类.字段和方法使用短无意义的名称进行重命名.最后,预校验的Jav

Android代码混淆指南

请尊重他人的劳动成果,转载请注明出处:<Android代码混淆指南> 本文将和大家分享使用Eclipse+ADT与使用Android Studio进行代码混淆打包的方法. 使用Eclipse+ADT进行代码混淆打包的方法 新版本SDK下进行打包混淆 如果使用新版本的SDK创建的Android项目会在项目的根目录下生成一个proguard-project.txt文件,该文件是默认的混淆规则文件. 混淆打包的步骤: 1.在proguard-project.txt文件中添加混淆的项目规则,大家可参考

Android代码混淆

混淆器(ProGuard) --- 混淆器通过删除从未用过的代码和使用晦涩名字重命名类.字段和方法,对代码进行压缩,优化和混淆.结果是一个比較小的.apk文件,该文件比較难进行逆向project.因此,当你的应用程序对安全敏感(要求高),比如当你授权应用程序的时候,混淆器是一种重要的保护手段. 混淆器被集成在android 构建系统中,所以你不必手动调用它.同一时候混淆器仅在公布模式下进行构建应用程序的时候才会执行起来,所以在调试模式下构建程序时,你不必处理混淆代码.让混淆器执行起来是可选择的,

Android代码混淆及项目发布步骤记录

本来整理了一份Android项目混淆与发布的文档,突然想到何不写篇博客,分享一下呢,如是便有了本文. 一.清理代码中的调试信息,如Log.System.out 二.在清单文件中修改版本为当前版本,如果需要更新数据库,则需要在配置类或配置文件中修改程序数据库版本. 三.在清单文件中将项目的debugable设置为false 四.创建签名证书keystore文件 五.在项目中的project.properites文件中添加语句proguard.config=proguard-project.txt来

【转】 Android代码混淆之混淆规则

请尊重他人的劳动成果,转载请注明出处:<Android代码混淆技巧> 因为Android是使用Java开发的,所以开发者可以使用ProGuard对代码进行混淆.SDK已经集成了ProGuard工具,开发者可以从SDK目录下的\tools\proguard目录中进行查看. ProGuard是一个免费的Java类文件收缩,优化,混淆和预校验器.它可以检测并删除未使用的类,字段,方法和属性.它可以优化字节码,并删除未使用的指令.它可以将类.字段和方法使用短无意义的名称进行重命名.最后,预校验的Jav