Android 混淆总结篇 Ⅰ. 简述
混淆的概念:将 Android 项目进行打包之时,可以将项目里的包名、类名、变量名进行更改,使得代码不容易泄露, 类似于对其 apk 中的文件加密.
混淆的作用:
1. 增加 Apk 反编译之后代码泄露的困难性 2. 生成的 apk 体积会缩小
什么是混淆
Android SDK 本身就提供混淆的功能,将混淆开关进行开启后,开发者需要做的是对 Android Studio 工程项目中的 proguard-rules.pro 文件进行混淆白名单的配置.
那么什么是混淆白名单呢?其实就是指定一些包名、类名、变量等不可以被混淆。假设没指定白名单就进行混淆打包,而某某类的类名被混淆了 (假设变成了 a),那么可能其他引用或使用该类的类就找不到该类,说不定应用就会因此崩溃或是导致相应的功能无法使用.
那么所谓的混淆也就是配置混淆白名单,那么下面看看混淆之后的 apk 的内部结构. 可以看到红圈圈出来的部分都是进行混淆的,而有部分是没有进行混淆的,比如黑圈圈出来的属性动画兼容库 nineoldandroids,其包名类名就没有变成 abc 这样的代替符
上面我是用 apk 逆向助手对 apk 进行反编译,市场上的反编译工具有很多种,可以自行 Google 搜索。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxzdHJvbmc+srmz5Dwvc3Ryb25nPjwvcD4NCjxibG9ja3F1b3RlPg0KCTxwPrG+xqrOxNXCvMfCvLXEu+zP/daqyra149b30qq7+dPaQW5kcm9pZCBTdHVkaW+/qreiuaS+36GjPC9wPg0KPC9ibG9ja3F1b3RlPg0KPGgyIGlkPQ=="ⅱ 开始混淆">Ⅱ. 开始混淆 1. 开启混淆开关
混淆的开关在项目 / app/build.gradle 文件里,看下面的截图,将 minifyEnabled 设置为 true 就是开启混淆,关于下面的配置代码可以直接写在 build.gradle 文件的 android 节点下
代码混淆一般是在上线前的 apk 打包才会去配置混淆开启,要是忘记配置的代码,那怎么办呢?直接进去 Project Structrue, 然后根据下面截图所标识的进行设置,如此这般,只要打 release 包就是开启混淆进行打包的.
2. 设置混淆白名单
基于 Android Studio 创建的项目里有一文件名称为 "proguard-rules.pro" 的文件,路径是 "项目 / app/proguard-rules.pro",没经过编辑之前,里面只有一些注释的代码,如下图
那么设置的混淆白名单又该怎么写呢? Google 搜索的话会有很多博客上的模板可以复制进行套用. 如下图, 那么就可以进行参考,下面第三部分将常用的混淆指令和对应的注释都列举出来,基本常用的都有,有疏漏的那就自行搜索下.
Ⅲ. 实际混淆指令
在应用中,大多数的混淆指令是已经确定的了,比如下面的基本指令部分,基本不用修改的。而其他的混淆指令,比如第三方的 SDK / 框架的混淆指令一般在其官方文档都可以找到,所以相对来说还是比较方便的,下面将这几天归类的混淆指令总结下.
基本指令:
- #设置混淆的压缩比率0~7 - optimizationpasses 5#混淆后类名都为小写Aa aA - dontusemixedcaseclassnames#指定不去忽略非公共库的类 - dontskipnonpubliclibraryclasses#不做预校验的操作 - dontpreverify#混淆时不记录日志 - verbose#混淆采用的算法. - optimizations ! code / simplification / arithmetic,
- !field
- /*,!class/merging/* #保留代码行号,方便异常信息的追踪 -keepattributes SourceFile,LineNumberTable #dump文件列出apk包内所有class的内部结构 -dump class_files.txt #seeds.txt文件列出未混淆的类和成员 -printseeds seeds.txt #usage.txt文件列出从apk中删除的代码 -printusage unused.txt #mapping文件列出混淆前后的映射 -printmapping mapping.txt*/
避免混淆 Android 基本组件,下面是兼容性比较高的规则:
- - keep public class * extends android.app.Activity - keep public class * extends android.app.Application - keep public class * extends android.app.Service - keep public class * extends android.content.BroadcastReceiver - keep public class * extends android.content.ContentProvider - keep public class * extends android.app.backup.BackupAgentHelper - keep public class * extends android.preference.Preference - keep public class com.android.vending.licensing.ILicensingService#不提示V4包下错误警告 - dontwarn android.support.v4. * *#保持下面的V4兼容包的类不被混淆 - keep class android.support.v4. * *{ * ;
- }
避免混淆所有 native 的方法, 涉及到 C、C++
- - keepclasseswithmembernames class * {
- native;
- }
避免混淆自定义控件类的 get/set 方法和构造函数
- - keep public class * extends android.view.View { * **get * ();
- void set * ( * **);
- public(android.content.Context);
- public(android.content.Context, android.util.AttributeSet);
- public(android.content.Context, android.util.AttributeSet, int);
- }
避免混淆枚举类
- - keepclassmembers enum * {
- public static * *[] values();
- public static * *valueOf(java.lang.String);
- }
避免混淆序列化类
- #不混淆Parcelable和它的实现子类,还有Creator成员变量 - keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator * ;
- }#不混淆Serializable和它的实现子类、其成员变量 - keepclassmembers class * implements java.io.Serializable {
- static final long serialVersionUID;
- private static final java.io.ObjectStreamField[] serialPersistentFields;
- private void writeObject(java.io.ObjectOutputStream);
- private void readObject(java.io.ObjectInputStream);
- java.lang.Object writeReplace();
- java.lang.Object readResolve();
- }
避免混淆 JSON 类的构造函数
- #使用GSON、fastjson等框架时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象 - keepclassmembers class * {
- public(org.json.JSONObject);
- }
避免混淆第三方 SDK
- # === ===============环信混淆start === ==============-keep class com.hyphenate. * *{ * ;
- } - dontwarn com.hyphenate. * *# === ===============环信end === ===================# === ===============bugly start === ===============-dontwarn com.tencent.bugly. * *-keep public interface com.tencent. * *-keep public class com.tencent. * *{ * ;
- } - keep public class com.tencent.bugly. * *{ * ;
- }# === ===============bugly end === =================# === ============百度定位start === =================-keep class vi.com.gdi. * *{ * ;
- } - keep public class com.baidu. * *{ * ;
- } - keep public class com.mobclick. * *{ * ;
- } - dontwarn com.baidu.mapapi.utils. * -dontwarn com.baidu.platform.comapi.b. * -dontwarn com.baidu.platform.comapi.map. * # === ============百度定位end === =================== //备注:其他的第三方包的混淆指令可以到其官方文档去拷贝
避免混淆第三方框架
- # === ===============picasso框架start === ============-keep class com.parse. * { * ;
- } - dontwarn com.parse. * *-dontwarn com.squareup.picasso. * *-keepclasseswithmembernames class * {
- native;
- }# === ===============picasso end === =================# === ===============EventBus start === ==============-keep class org.greenrobot. * *{ * ;
- } - keep class de.greenrobot. * *{ * ;
- } - keepclassmembers class * *{
- public void onEvent * ( * *);
- void onEvent * ( * *);
- }# === ===============EventBus end === ================# === ===============okhttp start === ================-dontwarn com.squareup.okhttp. * *-keep class com.squareup.okhttp. * *{ * ;
- } - dontwarn okio. * *-keep class okio. * *{ * ;
- } - keep interface okio. * *{ * ;
- }# === ===============okhttp end === ================== //备注:其它框架的混淆指令可以到其官方文档去拷贝
其它混淆指令
- #避免混淆属性动画兼容库 - dontwarn com.nineoldandroids. * -keep class com.nineoldandroids. * *{ * ;
- }#不混淆泛型 - keepattributes Signature#避免混淆注解类 - dontwarn android.annotation - keepattributes * Annotation * #避免混淆内部类 - keepattributes InnerClasses#避免混淆实体类,修改成你对应的包名 - keep class com.wyk.test.bean. * *{ * ;
- } - keep class com.wyk.test.event. * *{ * ;
- } - keep public class com.wyk.test.utils.eventbus. * *{ * ;
- }#避免混淆Rxjava / RxAndroid - dontwarn sun.misc. * *-keepclassmembers class rx.internal.util.unsafe. * ArrayQueue * Field * {
- long producerIndex;
- long consumerIndex;
- } - keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
- rx.internal.util.atomic.LinkedQueueNode producerNode;
- } - keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
- rx.internal.util.atomic.LinkedQueueNode consumerNode;
- }#避免混淆js相关的接口 - keepattributes * JavascriptInterface * -keep class com.wyk.test.js. * *{ * ;
- }
Ⅳ. 混淆配置注意点 1. 假设当配置 "-libraryjars libs/jpush-android-2.1.6.jar" 对 jar 包进行混淆白名单化, 如果 gradle 报错的话,可以考虑注释掉 (格式:-libraryjars [jar 包名]) 这样的配置信息. 采用下面的配置信息进行替换
- - dontwarn cn.jpush. * *-keep class cn.jpush. * *{ * ;
- }
2. 下面是对属性动画兼容库的混淆白名单配置信息,刚开始觉得只是保持 com.nineoldandroids 包下的类不被混淆,后来经过反编译混淆后的 apk 包,发现效果是 " 不混淆该 class com.nineoldandroids 包下的类、子包和子包的类,也不混淆其中类的成员变量.
- - keep class com.nineoldandroids. * *{ * ;
- }
Ⅴ. 其它 1. 混淆套用模板个人觉得下面链接的博文就写得非常好,所以可以进行参考.
参考博文:5 分钟搞定 android 混淆
2. 资源混淆
Proguard 混淆只是针对代码进行混淆,解压之后的 apk 包还是能看到项目的资源文件和其名称,比如布局、logo 图片等等. 这时可以选择对资源文件进行混淆,下面两个链接是腾讯推出的资源混淆工具相关的博文,可以参考.
资源混淆工具相关的博文
http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=42
https://github.com/shwenzhang/AndResGuard/blob/master/README.zh-cn.md
3. 加固
为了使得 apk 更加不容易被破解,混淆之后还可以对 apk 进行加固,现今市面上的加固技术有很多种,有 360 加固、爱加密加固、梆梆加固等等,可以自行选择,加固技术就相当于给 apk 包加多一个壳,相应的体积也会增大,大概增大 1M~2M 左右,需要的话可以自行搜索,加固还是挺简单的.
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/03-11/18478612.html