Android Studio和eclipse混淆打包总结

简介: Android Studio和eclipse混淆打包总结

最近项目有点闲,考虑到以前的项目没有做过混淆,只是用了加固软件进行加固,为了安全性,准备给项目加上,这里做个总结,都经本人亲自在项目实践,说是为了安全性,这好像说大了,一来项目中没用到什么特别的技术,二是大神真要弄你你也防不住呀,这样做只是为了让闲着的自己心安理得一点,哈哈哈。。。


Android项目在完工发布时,需要对代码和资源文件进行混淆,目的有两个:


1、减小压缩包的体积

2、防止代码被反编译后恶意利用


Android Apk混淆分两步走:


1、混淆代码

2、混淆资源文件


混淆资源文件直接使用第三方的就够了,看这个网址:

http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=42


我们再来看看混淆代码。


混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。


因为Android是使用Java开发的,所以开发者可以使用ProGuard对代码进行混淆。SDK已经集成了ProGuard工具,开发者可以从SDK目录下的\tools\proguard目录中进行查看。


ProGuard是一个免费的Java类文件收缩,优化,混淆和预校验器。它可以检测并删除未使用的类,字段,方法和属性。它可以优化字节码,并删除未使用的指令。它可以将类、字段和方法使用短无意义的名称进行重命名。最后,预校验的Java6或针对Java MicroEdition的所述处理后的码。


ProGuard默认会对第三方库也进行混淆的,而第三方库有的已经混淆过了,有的使用了Java反射技术,所以我们在进行代码混淆的时候要排除这些第三方库。排除对第三方库的混淆需要在混淆规则文件(通常是:proguard-project.txt或proguard.cfg或proguard-rules.pro或proguard-rules.txt也可以是其它的文件名只要在配置文件中将含有混淆规则的文件名配置进去就行了)中添加如下规则:


1.如果使用了Gson之类的工具要使JavaBean类即实体类不被混淆。


2.如果使用了自定义控件那么要保证它们不参与混淆。


3.如果使用了枚举要保证枚举不被混淆。


4.对第三方库中的类不进行混淆


这里看一下具体的规则:  

