android项目基于gradle的混淆编译--理论
来源:互联网 发布:完美刀塔助手没有网络 编辑:程序博客网 时间:2024/06/06 07:25
开发工具:win7 +android stduio
开发环境:android+svn+gradle
本文参考并转载以下文章部分内容
http://www.open-open.com/lib/view/open1418520643542.html
http://blog.csdn.net/catoop/article/details/47208833
在实际的开发成产品apk的发布过程中,我们经常会使用到代码混淆技术。不过在讲解如何进行代码混淆之前,我先跟大家演示一下反编译的过程,这样才能让大家明白为什么需要进行代码混淆。
一、代码反编译
1、准备工作
首先我们准备好一个项目的apk文件(未进行混淆打包)、dex2jar工具(下载地址:http://code.google.com/p/dex2jar/)、jd-gui工具(下载地址:http://jd.benow.ca/)。
2、解压APK
将apk后缀改为zip后解压,在解压出的文件中,我们可以看见有一个classes.dex文件,这就是我们的源代码打包生成的文件。
3、还原jar
dex2jar工具的作用就是将class.dex文件还原成.jar文件。这里使用的版本是2.0,先将dex2jar-2.0.zip解压,查看解压目录,d2j-dex2jar.bat就是处理文件,然后将上面获得的classes.dex文件拷贝至解压的目录中。
启动cmd,进入到dex2jar工具解压的目录中,运行命令:d2j-dex2jar.bat classes.dex,结果如下。
看dex2jar工具解压的目录中,生成了我们想要得到的classes_dex2jar.jar文件。
3、查看jar文件
通过jd-gui工具打开刚才得到的jar文件,就可以清楚的看见源代码
企业真实的项目中,如果不经过代码混淆,你的源码就如此赤裸裸的暴露着。这样对于公司来说是非常不安全的,并且不想发生的情况。既然我们已经看见了反编译如此的威力,那么我们有什么办法可以解决这个问题呢?
二、代码混淆
1、混淆原理
Java 是一种跨平台的、解释型语言,Java 源代码编译成中间”字节码”存储于 class 文件中。由于跨平台的需要,Java 字节码中包括了很多源代码信息,如变量名、方法名,并且通过这些名称来访问变量和方法,这些符号带有许多语义信息,很容易被反编译成 Java 源代码。为了防止这种现象,我们可以使用 Java 混淆器对 Java 字节码进行混淆。
混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。
混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因, 编译后 jar 文件体积大约能减少25% ,这对当前费用较贵的无线网络传输是有一定意义的。
2、代码混淆工具ProGuard
ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,它可以删除无用的类、字段、方法和属性。可以删除没用的注释,最大限度地优化字节码文件。它还可以使用简短的无意义的名称来重命名已经存在的类、字段、方法和属性。常常用于Android开发用于混淆最终的项目,增加项目被反编译的难度。
官网地址:http://proguard.sourceforge.net/
3、ProGuard使用
使用Android Studio的Gradle项目中在build.gradle中进行配置
正常我们只需要在proguard-rules.pro添加我们所需要的规则即可
3.1、基本语法
参数-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} -dontwarn 如果有警告也不终止-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} 设置源文件中给定的字符串常量
3.2、文件输出
混淆正常运行之后,会给我们输出一些文件,根据项目配置,存储位置可能有稍有变化
- dump.txt 描述apk文件中所有类文件间的内部结构。
- mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射。
- seeds.txt 列出了未被混淆的类和成员
- usage.txt 列出了从apk中删除的代码
3.3、不能混淆的代码
顾名思义,不能混淆代码如果被混淆了,就会出现错误。
- 需要反射的代码
- 系统接口
- Jni接口
- 需要序列号和反序列化的代码(即实现Serializable接口的JavaBean)
- 与服务端进行元数据交互的JavaBean(JSON、XML中对应的类)
- 等等
3.4、混淆后程序的调试
上面说了输出的几个文件,我们在改bug时可以使用,通过mapping.txt,通过映射关系找到对应的类,方法,字段等。
正常混淆后程序,无法用开发工具进行debug调试,如果混淆后有很多bug,查找起来会比较繁琐,通过Proguard文件中包含的retrace脚本可以重新建立映射关系后调试
window下时retrace.bat,linux和mac是retrace.sh,在 sdk目录的/tools/proguard/ 文件夹下。语法为:
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
具体用例
注:stacktrace_file暂时不知道作用
4、资料参考:
1.http://proguard.sourceforge.net/
2.http://developer.android.com/tools/help/proguard.html
- android项目基于gradle的混淆编译--理论
- android 基于Gradle 混淆jar包
- Gradle For Android(四)Gradle编译中神秘的混淆
- Gradle For Android(四)Gradle编译中神秘的混淆(转载DevSiven博客)
- AndroidStudio Gradle项目混淆
- gradle 编译android项目 Eclipse
- Gradle命令编译Android项目
- 为Android项目添加Proguard混淆编译的简单方法
- gradle android友盟多渠道混淆编译打包
- 用gradle编译任意结构的Android项目
- 提升gradle对android项目的编译速度
- gradle项目的编译、打包
- gradle 编译jar包+混淆
- 基于Gradle建立Android项目(1)
- Android 项目的代码混淆
- Android 项目的代码混淆
- Android项目的代码混淆
- Gradle自动化编译Android项目总结
- 数据结构清华大学公开课
- RabbitMQ各种交换机类型Exchange Types介绍
- ListView滚动时不加载图片
- php 对象和数组的赋值过程
- iOS开发之UIImagePickerController图片选择管理器
- android项目基于gradle的混淆编译--理论
- iOS学习之路-简易图片浏览器
- js变量,json格式编码困惑
- 可收缩分组表格(仿QQ联系人界面)
- Android 5.0系统以上获取所有运行进程
- android 堆内存的一些小知识
- 我的MYSQL学习心得(十四) 备份和恢复
- android下raw与assets文件夹区别
- JAVA学习【3】对JAVA值传递的理解