Android的代码混淆————ProGuard

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>]

注意:

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

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

看下面效果图:



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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值