Android 代码混淆

来源:互联网 发布:桌面显示激活windows 编辑:程序博客网 时间:2024/04/29 06:06

混淆是啥子?

代码混淆技术基本原理是使反编译工具反编译出来的代码人难以阅读,从而达到防止被逆向破解的目的。


混淆就是对发布出去的APP重新组织和整理,处理以后和原来功能一样,但是class文件中的字节码不容易被反编译,例如方法名,类名,变量名都被换成了简单的字符,反编译以后难以阅读源代码,而且混淆是单向的,并不能“反混淆”,有一些运行中不需要的东西可能丢失,使得代码更加难以阅读。


常用的工具:Proguard开源项目。  官网:http://proguard.sourceforge.net/



混淆的好处都有啥?谁说对了告诉他。

混淆的优点

1.缩小包体,让app更加轻便。

例如--Proguard官方文档中提到的:

Proguard通过移除没有用到的代码以及通过特定规则重命名类、变量、方法来压缩、优化、混淆你的代码。这样做可以让你的apk更小,更难被逆向分析。由于可以提高被逆向分析的难度,对相关功能安全敏感的应用使用它是十分必要的。


2.保护代码不被轻易使用,私密的一般不开源,不开源还是应该注意一下安全。


3.增加安全性,降低被破解的成功率。若程序之中有机密功能,比如涉及到用户安全,数据安全之类的,要是被别有用心的人剽窃了源代码。岂不是一大损失?



配置

在eclipse中是在proguard.cfg文件中配置。

在Android Studio是在proguard-rules.pro文件中配置。


Android Studio在build.gradle中添加

 buildTypes {        
<span style="white-space:pre"></span>release {            
<span style="white-space:pre"></span>minifyEnabled true            
<span style="white-space:pre"></span>proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        
<span style="white-space:pre"></span>}    
}




常用语法:

  • -libraryjars class_path 应用的依赖包,如android-support-v4  

  • -keep [,modifier,...] class_specification 不混淆某些类  

  • -keepclassmembers [,modifier,...] class_specification 不混淆类的成员  

  • -keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员  

  • -keepnames class_specification 不混淆类及其成员名  

  • -keepclassmembernames class_specification 不混淆类的成员名  

  • -keepclasseswithmembernames class_specification 不混淆类及其成员名  

  • -assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等  

  • -dontwarn [class_filter] 不提示warnning


有一些特殊情况,必须自己添加混淆:

  • 代码中使用了反射,如一些ORM框架的使用 
        保证类名方法不变, 若混淆后, 就反射不了
  •  使用GSON、fastjson等JSON解析框架所生成的对象类
        内部大多是通过反射来生成bean实体对象,这时候就不能混淆了
  •  引用了第三方开源框架或继承第三方SDK,如开源的okhttp网络访问框架,高德地图SDK等
        对应第三方文档中,有关于混淆的处理,按官方给的处理方法就行了。
  • 有用到WEBView的JS调用接口


  •  继承了Serializable接口的类
        反序列化的时候, 需要正确的类名等, 在Android 中大多是实现 Parcelable来序列化的




例子:

  

  #指定代码的压缩级别    -optimizationpasses 5        #包明不混合大小写    -dontusemixedcaseclassnames        #不去忽略非公共的库类    -dontskipnonpubliclibraryclasses         #优化  不优化输入的类文件    -dontoptimize         #预校验    -dontpreverify         #混淆时是否记录日志    -verbose         # 混淆时所采用的算法    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*        #保护注解    -keepattributes *Annotation*        # 保持哪些类不被混淆    -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 com.android.vending.licensing.ILicensingService    #如果有引用v4包可以添加下面这行    -keep public class * extends android.support.v4.app.Fragment                #忽略警告    -ignorewarning        ##记录生成的日志数据,gradle build时在本项目根目录输出##        #apk 包内所有 class 的内部结构    -dump class_files.txt    #未混淆的类和成员    -printseeds seeds.txt    #列出从 apk 中删除的代码    -printusage unused.txt    #混淆前后的映射    -printmapping mapping.txt        ########记录生成的日志数据,gradle build时 在本项目根目录输出-end######            #####混淆保护自己项目的部分代码以及引用的第三方jar包library#######        #-libraryjars libs/umeng-analytics-v5.2.4.jar        #三星应用市场需要添加:sdk-v1.0.0.jar,look-v1.0.1.jar    #-libraryjars libs/sdk-v1.0.0.jar    #-libraryjars libs/look-v1.0.1.jar        #如果不想混淆 keep 掉    -keep class com.lippi.recorder.iirfilterdesigner.** {*; }    #友盟    -keep class com.umeng.**{*;}    #项目特殊处理代码        #忽略警告    -dontwarn com.lippi.recorder.utils**    #保留一个完整的包    -keep class com.lippi.recorder.utils.** {        *;     }        -keep class  com.lippi.recorder.utils.AudioRecorder{*;}            #如果引用了v4或者v7包    -dontwarn android.support.**        ####混淆保护自己项目的部分代码以及引用的第三方jar包library-end####        -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*(...);    }        #保持 native 方法不被混淆    -keepclasseswithmembernames class * {        native <methods>;    }        #保持自定义控件类不被混淆    -keepclasseswithmembers class * {        public <init>(android.content.Context, android.util.AttributeSet);    }        #保持自定义控件类不被混淆    -keepclassmembers class * extends android.app.Activity {       public void *(android.view.View);    }        #保持 Parcelable 不被混淆    -keep class * implements android.os.Parcelable {      public static final android.os.Parcelable$Creator *;    }        #保持 Serializable 不被混淆    -keepnames class * implements java.io.Serializable        #保持 Serializable 不被混淆并且enum 类也不被混淆    -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();    }        #保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable即可    #-keepclassmembers enum * {    #  public static **[] values();    #  public static ** valueOf(java.lang.String);    #}        -keepclassmembers class * {        public void *ButtonClicked(android.view.View);    }        #不混淆资源类    -keepclassmembers class **.R$* {        public static <fields>;    }        #避免混淆泛型 如果混淆报错建议关掉    #–keepattributes Signature        #移除log 测试了下没有用还是建议自己定义一个开关控制是否输出日志    #-assumenosideeffects class android.util.Log {    #    public static boolean isLoggable(java.lang.String, int);    #    public static int v(...);    #    public static int i(...);    #    public static int w(...);    #    public static int d(...);    #    public static int e(...);    #}        #如果用用到Gson解析包的,直接添加下面这几行就能成功混淆,不然会报错。    #gson    #-libraryjars libs/gson-2.2.2.jar    -keepattributes Signature    # Gson specific classes    -keep class sun.misc.Unsafe { *; }    # Application classes that will be serialized/deserialized over Gson    -keep class com.google.gson.examples.android.model.** { *; }


PS: #是注释~












0 0
原创粉丝点击