Android混淆详解
当前是有些工具比如apktool,dextojar等是可以对我们android安装包进行反编译,获得源码的。为了减少被别人破解,导致源码泄露,程序被别人盗取代码,等等。我们需要对代码进行混淆,android的sdk中为我们提供了ProGrard这个工具,可以对代码进行混淆(一般是用无意义的名字来重命名),以及去除没有使用到的代码,对程序进行优化和压缩,这样可以增加你想的难度。
Tag 未整理
|
|
这种方式可以禁止混淆内部类。
如何启用ProGuard
在build.gradle中进行配置
如上面的代码所示,在release打包时就会按照我们的配置进行混淆,注意,在我们平时的debug时是不会进行混淆的。
如何配置ProGuard
具体详情请查看官网:http://proguard.sourceforge.net/
部分语法
后面的文件名,类名,或者包名等可以使用占位符代替
“?”表示一个字符 可以匹配多个字符,但是如果是一个类,不会匹配其前面的包名
“*”可以匹配多个字符,会匹配前面的包名。
- 输入输出选项
- -include filename 从给定的文件中读取配置参数
- -injars class_path输入(即使用的) jar文件路径
- -outjars class_path输出 jar 路径
- -libraryjars class_path指定的jar将不被混淆
- -skipnonpubliclibraryclasses跳过(不混淆) jars中的 非public classes
- -dontskipnonpubliclibraryclasses不跳过(混淆) jars中的 非public classes默认选项
- -dontskipnonpubliclibraryclassmembers不跳过 jars中的非public classes的members
- -keepdirectories [directory_filter]指定目录 keep 在 out jars中
- 保持不变的选项(混淆不进行处理的内容)
- -keep {Modifier} {class_specification}保护指定的类文件和类的成员
- -keepclassmembers {modifier} {class_specification}保护指定类的成员,如果此类受到保护他们会保护的更好
- -keepclasseswithmembers {class_specification}保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
- -keepnames {class_specification}保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
- -keepclassmembernames {class_specification}保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
- -keepclasseswithmembernames {class_specification}保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
- -printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
- 压缩选项
- -dontshrink不启用shrink。shrink操作默认启用,主要的作用是将一些无效代码给移除,即没有被显示调用的代码。
- -printusage [filename]打印被移除的代码,在标准输出
- -whyareyoukeeping class_specification打印 在shrink过程中 为什么有些代码被 keep
- 优化选项
- -dontoptimize 该选项表示不启用。optimization,默认启用当不使用该选项时,下面的才有效
- -optimizations optimization_filter 根据optimization_filter指定要优化的文件
- -optimizationpasses n 优化数量 n
- -assumenosideeffects class_specification 优化时允许访问并修改类和类的成员的 访问修饰符,可能作用域会变大。
- -mergeinterfacesaggressively 合并接口,即使它们的实现类未实现合并后接口的所有方法。
- 混淆选项
- -dontobfuscate 不混淆
- -printmapping [filename] 打印 映射旧名到新名
- -applymapping filename 打印相关
- -obfuscationdictionary filename 指定外部模糊字典
- -classobfuscationdictionary filename 指定class模糊字典
- -packageobfuscationdictionary filename 指定package模糊字典
- -overloadaggressively 过度加载,多个属性和方法使用相同的名字,只是参数和返回类型不同可能各种异常
- -useuniqueclassmembernames 类和类成员都使用唯一的名字
- -dontusemixedcaseclassnames 不使用大小写混合类名
- -keeppackagenames [package_filter] 保持packagename 不混淆
- -flattenpackagehierarchy [package_name] 指定重新打包,所有包重命名,这个选项会进一步模糊包名 好东西 将包里的类混淆成n个再重新打包到一个个的package中,注:混淆是有用,但是我用的时候安装会崩溃,不知道为什么?
- -repackageclasses [package_name] 将包里的类混淆成n个再重新打包到一个统一的package中会覆盖flattenpackagehierarchy选项
- -keepattributes [attribute_filter] 混淆时可能被移除下面这些东西,如果想保留,需要用该选项。“Annotation、Exceptions, Signature, Deprecated, SourceFile, SourceDir,LineNumberTable” 预校验选项
- -dontpreverify 不预校验,默认选项
- 通用选项
- -verbose 打印日志
- -dontnote [class_filter] 不打印某些错误
- -dontwarn [class_filter] 不打印警告信息
- -ignorewarnings 忽略警告,继续执行
- -printconfiguration [filename] 打印配置文件
- -dump [filename] 指定打印类结构
Demo实例
|
|
如何查看ProGuard输出文件
混淆之后,会给我们输出一些文件,在gradle方式下是在/build/proguard/目录下,ant是在/bin/proguard目录,eclipse构建在/proguard目录像。 分别有以下文件:
- dump.txt 描述apk文件中所有类文件间的内部结构。
- mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射。
- seeds.txt 列出了未被混淆的类和成员
- usage.txt 列出了从apk中删除的代码
当我们发布的release版本的程序出现bug时,可以通过以上文件(特别时mapping.txt)文件找到错误原始的位置,进行bug修改。 同时,可能一开始的proguard配置有错误,也可以通过错误日志,根据这些文件,找到哪些文件不应该混淆,从而修改proguard的配置。
资源混淆
- 美团 http://tech.meituan.com/mt-android-resource-obfuscation.html
- 微信:http://mp.weixin.qq.com/s?biz=MzAwNDY1ODY2OQ==&mid=208135658&idx=1&sn=ac9bd6b4927e9e82f9fa14e396183a8f&scene=0#rd
注意:重新release编译后,这些文件会被覆盖,所以没发布程序,最好都保存一份配置文件。