用proguard对代码进行混淆

对于android程序来说,因为java程序非常容易被反编译,所以开发的android程序也处于非常不安全的处境。

android编译后的apk文件其实是一个压缩包,把后缀名改为zip,打开后就可以看到apk由以下的文件组成:

assets

res

AndroidManifest.xml

resources.arsc

classes.dex
lib

META-INF。。。

classes.dex就是所有编译后的class,现在有很多工具可以对它反编译。我先用了dex2jar把classes.dex转换为一个jar,然后用jd-gui打开这个jar一看,所有的程序代码一清二楚。。。虽然现在提倡分享,并不介意分享源码,但因为程序中涉及到卖的产品本身需要安全控制,要不别人看明白代码,然后修改安全控制,重新编译后,等于是别人可以免费得到卖的产品了。

还好现在android好像从2.2开始内置了proguard工具,它位于android安装目录下tools/proguard目录中,它是一个开源的对java代码进行混淆优化的工具。而且使用非常简单,创建android工程以后,工程目录下会自动生成一个proguard.cfg文件,这个文件是用于proguard对代码混淆的配置文件,默认情况如下:

-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 *;
}

proguard在这最重要的作用就是混淆代码,看上面的配置,大概可以知道它怎么使用,比如-keepclasseswithmembernames就是要保留类中的成员函数,在这里它保留了native函数的声明,这是由于jni调用的时候,是根据native函数名,所以如果它被混淆了,程序将无法用jni调用c写的这个函数。同理,由于我在程序中需要jni改变java类中的成员变量的值,所以我还需要保留这些变量,我在cfg加上如下规则:

-keepclassmembernames class * {
    int mBitmapWidth;
    int mBitmapHeight;
}

更多的配置查看http://proguard.sourceforge.net/

 

在默认情况下,proguard是不打开的。如果需要proguard混淆代码,首先在default.properties中加上proguard.config=proguard.cfg,编译后然后右键工程弹出菜单,选择"Android Tools"->"Export signed application package...",按弹出的对话框操作(如果没生成keystore,首先创建,然后导出数字签名的apk)。成功后在工程目录会加一个目录proguard,里面包含四个文件:dump.txt,mapping.txt,seeds.txt,usage.txt,这些文件包含了proguard到底如何替换混淆代码的信息,retrace时需要用到。

至此,java代码就被混淆优化了。再用dex2jar,jd-gui查看反编译的java代码。发现所有的变量还有自己写的class都被替换成a,b,c,ab等等的,要读懂程序就没那么容易了。

虽然现在读懂程序比较难,但相信还是难不住那些有耐心有“钻研”的家伙啊,因为混淆后程序结构还是一目了然呀,所以仅仅如此并不能加大破解的难度,这时候我自己觉得的有几种方法来增加破解难度:1。关键性代码用c写,然后用jni调用;2。关键性的class动态从服务器上取得,避免在客户端被反编译;3。对class加密,然后自己重写class load的地方再解密;4。好像说都写中文变量名,就反编译不了,因为大部分工具都只支持英文,但如此程序也只能运行在中文环境;5。java防反编译可以做到反编译后的代码是乱七八糟的,但用的工具忘记了,(哎,没有记录的习惯惹的)。这些方法由于项目时间的原因,下一步要好好研究

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值