JAVA之代码混淆proguard基础(一)

讲解的比较全面的一篇文章http://blog.csdn.net/glony/article/details/8852245


一官方网站用法

              http://proguard.sourceforge.net/index.html#/manual/examples.html

   基础:

Input/Output Options
Keep Options
Shrinking Options
Optimization Options
Obfuscation Options
Preverification Options
General Options
Class Paths
File Names
File Filters
Filters
Overview of Keep Options
Keep Option Modifiers
Class Specifications

  二proguard主要三部分功能

         缩减代码、优化代码、混淆代码。三部分功能都可以在配置文件里配置不启用此功能。

 #Shrink Options

#不缩减代码
-dontshrink


#Optimization Options
-dontoptimize


#Obfuscate Options 
#-不混淆输入的类文件 
#-dontobfuscate 



三用法

Class Specifications 类规范,详细定义了类、接口、枚举、成员、方法等 -keep options 和-assumenosideeffects option的保留规则。

   匹配符*在类、接口、枚举、成员、方法的使用方法。

   仔细阅读

Filters

Overview of Keep Options

Keep Option Modifiers

Class Specifications

   1.在配置文件中例如xml中引用到的类名,不能混淆重命名。因为配置时需要通过配置文件路径加载类。

     android中的例如Activity的配置-keep public class * extends android.app.Activity(只保留类名,类名不会混淆重命名,但是其成员和方法会混淆)

     在xml中出现的有Activity、Application、Service、BroadcastReceiver、ContentProvider、Fragment、Context、LinearLayout、View等自定义视图。

   

   2.保留sdk系统自带的一些内容。

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

     比如-keepattributes *Annotation*会保留Activity的被@Override注释的方法onCreate、onDestroy方法等。

   3.资源类变量需要保留

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

   4.保留第三方jar包的所有类及其成员和方法,例如{ *;}匹配了类内的所有成员和方法。

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

  5.缺省情况下,proguard 会混淆所有代码,但是下面几种情况是不能改变java 元素的名称,否则就会这样就会导致程序出错。
一,我们用到反射的地方
二, 我们代码依赖于系统的接口,比如被系统代码调用的回调方法,这种情况最复杂。
三, 是我们的java 元素名称是在配置文件中配置好的。

   6.对出现问题的类的处理。遇见一个及添加。


    -keep用法区别

1)保留某个类名不被混淆

-keep public class com.ebt.app.common.bean.Customer

2)保留类及其所有成员不被混淆

-keep public class com.ebt.app.common.bean.Customer { *;}

或者
-keepclasseswithmembers class com.ebt.app.common.bean.Customer {

    <init>;#匹配所有构造函数

    <fields>;#匹配所有成员
    <methods>;#匹配所有方法
}

3)只保留类名及其部分成员不被混淆

-keep public class com.ebt.app.common.bean.Customer { 

    static final<fields>;

    private void get*();

}

4)#保留包路径下所有的类及其属性和方法
-keep class com.ebt.app.sync.** { *;}


6.混淆后出现问题的调试方法

  1)打印日志,保留异常,源文件行数信息。

-printmapping out.map
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,SourceFile

  2)确定哪一行哪个类出错。

也可以使用Log或者System.out在可能出错的行前后打印测试日志,以确定具体出错的类是哪一个。来决定是否保留。


参考http://blog.csdn.net/fastthinking/article/details/49420467


http://blog.chengyunfeng.com/?p=545


   7.常见*的用法区别

修饰类、接口、枚举等时


*matches any part of a class name not containing the package separator. For example, "mypackage.*Test*" matches "mypackage.Test" and "mypackage.YourTestApplication", but not "mypackage.mysubpackage.MyTest". Or, more generally, "mypackage.*" matches all classes in "mypackage", but not in its subpackages.
**matches any part of a class name, possibly containing any number of package separators. For example, "**.Test" matches all Test classes in all packages except the root package. Or, "mypackage.**" matches all classes in "mypackage" and in its subpackages.
   修饰构造函数、成员变量、方法

  • Fields and methods are specified much like in Java, except that method argument lists don't contain argument names (just like in other tools like javadoc and javap). The specifications can also contain the following catch-all wildcards:
    <init>matches any constructor.
    <fields>matches any field.
    <methods>matches any method.
    *matches any field or method.
    Note that the above wildcards don't have return types. Only the <init> wildcard has an argument list.

    Fields and methods may also be specified using regular expressions. Names can contain the following wildcards:

    ?matches any single character in a method name.
    *matches any part of a method name.
    Types in descriptors can contain the following wildcards:
    %matches any primitive type ("boolean", "int", etc, but not "void").
    ?matches any single character in a class name.
    *matches any part of a class name not containing the package separator.
    **matches any part of a class name, possibly containing any number of package separators.
    ***matches any type (primitive or non-primitive, array or non-array).
    ...matches any number of arguments of any type.
    Note that the ?*, and ** wildcards will never match primitive types. Furthermore, only the *** wildcards will match array types of any dimension. For example, "** get*()" matches "java.lang.Object getObject()", but not "float getFloat()", nor "java.lang.Object[] getObjects()".

  • Constructors can also be specified using their short class names (without package) or using their full class names. As in the Java language, the constructor specification has an argument list, but no return type.
  • The class access modifiers and class member access modifiers are typically used to restrict wildcarded classes and class members. They specify that the corresponding access flags have to be set for the member to match. A preceding ! specifies that the corresponding access flag should be unset.

    Combining multiple flags is allowed (e.g. public static). It means that both access flags have to be set (e.g. public and static), except when they are conflicting, in which case at least one of them has to be set (e.g. at least public or protected).

    ProGuard supports the additional modifiers syntheticbridge, and varargs, which may be set by compilers.


