转载自:http://www.cnblogs.com/cc-Cheng/archive/2013/02/17/2914584.html
上一篇介绍了apk反编译的步骤,现在来研究下代码混淆,因为第三方人员完全可以通过解压APK文件并从中获取项目源码,所以对APK文件的保护显得至关重要。
代码混淆亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为,代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。
一、工具:Proguard
\android-sdks\tools\proguard即可找到该工具,可以再docs里面找到相关手册
二、 配置脚本
在2.3以上的项目里可以看到proguard-project.txt文件,对于2.3以下的版本,可以去2.3以上版本的项目中复制一份。(我看到有的项目里是proguard.cfg,还没有验证)
这个文件时proguard混淆代码的脚本文件,打开project.properties(老版本为default.properties),在文件的末尾处添加这样一行代码:proguard.config=proguard-project.txt,保存该文件,接下来从新编译你的项目,这时生成的APK文件就已经进行了代码混淆。
三、主要用法
简单说下keep参数,这个是设定要保留不参与混淆的类和成员。
keepclass_specification保留指定的类和成员名称和内容
keepclassmembersclass_specification只保留指定的类成员名称和内容
keepclasseswithmembersclass_specification
keepnamesclass_specification保留类和成员名称,混淆内容
keepclassmembernamesclass_specification只保留成员名称,混淆内容
keepclasseswithmembernames class_specification
在使用过程中,我比较 喜欢建立几个抽象类,Keep,KeepClassMembers,
KeepClassesWithMembers,KeepNames,KeepClassMemberNames,
KeepClassesWithMemberNames,把需要混淆的核心代码单独打包,需要保留特定属性的类分别继承各个方法,这样设定混淆配置时就比较容易。
例:
-dontwarn com.baidu.mapapi.**
-keep class com.baidu.mapapi.**{*;}
这段代码的意思是com.baidu.mapapi.包下的都不参与混淆(com.baidu.mapapi.是引用的包)
四、签名打包
五、混淆后代码
使用反编译方法反编译打包后的apk,看到有的类名,方法名变成了没有意义的字母,说明混淆成功
六、已发布应用程序的调试注意事项
打包后会发现在程序的根目录下生成了proguard文件夹
里面包含四个文件
dump.txt 描述apk保重所有class的代码结构
mapping.txt 列出了源代码与混淆后的类,方法和属性名字之间的映射。这个文件对于在构建之后得到的bug报告是有用的,因为它把混淆的堆栈跟踪信息反翻译为源代码中的类,方法和成员名字。更多信息,查看解码混淆过的堆栈跟踪信息。
seeds.txt 表示没有混淆的类和成员
usage.txt表示被剥离的类
保存好每一个已发布给用户的程序的mapping.txt文件。通过保存发布构建版本的mapping.txt文件拷贝,确保当用户碰到bug,并把混淆后的堆栈调试跟踪信息提交给你时,你可以进行调试从而修复问题。程序的mapping.txt文件在每次发布构建时都会被覆盖,所以你一定要注意保存正确的版本。
例如,假设你已经发布了一个应用程序并在继续在新的版本中开发添加新的功能。接着你马上启动混淆器并创建一个新的发布版本。该操作把mapping.txt文件覆盖了。一个用户提交了来自当前发布版本的bug报告,该报告包含了堆栈调试信息。你再也不能对用户的堆栈信息进行调试了,因为这个对应用户本机上版本的mapping.txt文件不存在了。其他覆盖mapping.txt文件的情况还有很多,所以对于每一个可能需要调试的版本,你都要确保有一份拷贝。
如何保存mapping.txt文件由你决定。例如,你可以根据版本和构建号来重命名它们,或者连同你的源代码进行版本控制。
七、 解码混淆过的堆栈跟踪信息
当混淆代码并输出了一个堆栈调试信息时,这些方法名字是混淆过的,虽然可以进行调试,但是调试变得困难。幸运的是,每当混淆器运行时候,它都会输出到文件<project_root>/bin/proguard/mapping.txt中,该文件包含了从原始类,方法和属性名字到混淆后名字的映射。
Windows系统中retrace.bat脚本命令或者Linux和Mac OS X系统中retrace.sh脚本命令能把混淆后的堆栈调试信息转换为可以理解的文件。它被放在<sdk_root>/tools/proguard/目录下。运行retrace工具的命令语法是:
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
例如:
retrace.bat -verbose mapping.txt obfuscated_trace.txt
如果你没有为<stracktrace_file>指定值,那么retrace工具从标准输入读取。
八、需要注意的地方
参考:http://blog.csdn.net/alex197963/article/details/2620619
1、注意版本,如果不是项目需要,最好使用最新稳定版本,这样出错的机会小一些,学习曲线会明显缩短。2、最好以源码的同编译版本的jvm来启动proguardgui.jar,不要直接用默认的jvm打开。3、注意proguaardgui启动后默认加载的libraryjar中包含的rt.jar,它的版本和你使用到的jvm版本一致。4、使用1.4的jvm打开proguard时,注意在optimization选项卡中,不要勾中keep enumerations选项,因为勾中这个选项会导致configration文件中出现java.lang.Enum,这个类只有在1.5的环境下才有。报错信息如下: [proguard] Note: the configuration refers to the unknown class 'java.lang.Enum' [proguard] Note: there were 1 references to unknown classes. [proguard] You should check your configuration for typos.5、嵌入ant脚本时,通常会有这么一段 <target name="proguard" depends="init"> <taskdef resource="proguard/ant/task.properties" classpath="${lib.dir}/proguard/proguard.jar" /> <proguard configuration="${src.dir}/config.pro" /> </target> task.properties在proguard.jar中,保留,config.pro是proguard的配置文件,最好使用proguardgui.jar先生成,然后再根据需求手动修改。九、 android 原始混淆模板http://www.verydemo.com/demo_c131_i5524.html十、问题-keep public class * extends com.baidu.mapapi{*;}-keep class com.baidu.mapapi.**{*;}这两个的区别?使用指南 http://wenku.baidu.com/view/5ec1d320ccbff121dd36836e.html