-optimizationpasses 7 #指定代码的压缩级别 0 - 7
-dontusemixedcaseclassnames #是否使用大小写混合
-dontskipnonpubliclibraryclasses #如果应用程序引入的有jar包,并且想混淆jar包里面的class
-dontpreverify #混淆时是否做预校验(可去掉加快混淆速度)
-verbose #混淆时是否记录日志(混淆后生产映射文件 map 类名 -> 转化后类名的映射
-optimizations !code/simplification/arithmetic,!field/,!class/merging/ #淆采用的算法
-keep public class * extends android.app.Activity #所有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 #指定具体类不要去混淆
-keepclasseswithmembernames class * {
native < methods>; #保持 native 的方法不去混淆
}
-keepclasseswithmembers class * {
public < init>(android.content.Context, android.util.AttributeSet); #保持自定义控件类不被混淆,指定格式的构造方法不去混淆
}
-keepclasseswithmembers class * {
public < init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View); #保持指定规则的方法不被混淆(Android layout 布局文件中为控件配置的onClick方法不能混淆)
}
-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*(…);
}
-keepclassmembers enum * { #保持枚举 enum 不被混淆
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { #保持 Parcelable 不被混淆(aidl文件不能去混淆)
public static final android.os.Parcelable$Creator *;
}
-keepnames class * implements java.io.Serializable #需要序列化和反序列化的类不能被混淆(注:Java反射用到的类也不能被混淆)
-keepclassmembers class * implements java.io.Serializable { #保护实现接口Serializable的类中,指定规则的类成员不被混淆
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient < fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keepattributes Signature #过滤泛型(不写可能会出现类型转换错误,一般情况把这个加上就是了)
-keepattributes Annotation #假如项目中有用到注解,应加入这行配置
-keep class *.R$ { *; } #保持R文件不被混淆,否则,你的反射是获取不到资源id的
-keep class *.Webview2JsInterface { ; } #保护WebView对HTML页面的API不被混淆
-keepclassmembers class * extends android.webkit.WebViewClient { #如果你的项目中用到了webview的复杂操作 ,最好加入
public void *(android.webkit.WebView,java.lang.String,android.graphics.Bitmap);
public boolean *(android.webkit.WebView,java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebChromeClient { #如果你的项目中用到了webview的复杂操作 ,最好加入
public void *(android.webkit.WebView,java.lang.String);
} 


#对WebView的简单说明下:经过实战检验,做腾讯QQ登录,如果引用他们提供的jar,若不加防止WebChromeClient混淆的代码,oauth认证无法回调,反编译基代码后可看到他们有用到WebChromeClient,加入此代码即可。


-keepclassmembernames class com.cgv.cn.movie.common.bean.* { ; } #转换JSON的JavaBean,类成员名称保护,使其不被混淆

关于如何配置忽略第三方jar,附上一个图进行说明。  


20170417191129349.png

要想让eclipse的混淆产生效果,就必须打开工程目录的project.properties文件,默认如下:

20170417191526245.png


将 proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt前面的#删除,混淆就起作用了,如果没有的话,随便找一个工程将这个文件拷贝过来即可,或者直接将这句话复制到这个文件中即可。


基本规则大概如上所示,有一些是共用的,这里说一下eclipse的混淆,看一下我的混淆文件。  20170417193930874.png

20170417193940515.png

20170417193950015.png


20170417193958655.png


20170417194007638.png


20170417194016515.png


在release模式下打包apk时会自动运行ProGuard,这里的release模式指的是通过ant release命令或eclipse project->android tools->export signed(unsigned) application package生成apk。


在debug模式下为了更快调试并不会调用proguard。


如果是ant命令打包apk,proguard信息文件会保存于工程代码下的/bin/proguard文件夹内;

如果用eclipse export命令打包,会在/proguard文件夹内。其中包含以下文件:


mapping.txt

表示混淆前后代码的对照表,这个文件非常重要。如果你的代码混淆后会产生bug的话,log提示中是混淆后的代码,希望定位到源代码的话就可以根据mapping.txt反推。


每次发布都要保留它方便该版本出现问题时调出日志进行排查,它可以根据版本号或是发布时间命名来保存或是放进代码版本控制中。


dump.txt

描述apk内所有class文件的内部结构。


seeds.txt

列出了没有被混淆的类和成员。


usage.txt

列出了源代码中被删除在apk中不存在的代码。

下面再来看一下Android Studio应该怎么做?  



20170417192609838.png


只需要在工程的module的build.gradle里面将minifyEnabled设置为true即可。下面来看看我的混淆文件

20170417193511881.png

20170417193523107.png


20170417193536685.png

20170417193546857.png

20170417193559123.png


20170417193609070.png

20170417193617914.png


混淆以后一定要注意测试,避免因为混淆而引入了不必要的bug。


这里还是要提醒一下,混淆的时候有些是不能混淆的:


顾名思义,不能混淆代码如果被混淆了,就会出现错误。


1、需要反射的代码

2、系统接口

3、Jni接口

4、需要序列号和反序列化的代码(即实现Serializable接口的JavaBean)

5、与服务端进行元数据交互的JavaBean(JSON、XML中对应的类)

。。。。。。


后续更新



欢迎start,欢迎评论,欢迎指正










相关文章
|
3月前
|
Java Android开发 C++
Android Studio JNI 使用模板:c/cpp源文件的集成编译,快速上手
本文提供了一个Android Studio中JNI使用的模板,包括创建C/C++源文件、编辑CMakeLists.txt、编写JNI接口代码、配置build.gradle以及编译生成.so库的详细步骤,以帮助开发者快速上手Android平台的JNI开发和编译过程。
232 1
|
1月前
|
Java Unix Linux
Android Studio中Terminal运行./gradlew clean build提示错误信息
遇到 `./gradlew clean build`命令执行出错时,首先应检查错误信息的具体内容,这通常会指向问题的根源。从权限、环境配置、依赖下载、版本兼容性到项目配置本身,逐一排查并应用相应的解决措施。记住,保持耐心,逐步解决问题,往往复杂问题都是由简单原因引起的。
209 2
|
2月前
|
XML IDE 开发工具
🔧Android Studio高级技巧大公开!效率翻倍,编码不再枯燥无味!🛠️
【9月更文挑战第11天】在软件开发领域,Android Studio凭借其强大的功能成为Android开发者的首选IDE。本文将揭示一些提升开发效率的高级技巧,包括自定义代码模板、重构工具、高级调试技巧及多模块架构。通过对比传统方法,这些技巧不仅能简化编码流程,还能显著提高生产力。例如,自定义模板可一键插入常用代码块;重构工具能智能分析并安全执行代码更改;高级调试技巧如条件断点有助于快速定位问题;多模块架构则提升了大型项目的可维护性和团队协作效率。掌握这些技巧,将使你的开发之旅更加高效与愉悦。
63 5
|
3月前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
55 1
|
3月前
|
Android开发
Android Studio: 解决Gradle sync failed 错误
本文介绍了解决Android Studio中出现的Gradle同步失败错误的步骤,包括从`gradle-wrapper.properties`文件中获取Gradle的下载链接,手动下载Gradle压缩包,并替换默认下载路径中的临时文件,然后重新触发Android Studio的"Try Again"来完成同步。
1270 0
Android Studio: 解决Gradle sync failed 错误
|
3月前
|
Java Android开发 芯片
使用Android Studio导入Android源码:基于全志H713 AOSP,方便解决编译、编码问题
本文介绍了如何将基于全志H713芯片的AOSP Android源码导入Android Studio以解决编译和编码问题,通过操作步骤的详细说明,展示了在Android Studio中利用代码提示和补全功能快速定位并修复编译错误的方法。
123 0
使用Android Studio导入Android源码:基于全志H713 AOSP,方便解决编译、编码问题
|
3月前
|
API 开发工具 Android开发
Android Studio:解决AOSP自编译framework.jar引用不到的问题
在Android Studio中解决AOSP自编译framework.jar引用问题的几种方法,包括使用相对路径、绝对路径和通过`${project.rootDir}`动态获取路径的方法,以避免硬编码路径带来的配置问题。
205 0
Android Studio:解决AOSP自编译framework.jar引用不到的问题
|
Java Android开发 数据安全/隐私保护
将Android应用程序打包
选中项目右击àExportàAndroidàExport Android ApplicationàNextàNextàCreate new keystore(创建新密钥)               {                      Location:表示要将打包的项目放置的位置                      Password:表示密码       
1095 0
|
1天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。