利用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的参数看起来确实也有点不好理解,打包过程慢,测试也比较浪费时间。东西虽好,但真不是那么容易上手。

利用Ant与Proguard混淆的更多相关文章

  1. 利用android proguard混淆代码

    利用android proguard混淆代码 2014-02-05 17:50 1207人阅读 评论(1) 收藏 举报 网上虽然有很多相关博客,不过貌似都不是最新版的..于是百度+谷歌+github上 ...

  2. 使用proguard混淆android代码

    当前是有些工具比方apktool,dextojar等是能够对我们android安装包进行反编译,获得源代码的.为了降低被别人破解,导致源代码泄露,程序被别人盗代替码,等等.我们须要对代码进行混淆,an ...

  3. android开发Proguard混淆与反射

    http://charles-tanchao.diandian.com/post/2012-05-24/20118715 由于前面开发数据操作类,所以利用反射,封装了一个BaseDao,本来在平常的时 ...

  4. Android 代码混淆、Android Proguard(混淆)

    Android Proguard(混淆)   混淆(Proguard)用法 最近项目中遇到一些混淆相关的问题,由于之前对proguard了解不多,所以每次都是面向Stackoverflow的编程.co ...

  5. Android Proguard混淆对抗之我见

    关于何为Proguard,可以参考GuardSquare官网其优化业务及Wikipedia相关条目. Proguard:https://www.guardsquare.com/proguard Wik ...

  6. 利用ant脚本 自动构建svn增量/全量 系统程序升级包

    首先请允许我这样说,作为开发或测试,你一定要具备这种 本领.你可以手动打包.部署你的工程,但这不是最好的方法.最好的方式就是全自动化的方式.开发人员提交了代码后,可以自动构建.打包.部署到测试环境. ...

  7. linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件

    原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html  之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...

  8. Android:如何从堆栈中还原ProGuard混淆后的代码

    本文翻译自Android: How To Decode ProGuard's Obfuscated Code From Stack Trace 本篇文章是写给那些在他们的应用中使用ProGuard并且 ...

  9. 利用 Ant 和 Eclipse 有效地提高部署工作效率

    读者定位为具有 Java 和 Ant 使用经验的开发人员. 读者可以学习到如何使用 Ant 解决一些多用户开发环境中,根据不同的目标环境编译成不同部署包的问题. 工作场景 现在有一个 web 项目,是 ...

随机推荐

  1. Mybatis数据的增删改查

    数据: Student{id int,name String ,age int} 配置mybatis-config.xml <?xml version="1.0" encod ...

  2. scanf在竞赛中的技巧总结ing

    前言 当输入流是一个字符串,我们需要在其中提取我们所需要的数值时,我们可以在读入阶段就完成数据的筛选工作. 使用方法 scanf("%ns", str); 表示读取长度为n的字符串 ...

  3. Bootstrap组件系列之福利篇几款好用的组件(推荐)

    引用 :http://www.jb51.net/article/87189.htm 一.时间组件 bootstrap风格的时间组件非常多,你可以在github上面随便搜索“datepicker”关键字 ...

  4. martin/docker-cleanup-volumes

    https://hub.docker.com/r/martin/docker-cleanup-volumes/

  5. Python Twisted系列教程18:Deferreds 全貌

    作者:dave@http://krondo.com/deferreds-en-masse/  译者: Cheng Luo 你可以从”第一部分 Twist理论基础“开始阅读:也可以从”Twisted 入 ...

  6. 深入浅出 Java Concurrency (7): 锁机制 part 2 AQS

      在理解J.U.C原理以及锁机制之前,我们来介绍J.U.C框架最核心也是最复杂的一个基础类:java.util.concurrent.locks.AbstractQueuedSynchronizer ...

  7. 使用Spring MVC创建 REST API

    1.REST的基础知识 当谈论REST时,有一种常见的错误就是将其视为“基于URL的Web服务”——将REST作为另一种类型的远程过程调用(remote procedurecall,RPC)机制,就像 ...

  8. 数据库,使用Druid 加密数据库密码

    首先我们得下载一个druid-1.0.16.jar的包 其次键入命令 java -cp druid-1.0.16.jar com.alibaba.druid.filter.config.ConfigT ...

  9. iOS学习之UIDatePicker控件使用

    iOS上的选择时间日期的控件是这样的,左边是时间和日期混合,右边是单纯的日期模式. ,   您可以选择自己需要的模式,Time, Date,Date and Time  , Count Down Ti ...

  10. C# 调用动态代码

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...