1. 用proguard混淆代码
android sdk 自带 proguard 包,因此用proguard混淆 很简单,只需简单配置下就好
1. 在 project.properties里开启 proguard :
sdk.dir=D:\\android\\tool\\android-sdk-windows_4.0
proguard.config=${sdk.dir}\\tools\\proguard\\proguard-android.txt:proguard.cfg
2. 在 proguard.cfg做具体配置
某些情况下,proguard.cfg文件的缺省配置可以满足需求了。但是,对于混淆器来说,大多数情况做出正确的分析是困难的,并且它或许会删除在它看来是无用的,但对于程序来说却确实需要的代码。一些例子如下:
l 一个仅引用于AndroidManifest.xml文件的类。
l 一个通过JNI调用的方法。
l 动态引用的属性和方法。
缺省的proguard.cfg文件试图覆盖普通的情况,但是你可能碰到类似ClassNotFoundException的异常,这个异常出现在当你的程序去访问一个被混淆器移除了的类的时候。
你可以在proguard.cfg文件中添加-keep这一行来修复这些错误。例如:
-keep public class <MyClass>
-Keep设置有很多可选项和注意地方,所以为了获得更多关于配置信息,强烈推荐你阅读混淆器用户手册。特别有用的有Keep选项综述和举例部分。在混淆器手册问题解决方案部分,介绍了代码在混淆过程中你可能碰到的其他常见问题。
如 不混淆 某些jia包 等
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-dontwarn com.unionpay.**
-keep class com.unionpay.** { *; }
3.可能出现的错误 :
missing type parameter at com.google.gson.b.a.a
程序中用到了gson的new typeToken,结果打包成apk发布时,发现抛出异常,解决方法:
在 proguard.cfg中添加
-dontobfuscate
-dontoptimize
xx cannot be resolved to a type
出现这个错误 就是引用的jar包也被混淆了,找到具体的jar包,设置下 keep即可
-keep class cn.sharesdk.** { *; }
注意 : 如果因为引用包混淆出现的错误 很有可能 不会直接显示,只有程序调用引用包的时候 才会报错,因此混淆后需要充分测试,特别是针对引包,如
分享 登陆 二维码扫描 百度地图 jpush 支付宝 银联 等 需要跑一便看看是否正常。
4 已发布应用程序的调试注意事项
保存好每一个已发布给用户的程序的mapping.txt文件。通过保存发布构建版本的mapping.txt文件拷贝,确保当用户碰到bug,并把混淆后的堆栈调试跟踪信息提交给你时,你可以进行调试从而修复问题。程序的mapping.txt文件在每次发布构建时都会被覆盖,所以你一定要注意保存正确的版本。
例如,假设你已经发布了一个应用程序并在继续在新的版本中开发添加新的功能。接着你马上启动混淆器并创建一个新的发布版本。该操作把mapping.txt文件覆盖了。一个用户提交了来自当前发布版本的bug报告,该报告包含了堆栈调试信息。你再也不能对用户的堆栈信息进行调试了,因为这个对应用户本机上版本的mapping.txt文件不存在了。其他覆盖mapping.txt文件的情况还有很多,所以对于每一个可能需要调试的版本,你都要确保有一份拷贝。
如何保存mapping.txt文件由你决定。例如,你可以根据版本和构建号来重命名它们,或者连同你的源代码进行版本控制。
5. 混淆语法:
参数:
-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} 设置源文件中给定的字符串常量
我这里加上了-keep public class com.emag.ui.GameCommunity{ public *;} 的参数,含义就是 class com.emag.ui.GameCommunity这个类下面的所有public方法和字段都不需要混淆。
这里放上另外一份配置文件,希望对大家有所帮助:
这个是web的项目,使用ProGuard混淆打包的。
是webwork+spring+hibernate的架构的项目,所有需要很详细的配置。(经过n次失败后总结)
Example:
-injars <project>.jar
-outjars <project>_out.jar
-libraryjars <java.home>/lib/rt.jar
-libraryjars <project.home>/webroot/WEB-INF/lib/webwork.jar
.......
# 保留实现Action接口类中的公有的,友好的,私有的属性 和 公有的,友好的方法。其它的全部压缩,优化,混淆。
# 因为配置文件中的类名是一个完整的类名,如果经过处理后就有可能找不到这个类。
# 属性是jsp页面所需要的,如果经过处理jsp页面就无法得到action中的数据。
-keep public class * implements com.opensymphony.xwork.Action{
public protected private <fields>;
public protected <methods>;
}
# 保留实现了Serializable接口类中的公有的,友好的,私有的成员(属性和方法)
# 这个配置主要是对应实体类的配置。
-keep public class * implements java.io.Serializable{
public protected private *;
}
2.代码反编译
1. 把apk文件 修改zip 解压 ,解压出 classes.dex文件
2、还原.jar文件;这一步需要用到一个工具 dex2jar (http://download.csdn.net/detail/socketsyuhai/9296139)
看名字也不难知道他是干嘛的了吧?(没错,就是 把 dex 还原 成 jar包 )
下载完了,解压,然后把第一步的 产物(即那个classes.dex文件)放到 dex2jar的解压目录里
cmd 命令行 ,目录切换到 dex2jar的目录下
“ dex2jar.bat classes.dex” (版本不一样,前面 dex2jar.bat 可能有细微差别,具体看 安装的dex2jar下面的bat的文件名称)
dex2jar 文件夹里 有“classes.dex.dex2jar.jar” 文件,说明还原jar文件成功
这个就是 传说中的 jar包了
3、查看.jar文件;这一步就是传统的 反编译 了,需要工具辅助,我这里用到的工具是jd-gui(http://download.csdn.net/detail/socketsyuhai/9296139)
下载你的系统对应的版本,解压,你会看到一个 .exe文件
双击,选择 第二步 生成的 .jar, 好吧,你的项目是不是 完全还原了呢?
上面是没有混淆的,混淆的 就看不到了: