Android混淆总结篇

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/框架的混淆指令一般在其官方文档都可以找到,所以相对来说还是比较方便的,下面将这几天归类的混淆指令总结下.

基本指令:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 设置混淆的压缩比率 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基本组件,下面是兼容性比较高的规则:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
-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++

?
1
2
3
-keepclasseswithmembernames class * {
         native <methods>;
}</methods>

避免混淆自定义控件类的get/set方法和构造函数

?
1
2
3
4
5
6
7
8
9
-keep public class * extends android.view.View{
         *** get*();
         void set*(***);
         public <init>(android.content.Context);
         public <init>(android.content.Context,
                                     android.util.AttributeSet);
         public <init>(android.content.Context,
                                     android.util.AttributeSet, int );
}</init></init></init>

避免混淆枚举类

?
1
2
3
4
     -keepclassmembers enum * {
         public static **[] values();
         public static ** valueOf(java.lang.String);
}

避免混淆序列化类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#不混淆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类的构造函数

?
1
2
3
4
5
     #使用GSON、fastjson等框架时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象
     -keepclassmembers class * {
         public <init>(org.json.JSONObject);
     }
</init>

避免混淆第三方SDK

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# ==================环信混淆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======================
 
//备注:其他的第三方包的混淆指令可以到其官方文档去拷贝

避免混淆第三方框架

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# ==================picasso框架 start===============
-keep class com.parse.*{ *; }
-dontwarn com.parse.**
-dontwarn com.squareup.picasso.**
-keepclasseswithmembernames class * {
     native <methods>;
}
# ==================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=====================
 
//备注:其它框架的混淆指令可以到其官方文档去拷贝   </methods>

其它混淆指令

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
     #避免混淆属性动画兼容库
     -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包名])这样的配置信息.采用下面的配置信息进行替换

?
1
2
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }

2.下面是对属性动画兼容库的混淆白名单配置信息,刚开始觉得只是保持com.nineoldandroids包下的类不被混淆,后来经过反编译混淆后的apk包,发现效果是”不混淆该class com.nineoldandroids包下的类、子包和子包的类,也不混淆其中类的成员变量.

?
1
-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左右,需要的话可以自行搜索,加固还是挺简单的.

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android混淆是一种通过对代码进行重命名和优化来增加应用程序安全性和性能的技术。在Android开发中,可以使用自带的混淆工具来进行代码混淆。默认情况下,Android SDK提供了一些默认的混淆文件,如proguard-android.txt或proguard-android-optimize.txt。这些文件包含了一些常用的混淆命令,可以对代码进行混淆处理。如果需要对自定义的混淆进行配置,可以在proguard-rules.pro文件中进行设置。\[1\] 在进行混淆时,需要注意不要混淆Activity中参数是View的方法。因为在Android开发中,有一种常见的用法是在XML中配置android:onClick属性,当用户点击按钮时,会调用Activity中的对应方法,例如buttonClick(View view)。如果这个方法被混淆,就无法找到对应的方法了。为了避免这种情况,可以使用如下混淆命令来保留Activity中参数是View的方法:-keepclassmembers class * extends android.app.Activity { public void *(android.view.View); }\[2\] 此外,还可以使用一些通用的混淆命令来保留Android中的一些常用类,例如Activity、Application、Service、BroadcastReceiver和ContentProvider:-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\[3\] 通过使用混淆技术,可以有效地保护Android应用程序的代码安全性,并提高应用程序的性能。 #### 引用[.reference_title] - *1* [Android:代码混淆概念整理](https://blog.csdn.net/qjyws/article/details/126488356)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Android--混淆配置(比较详细的混淆规则)](https://blog.csdn.net/weixin_42602900/article/details/127671586)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值