首页 > 代码库 > Android开发之反编译与防止反编译

Android开发之反编译与防止反编译

Android开发之反编译与防止反编译

            

    防止反编译是每个程序员的必修课,因为当你辛辛苦的研发一个应用,被人家三下五除二给反编译了,是一件多么尴尬的事啊。那么如何防止反编译啊?这里就用Google Android自带的代码混编的方式来防止反编译。孙子兵法中讲得好:“知彼知己百战不殆”,所以在讲解防止反编译之前,先让我们了解一下如何反编译一个应用。

一、反编译Android应用

实验环境:

Windows8.1企业版、dex2jar-0.0.9.9

反编译工具包:

Android反编译工具包(升级版)

1.Apk反编译得到Java源代码

具体步骤:

1)        首先将apk文件后缀改为zip并解压,得到其中的classes.dex,它就是java文件编译再通过dx工具打包而成的,将classes.dex复制到dex2jar.bat所在目录dex2jar-0.0.9.9文件夹。

在命令行下定位到dex2jar.bat所在目录,运行

dex2jar.bat   classes.dex

如图:

 dex2jar.bat    classes.dex

生成classes_dex2jar.jar

如图:

生成classes_dex2jar.jar

2)        进入jdgui文件夹双击jd-gui.exe,打开上面生成的jarclasses_dex2jar.jar,即可看到源代码了,如下图:


2. apk反编译生成程序的源代码和图片、XML配置、语言资源等文件

具体步骤:

1)下载上述反编译工具包,打开apk2java目录下的apktool1.4.1文件夹,内含三个文件:apktool.jar aapt.exeapktool.bat

注:里面的apktool_bk.jar是备份的老版本,最好用最新的apktool.jar

在命令行下定位到apktool.bat文件夹,输入以下命令apktool.bat d  -f   abc123.apk   abc123

如下图:

上图中,apktool.bat命令行解释apktool.bat  d  -f    [apk文件 ]   [输出文件夹]

<?xml version="1.0" encoding="utf-8"?>
<manifest android:versionCode="1" android:versionName="1.0" package="com.jph.recorder"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <application android:theme="@style/AppTheme" android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:allowBackup="true">
        <activity android:label="@string/app_name" android:name="com.jph.recorder.Recorder">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:label="@string/show_recordFile" android:name="com.jph.recorder.ShowRecordFiles" />
        <activity android:theme="@android:style/Theme.Dialog" android:name=".AboutActivity" />
        <activity android:label="@string/feedback_label" android:name=".FeedBackActivity" />
        <service android:name="com.jph.recorder.RecordService" />
    </application>
</manifest>


将反编译完的文件重新打包成apk,很简单,输入apktool.bat   b    abc123(你编译出来文件夹)即可,命令如下:

打包apk后的文件在目录C:\HelloAndroid下,生成了两个文件夹:

build

dist

其中,打包生成的HelloAndroid.apk,在上面的dist文件夹下,Ok


3.图形化反编译apk

上述步骤一、二讲述了命令行反编译apk,现在提供一种图形化反编译工具:Androidfby

首先,下载上述反编译工具包,打开Androidfby目录,双击Android反编译工具.exe,就可以浏览打开要反编译的apk文件。

图形化反编译apk


二、防止应用被反编译

先介绍一下什么是代码混淆:

代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作代码混淆器。目前已经存在许多种功能各异的代码混淆器。

将代码中的各种元素,如变量,函数,类的名字改写成无意义的名字。比如改写成单个字母,或是简短的无意义字母组合,甚至改写成“__”这样的符号,使得阅读的人无法根据名字猜测其用途。重写代码中的部分逻辑,将其变成功能上等价,但是更难理解的形式。比如将for循环改写成while循环,将循环改写成递归,精简中间变量,等等。打乱代码的格式。比如删除空格,将多行代码挤到一行中,或者将一行代码断成多行等等。

混淆前和混淆后反编译出来的代码对比:

混淆前和混淆后反编译出来的代码对比

提示:有心的朋友可以发现:混淆后生成apk文件比混淆前生成的apk文件要小不少。这样不仅减小了项目的大小而且可以提高代码的执行速度。如下图:

混淆前和混淆后反编译出来的代码对比2

具体步骤:

1)      查看项目中有没有proguard.cfg

如果没有的话从这下载:

proguard.cfg

 

然后将proguard.cfg复制到项目中。

 

2)在项目中的project.properties文件中添加:proguard.config=proguard.cfg

3)然后按照正常的签名对自己的应用进行签名,生成后的apk经过反编译后就会和源代码有很大的不一样。

注意:一定要通过正常的签名方式对应用进行签名,项目bin目录中生成的apk文件是使用系统默认签名的方式,没有达到代码混编的效果的。

如果签名不成功请往下看:

4)不过这一步你会遇到很多问题,根本就签名不成功。例如:①如果工程引入了android-support-v4jar类库,那么在工程打包混淆时,就会出现报错提示你:You may need to specify additional library jars (using‘-libraryjars‘)。②引用第三方包等问题

如果工程引入了android-support-v4jar类库,那你就在proguard.cfg里的后面,添加如下内容:

-libraryjars /android-support-v4.jar

-dontwarn android.support.v4.**

-keep class android.support.v4.** { *; }

-keep public class * extendsandroid.support.v4.**

-keep public class * extendsandroid.app.Fragment

然后你再打包看看,应该可以正常生成apk安装包了。

如果出现:"1 can‘t find referenced class2" 字面上的意思就是类1找不到类2的引用;它会建议你:"You may need to specify additional library jars (using‘-libraryjars‘).";

需要使用-libraryjars加上项目中使用到的第三方库就OK了。

例如:-libraryjars /android-support-v4.jar

注意:这里引用方式是当前工程的根目录(也可以配置其他目录),也就是说,你要把第三方jar放到当前目录下,否则就会警告说找不到jar文件!

       如果出现: can‘t find superclass or interfaceandroid.os.Parcelable$ClassLoaderCreator,碰到这样的情况,可以使用-dontwarncom.xx.yy.**,不对错误提出警告。

注意:使用这个方式的话,要确保自己没有用到这个库里面的类!否则就会抛ClassNotFoundException

如果在工程中确实用到了该类,采用上面方式还是不行。这个时候就要再增加一项:-keep class com.xx.yy.** { *;},让当前类不混淆。

总结:

对于引用第三方包的情况,可以采用下面方式避免打包出错:

-libraryjars /aaa.jar

-dontwarn com.xx.yy.**

-keep class com.xx.yy.** { *;}

最后打包成功,祝君成功混淆加密!

 

Android开发之反编译与防止反编译