四常见实例

   http://proguard.sourceforge.net/index.html#/manual/examples.html

   

五总结常见的保留原则

   -keep options选项里说明了一些要保留的选项。

   

六一个android apk 配置实例

#Shrink Options
#不缩减代码
-dontshrink

#Optimization Options
-dontoptimize
-optimizations !code/simplification/arithmetic
-allowaccessmodification

#Obfuscate Options 
#-不混淆输入的类文件 
#-dontobfuscate 
-printmapping out.map
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-repackageclasses ''

# Add any project specific keep options here:
#Keep Options

<span style="color:#ff0000;">#android config</span>
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-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.Fragment
-keep public class * extends LinearLayout
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.content.Context {
   public void *(android.view.View);
   public void *(android.view.MenuItem);
}

-keepclassmembers class * implements android.os.Parcelable {
    static ** CREATOR;
}

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

-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

# Keep serializable classes and necessary members for serializable classes
# Copied from the ProGuard manual at http://proguard.sourceforge.net.
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}

<span style="color:#ff0000;">#jar config</span>
-dontwarn org.apache.log4j.**
-keep class org.apache.log4j.** { *;}

-dontwarn com.baidu.oauth.**
-keep class com.baidu.oauth.** { *;}

-dontwarn org.achartengine.**
-keep class org.achartengine.** { *;}

-dontwarn net.sourceforge.jeval.**
-keep class net.sourceforge.jeval.** { *;}

-dontwarn de.greenrobot.dao.**
-keep class de.greenrobot.dao.** { *;}

-dontwarn org.wltea.expression.**
-keep class org.wltea.expression.** { *;}

-dontwarn org.apache.commons.net.**
-keep class org.apache.commons.net.** { *;}

-dontwarn com.baidu.pcs.**
-keep class com.baidu.pcs.** { *;}

-dontwarn de.mindpipe.android.logging.log4j.**
-keep class de.mindpipe.android.logging.log4j.** { *;}

-dontwarn com.google.gson.**
-keep class com.google.gson.** { *;}

-dontwarn com.google.**
-keep class com.google.** { *;}

-dontwarn org.apache.http.entity.mime.**
-keep class org.apache.http.entity.mime.** { *;}


<span style="color:#ff0000;">#special config</span>
-keep public class com.app.common.bean.CustomerData { *;}
#-keep public class com.app.common.bean.Customer { *;}
-keepclasseswithmembers class com.app.common.bean.Customer {
    <fields>;
    <methods>;
}
-keep public class com.app.common.bean.VRepositoryCategory {*;}


  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
ProGuard 是一个可以对 Java 代码进行混淆、优化、压缩的工具,它可以有效地保护你的代码不被反编译或者修改。ProGuard混淆功能是通过将代码中的方法、变量名等替换成无意义的字符来实现的,这样可以使得反编译后的代码难以阅读和理解,从而提高了代码的安全性。 要使用 ProGuard 进行混淆,首先需要在项目的 build.gradle 文件中添加如下依赖: ``` buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } ``` 其中,minifyEnabled 设置为 true 表示开启混淆;getDefaultProguardFile('proguard-android-optimize.txt') 表示使用默认的 ProGuard 配置文件;'proguard-rules.pro' 是自定义的 ProGuard 配置文件,可以在其中指定需要混淆代码和保留不混淆代码等。 接下来,在 proguard-rules.pro 文件中添加混淆规则,可以根据具体的项目需求进行配置。例如,可以添加以下规则: ``` # 保留代码中的所有的成员 -keepclassmembers class * { *; } # 保留特定的的成员 -keep class com.example.MyClass { public <methods>; protected <methods>; } # 指定混淆规则 -obfuscationdictionary dictionary.txt ``` 其中,-keep 表示保留特定的代码,-obfuscationdictionary 表示指定混淆规则字典。 最后,编译项目即可进行混淆。需要注意的是,代码混淆虽然可以提高代码的安全性,但同时也可能会影响代码的性能和运行结果,因此需要进行充分的测试和验证。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值