Android 混淆详解

来源:互联网 发布:vb中index 编辑:程序博客网 时间:2024/06/08 05:00

1. 概念 混淆维基百科的解释

代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。

2. 目的

混淆的目的是为了加大反编译的成本,但是并不能彻底防止反编译,比如Android App反编译后虽然代码很难读懂,但依旧是可以读懂的,只是比较费劲;相比较java语言写的程序,C/C++程序反编译后就更难读懂了。

3. 优缺点

Proguard混淆让代码更加安全, 但是这也使收集的崩溃变得更加难以读懂, 为了解决这个问题我们用 retrace 工具来将混淆后的 StackTrace 还原成混淆之前的信息. retrace脚本 Android 开发环境默认带着retrace脚本,一般情况下路径为./tools/proguard/bin/retrace.sh mapping映射表 Proguard进行混淆之后,会生成一个映射表,文件名为mapping.txt。

4. Java 代码混淆工具

proguard Java官网对Proguard的定义 Proguard是一个集文件压缩,优化,混淆和校验等功能的工具 它检测并删除无用的类,变量,方法和属性 它优化字节码并删除无用的指令. 它通过将类名,变量名和方法名重命名为无意义的名称实现混淆效果. 最后它还校验处理后的代码

5. 影响元素 代码混淆影响到的元素有

包名
类名
变量名
方法名
其他元素

不混淆类的成员
-keepclassmembers

不混淆类及其成员
-keepclasseswithmembers

不混淆类及其成员名
-keepnames class_specification

不混淆类的成员名
-keepclassmembernames

不混淆类及其成员名
-keepclasseswithmembernames

代码混淆的压缩比例,值在0-7之间
-optimizationpasses 5

混淆后类名都为小写
-dontusemixedcaseclassnames

指定不去忽略非公共的库的类
-dontskipnonpubliclibraryclasses

指定不去忽略非公共的库的类的成员 -dontskipnonpubliclibraryclassmembers

不做预校验的操作
-dontpreverify

生成原类名和混淆后的类名的映射文件
-verbose -printmapping proguardMapping.txt

指定混淆是采用的算法
-optimizations !code/simplification/cast,!field/,!class/merging/

不混淆Annotation
-keepattributes Annotation,InnerClasses

不混淆泛型
-keepattributes Signature

抛出异常时保留代码行号 -keepattributes SourceFile,LineNumberTable

dontwarn是一个和keep可以说是形影不离,尤其是处理引入的library时.
引入的library可能存在一些无法找到的引用和其他问题,在build时可能会发出警告,如果我们不进行处理,通常会导致build中止.因此为了保证build继续,我们需要使用dontwarn处理这些我们无法解决的library的警告.

比如关闭Twitter sdk的警告,我们可以这样做
-dontwarn com.twitter.sdk.**

6. Android 混淆原则

  1. 反射用到的类不混淆, 需要保证类名方法不变
  2. JNI 方法调用的 java 方法不混淆
  3. Java 的 native 方法
  4. js 调用的 java 方法
  5. AndroidMainfest 中的类不混淆,四大组件和 Application 的子类和Framework层下所有的类默认不会进行混淆

  6. Parcelable的子类和Creator静态成员变量不混淆,否则会产生android.os.BadParcelableException异常

  7. 使用GSON、fastjson等框架时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象;生成的bean实体对象,内部大多是通过反射来生成, 不能混淆

  8. 使用第三方开源库或者引用其他第三方的SDK包时,需要在混淆文件中加入对应的混淆规则; 这些第三库的文档中 一般会给出相应的混淆规则, 复制过来即可

  9. 有用到WEBView的JS调用也需要保证写的接口方法不混淆

  10. 四大组件不建议混淆 四大组件声明必须在manifest中注册,如果混淆后类名更改,而混淆后的类名没有在manifest注册,是不符合Android组件注册机制的. 外部程序可能使用组件的字符串类名,如果类名混淆,可能导致出现异常

  11. 注解不能混淆 注解在Android平台中使用的越来越多,常用的有ButterKnife和Otto.很多场景下注解被用作在运行时反射确定一些元素的特征. 为了保证注解正常工作,我们不应该对注解进行混淆.Android工程默认的混淆配置已经包含了下面保留注解的配置

  12. 枚举也不要混淆
    -keep attributes Annotation

原创粉丝点击