proguard混淆

来源:互联网 发布:淘宝云客服培训中心 编辑:程序博客网 时间:2024/05/09 16:36

为了防止开发APP的重要code 被泄露,我们往往需要混淆(Obfuscation code ), 也就是把方法,字段,包和类这些java 元素的名称改成无意义的名称,这样代码结构没有变化,还可以运行,但是想弄懂代码的架构却很难。 proguard 就是这样的混淆工具,它可以分析一组class 的结构,根据用户的配置,然后把这些class 文件的可以混淆java 元素名混淆掉。在分析class 的,同时他还有其他两个功能,删除无效代码(Shrinking 收缩),和代码进行优化 (Optimization Options)。

缺省情况下,proguard 会混淆所有代码,但是有些情况我们是不能改变java 元素的名称,否则就会这样就会导致程序出错。例如,用到反射的地方,我们代码依赖于系统的接口,比如被系统代码调用的回调方法,这种情况最复杂。这就需要我们在proguard-rules文件中告诉proguard 哪些java 元素是不能混淆的。

1. ProGuard配置

ProGuard关键字

保留选项(配置不进行处理的内容)

-keep {Modifier} {class_specification} 保留类和类中的成员,防止它们被混淆或移除。
-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保留类和类中的成员,防止它们被混淆或移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆。
-keepnames {class_specification} 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除。
-keepclassmembernames {class_specification} 只保留类中的成员,防止它们被混淆,但当成员没有被引用时会被移除。
-keepclasseswithmembernames {class_specification} 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆。

压缩

-dontshrink 不压缩输入的类文件
-whyareyoukeeping {class_specification}

优化

-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员

混淆

-dontobfuscate 不混淆输入的类文件
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
-keepattributes {attribute_name,…} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string} 设置源文件中给定的字符串常量

输出:

-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
-printusage {filename}

通配符

通配符 描述 <field> 匹配类中的所有字段 <method> 匹配类中的所有方法 <init> 匹配类中的所有构造函数 * 匹配任意长度字符,但不含包名分隔符(.)。比如说我们的完整类名是com.example.test.MyActivity,使用com.,或者com.exmaple.都是无法匹配的,因为无法匹配包名中的分隔符,正确的匹配方式是com.exmaple..,或者com.exmaple.test.,这些都是可以的。但如果你不写任何其它内容,只有一个*,那就表示匹配所有的东西。 ** 匹配任意长度字符,并且包含包名分隔符(.)。比如proguard-android.txt中使用的-dontwarn android.support.**就可以匹配android.support包下的所有内容,包括任意长度的子包。 匹配任意参数类型。比如void set*()就能匹配任意传入的参数类型, get*()就能匹配任意返回值的类型。 … 匹配任意长度的任意类型参数。比如void test(…)就能匹配任意void test(String a)或者是void test(int a, String b)这些方法。
  • 在android中在android Manifest文件中的activity,service,provider, receviter,等都不能进行混淆。一些在xml中配置的view也不能进行混淆,android提供的默认配置中都有。
  • keep和keepclasseswithmembers区别在于:keep关键字看到class *就认为应该将所有类名进行保留,不关心{}中的参数。而keepclasseswithmembers前提是{}的类中的成员必须存在,如果不存在则还是会混淆

不能混淆的东西

(1)Android 程序 ,下面这样代码混淆的时候要注意保留。
(2)Android系统组件,系统组件有固定的方法被系统调用。
(3) 被Android Resource 文件引用到的。名字已经固定,也不能混淆,比如自定义的View 。
(4)Android Parcelable ,需要使用android 序列化的。
(5) android.app.backup.BackupAgentHelper
(6) android.preference.Preference
(7) com.android.vending.licensing.ILicensingService
(8) Java序列化方法,系统序列化需要固定的方法。
(9) 枚举 ,系统需要处理枚举的固定方法。
(10)native 本地方法,不能修改本地方法名
(11)annotations 注释
(12)数据库驱动
(13)有些resource 文件
(14)用到反射的地方,比如调用aidl

常见问题

1、打包过程中,提示 Warning: can’t find superclass or interface/ Warning: can’t find referenced class等警告信息!
解决方法:
(1) 确保你的代码是否使用这个类,如果使用了,查看对应的第三方包有没有加上去,并且是否拉下来存在项目中
(2)如果该类存在,工程中确实使用了这个类,就在proguard中加上-keep class com.xx.yy.** { *;},让当前类不混淆。
(3) 确保报错的类没有在你的项目中使用到,可以使用”-dontwarn 类名正则表达式”屏蔽警告。
2、程序中使用泛型导致运行错误!
使用的泛型需要在混淆配置文件加了一个过滤泛型的语句,如下。
-keepattributes Signature

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的配置。

注意:重新release编译后,这些文件会被覆盖,所以每次发布程序,最好都保存一份配置文件。一般去友盟统计等统计网站分析错误时,需要上传对应的mapping.txt才能看到错误信息对应的app原始类、方法、变量名。

