Android 混淆机制详解
前言
混淆是增加逆向工程和破解的难度,防止App知识产权被窃取的一个有力手段,高级的代码混淆甚至可以有效地保护存储在客户端的密钥,同时混淆也有很多要注意的地方。
从广义上讲,Android 中的混淆包括三种类型
- java 代码的混淆
- Native (C & C++) 代码的混淆
- 资源文件的混淆
java 代码的混淆
java 代码的混淆在Android 中是最为常见的一种混淆方式,一般依赖于Proguard
或者 DexGuard
工具,其中Progurad 是免费且开源的,DexGuard 是付费的。
Proguard 的特性
在Android 中使用 Proguard
,它不仅仅为我们提供代码混淆的功能,事实上Proguard
主要提供了4个功能特性
- 压缩:java源代码通常被编译为字节码,虽然字节码比源代码更简洁,但它本身依然会包含很多无用的代码,Proguard 的压缩功能通过分析字节码,能够检测并移除没有使用到的类,字段,方法和属性。
- 优化:优化Java 字节码,同时移除没有使用到的指令。
- 混淆:使用无意义的简短字母组合对类名,字段名、和方法名进行重命名。
- 预检验:对上述处理后的代码进行预检验(Android 不需要此项)
buildTypes {release {minifyEnabled true //true 表示进行Proguard 混淆proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
其中,proguard-android.txt
是 Proguard 默认的混淆配置文件,位于Androdi SDK 的 tools/proguard 目录中,该文件是对Proguard 基本的配置,几乎是每个App 都要用到的配置,当然这个默认文件的配置是远远不够的。我们需要自身App 的特殊性增加或者减少相关的配置。
proguard-rules.pro 文件的编写
混淆文件的规则可以大致分为三种类型:
公共的混淆规则:每个App 都通用的,主要是对Proguard 的基本配置,以及Android SDK 中 API 设置的规则,例如Avtivity 、Parcelable 等。
App 特有的混淆规则:根据App自身的特点进行设置,例如某些类会被反射调用,如果被混淆,那么反射就找不到了。
- 第三方函数库或者SDK 的混淆规则:如果App 引入了第三方开源库或者SDK ,那么需要查看这些函数库或者SDK 的使用说明,将需要去混淆的地方加上去。
下面是一个比较完整的 proguard-rules.pro
文件的内容
#代码混淆的压缩比例,取值范围在0-7之间,默认为5
-optimizationpasses 5
#混淆时不使用大小写混合的方式,这样混淆后都是小写字母的组合
-dontusemixedcaseclassnames
#混淆时不做预校验,在Android 中一般不需要预校验,这样可以加快混淆的速度
-dontpreverify
#混淆时记录日志,同时会生成映射文件,
#Android Studio 中,生成的默认映射文件是
‘build/outputs/mapping/release/mapping.txt’
-verbose
#指定生成的映射文件的路劲和名称(生成原类名和混淆后的类名的映射文件)
-printmapping proguardMapping.txt
#指定混淆是采用的算法 ,参数是Google 官方推荐的过滤器算法
-optimizations !code/simplification/cast,!field/*,!class/merging/*
#如果项目中使用到注解,需要保护注解属性
-keepattributes *Annotation*
#不混淆泛型
-keepattributes Signature
#保留代码行号,这在混淆后代码运行中抛出异常信息时,有利于定位出错的代码
-keepattributes SourceFile,LineNumberTable
#保持 Android SDK 相关API 类不被混淆
-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
-keep public class * extends android.app.Fragment
-keep public class * extends android.view.View
#如果引用了v4或者v7包
-keep class android.support.** {*;}
#保持 native 方法不被混淆
-keepclasseswithmembernames class * { native <methods>;
}
#保留R类
-keep class **.R$* { *;
}
#保持自定义控件类不被混淆
-keepclasseswithmembers class * {public <init>(android.content.Context, android.util.AttributeSet);public <init>(android.content.Context, android.util.AttributeSet, int);
}
#保持自定义控件不被混淆
-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);
}
#保持 Activity 中参数是View 类型的函数,
#保证在 layout XML 文件中配置的 onClick 属性的值能够正常调用到
-keepclassmembers class * extends android.app.Activity{public void *(android.view.View);
}
#保持枚举 enum类不被混淆 如果混淆报错,
-keepclassmembers enum * {public static **[] values();public static ** valueOf(java.lang.String);
}
#保持 Parcelable 不被混淆
-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();
}
#对于待有回调函数 onXXEvent 的,不能被混淆
-keepclassmembers class * { void *(**On*Event);
}
1.保留实体类和成员不被混淆
对于实体类,要保留它们的set
和get
方法,对于boolean 型的get 方法,有人喜欢命名为isXXX
的方式,所以不要遗漏了。
这是保留一个类和其成员不被混淆
一种好的做法是把所有实体都放在一个包下进行管理,这样只写一次混淆就够了(如下)。避免以后在别的包中新增的实体而忘记保留,代码在混淆后因为找不到相应的实体类而崩溃。
Android 混淆机制详解相关推荐
- Android学习笔记——Android 签名机制详解
Android 签名机制详解 近期由于工作需要在学习 Android 的签名机制,因为没有现成资料,只能通过开发者文档和阅读博客的方式对 Android 签名机制进行大致了解.过程中查阅到的资料相对零 ...
- 【Android签名机制详解】二:Android V1、V2、V3、V4签名方案
前言 书接上回[Android签名机制详解]一:密码学入门,在了解了消息摘要.非对称加密.数字签名.数字证书的基本概念后,我们趁热打铁.直奔主题,讲解签名在Android中的实际应用. 基础知识 An ...
- Android Intent机制详解
什么是Intent Intent 是一个将要执行的动作的抽象描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯.比如说调用startActivity()来启动一 ...
- Android 消息机制详解(Android P)
前言 Android 消息机制,一直都是 Android 应用框架层非常重要的一部分,想更加优雅的进行 Android 开发,我想了解消息机制是非常必要的一个过程,此前也分析过很多次 Handler ...
- Android事件机制详解
转自:http://www.codeceo.com/article/android-event.html 1概述 在Android平台上,主要用到两种通信机制,即Binder机制和事件机制,前者用于跨 ...
- Android 广播机制详解
一.广播的简介 首先,当我们一听到广播这个词时.就可以想到小学是教室的广播.不错Android中的广播机制与我们生活中的广播是有异曲同工之妙的.Android中的发送广播也就像广播室播广播,可以让很多 ...
- Android消息机制详解
*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 Android消息机制 这一定是一个被写烂了的专题吧.那本媛也来凑一个热闹吧.哈哈 这篇博客将会涉及以下内容: 消息机制概述 UM ...
- Android运行机制详解
Android应用程序是用Java语言写的,通过aapt工具把应用程序所需要的任何数据.资源文件打包成apk文件,这个文件是一个将应用安装到手机上的一个载体. 每个android应用程序存在于不同的世 ...
- (转)Android IPC机制详解
o IBinder接口 IBinder接口是对跨进程的对象的抽象.普通对象在当前进程可以访问,如果希望对象能被其它进程访问,那就必须实现IBinder接口.IBinder接口可以指向本地对象,也可以指 ...
最新文章
- 大学生计算机基础excel视频,大学生计算机基础Excel.doc
- 矩阵快速幂求大斐波那契poj3070(java)
- java图形化界面设置焦点_如何在更新窗口时防止Java图形程序窃取焦点?
- JQuery 表单校验
- 云服务器的购买和宝塔面板的使用
- 【OpenCV】音符提取(形态学实例)
- 提高“磁盘清理”速度的方法
- studioone唱歌效果精调_Sidechain是如何工作的,为什么sidechain可以带来如此酷炫的效果...
- 2008域控服务器创建本地用户,windows 2008 r2 用域帐户登陆后怎么修改本地用户密码?...
- Software caused connection abort: socket write error 问题原因推测
- Java速成课程建议
- red5流媒体服务器网站,[RED5]red5流媒体服务器(开源免费)的安装方法
- Android 修改阿拉伯语数字显示
- 错误号 MSSQL_REPL20011 错误号:15517
- iphone手机如何修改Apple ID密码
- 服务器ubuntu系统调节亮度,Ubuntu系统下调节屏幕亮度的两种Linux命令
- untiy 串口通信
- 【服务器数据恢复】华为OceanStor服务器热备盘同步数据失败的数据恢复案例
- 广义线性模型到底是个什么鬼?
- 【算法学习笔记】74. 枚举 状态压缩 填充方案 SJTU OJ 1391 畅畅的牙签袋(改)...
热门文章
- 黑白棋游戏源代码分析
- x265-1.7版本-encoder/frameencoder.h注释
- oracle10503事件,使用10203事件来跟踪oracle块清除
- python微信自动群发脚本_python 微信批量发送消息脚本
- 遗传算法基本简介及改进方向
- 使用“黑魔法”优雅的修改第三方依赖包
- 【Proteus仿真】【STM32单片机】智能温控风扇设计
- 前端解决表情符号乱码问题(前端处理表情符号编码)@令狐张豪
- 【接口工具ApiPost】生成代码(17)
- 个人喜欢的网站http://www.w3school.com.cn