Android的代码混淆————ProGuard

时间:2022-06-01 17:17:41

ProGuard简介

Android2.3之后工程中自带了ProGuard混淆
Android的官网ProGuard介绍地址:
Develop-tools-Tools Help-ProGuard
官网访问太慢
Android developer 最新国内镜像:
http://wear.techbrood.com
对应的ProGuard网址:
http://developer.android.com/guide/developing/tools/proguard.html
中文翻译:
http://www.cnblogs.com/over140/archive/2011/04/22/2024528.html
ProGuard用户手册(英版)
https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/usage.html

Android中ProGuard的文件构成

使用ProGuard之后
<project_dir>/proguard目录里有以下文件:

+ dump.txt 描述apk文件中所有类文件间的内部结构。
+ mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射。
+ seeds.txt 列出了未被混淆的类和成员
+ usage.txt 列出了从apk中删除的代码

基本配置使用方法

首先,工程中project.properties文件中的proguard配置信息屏蔽去掉
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

其次,工程中proguard-project.txt文件,添加必要的不混淆信息
最基本的不混淆声明如下:

-optimizationpasses 5                                                       # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontskipnonpubliclibraryclasses # 是否混淆第三方jar
-dontpreverify # 混淆时是否做预校验

-ignorewarnings # 屏蔽警告
-dontwarn # 也是屏蔽警告的意思

-verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法

-keepattributes *Annotation*
-keepattributes Signature
# 不混淆第三方jar包中的类# 第三方jar包中如果有.so文件,不用去理会# 引入的第三方jar文件不要混淆,否则可能会报异常-libraryjars libs/armeabi/libfaceppapi.so-libraryjars libs/android-support-v4.jar-libraryjars libs/faceppsdk.jar-keep class com.baidu.mapapi.** {*;}-keep class com.tencent.tauth.** {*;}-keep class com.weibo.sdk.android.** {*;}-keep class com.sina.sso.** {*;}-keep class org.apache.http.entity.mime.** {*;}-keep class android.support.v4.** {*;}-keep class android.net.http.** {*;}
# 保持哪些类不被混淆-keep public class * extends android.app.Fragment  -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 * extends android.support.v4.**-keep public class com.android.vending.licensing.ILicensingService-keep public class * implements java.io.Serializable
# 基本的不混淆方法-keepclasseswithmembernames class * {                                       # 保持 native 方法不被混淆    native <methods>;}-keepclasseswithmembernames class * {                                       # 保持自定义控件类不被混淆    public <init>(android.content.Context, android.util.AttributeSet);}-keepclasseswithmembernames class * {    public <init>(android.content.Context, android.util.AttributeSet, int);}-keepclassmembers enum * {                                                  # 保持枚举 enum 类不被混淆    public static **[] values();    public static ** valueOf(java.lang.String);}-keep class * implements android.os.Parcelable {                            # 保持 Parcelable 不被混淆  public static final android.os.Parcelable$Creator *;}

基本的混淆keep语法

## 测试
#1
-keep public class * extends com.zhang.service 并不能保证自定义包名下的所有类都不混淆
#2
-keep public class com.zhang.service.TeacherService{ # 这种方法同时把类和类中指定的方法声明不混淆
public <methods>;
}
#3
-keepclassmembers class com.zhang.util.FaceDetect{
public int getFaceNumber(org.json.JSONObject); # 只保持对应类下的特定方法不被混淆
}
#4
-keepclasseswithmembers class com.zhang.util.ImageHandle { # 保持对应类以及类下特定的方法不被混淆
public java.lang.String getPhotoPath(android.content.Intent);
}
#5
-keepclasseswithmembernames class com.zhang.util.FaceHandle { # 同样保持对应类以及类下特定的方法不被混淆
public <methods>;
}
#6
-keep class com.facepp.http.* { #保证第三方jar包不被混淆
*;
}
#7
-keep class com.facepp.http.** { #保证第三方jar包不被混淆
*;
}
#8
-keep class com.zhang.service.SyncHttp { #保证此类下所有方法不被混淆
*;
}
"*" 与 “**”的区别
*表示匹配任何的类名但是不包括包的分隔符
**则是匹配任何的类名并且包括任意数量的包分隔符

第6例代码意思
保持com.facepp.http下的【所有类】及对应的所有方法都不混淆
第7例代码的意思
保持com.facepp.http下的【所有类和子包下的类】及对应的所有方法和成员变量都不混淆。

混淆下的调试(对能够显示出错误信息的)

对Ecplise中出现的错误信息,导出为log.txt
然后在D:\Java\android-sdk-windows\tools\proguard\bin目录下
使用如下命令(前提是把文件拷贝到当前目录下)
retrace.bat mapping.txt log.txt
要追踪的文件
retrace.bat [-verbose] mapping.txt [<stacktrace_file>]

Android的代码混淆————ProGuard

注意:

混淆最重要的是了解工程中哪些可以混淆,哪些不应该混淆,你要对工程中有系统了解。
目前阶段,我们只需要把引用的系统的所有包,以及第三方Jar包全部声明不混淆那么绝大多数情况均可!

通过上面的代码在Android上添加必要的混淆,那么再通过上一篇文章apk的反编译,反编译出工程文件,我们就可看到,除去引入的第三方包,工程中很多字母类,自己看着都会很乱。通过安装apk,验证功能也都可以正常使用,那么我们混淆就成功啦!

看下面效果图:

Android的代码混淆————ProGuard


以下博文可以参阅:
android 代码混淆:
http://idyll.blog.51cto.com/4719035/1287745
侧重讲混淆语法

移动安全:android app proguard混淆配置与常见问题:http://www.cnseay.com/3792/
侧重讲混淆中哪些该混淆,哪些不该混淆