zoukankan      html  css  js  c++  java
  • 利用Ant与Proguard混淆

    利用Ant与Proguard混淆

    摘自:https://blog.csdn.net/forlong401/article/details/22956711 

    2014年04月04日 20:20:21 forlong401 阅读数:1409更多
    个人分类: android混淆Ant

    http://www.saikoa.com/dexguard

    http://blog.csdn.net/chenrunhua/article/details/8660616

    当前的web项目有引用到子工程项目,而且多个子工程项目也有引用到其它的工程项目,现要求利用Ant自动将web项目打包成war包,其中引用到的子工程项目需打成jar包,而且必须是混淆后的jar包。其中混淆代码的工具选择了开源的Proguard(http://proguard.sourceforge.net/),可以运行proguard自带的proguardgui.jar(图形化用户界面)生成proguard配置文件。

     

     

    ProGuard是一个免费的java类文件压缩,优化,混淆器.它探测并删除没有使用的类,字段,方法和属性.它删除没有用的说明并使用字节码得到最大优化.它使用无意义的名字来重命名类,字段和方法. 
    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}    设置源文件中给定的字符串常量 


    因为我们开发的是struts2+spring+openjpa的架构的项目,所有需要很详细的配置,其中proguard需要的injars,outjars还有其它的一些libraryjars在Ant的build.xml文件以参数形式加入。
    proguard.pro文件具体内容:
    -libraryjars  <java.home>/lib/rt.jar
    -libraryjars  <java.home>/lib/jce.jar
    -libraryjars  <java.home>/lib/jsse.jar

    -obfuscationdictionary dictionaries/compact.txt
    -classobfuscationdictionary dictionaries/shakespeare.txt

    # -printmapping proguard.map 
    -overloadaggressively 
    -defaultpackage '' 
    # -flattenpackagehierarchy ''
    # -dontusemixedcaseclassnames
    # -keeppackagenames
    -allowaccessmodification 
    -dontoptimize 
    # 因为项目中使用到了jpa的Annotation注解,需要保留这个属性
    -keepattributes *Annotation*

    # Keep web listener-class,自己编写的web listener,不能混淆,不然启动服务的时候会报错
    -keep public class com.test.mylistener {
    public protected *;
    }

    # Keep jpa dao, 自身编写的一些dao接口不能混淆,而且如果是有被spring管理的dao, 也应该不进行混淆
    -keep public class com.test.dao.* {
    public protected *;
    }
    # 其中jpa dao中使用到的一些重要接口也能进行混淆
    -keep public class com.test.persistence.core.QueryLiteral {
    public protected *;
    }
    -keep public class com.test.persistence.JpaDao {
    public protected *;
    }

    # Keep beans managed by spring framework,spring管理的bean不进行混淆
    -keep public class com.test.provider.* {
    public protected *;
    }

    # Keep Network interface
    -keep public class com.test.loader.Network {
    public protected *;
    }

    # Keep entity classes extends java.io.Serializable
    # 保留jpa中使用到的所有实体类,不进行混淆
    -keep public class * implements java.io.Serializable{ 
    public protected private *; 
    }

    -keep public class com.test.entity.* { 
        public protected private *; 

    # Keep - Applications. Keep all application classes, along with their 'main' methods.
    -keepclasseswithmembers public class * {
        public static void main(java.lang.String[]);
    }

    # Keep names - Native method names. Keep all native class/method names.
    -keepclasseswithmembers,allowshrinking class * {
        native <methods>;
    }
    proguard和build.xml文件具体目录结构:
    server工程
       -src目录
       -build目录
       -proguard目录
            -dictionaries 主要存放混淆时需要用到字典文件,可以使用官网下载到的proguard.zip包中dictionaries的两个文件(dictionaries/compact.txt,dictionaries/shakespeare.txt)
            -lib 存放proguard.jar包,这是混淆中使用到的最主要的一个jar包(下载到的proguard.zip中)
            -proguard.pro  主要的混淆配置文件
       -build.xml
    结合文件形式来配置

    ANDROID代码混淆的实践


    1. 基本配置

    eclipse下建立android工程,就会生成proguard.cfg和project.properties,在后面的文件追加proguard.config=proguard.cfg即可让前面的配置文件在export时生效。默认的那个文件有一些内容,这里给一个更通用点的。

    ##—————Begin: proguard configuration common for all Android apps ———-
    -optimizationpasses 5
    -dontusemixedcaseclassnames
    -dontskipnonpubliclibraryclasses
    -dontskipnonpubliclibraryclassmembers
    -dontpreverify
    -verbose
    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
    -keepattributes *Annotation*
    -renamesourcefileattribute SourceFile
    -keepattributes SourceFile,LineNumberTable

    # 以下两个命令配合让类的路径给删除了
    -allowaccessmodification
    -repackageclasses ”

    # 记录生成的日志数据,在proguard目录下
    -dump class_files.txt
    -printseeds seeds.txt
    -printusage unused.txt
    -printmapping mapping.txt

    # 异常都可以忽略就打开
    #-dontwarn

    -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
    -dontnote com.android.vending.licensing.ILicensingService

    -keepnames class * implements java.io.Serializable

    # Explicitly preserve all serialization members. The Serializable interface
    # is only a marker interface, so it wouldn’t save them.
    -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();
    }

    # Preserve all native method names and the names of their classes.
    -keepclasseswithmembernames class * {
    native ;
    }

    -keepclasseswithmembernames class * {
    public (android.content.Context, android.util.AttributeSet);
    }

    -keepclasseswithmembernames class * {
    public (android.content.Context, android.util.AttributeSet, int);
    }

    # Preserve static fields of inner classes of R classes that might be accessed
    # through introspection.
    -keepclassmembers class **.R$* {
    public static ;
    }

    # Preserve the special static methods that are required in all enumeration classes.
    -keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
    }

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

    # 如果你的工程是对外提供方法调用就打开
    #-keep public class * {
    # public protected *;
    #}

    ##—————End: proguard configuration common for all Android apps ———-

    2. 解决export打包的报错

    这个时候export提示“conversion to Dalvik format failed with error 1”错误,网上说法有好多种,最后我还是把proguard从4.4升级到4.8就解决了。官方地址是http://proguard.sourceforge.net。上面的配置文件参数可以在这里查阅。

    升级办法很简单,就是把android sdk目录下的tool/proguard目录覆盖一下即可。

    3. 打包出来的程序如何调试

    一旦打包出来,就不能用eclipse的logcat去看了,这里可以用android sdk中ddms.bat的tool来看,一用就发现和logcat其实还是一个东西,就是多了个设备的选择。

    4. 使用 gson 需要的配置

    当Gson用到了泛型就会有报错,这个真给郁闷了半天,提示“Missing type parameter”。最后找到一个资料给了一个解决办法,参考:http://stackoverflow.com/questions/8129040/proguard-missing-type-parameter。

    另外我又用到了JsonObject,提交的Object里面的members居然被改成了a。所以上面给的东西还不够,还要加上

    # 用到自己拼接的JsonObject
    -keep class com.google.gson.JsonObject { *; }

    我个人建议减少这些依赖包混淆带来的麻烦,干脆都全部保留不混淆。例如

    -keep class com.badlogic.** { *; }
    -keep class * implements com.badlogic.gdx.utils.Json*
    -keep class com.google.** { *; }

    5. 使用libgdx需要的配置

    参考http://code.google.com/p/libgdx-users/wiki/Ant

    6. 验证打包效果

    我是利用了apktool的反编译工具,把打包文件又解压了看了一下,如果包路径、类名、变量名、方法名这些变化和你期望一致,那就OK了。命令:

    apktool.bat d xxx.apk destdir

    总结

    这个东西用起来也不是很简单,特别是你程序用到的高级特性多,就更容易出问题。另外proguard的参数看起来确实也有点不好理解,打包过程慢,测试也比较浪费时间。东西虽好,但真不是那么容易上手。

  • 相关阅读:
    BigDecimal中的8中舍入模式详解
    使用二倍均值法完成红包算法
    使用Calendar类和它的子类GregorianCalendar类实现构建动态日历
    『MelodyHub』书写是对思维的缓存
    本站已接入音乐播放器API
    【LeetCode】35. 搜索插入位置
    配置NodeJs环境变量
    利用GitHub博客连接多仓库
    hexo 大型车祸现场
    随机图片API
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/9640013.html
Copyright © 2011-2022 走看看