Android ProGuard混淆分析

# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# 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 *;
#}

# 需要混淆的jar包
-injars androidtest.jar

# 混淆后输出的jar包路径
-outjars out

# 需要混淆的jar包所依赖的jar包
-libraryjars /Users/tustar/Documents/Android/ADT/sdk/platforms/android-19/android.jar

-optimizationpasses 5  

# 混淆时不会产生形形色色的类名
-dontusemixedcaseclassnames  

# 指定不去忽略非公共的库类
-dontskipnonpubliclibraryclasses  

# 不预校验
-dontpreverify
 
-verbose  

# 优化
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

# 保留了继承自Activity、Application、Service、BroadcastReceiver、ContentProvider、BackupAgentHelper、Preference和ILicensingService  的子类。因为这些子类,都是可能被外部调用的。
-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.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

# 若webview中调用了js代码, 保持原样不混淆
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
    public *;
}

-keep public abstract interface com.asqw.android.Listener{
    # 所有方法不进行混淆
    public protected <methods>;  
}

-keep public class com.asqw.android {
    # 对该方法不进行混淆
    public void start(java.lang.String);
}

# 保留了含有native方法的类
-keepclasseswithmembernames class * {  
    native <methods>;  
}  

# 保留构造函数从xml构造的类(一般为View的子类)
-keepclasseswithmembernames class * {  
    public <init>(android.content.Context, android.util.AttributeSet);  
}

# 保留构造函数从xml构造的类(一般为View的子类)
-keepclasseswithmembernames class * {  
    public <init>(android.content.Context, android.util.AttributeSet, int);  
}

# 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclassmembers class * extends android.app.Activity {
    public void *(android.view.View);
}
 
# 保留枚举类型中的values和valueOf静态方法
-keepclassmembers enum * {  
    public static **[] values();  
    public static ** valueOf(java.lang.String);  
}  

# 保留继承Parcelable的跨进程数据类
-keep class * implements android.os.Parcelable {  
  public static final android.os.Parcelable$Creator *;  
}


ProGuard的作用:
 
1.创建紧凑的代码文档是为了更快的网络传输,快速装载和更小的内存占用.
2.创建的程序和程序库很难使用反向工程.
3.所以它能删除来自源文件中的没有调用的代码
4.充分利用java6的快速加载的优点来提前检测和返回java6中存在的类文件.
 
参数:
 
-include {filename}    从给定的文件中读取配置参数
-basedirectory {directoryname}    指定基础目录为以后相对的档案名称
-injars {class_path}    指定要处理的应用程序jar,war,ear和目录
-outjars {class_path}    指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath}    指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses    指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers    指定不去忽略包可见的库类的成员。

保留选项

-keep {Modifier} {class_specification}    保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification}    保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification}    保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification}    保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification}    保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification}    保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename}    列出类和类的成员-keep选项的清单,标准输出到给定的文件
 
压缩

-dontshrink    不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}    
 
优化

-dontoptimize    不优化输入的类文件
-assumenosideeffects {class_specification}    优化时假设指定的方法,没有任何副作用
-allowaccessmodification    优化时允许访问并修改有修饰符的类和类的成员
 
混淆

-dontobfuscate    不混淆输入的类文件
-printmapping {filename}
-applymapping {filename}    重用映射增加混淆
-obfuscationdictionary {filename}    使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively    混淆时应用侵入式重载
-useuniqueclassmembernames    确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name}    重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name}    重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames    混淆时不会产生形形色色的类名
-keepattributes {attribute_name,...}    保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string}    设置源文件中给定的字符串常量


Ant Example:

<!-- This Ant build file illustrates how to process applications,
     by including ProGuard-style configuration options.
     Usage: ant -f applications2.xml -->

<project name="Applications" default="obfuscate" basedir="../..">

<target name="obfuscate">
  <taskdef resource="proguard/ant/task.properties"
           classpath="lib/proguard.jar" />

  <proguard>

    <!-- Specify the input jars, output jars, and library jars. -->

    -injars  in.jar
    -outjars out.jar

    -libraryjars ${java.home}/lib/rt.jar
    <!-- -libraryjars junit.jar    -->
    <!-- -libraryjars servlet.jar  -->
    <!-- -libraryjars jai_core.jar -->
    <!-- ...                       -->

    <!-- Save the obfuscation mapping to a file, and preserve line numbers. -->

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

    <!-- Preserve all annotations. -->

    -keepattributes *Annotation*

    <!-- Preserve all public applications. -->

    -keepclasseswithmembers public class * {
        public static void main(java.lang.String[]);
    }

    <!-- Preserve all native method names and the names of their classes. -->

    -keepclasseswithmembernames class * {
        native &lt;methods&gt;;
    }

    <!-- Preserve the methods that are required in all enumeration classes. -->

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

    <!-- Explicitly preserve all serialization members. The Serializable
         interface is only a marker interface, so it wouldn‘t save them.
         You can comment this out if your library doesn‘t use serialization.
         If your code contains serializable classes that have to be backward
         compatible, please refer to the manual. -->

    -keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        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();
    }

    <!-- Your application may contain more items that need to be preserved;
         typically classes that are dynamically created using Class.forName -->

  </proguard>
</target>

</project>


 运行混淆器之后输出的文件有:

         dump.txt

                   描述.apk包中所有class文件的内部结构。

         mapping.txt

                   列出了源代码与混淆后的类,方法和属性名字之间的映射。这个文件对于在构建之后得到的bug报告是有用的,因为它把混淆的堆栈跟踪信息反翻译为源代码中的类,方法和成员名字。更多信息,查看解码混淆过的堆栈跟踪信息。

         seeds.txt

                   列出那些未混淆的类和成员。

         usage.txt

                   列出从.apk中剥离的代码。


每次混淆后,都需要保存dump.txt、mapping.txt 、seeds.txt 、usage.txt. 其中mapping.txt必须要保存,因为该文件丢失会导致查找不到BUG的源头

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。