Android 代码混淆语法讲解及常用模板

来源:互联网 发布:asc软件 编辑:程序博客网 时间:2024/05/21 07:04

转载请注明原博客地址 Android 代码混淆语法讲解及常用模板

前言

混淆对于每一个开发者来说都不陌生,对于大多数 APP 而言,在上线之前,通常会进行代码混淆,加固,防止自己的 APP 被别人轻易破解。

一般来说,混淆有以下好处

  • 提高自己 APP 的安全性,防止被别人轻易破解
  • 在一定程度上起到 APK 瘦身的作用,因为方法名,类名都变成 a,b,c 等这样的形式,这无疑会节省资源

Android 混淆模板代码讲解

在现在的 Android 开发中,基本都是以 AndroidStudio 为主,因此,本篇文章也主要以 AndroidStudio 为例进行讲解。

在 AndroidStudio 中,在 moudle 的根目录中我们一般可以看到 proguard-rules.pro 文件,这个文件就是用来配置代码混淆的。

至于它是怎样指定 proguard-rules.pro 文件来配置代码混淆的,我们可以在看一下 build.gradle 是怎样配置的

// 对正式版的进行混淆配置    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }

了解了在哪里配置混淆代码之后,下面我们一起来看一下怎样混淆代码

首先,我们先来看一下 Android 默认的代码混淆配置,在 {SDKHOME}\tools\proguard 目录下,有 proguard-android.txt 文件,该文件就是默认的代码混淆配置

# This is a configuration file for ProGuard.# http://proguard.sourceforge.net/index.html#manual/usage.html-dontusemixedcaseclassnames-dontskipnonpubliclibraryclasses-verbose# Optimization is turned off by default. Dex does not like code run# through the ProGuard optimize and preverify steps (and performs some# of these optimizations on its own).-dontoptimize-dontpreverify# Note that if you want to enable optimization, you cannot just# include optimization flags in your own project configuration file;# instead you will need to point to the# "proguard-android-optimize.txt" file instead of this one from your# project.properties file.-keepattributes *Annotation*-keep public class com.google.vending.licensing.ILicensingService-keep public class com.android.vending.licensing.ILicensingService# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native-keepclasseswithmembernames class * {    native <methods>;}# keep setters in Views so that animations can still work.# see http://proguard.sourceforge.net/manual/examples.html#beans-keepclassmembers public class * extends android.view.View {   void set*(***);   *** get*();}# We want to keep methods in Activity that could be used in the XML attribute onClick-keepclassmembers class * extends android.app.Activity {   public void *(android.view.View);}# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}-keepclassmembers class * implements android.os.Parcelable {  public static final android.os.Parcelable$Creator CREATOR;}-keepclassmembers class **.R$* {    public static <fields>;}# The support library contains references to newer platform versions.# Don't warn about those in case this app is linking against an older# platform version.  We know about them, and they are safe.-dontwarn android.support.**# Understand the @Keep support annotation.-keep class android.support.annotation.Keep-keep @android.support.annotation.Keep class * {*;}-keepclasseswithmembers class * {    @android.support.annotation.Keep <methods>;}-keepclasseswithmembers class * {    @android.support.annotation.Keep <fields>;}-keepclasseswithmembers class * {    @android.support.annotation.Keep <init>(...);}

解释说明

-dontusemixedcaseclassnames 表示混淆时不使用大小写类名

-dontskipnonpubliclibraryclasses 表示不跳过library中的非public的类。

-verbose 打印混淆的详细信息

-dontskipnonpubliclibraryclasses 表示不跳过 library 中非 public 的类

-dontoptimize 表示不进行优化,建议使用此选项,因为根据proguard-android-optimize.txt中的描述,优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行。

-dontpreverify 表示不进行预校验。这个预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度。

-keepattributes *Annotation* 表示对注解中的参数进行保留

-keepclasseswithmembernames class * {    native <methods>;}

保持所有类的 native 方法不被混淆

-keepclassmembers public class * extends android.view.View {   void set*(***);   *** get*();}

表示不混淆 View 的子类中的 set 和 get 方法,因为 View 中的属性动画需要 setter 和 getter,混淆了就无法工作了。

