最近在做一些android的项目,对apk文件能够被反编译这一情况有点头大,就花了点时间,研究了下关于apk被反编译的一些解决方法。

       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文件,在文件最后加入下面红色部分。

# This file is automatically generated by Android Tools.  
  1. # Do not modify this file -- YOUR CHANGES WILL BE ERASED!  
  2. #  
  3. # This file must be checked in Version Control Systems.  
  4. #  
  5. # To customize properties used by the Ant build system use,  
  6. # "ant.properties", and override values to adapt the script to your  
  7. # project structure.  
  8.    
  9. # Project target.  
  10. target=android-4  
  11. proguard.config=proguard.cfg  
# 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签名就可以直接发布了。

代码混淆—android被反编译的两种解决方案_第1张图片

       对该APK进行反编译,打开产生的jar包可以看到,多了好多a、b、c之类的类文件。说明混淆结果已经成功

关于proguard.cfg的配置

       稍微深入想一下混淆后的结果,会发现如果一些提供给外部的类、方法、变量等名字被改变了,那么程序本身的功能就无法正常实现。那么Proguard如何知道哪些东西是可以改名,而哪些是不能改变的呢?

       这个就是靠proguard.cfg文件来进行配置的。Android工程中默认自动生成的proguard.cfg已经针对Android的一般情况进行了配置,我们打开这个配置文件。内容大概如下: 

  1. -optimizationpasses 5  
  2. -dontusemixedcaseclassnames  
  3. -dontskipnonpubliclibraryclasses  
  4. -dontpreverify  
  5. -verbose  
  6. -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*  
  7. -keep public class * extends android.app.Activity  
  8. -keep public class * extends android.app.Application  
  9. -keep public class * extends android.app.Service  
  10. -keep public class * extends android.content.BroadcastReceiver  
  11. -keep public class * extends android.content.ContentProvider  
  12. -keep public class * extends android.app.backup.BackupAgentHelper  
  13. -keep public class * extends android.preference.Preference  
  14. -keep public class com.android.vending.licensing.ILicensingService  
  15.   
  16. -keepclasseswithmembernames class * {  
  17.     native ;  
  18. }  
  19.   
  20. -keepclasseswithmembernames class * {  
  21.     public (android.content.Context, android.util.AttributeSet);  
  22. }  
  23.   
  24. -keepclasseswithmembernames class * {  
  25.     public (android.content.Context, android.util.AttributeSet, int);  
  26. }  
  27.   
  28. -keepclassmembers enum * {  
  29.     public static **[] values();  
  30.     public static ** valueOf(java.lang.String);  
  31. }  
  32.   
  33. -keep class * implements android.os.Parcelable {  
  34.   public static final android.os.Parcelable$Creator *;  
  35. }  
 -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 ; }  -keepclasseswithmembernames class * {     public (android.content.Context, android.util.AttributeSet); }  -keepclasseswithmembernames class * {     public (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。下图:

代码混淆—android被反编译的两种解决方案_第2张图片

代码混淆—android被反编译的两种解决方案_第3张图片

       之后,在官网下载ProGuard,然后找到ProGuard/lib/proguard.jar文件。新建文件夹,将ProGuard.jar和Demo.jar放到同一个目录,打开命令行,定位到这个文件夹,执行下面的命令。

[plain] view plain copy print ?
  1. 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,解压。得到如下图文件。

代码混淆—android被反编译的两种解决方案_第4张图片

 

2、取出classes.dex文件,拷贝至dex2jar目录。

代码混淆—android被反编译的两种解决方案_第5张图片

 

3、在dex2jar目录运行下列命令行:dex2jar.bat classes.dex,回车。

 

4、会发现该目录生成了classes.dex.dex2jar.jar文件

代码混淆—android被反编译的两种解决方案_第6张图片

5、使用jd-gui.exe打开该文件,便可得到反编译的源码。下图:

代码混淆—android被反编译的两种解决方案_第7张图片


更多相关文章

  1. AS下如何生成自定义的.jks签名文件, 以及如何生成数字签名
  2. 【Android自学笔记】对应资源文件夹中的图标尺寸
  3. Android 查看/data/data文件夹并取回文件
  4. Android中解析与创建XML文件
  5. Android中读取properties文件2
  6. Android下载 文件(APP) 并且静默安装
  7. Android开发之如何手写代码进行页面布局

随机推荐

  1. android 广播传参数
  2. Android中getWidth()和getMeasureWidth()
  3. android如何让webview里的资源访问本地缓
  4. android中设置一些没有maxHeight属性控件
  5. Android按钮的五种点击监听事件处理
  6. anroid 7.1添加自定义api服务
  7. Android apk下载 安装 卸载 打开
  8. Android圆角自定义View
  9. Android之ShortCut[setResult方式]
  10. Writing code that captures videos on A