Android代码混淆

来源:互联网 发布:帝国cms会员中心模板 编辑:程序博客网 时间:2024/06/17 18:28

作为一名技术开发人员,为了保护源代码,阻止反向工程我们势必会接触到代码混淆。代码混淆亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为,代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。今天我主要讲一下如何对Android项目进行代码混淆。

    首先,我来讲解一下对Android工程编译成功后所生成的APK文件(即应用安装文件)的代码混淆,因为第三方人员完全可以通过解压APK文件并从中获取项目源码,所以对APK文件的保护显得至关重要。做过Android开发的人都知道,我们在创建一个新的Android项目的时候,需要为该项目选择API版本,在不同的API版本中google为我们提供了不同的封装方法,这里我们以2.3版本为中界点。细心的同学应该能够发现在Android-SDK的tools目录下有这样命名的一个文件夹proguard,它就是目前在JAVA领域最常用到的代码混淆工具。

OK! 接下来介绍如何去使用该工具,打开的Eclipse,选择创建一个Android项目,API版本选择2.3.3,工程创建完毕之后打开工程的根目录,你会发现这样一个文件proguard-project.txt,

相信没有接触过代码混淆的同学对这个文件肯定很陌生,但是我要告诉你的就是,没错,你猜对了!它就是proguard混淆代码的脚本文件,伟大的google已经帮我们将这件事做好了,我们唯一需要做的就是去编译自己的项目,生成APK文件;还记得我前面说到吗?我们以2.3版本为中界点,接下来我们再次创建一个Android项目,这次将API版本选为2.2,创建完毕后打开项目的根目录,你还能找到proguard-project.txt文件吗?答案显然是否定的,因为google从2.3版本以后才开始为我们封装代码混淆的脚本文件。那么2.3以下的版本怎么办呢?这里我们有两步需要去做,首先,去2.3以上版本的项目中复制一份proguard-project.txt文件,拷贝到当前项目的根目录下;然后,打开当前项目中的project.properties(老版本为default.properties )文件,在文件的末尾处添加这样一行代码:proguard.config=proguard-project.txt,保存该文件,接下来从新编译你的项目,这时生成的APK文件就已经进行了代码混淆。

  介绍完了APK文件的代码混淆,接下来我们来说说另外一种情况,我们需要交付给第三方的产品并不是一个APK文件,而是将一个完整的Android项目作为一个Library供他们使用,这时我们应该如何来进行代码混淆呢?首先我们要确认已经将项目中所有源代码即.java文件打成了jar包(jar包中为.class文件),接下来我们需要做的就是对jar包进行混淆,脚本文件的编写规格如下:

-injars  androidtest.jar //jar包所在地址
-outjars  out //输出地址
-libraryjars    'D:\android-sdk-windows\platforms\android-9\android.jar'  //引用的库的jar,用于解析injars所指定的jar类
 
-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
-keep public abstract interface com.asqw.android.Listener{
public protected <methods>;  //所有方法不进行混淆
}
-keep public class com.asqw.android{
public void Start(java.lang.String);  //对该方法不进行混淆
}
-keepclasseswithmembernames class * {  //保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
native <methods>;
}
-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);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { //保护指定的类文件和类的成员
public static final android.os.Parcelable$Creator *;
}


在混淆Android代码的时候我们不能混淆Activity,Service,BroadcastRevicer的子类,否则的话会造成资源文件的丢失,保存该文件时以.pro结尾,接下来打开SDK中的proguard文件夹,找到bin目录下的proguardgui.bat文件,双击打开,

点解Load Configuration按钮,导入我们编写的脚本文件,然后点击Next,当提示我们Processing completed successfully!表示我们的jar包已经成功进行了混淆,这时再来看我们jar包里面的内容:

将这样的工程交付给第三方使用,你一定不会再为源码的保密发愁了吧!

转自:http://blog.chukong-inc.com/index.php/2012/06/05/android%E4%BB%A3%E7%A0%81%E6%B7%B7%E6%B7%86/