-keepclassmembers class * extends android.app.Activity {   public void *(android.view.View);}

表示不混淆 Activity 及 Activity 子类中方法参数是 (android.view.View) 的方法。因为我们平时在 xml 文件里面可以这样写 onClick=”onButtonClick”,这样点击 Button 的时候会自动到 Activity 里面查找是否有 onButtonClick (android.view.View),有的话,该方法会响应,没有找到的话会报错。因此,一般也不混淆。

-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}

表示不对美剧类中的 calues 和 valueOf(java.lang.String) 进行混淆

-keepclassmembers class * implements android.os.Parcelable {  public static final android.os.Parcelable$Creator CREATOR;}

表示不混淆 Parcelable 的实现类中的 CREATOR,我们知道序列化与反序列化的过程都需要 CREATOR, 混淆了就无法工作了。

-keepclassmembers class **.R$* {    public static <fields>;}

表示不混淆 R 类中 的 static 变量,在 R 类中。这些资源 ID 是系统自动帮我们生成的,混淆了就无法找到相应的资源。

-dontwarn android.support.**

表示混略 android.support 包下代码的警告。因为 android.support 包下,许多类都是在高版本中才能使用的,不过你不用担心低版本使用了会报错,因为在 support 包里面的类都已经对版本进行判断,所有直接忽略即可。

-keep class android.support.annotation.Keep

表示不混淆 Keep 类

-keep @android.support.annotation.Keep class * {*;}

表示不混淆 以下形式的代码

 @Keep *{}
-keepclasseswithmembers class * {    @android.support.annotation.Keep <methods>;}

表示不混淆所有类中用 @Keep 注解的方法

-keepclasseswithmembers class * {    @android.support.annotation.Keep <fields>;}

表示不混淆所有类中用 @Keep 的变量

-keepclasseswithmembers class * {    @android.support.annotation.Keep <init>(...);}

表示不混淆所有类中用 @Keep 注解的构造方法


Android 混淆代码示例

如上图,假如我们的项目中的配置是这样的,如果我们想保持项目中 xj.progurddemo.been 包下的类都不被混淆,我们可以这样写

-keep class  xj.progurddemo.been.**

而 -keep class xj.progurddemo.been.* 只能保证 People,Test 类不被混淆。Debug 包下的 Debug 类还是会被混淆。

到这里,相信你已经明白 ** 和 * 之间的区别了。 ** 包含目录下的所有子目录,而 * 只包含 目录下的直接目录。

假如我们有以下类 Test,

public class Test {    String name;    public void  test(){    }    public abstract String test(String name)}

