Proguard说明,android代码混淆
2017-05-17 16:18
477 查看
Proguard简介
介绍
ProGuard is a Java class file shrinker, optimizer, obfuscator, and preverifier.shrink:去除无用的类和成员
optimize:进一步优化,方法内联,去除无用方法参数,非入口方法变成私有,静态的,final
obfuscate:非入口点的方法和类进行重命名
preverify:android是不需要这一步的,只针对标准的.jar
我是官方文档,戳我!
jar转换关系
inputjars 到 outputjars的关系 是多对多多对一
-injars in.jar -injars /usr/local/java/scala-2.9.1/lib/scala-library.jar -outjars out.jar
多对多
-injars proguardgui.jar -outjars proguardgui_out.jar -injars proguard.jar -outjars proguard_out.jar -libraryjars <java.home>/lib/rt.jar -applymapping proguard.map -keep public class proguard.gui.ProGuardGUI { public static void main(java.lang.String[]); }
一对多
-injars in.jar -outjars code_out.jar(**.class) -outjars resources_out.jar
简单的关键字说明
-keep [,modifier,…] class_specification保存类和类成员 ,先查找指定的类,然后保存指定的类中的相关成员,同时做为入口点
-keepclassmembers [,modifier,…] class_specification
保存类成员
-keepclasseswithmembers [,modifier,…] class_specification
保存指定的类成员存在的类和类成员,先查找包含指定成员的类,然后匹配指定的类
**-keepnames class_specification
缩写 -keep,allowshrinking class_specification**
保存在瘦身阶段没有被移除的类和类成员的名字,仅仅用来obfuscate阶段
**-keepclassmembernames class_specification
缩写 -keepclassmembers,allowshrinking class_specification**
保存在瘦身阶段没有被移除的类成员的名字,仅仅用来obfuscate阶段
**-keepclasseswithmembernames class_specification
缩写 -keepclasseswithmembers,allowshrinking class_specification**
保存在瘦身阶段没有被移除的,并且指定的类成员出现的类和类成员的名字,仅仅用来obfuscate阶段
-printseeds [filename]
列出所有匹配-keep的类和类成员,在处理过程进行标准的输出,或者输出在文件中
-printmapping [filename]
将混淆后的映射关系输出到指定的文件.
-dontwan [class_filter]
不处理无法解析引用以及一些其它重要的问题
基本的匹配规则
[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname [extends|implements [@annotationtype] classname] [{ [@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> | (fieldtype fieldname); [@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> | <init>(argumenttype,...) | classname(argumenttype,...) | (returntype methodname(argumenttype,...)); [@annotationtype] [[!]public|private|protected|static ... ] *; ... }]
基本符号说明:
字符 | 解释 | 例子 |
---|---|---|
@ | 注释 | @Deprecated public class * // 可以匹配所有被@Deprecated修饰的类 |
! | 非 | |
[] | 可选项 | |
<> | 特定的含义,下面详细说明 | |
| | 或者 | |
() | 组合 | (fieldtype filedname)组合在一起进行限定 |
; | 域或者方法后面需要加上 | |
* | 通配符 |
<>的说明:
<> | 说明 |
---|---|
< init > | 匹配任意的构造函数 |
< fields > | 匹配任意的域 |
< methods > | 匹配任意的方法 |
classname的说明:
classname是必选项,是带上包名的完整类名.如果有内部类可以用符号进行组合.如android.view.ViewOnClickListener同时可以使用通配符:符号 | 说明 |
---|---|
? | 用来匹配除包分隔符.之外的其他任意单个字符 |
* | 用来匹配任意多个字符(包括0个),匹配不能跨越包分隔符.。 |
** | 用来匹配任意多个字符(包括0个),和*不同的是,**匹配可以跨越包分隔符。 |
filedtype 和 filename一起使用:
filedtype的通配符:符号 | 说明 |
---|---|
% | 用来匹配任意Java基本数据类型(包括byte,short,int,long,float,double,char和boolean,不包括void) |
\? | 用来匹配成员变量类型中除包分隔符.之外的任意单个字符 |
* | 用来匹配成员变量类型中除包分隔符.之外的任意多个字符(包括0个) |
** | 用来匹配成员变量类型中任意多个字符(包括0个),包括包分隔符. |
*** | 用来匹配任意类型,包括基本数据类型和数组 |
符号 | 说明 |
---|---|
? | 用来匹配成员变量名中任意单个字符 |
* | 用来匹配成员变量名中任意多个字符(包括0个) |
优化参数说明
官方优化选项说明语句(部分) | 说明 |
---|---|
class/marking/final | 尽可能的使类成为final类型 |
class/unboxing/enum | 尽可能的简化枚举类型为整数常来功能 |
class/merging/vertical | 尽可能的在类层级垂直方向进行合并 |
class/merging/horizontal (⇒ code/removal/advanced) | 尽可能的在类层级水平方向进行合并 |
field/removal/writeonly | 移除只读的域 |
field/marking/private (⇒ code/simplification/advanced) | 尽可能的使域权限为私有 |
field/propagation/value | 通过方法传递域值 |
method/marking/private (⇒ code/removal/advanced) | 尽可能的使方法为私有 |
method/marking/static | 尽可能的使方法为私有 |
method/marking/final (⇒ code/removal/advanced) | 尽可能使方法为final |
method/removal/parameter(⇒ code/simplification/advanced) | 移除无用的方法参数 |
混淆保留的分类
保留原则:1.外部可能需要使用的
2.反射相关
保留序列化
//仅仅在内存使用 -keepclassmembers class * implements java.io.Serializable { 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(); } //需要存储的序列化,需要额外加上 -keepnames class * implements java.io.Serializable //需要兼容老的数据 -keepnames class * implements java.io.Serializable -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; !static !transient <fields>; !private <fields>; !private <methods>; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); }
保留反射
保留枚举
-keepclassmembers,allowoptimization enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
保留bean
keep public class mypackage.MyBean { public void setMyProperty(int); public int getMyProperty(); } -keep public class mypackage.MyBeanEditor #更加通用的方式 -keep class mybeans.** { void set*(***); void set*(int, ***); boolean is*(); boolean is*(int); *** get*(); *** get*(int); }
保留native
-keepclasseswithmembernames,includedescriptorclasses class * { native <methods>; }
保留回调
-keep class mypackage.MyCallbackClass { void myCallbackMethod(java.lang.String); }
保留数据库驱动
-keep class * implements java.sql.Driver
8. 保留UI
#java的UI -keep class * extends javax.swing.plaf.ComponentUI { public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent); } #android的UI -keep public class * extends android.view.View { public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); }
9. 保留RMI代码
对于android来说就AIDL
-keep class com.xx.xxxxx.token.ITokenService
proguard的使用
Proguard被集成在android sdk 中,其目录是\buildTypes { release { signingConfig signingConfigs.release minifyEnabled true proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘ } }
通过makefile编译, 混淆
android.mk文件中加入
ifeq ("$(isProguard)","false") //isProguard是上层脚本定义的一个变量 LOCAL_PROGUARD_ENABLED := disabled else LOCAL_PROGUARD_ENABLED := custom endif proguard_options_file := $(LOCAL_PATH)/src/app/proguard-rules.pro LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
android 官方混淆模板
# # This ProGuard configuration file illustrates how to process Android # applications. # Usage: # java -jar proguard.jar @android.pro # # If you're using the Android SDK (version 2.3 or higher), the android tool # already creates a file like this in your project, called proguard.cfg. # It should contain the settings of this file, minus the input and output paths # (-injars, -outjars, -libraryjars, -printmapping, and -printseeds). # The generated Ant build file automatically sets these paths. # Specify the input jars, output jars, and library jars. # Note that ProGuard works with Java bytecode (.class), # before the dex compiler converts it into Dalvik code (.dex). -injars bin/classes -injars libs -outjars bin/classes-processed.jar -libraryjars /usr/local/android-sdk/platforms/android-9/android.jar #-libraryjars /usr/local/android-sdk/add-ons/google_apis-7_r01/libs/maps.jar # ... # Save the obfuscation mapping to a file, so you can de-obfuscate any stack # traces later on. -printmapping bin/classes-processed.map # You can print out the seeds that are matching the keep options below. #-printseeds bin/classes-processed.seeds # Preverification is irrelevant for the dex compiler and the Dalvik VM. -dontpreverify # Reduce the size of the output some more. -repackageclasses '' -allowaccessmodification # Switch off some optimizations that trip older versions of the Dalvik VM. -optimizations !code/simplification/arithmetic # Keep a fixed source file attribute and all line number tables to get line # numbers in the stack traces. # You can comment this out if you're not interested in stack traces. -renamesourcefileattribute SourceFile -keepattributes SourceFile,LineNumberTable # RemoteViews might need annotations. -keepattributes *Annotation* # Preserve all fundamental application classes. -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 # Preserve all View implementations, their special context constructors, and # their setters. -keep public class * extends android.view.View { public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); } # Preserve all classes that have special context constructors, and the # constructors themselves. -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet); } # Preserve all classes that have special context constructors, and the # constructors themselves. -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); } # Preserve the special fields of all Parcelable implementations. -keepclassmembers class * implements android.os.Parcelable { static android.os.Parcelable$Creator CREATOR; } # Preserve static fields of inner classes of R classes that might be accessed # through introspection. -keepclassmembers class **.R$* { public static <fields>; } # Preserve the required interface from the License Verification Library # (but don't nag the developer if the library is not used at all). -keep public interface com.android.vending.licensing.ILicensingService -dontnote com.android.vending.licensing.ILicensingService # The Android Compatibility library references some classes that may not be # present in all versions of the API, but we know that's ok. -dontwarn android.support.** # Preserve all native method names and the names of their classes. -keepclasseswithmembernames class * { native <methods>; } # Preserve the special static methods that are required in all enumeration # classes. -keepclassmembers class * extends java.lang.Enum { public static **[] values(); public static ** valueOf(java.lang.String); } # Explicitly preserve all serialization members. The Serializable interface # is only a marker interface, so it wouldn't save them. # You can comment this out if your application doesn't use serialization. # If your code contains serializable classes that have to be backward # compatible, please refer to the manual. -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; 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(); } # Your application may contain more items that need to be preserved; # typically classes that are dynamically created using Class.forName: # -keep public class mypackage.MyClass # -keep public interface mypackage.MyInterface # -keep public class * implements mypackage.MyInterface
优雅的混淆
仅供参考,思路类似在需要保留的地方加上标识@android.support.annotation.Keep
#手动启用support keep注解 #http://tools.android.com/tech-docs/support-annotations -dontskipnonpubliclibraryclassmembers -printconfiguration -keep @android.support.annotation.Keep class * -keepclassmembers class * { @android.support.annotation.Keep *; }
相关文章推荐
- Android 项目的代码混淆,Android proguard 使用说明
- Android 项目的代码混淆,Android proguard 使用说明
- Android 项目的代码混淆,Android proguard 使用说明
- Android 代码混淆,Android proguard 使用说明
- Android 项目的代码混淆,Android proguard 使用说明
- Android 项目的代码混淆,Android proguard 使用说明
- Android 项目的代码混淆,Android proguard 使用说明
- Eclipse+ADT对android apk 进行代码混淆(proguard)
- 关于Android使用proguard进行代码混淆
- 使用ProGuard混淆Android工程 保护好自己的代码
- 在android中使用proguard混淆代码出现“Conversion to Dalvik format failed with error 1”错误的解决方法
- Android 2.3 代码混淆proguard技术介绍
- 如何混淆Android项目代码(ProGuard)防止反编译
- 命令行编译android程序,欢迎探讨命令行如何使用proguard混淆优化代码
- Android 2.3 代码混淆proguard技术介绍
- 使用ProGuard使你android代码保持混淆
- Android 4.0 ProGuard 代码混淆
- Proguard android代码混淆 防止反编译
- 在android中使用proguard混淆代码出现“Conversion to Dalvik format failed with error 1”错误的解决方法
- 在android中使用proguard混淆代码出现“Conversion to Dalvik format failed with error 1”错误的解决方法