代码混淆—android被反编译的两种解决方案
来源:互联网 发布:卖家淘宝客怎么付佣金 编辑:程序博客网 时间:2024/04/30 18:54
Java的字节码一般是非常容易反编译的,而android采用java编写,生成的apk安装文件实际上就是一个压缩格式,后缀改为.zip,解压缩,再借用其他工具就能被反编译出来,目前android程序所谓的去广告版、汉化版都是通过反编译修改源码再编译发布的。为了能对源代码就行一些必要的保护,我们可以对编译好的class文件进行混淆处理。这里我使用了两种解决方案,不过都是通过ProGuard来实现的。ProGuard的就是一个混淆器。混淆器通过删除从未用过的代码和使用晦涩名字重命名类、字段和方法,对代码进行压缩,优化和混淆。混淆后的结果是一个比较小的.apk文件,该文件比较难进行逆向工程。
ProGuard是一个SourceForge上非常知名的开源项目。官网网址是:http://proguard.sourceforge.net/
方案一:
目前android SDK工具集里面已经自带有ProGuard代码混淆,不过,ProGuard混淆默认没有启动,我们可以通过添加一行配置打开混淆。创建新的Android工程时,如果在工程目录看到了ProGuard的配置文件proguard.cfg,说明你的工程已经加入了ProGuard,这时候只需要打开project.properties文件,在文件最后加入下面红色部分。
- # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
- #
- # This file must be checked in Version Control Systems.
- #
- # To customize properties used by the Ant build system use,
- # "ant.properties", and override values to adapt the script to your
- # project structure.
- # Project target.
- target=android-4
- <SPAN style="COLOR: #ff0000">proguard.config=proguard.cfg</SPAN>
# This file is automatically generated by Android Tools.# Do not modify this file -- YOUR CHANGES WILL BE ERASED!## This file must be checked in Version Control Systems.## To customize properties used by the Ant build system use,# "ant.properties", and override values to adapt the script to your# project structure. # Project target.target=android-4proguard.config=proguard.cfg
这样,ProGuard就启动了,在打包生成apk的时候变会自动进行代码混淆及优化。通过下面的方式导出,并添加android签名就可以直接发布了。
对该APK进行反编译,打开产生的jar包可以看到,多了好多a、b、c之类的类文件。说明混淆结果已经成功。
关于proguard.cfg的配置
稍微深入想一下混淆后的结果,会发现如果一些提供给外部的类、方法、变量等名字被改变了,那么程序本身的功能就无法正常实现。那么Proguard如何知道哪些东西是可以改名,而哪些是不能改变的呢?
这个就是靠proguard.cfg文件来进行配置的。Android工程中默认自动生成的proguard.cfg已经针对Android的一般情况进行了配置,我们打开这个配置文件。内容大概如下:
- -optimizationpasses 5
- -dontusemixedcaseclassnames
- -dontskipnonpubliclibraryclasses
- -dontpreverify
- -verbose
- -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
- -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
- -keepclasseswithmembernames class * {
- 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 * {
- public static **[] values();
- public static ** valueOf(java.lang.String);
- }
- -keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
- }
-optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -verbose -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -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 -keepclasseswithmembernames class * { 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 * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }它主要保留了继承自Activity、Application、Service、BroadcastReceiver、ContentProvider、BackupAgentHelper、Preference和ILicensingService的子类。因为这些子类,都是可能被外部调用的。
另外,它还保留了含有native方法的类、构造函数从xml构造的类(一般为View的子类)、枚举类型中的values和valueOf静态方法、继承Parcelable的跨进程数据类。
在实际的一个工程项目中,可能Google自动生成的配置不能胜任我们的混淆工作。所以,我们往往需要自己编写一些ProGuard配置。这方面的资料在官网的Manual -> Usage里有详细说明。做android的同学可以研究一下。
方案2:
通过将比较敏感的包导出为.jar格式,然后再将混淆过的.jar文件导入原来的工程中作为第三方类库进行调用。
先导出自己工程里面的包为.jar格式,例如为Demo.jar。下图:
之后,在官网下载ProGuard,然后找到ProGuard/lib/proguard.jar文件。新建文件夹,将ProGuard.jar和Demo.jar放到同一个目录,打开命令行,定位到这个文件夹,执行下面的命令。
- java -jar proguard.jar -injars Demo.jar -outjars MyDemo.jar -libraryjars D:android/android-sdk/platforms/android-8/android.jar -printmapping sdk.map -keep "public class * {public *;}"
java -jar proguard.jar -injars Demo.jar -outjars MyDemo.jar -libraryjars D:android/android-sdk/platforms/android-8/android.jar -printmapping sdk.map -keep "public class * {public *;}"
具体参数的作用,大家查一下官方文档吧。
文件下载地址(ProGuard 及下面的反编译工具):点击打开链接
附:android反编译方法。
1、将要反编译的APK文件后缀改为.zip,解压。得到如下图文件。
2、取出classes.dex文件,拷贝至dex2jar目录。
3、在dex2jar目录运行下列命令行:dex2jar.bat classes.dex,回车。
4、会发现该目录生成了classes.dex.dex2jar.jar文件
5、使用jd-gui.exe打开该文件,便可得到反编译的源码。下图:
- 代码混淆—android被反编译的两种解决方案
- 代码混淆—android被反编译的两种解决方案
- Android代码混淆 反编译
- Android 代码混淆防止反编译
- Android 代码混淆 防止反编译
- Android代码混淆及反编译
- android代码混淆和反编译
- android 反编译---and---混淆代码
- android 代码混淆与反编译
- android混淆代码与反编译
- android 如何防止代码被反编译(代码混淆)
- Android 上线前的代码混淆之(一)反编译
- [TODO] 矛与盾——浅析android项目的代码混淆和反编译
- Android 代码混淆及反编译方法
- Proguard android代码混淆 防止反编译
- android,代码混淆,反编译,ADT 20版本
- Proguard android代码混淆 防止反编译
- Android APK之代码混淆与反编译
- 搭建cocos2d-x-android环境 Windows XP3 + Eclipse + NDKR7+COCOS2DX(没有用到cygwin和minigw)
- 使用Dialog AlertDialog ----模态异步
- Android权限之sharedUserId和签名
- com.android.dx.util.DexException: Multiple dex files define的解决方法
- java-使用package分类管理
- 代码混淆—android被反编译的两种解决方案
- 酒弄人生
- linux下查看每个CPU的使用率
- 位模式转换-----C++实现浮点数存储格式输出
- java内省机制
- linux i 节点
- c/c++:extern,extern "C"
- 控件组件篇:Dialog汇总
- JSP 中 request的几个常用方法