我们不想 test 类中的 test 方法不被混淆,而 name 字段可以被混淆,我们可以这样配置

 -keepclassmembers public class xj.progurddemo.been.Test {   *** test*(***);

*** 表示匹配任意参数,这样 Test 类中的 test 方法都不会被混淆,不管该方法含有什么类型的参数和该方法的返回类型。


Android 混淆语法介绍

看完简单的代码示例,下面我们一起拉看一下混淆的语法。

首先我们先来看一下 keep 关键字

关键字 描述 keep 保留类和类中的成员,防止被混淆或者移除 keepnames 保留类和类中的成员,防止被混淆,但是当成员没有被引用时会被移除 keepclassmembers 只保留类中的成员,防止他们被混淆或者移除 keepclassmembersnames 只保留类中的成员,防止他们被混淆或者移除,但是当类中的成员没有被引用时还是会被移除 keepclasseswithmembers 保留类和类中的成员,前提是指明的类中必须含有该成员,没有的话还是会被混淆 keepclasseswithmembersnames 保留类和类中的成员,前提是指明的类中必须含有该成员,没有的话还是会被混淆。需要注意的是没有被引用的成员会被移除

接下来我们一起来看一下通配符

关键字 描述 <filed> 匹配类中的所有字段 <method> 匹配类中的所有方法 <init> 匹配类中的所有构造函数 * 匹配任意长度字符,但不含包名分隔符(.)。比如说我们的完整类名是com.example.test.MyActivity,使用com.,或者com.exmaple.都是无法匹配的,因为无法匹配包名中的分隔符,正确的匹配方式是com.exmaple..,或者com.exmaple.test.,这些都是可以的。但如果你不写任何其它内容,只有一个*,那就表示匹配所有的东西。 ** 匹配任意长度字符,并且包含包名分隔符(.)。比如proguard-android.txt中使用的-dontwarn android.support.**就可以匹配android.support包下的所有内容,包括任意长度的子包。 *** 匹配任意参数类型。比如void set*()就能匹配任意传入的参数类型, get*()就能匹配任意返回值的类型。 … 匹配任意长度的任意类型参数。比如void test(…)就能匹配任意void test(String a)或者是void test(int a, String b)这些方法。

Android 混淆插件推荐及常用的混淆模板

Github 上面的混淆插件

Github 上有这样一个插件,AndroidProguardPlugin,他帮我们收集了常用的混淆模板,基本能满足我们的大部分需求。详情大家可以自己点击查看,这里就不教大家怎样使用了,该链接已经讲解地很清楚了。AndroidProguardPlugin

Android 常用混淆模板

# copyright zhonghanwen#-------------------------------------------基本不用动区域--------------------------------------------#---------------------------------基本指令区-----------------------------------optimizationpasses 5-dontskipnonpubliclibraryclassmembers-printmapping proguardMapping.txt-optimizations !code/simplification/cast,!field/*,!class/merging/*-keepattributes *Annotation*,InnerClasses-keepattributes Signature-keepattributes SourceFile,LineNumberTable#----------------------------------------------------------------------------#---------------------------------默认保留区---------------------------------#继承activity,application,service,broadcastReceiver,contentprovider....不进行混淆-keep public class * extends android.app.Activity-keep public class * extends android.app.Application-keep public class * extends android.support.multidex.MultiDexApplication-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);}#这个主要是在layout 中写的onclick方法android:onclick="onClick",不进行混淆-keepclassmembers class * extends android.app.Activity {   public void *(android.view.View);}-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 *(*Event);}-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}-keep class * implements android.os.Parcelable {  public static final android.os.Parcelable$Creator *;}#// natvie 方法不混淆-keepclasseswithmembernames class * {    native <methods>;}#保持 Parcelable 不被混淆-keep class * implements android.os.Parcelable {  public static final android.os.Parcelable$Creator *;}#----------------------------------------------------------------------------#---------------------------------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);}#----------------------------------------------------------------------------#---------------------------------------------------------------------------------------------------#---------------------------------实体类---------------------------------修改成你对应的包名-keep class [your_pkg].** { *; }#---------------------------------第三方包-------------------------------#支付宝支付-keep class com.alipay.android.app.IAlixPay{*;}-keep class com.alipay.android.app.IAlixPay$Stub{*;}-keep class com.alipay.android.app.IRemoteServiceCallback{*;}-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}-keep class com.alipay.sdk.app.PayTask{ public *;}-keep class com.alipay.sdk.app.AuthTask{ public *;}-keep public class * extends android.os.IInterface#微信支付-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*;}-keep class com.tencent.wxop.** { *; }-dontwarn com.tencent.mm.**-keep class com.tencent.mm.**{*;}-keep class sun.misc.Unsafe { *; }-keep class com.taobao.** {*;}-keep class com.alibaba.** {*;}-keep class com.alipay.** {*;}-dontwarn com.taobao.**-dontwarn com.alibaba.**-dontwarn com.alipay.**-keep class com.ut.** {*;}-dontwarn com.ut.**-keep class com.ta.** {*;}-dontwarn com.ta.**-keep class anet.**{*;}-keep class org.android.spdy.**{*;}-keep class org.android.agoo.**{*;}-dontwarn anet.**-dontwarn org.android.spdy.**-dontwarn org.android.agoo.**-keepclasseswithmembernames class com.xiaomi.**{*;}-keep public class * extends com.xiaomi.mipush.sdk.PushMessageReceiver-dontwarn com.xiaomi.push.service.b-keep class org.apache.http.**-keep interface org.apache.http.**-dontwarn org.apache.**#okhttp3.x-dontwarn com.squareup.okhttp3.**-keep class com.squareup.okhttp3.** { *;}-dontwarn okio.**#sharesdk-keep class cn.sharesdk.**{*;}-keep class com.sina.**{*;}-keep class **.R$* {*;}-keep class **.R{*;}-keep class com.mob.**{*;}-dontwarn com.mob.**-dontwarn cn.sharesdk.**-dontwarn **.R$*## nineoldandroids-2.4.0.jar-keep public class com.nineoldandroids.** {*;}####################zxing#####################-keep class com.google.zxing.** {*;}-dontwarn com.google.zxing.**##百度定位-keep class com.baidu.** {*;}-keep class vi.com.** {*;}-dontwarn com.baidu.**## okhttp-dontwarn com.squareup.okhttp.**-keep class com.squareup.okhttp.{*;}#retrofit-dontwarn retrofit.**-keep class retrofit.** { *; }-keepattributes Signature-keepattributes Exceptions-dontwarn okio.**#recyclerview-animators-keep class jp.wasabeef.** {*;}-dontwarn jp.wasabeef.*#multistateview-keep class com.kennyc.view.** { *; }-dontwarn com.kennyc.view.*# universal-image-loader 混淆-dontwarn com.nostra13.universalimageloader.**-keep class com.nostra13.universalimageloader.** { *; }#ormlite-keep class com.j256.**-keepclassmembers class com.j256.** { *; }-keep enum com.j256.**-keepclassmembers enum com.j256.** { *; }-keep interface com.j256.**-keepclassmembers interface com.j256.** { *; }#umeng# ========= 友盟 =================-dontshrink-dontoptimize-dontwarn com.google.android.maps.**-dontwarn android.webkit.WebView-dontwarn com.umeng.**-dontwarn com.tencent.weibo.sdk.**-dontwarn com.facebook.**-keep enum com.facebook.**-keepattributes Exceptions,InnerClasses,Signature-keepattributes *Annotation*-keepattributes SourceFile,LineNumberTable-keep public interface com.facebook.**-keep public interface com.tencent.**-keep public interface com.umeng.socialize.**-keep public interface com.umeng.socialize.sensor.**-keep public interface com.umeng.scrshot.**-keep public class com.umeng.socialize.* {*;}-keep public class javax.**-keep public class android.webkit.**-keep class com.facebook.**-keep class com.umeng.scrshot.**-keep public class com.tencent.** {*;}-keep class com.umeng.socialize.sensor.**-keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;}-keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;}-keep class im.yixin.sdk.api.YXMessage {*;}-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;}下面中括号的地方需要要填你的包名-keep public class [your_pkg].R$*{    public static final int *;}-keepclassmembers class * {   public <init> (org.json.JSONObject);}-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}#友盟自动更新-keep public class com.umeng.fb.ui.ThreadView {}-keep public class * extends com.umeng.**# 以下包不进行过滤-keep class com.umeng.** { *; }#-ButterKnife 7.0 -keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * {  @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; }#AndFix-keep class * extends java.lang.annotation.Annotation-keepclasseswithmembernames class * {    native <methods>;}#eventbus 3.0-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);}#EventBus-keepclassmembers class ** {    public void onEvent*(**);}-keepclassmembers class ** {public void xxxxxx(**);}################gson##################-keep class com.google.gson.** {*;}-keep class com.google.**{*;}-keep class sun.misc.Unsafe { *; }-keep class com.google.gson.stream.** { *; }-keep class com.google.gson.examples.android.model.** { *; }-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 public class * implements java.io.Serializable {*;}# support-v4#https://stackoverflow.com/questions/18978706/obfuscate-android-support-v7-widget-gridlayout-issue-dontwarn android.support.v4.**-keep class android.support.v4.app.** { *; }-keep interface android.support.v4.app.** { *; }-keep class android.support.v4.** { *; }# support-v7-dontwarn android.support.v7.**-keep class android.support.v7.internal.** { *; }-keep interface android.support.v7.internal.** { *; }-keep class android.support.v7.** { *; }# support design#@link http://stackoverflow.com/a/31028536-dontwarn android.support.design.**-keep class android.support.design.** { *; }-keep interface android.support.design.** { *; }-keep public class android.support.design.R$* { *; }#-------------------------------------------------------------------------# picasso-keep class com.squareup.picasso.** {*; }  -dontwarn com.squareup.picasso.**#glide-keep public class * implements com.bumptech.glide.module.GlideModule-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {  **[] $VALUES;  public *;}# #  ######## greenDao混淆  ########## # # --------------------------------------------keep class de.greenrobot.dao.** {*;}-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {    public static Java.lang.String TABLENAME;}-keep class **$Properties# #  ############### volley混淆  ############### # # --------------------------------------------keep class com.android.volley.** {*;}-keep class com.android.volley.toolbox.** {*;}-keep class com.android.volley.Response$* { *; }-keep class com.android.volley.Request$* { *; }-keep class com.android.volley.RequestQueue$* { *; }-keep class com.android.volley.toolbox.HurlStack$* { *; }-keep class com.android.volley.toolbox.ImageLoader$* { *; }#jpush极光推送-dontwarn cn.jpush.**-keep class cn.jpush.** { *; }#activeandroid-keep class com.activeandroid.** { *; }-dontwarn com.ikoding.app.biz.dataobject.**-keep public class com.ikoding.app.biz.dataobject.** { *;}-keepattributes *Annotation*#log4j-dontwarn org.apache.log4j.**-keep class  org.apache.log4j.** { *;}#下面几行 是环信即时通信的代码混淆-keep class com.easemob.** {*;}-keep class org.jivesoftware.** {*;}-dontwarn  com.easemob.**#融云-keepclassmembers class fqcn.of.javascript.interface.for.webview { public *;}-keepattributes Exceptions,InnerClasses-keep class io.rong.** {*;}-keep class * implements io.rong.imlib.model.MessageContent{*;}-keepattributes Signature-keepattributes *Annotation*-keep class sun.misc.Unsafe { *; }-keep class com.google.gson.examples.android.model.** { *; }-keepclassmembers class * extends com.sea_monster.dao.AbstractDao { public static java.lang.String TABLENAME;}-keep class **$Properties-dontwarn org.eclipse.jdt.annotation.**-keep class com.ultrapower.** {*;}#高徳地图-dontwarn com.amap.api.**   -dontwarn com.a.a.**   -dontwarn com.autonavi.**   -keep class com.amap.api.**  {*;}      -keep class com.autonavi.**  {*;}-keep class com.a.a.**  {*;}#---------------------------------反射相关的类和方法-----------------------在这下面写反射相关的类和方法,没有就不用写!#---------------------------------与js互相调用的类------------------------在这下面写与js互相调用的类,没有就去掉这句话!#---------------------------------自定义View的类------------------------在这下面写自定义View的类的类,没有就去掉这句话!#SuperID#由*郭宇翔*贡献混淆代码#作者Github地址:https://github.com/yourtion-keep class **.R$* {*;}-keep class com.isnc.facesdk.aty.**{*;}-keep class com.isnc.facesdk.**{*;}-keep class com.isnc.facesdk.common.**{*;}-keep class com.isnc.facesdk.net.**{*;}-keep class com.isnc.facesdk.view.**{*;}-keep class com.isnc.facesdk.viewmodel.**{*;}-keep class com.matrixcv.androidapi.face.**{*;}#retrofit2.x-dontwarn retrofit2.**-keep class retrofit2.** { *; }-keepattributes Signature-keepattributes Exceptions#Rxjava RxAndroid-dontwarn rx.*-dontwarn sun.misc.**-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {   long producerIndex;   long consumerIndex;}-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {    rx.internal.util.atomic.LinkedQueueNode producerNode;}-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {    rx.internal.util.atomic.LinkedQueueNode consumerNode;}#litepal-dontwarn org.litepal.-keep class org.litepal.* { ; }-keep enum org.litepal.*-keep interface org.litepal. { ; }-keep public class  extends org.litepal.-keepattributes Annotation-keepclassmembers class * extends org.litepal.crud.DataSupport{*;}  #fastJson-dontwarn com.alibaba.fastjson.**-keep class com.alibaba.fastjson.** { *; }# Okio-dontwarn com.squareup.**  -dontwarn okio.**  -keep public class org.codehaus.* { *; }  -keep public class java.nio.* { *; }# Retrolambda-dontwarn java.lang.invoke.*

转载请注明原博客地址 Android 代码混淆语法讲解及常用模板

阅读全文
0 0
原创粉丝点击