proguard混淆
来源:互联网 发布:ubuntu安装firefox57 编辑:程序博客网 时间:2024/05/10 03:24
proguard混淆
Android源码很容易被工具反编译出来,因此,对源码做混淆是一种非常常用的保护源码的方式,不仅如此,proguard还会对源码做一些优化,可以对代码进行去冗余压缩,代码优化,代码混淆等。在Android中的主要应用就是对代码混淆:就是将类名,方法名,Field名变成如a,b,c或者1,2,3等难以阅读和理解的名字,以防止逆向工程和被反编译阅读源码。
开启proguard混淆配置
下面说一下怎样在Eclipse
和Android Studio
中为项目开启proguard混淆。 Eclipse:
在项目根路径下有两个文件:project.properties
和 proguard-project.txt
,在创建项目时默认生成的,如果没有手动创建即可。
在project.properties
里有下面一段被注释的话,去掉#号取消注释即开启了proguard混淆:
...# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):...
Android Studio:
在项目根路径下有两个文件:build.gradle
和 proguard-rules.pro
,其中proguard-rules.pro
是创建项目是默认生成的。
在build.gradle
中有下面的配置,即表示开启proguard混淆:
android{...... buildTypes { release { shrinkResources true minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }}
proguard-android.txt:这是Android SDK tools下面提供的一个默认的配置文件。
proguard-project.txt / proguard-rules.pro:这是我们自定义的配置文件,在proguard-android.txt的基础上,添加一些项目相关的自定义配置。
proguard-android.txt的默认配置:
这个文件存放于Android SDK/tools/proguard目录下,打开可以看到如下内容:
# This is a configuration file for ProGuard.# http://proguard.sourceforge.net/index.html#manual/usage.html-dontusemixedcaseclassnames-dontskipnonpubliclibraryclasses-verbose# Optimization is turned off by default. Dex does not like code run# through the ProGuard optimize and preverify steps (and performs some# of these optimizations on its own).-dontoptimize-dontpreverify# Note that if you want to enable optimization, you cannot just# include optimization flags in your own project configuration file;# instead you will need to point to the# "proguard-android-optimize.txt" file instead of this one from your# project.properties file.-keepattributes *Annotation*-keep public class com.google.vending.licensing.ILicensingService-keep public class com.android.vending.licensing.ILicensingService# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native-keepclasseswithmembernames class * { native <methods>;}# keep setters in Views so that animations can still work.# see http://proguard.sourceforge.net/manual/examples.html#beans-keepclassmembers public class * extends android.view.View { void set*(***); *** get*();}# We want to keep methods in Activity that could be used in the XML attribute onClick-keepclassmembers class * extends android.app.Activity { public void *(android.view.View);}# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String);}-keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator CREATOR;}-keepclassmembers class **.R$* { public static <fields>;}# The support library contains references to newer platform versions.# Don't warn about those in case this app is linking against an older# platform version. We know about them, and they are safe.-dontwarn android.support.**
这个就是默认的混淆配置文件了,挨着来浏览一下。 -dontusemixedcaseclassnames
表示混淆时不使用大小写混合类名。 -dontskipnonpubliclibraryclasses
表示不跳过library中的非public的类。 -verbose
表示打印混淆的详细信息。 -dontoptimize
表示不进行优化,建议使用此选项,因为根据proguard-android-optimize.txt中的描述,优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行。 -dontpreverify
表示不进行预校验。这个预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度。 -keepattributes *Annotation*
表示对注解中的参数进行保留。
-keep public class com.google.vending.licensing.ILicensingService-keep public class com.android.vending.licensing.ILicensingService
表示不混淆上述声明的两个类,这两个类我们基本也用不上,是接入Google原生的一些服务时使用的。
-keepclasseswithmembernames class * { native <methods>;}
表示不混淆任何包含native方法的类的类名以及native方法名,这个和我们刚才验证的结果是一致的。
-keepclassmembers public class * extends android.view.View { void set*(***); *** get*();}
表示不混淆任何一个View中的setXxx()和getXxx()方法,因为属性动画需要有相应的setter和getter的方法实现,混淆了就无法工作了。
-keepclassmembers class * extends android.app.Activity { public void *(android.view.View);}
表示不混淆Activity中参数是View的方法,因为有这样一种用法,在XML中配置android:onClick=”buttonClick”属性,当用户点击该按钮时就会调用Activity中的buttonClick(View view)方法,如果这个方法被混淆的话就找不到了。
-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String);}
表示不混淆枚举中的values()和valueOf()方法,枚举我用的非常少,这个就不评论了。
-keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator CREATOR;}
表示不混淆Parcelable实现类中的CREATOR字段,毫无疑问,CREATOR字段是绝对不能改变的,包括大小写都不能变,不然整个Parcelable工作机制都会失败。
-keepclassmembers class **.R$* { public static <fields>;}
表示不混淆R文件中的所有静态字段,我们都知道R文件是通过字段来记录每个资源的id的,字段名要是被混淆了,id也就找不着了。 -dontwarn android.support.**
表示对android.support包下的代码不警告,因为support包中有很多代码都是在高版本中使用的,如果我们的项目指定的版本比较低在打包时就会给予警告。不过support包中所有的代码都在版本兼容性上做足了判断,因此不用担心代码会出问题,所以直接忽略警告就可以了。
proguard中的keep关键字
proguard中有下面几个keep关键字:
proguard中的通配符
proguard还包括下面一些通配符:
对项目做混淆配置proguard-android.txt
我们可以修改proguard-android.txt
中的规则,但是直接在proguard-android.txt
中修改会对我们本机上所有项目的混淆规则都生效,那么有没有什么办法只针对当前项目的混淆规则做修改呢?当然是有办法的了,你会发现任何一个Android Studio项目在app模块目录下都有一个proguard-rules.pro
文件,这个文件就是用于让我们编写只适用于当前项目的混淆规则的,那么接下来用上面的知识来对项目混淆规则做修改。
对项目中使用到的三方库做处理
-dontwarn xxx.xxx.**
某些三方库中对某些API做了引用,如果不存在,则在打包的时候会报错,使用-dontwarn
,可以在打包的时候忽略此错误.-keep class xxx.xxx.** { *; }
这样是不对指定包下面的所有子包和类做任何混淆,因为引用的都是三方开源库,既然是开源的,所以也没用必要做混淆.
下面列出了项目中用到的三方库混淆:
google的support库:-keep class android.support.** { *; }
EventBus:
-keep class de.** { *; }
Volley:
-keep class com.android.volley.** { *; }
百度推送和百度地图:
-keep class com.baidu.** { *; }
Gson:
-keep class com.google.gson.** { *; }
universal-image-loader
-keep class com.nostra13.universalimageloader.** { *; }
友盟统计
-keep class com.umeng.analytics.** { *; }
OkHttp
-keep class okhttp3.** { *; }
okio
-keep class okio.** { *; }
LitePal
-keep class org.litepal.** { *; }
对Gson解析的实体类不能做混淆
因为Gson在把Json串解析成实体类的时候,是通过反射来获取类的字段名,所以不能对类做混淆.因为项目里面需要由Gson解析的实体类都存放在reponse包下面,所以添加下面的配置:-keep class **.response.** { *; }
另外,所有请求返回需要解析的对应的实体类跟请求URL关联,存放在ResponseTypeProvider 里面的,所以需要添加下面的配置:-keep class **.ResponseTypeProvider { *; }
最后,Gson还需要添加下面的配置:-keepattributes Signature
LitePal
项目中应用了ORM数据库LitePal,会把继承了DataSupport
的类通过反射获取想要属性生成对应表和字段,所以对继承了DataSupport
的类不能做混淆:-keep class * extends org.litepal.crud.DataSupport { *; }
EventBus
项目中用到了EventBus作为事件总线处理库,它会通过反射去看注册了的类,需要用OnEvent***()的方法,如果找不到则会直接Crash,所以需要对所有onEvent***()不做混淆,其中方法参数也是不定的,所以()里面参数用**代替:-keepclassmembers class ** { public void onEvent*(**);}
百度地图
由于对百度地图下面的所有类都做了混淆,在运行百度地图的时候,应用会Crash掉,提示vi.com.gdi.bgl.android.java.EnvDrawText
找不到,所以需要添加下面的配置:-keep class vi.com.gdi.bgl.android.java.EnvDrawText { *; }
- proguard混淆
- proguard混淆
- proguard混淆
- Proguard混淆总结 Proguard语法
- ProGuard混淆器
- android 代码混淆proguard
- Android Java混淆(ProGuard)
- java代码混淆 proguard
- Android Java混淆(ProGuard)
- android 混淆器(ProGuard)
- Proguard混淆器Android
- android 混淆器(ProGuard)
- Android Java混淆(ProGuard)
- Android 混淆器 - ProGuard
- android 混淆 proguard
- ProGuard混淆器
- Proguard 混淆Java源代码
- Proguard混淆器
- C++ 字符串分隔
- 面试注意事项
- URL传参问题
- 将博客搬至51CTO
- Codeforces Round #346 (Div. 2)
- proguard混淆
- Oracle ORA-01033: ORACLE initialization or shutdown in progress 错误解决办法
- 可编辑的jquery表格插件
- iOS项目开发中 webView 服务器返回来一堆不标准的html 语言 处理办法
- Linux练习题
- 退出 android 应用程序
- 【BZOJ1503】[NOI2004]郁闷的出纳员【Splay】
- 管理照相机-拍照(摘自Android官方培训课程中文版(v0.9.5))
- iTween基础之Color(变换颜色)