proguard-android.txt 说明

# This is a configuration file for ProGuard.# http://proguard.sourceforge.net/index.html#manual/usage.html#混淆时不使用大小写混合类名-dontusemixedcaseclassnames#不跳过library中的非public的类-dontskipnonpubliclibraryclasses#打印混淆的详细信息-verbose# Optimization is turned off by default. Dex does not like code run# through the ProGuard optimize and preverify steps (and performs some# of these optimizations on its own).#不进行优化,建议使用此选项,因为根据proguard-android-optimize.txt中的描述,#优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行。-dontoptimize#不进行预校验。这个预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度。-dontpreverify# Note that if you want to enable optimization, you cannot just# include optimization flags in your own project configuration file;# instead you will need to point to the# "proguard-android-optimize.txt" file instead of this one from your# project.properties file.#对注解中的参数进行保留。-keepattributes *Annotation*#不混淆下面声明的两个类,这两个类我们基本也用不上,是接入Google原生的一些服务时使用的。-keep public class com.google.vending.licensing.ILicensingService-keep public class com.android.vending.licensing.ILicensingService# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native#不混淆任何包含native方法的类的类名以及native方法名。-keepclasseswithmembernames class * {    native <methods>;}# keep setters in Views so that animations can still work.# see http://proguard.sourceforge.net/manual/examples.html#beans#不混淆任何一个View中的setXxx()和getXxx()方法,因为属性动画需要有相应的setter和getter的方法实现,混淆了就无法工作了-keepclassmembers public class * extends android.view.View {   void set*(***);   *** get*();}# We want to keep methods in Activity that could be used in the XML attribute onClick#不混淆Activity中参数是View的方法,因为有这样一种用法,在XML中配置android:onClick=”buttonClick”属性,#当用户点击该按钮时就会调用Activity中的buttonClick(View view)方法,如果这个方法被混淆的话就找不到了。-keepclassmembers class * extends android.app.Activity {   public void *(android.view.View);}# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations#不混淆枚举中的values()和valueOf()方法,枚举我用的非常少-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}#不混淆Parcelable实现类中的CREATOR字段,毫无疑问,CREATOR字段是绝对不能改变的,包括大小写都不能变,不然整个Parcelable工作机制都会失败-keepclassmembers class * implements android.os.Parcelable {  public static final android.os.Parcelable$Creator CREATOR;}#不混淆R文件中的所有静态字段,我们都知道R文件是通过字段来记录每个资源的id的,字段名要是被混淆了,id也就找不着了-keepclassmembers class **.R$* {    public static <fields>;}# The support library contains references to newer platform versions.# Dont warn about those in case this app is linking against an older# platform version.  We know about them, and they are safe.#对android.support包下的代码不警告,因为support包中有很多代码都是在高版本中使用的,如果我们的项目指定的版本比较低在打包时就会给予警告。不过support包中所有的代码都在版本兼容性上做足了判断,因此不用担心代码会出问题,所以直接忽略警告就可以了。-dontwarn android.support.**
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机刷机忘记注册邮箱了怎么办 刺激战场模拟器注册已达上限怎么办 用模拟器玩刺激战场注册上限怎么办 微信解除实名认证后退款怎么办 苹果为什么qq收消息有延迟怎么办 qq忘记密码手机号也换了怎么办 扣扣空间圈人时照片服务错误怎么办 删了qq好友怎么找回来怎么办 苹果5s语音控制打开了怎么办 lv迷你水桶包肩带长了怎么办 在香港买个lv包包过海关怎么办 国际快递手表被海关查应该怎么办 把档案放到人才市场后报到证怎么办 皮表带带久了有异味怎么办 英语中用词不当和拼写错误怎么办 爬楼梯的购物车车轮坏了怎么办? 帮别人买东西不给我钱怎么办 老师念错名字有同学指出来你怎么办 老公婚前买的房子婆婆想霸占怎么办 我想查我的基金收益情况怎么办 儿童票买好了但大人退票了怎么办 没有享受到国家政策的农民怎么办? 股票涨了没抛然后一直跌怎么办 苹果手机放久了开不了机怎么办 部门要辞退你你不想走该怎么办 口头说辞职现在又不想走了怎么办 网上买的理财不给退本金怎么办 买东西遇到态度不好的人你会怎么办 app在下载东西时被停用了怎么办 买东西填错地址 但已签收怎么办 网购手机受骗后电话打不通怎么办 淘宝买的东西发错了怎么办 淘宝上买的东西发错了怎么办 淘宝上买的东西发多了怎么办 淘宝上买的东西出现问题怎么办 淘宝买东西未收到货显示签收怎么办 网上一张车票两人同时付款了怎么办 微信付款时显示银行卡被锁定怎么办 微信忘记支付密码怎么办没有银行卡 支付宝赏金扫码支付不行怎么办 网购收货时发现货物已破损怎么办