手把手教你搞懂Android反编译

转载时请必须注明出处:http://www.iosxxoo.com/2016/06/29/2016-06-29/

一、反编译代码

1、反编译java代码首先需要下载dex2jar这个工具,下载地址:
下载完后并解压缩。2、将要反编译的apk文件重命名为zip格式并解压缩,注意其中的classes.dex文件,它存放了全部的java代码,将classes.dex文件拷贝到dex2jar解压后的根目录下。3、打开cmd,进入dex2jar解压后的根目录,执行命令:

d2j-dex2jar classes.dex

如下图:

亚洲城ca88 1dex2jar命令执行完后在对应目录下会生成classes-dex2jar.jar文件亚洲城ca88 2jar文件4、要查看java代码,还需要下载jd-gui这个工具,下载地址:
code到此,已经顺利的反编译出了java代码那资源文件呢,再回头看一下刚才apk文件对应的解压缩文件,所有的xml文件都是乱码,例如AndroidManifest.xml亚洲城ca88 3AndroidManifest.xml当然要还原原始的资源文件还是有办法的,继续往下看。

什么是反编译

我们知道,Android的程序打包后会生成一个APK文件,这个文件可以直接安装到任何Android手机上,因此,反编译就是对这个APK进行反编译。Android的反编译分成两个部分:

一个是对 代码 反编译,也就是java文件的反编译。

一个是对 资源 反编译,也就是res文件的反编译。

前言

反编译别人的程序不是什么值得炫耀的事,希望大家最好只是兴趣探索,而不是利益驱动。本文主要目的是绕开一个简单的激活程序。

二、反编译资源

1、要反编译apk中的资源文件,就需要apktool这个工具了,下载地址:

亚洲城ca88 4apktool
download按照图中1、2两条的提示,下载apktool.bat和apktool.jar这两个文件,目前最新的apktool是2.1.1,并放到同一文件夹:亚洲城ca88 5apktool,2、将要反编译的apk文件放到apktool文件夹,打开cmd,进入apktool文件夹目录,执行命令:

apktool d test.apk

如下图:

亚洲城ca88 6apktool
d
test.apk执行成功后,在当前目录下会生成一个test文件夹:亚洲城ca88 7test文件夹目录其中,res文件夹下存放的是反编译出来的所有资源,smali文件夹下存放的是反编译出来的所有代码,AndroidManifest.xml则是经过反编译还原后的manifest文件。smali文件夹下的文件smali文件使用的是Android虚拟机所使用的寄存器语言,如果看的懂smail文件的话,就可以修改源代码的逻辑了,好可怕的事…当然这不是我们重点讨论的。此时查看AndroidManifest.xml文件,发现已经成功反编译出来了:亚洲城ca88 8AndroidManifest.xml

反编译结构图

亚洲城ca88 9

什么是反编译

我们知道,Android的程序打包后会生成一个APK文件,这个文件可以直接安装到任何Android手机上,因此,反编译就是对这个APK进行反编译。Android的反编译分成两个部分:

  1. 一个是对代码反编译,也就是java文件的反编译。
  2. 一个是对资源反编译,也就是res文件的反编译。

三、重新打包

1、既然资源文件已经顺利的反编译出来了,那我们就可以适当的修改点东西了,例如换个图标啥的、改下布局文件等,这里我们将AndroidManifest.xml中的channel值改为10001,然后开始重新打包,同样在cmd中切换到apktool文件夹目录,执行命令:

apktool b test -o new_test.apk

如下图:

亚洲城ca88 10重新打包执行成功后,在当前目录会生成一个新的new_test.apk文件:亚洲城ca88 11new_test.apk2、但是呢,这个apk文件目前并不能安装,因为需要重新签名。没有签名文件的话,通过Android
Studio可以很简单的生成一个哦,将准备好的签名文件放到apktool文件夹根目录,继续在cmd执行命令:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore
签名文件名 -storepass 签名密码 待签名的APK文件名 签名的别名

如下图:

亚洲城ca88 12jarsigner
start亚洲城ca88 13jarsigner
success注意,其中jarsigner命令文件是存放在jdk的bin目录下的,需要将bin目录配置在系统的环境变量中才可以在任何位置执行此命令。3、签名完成后,建议对APK文件进行一次对齐操作,这样可以使得程序在Android系统中运行得更快,对齐操作使用的是zipalign工具,该工具在<Android
SDK>/build-tools/<version>
目录下,需要将这个目录配置到系统环境变量当中才可以在任何位置执行此命令。继续在cmd中执行命令:

zipalign 4 new_test.apk new_test_aligned.apk

执行成功后,会生成一个对齐后的new_test_aligned.apk文件:

亚洲城ca88 14new_test_aligned.apk

4、最后可以通过如下命令验证apk签名是否成功:

jarsigner -verify -verbose -certs new_test_aligned.apk

如下图:

亚洲城ca88 15verify
start亚洲城ca88 16verify
success

到这里apk反编译及重新打包流程就介绍完毕了。

**以上用到的工具也可以在此下载哦:反编译及二次打包工具 **

反编译并查看java代码的工具:

dex2jar:
把dex文件转成jar文件下载地址: 

jd-gui: 这个工具用于将jar文件转换成java代码

1 解压dex2jar。使用Dr.Unarchiver解压dex2jar-2.0.zip。

2
安装JD-GUI。官网上下载的dmg安装包,无法安装。需要使用Mac上的软件包管理工具Homebrew来安装。

brew cask install jd-gui

亚洲城ca88 17

所需的工具

亚洲城ca88 18

  • Android Studio:安卓开发IDE

    下载地址:https://developer.android.com/studio/index.html

反编译代码的工具:

  • dex2jar: 把dex文件转成jar文件

    下载地址:https://sourceforge.net/projects/dex2jar/files/

  • jd-gui: 这个工具用于将jar文件转换成java代码

    下载地址:http://jd.benow.ca/

反编译资源的工具:

  • APKTool: 本文重要工具,APK逆向工具,使用简单

    下载地址:
    http://ibotpeaches.github.io/Apktool/install/

反编译安装包、重新打包的工具

APKTool:
本文重要工具,APK逆向工具,使用简单下载地址: 

亚洲城ca88 19

1
将下载的apktool、apktool_2.2.2.jar分别重命名为apktool、apktool.jar,拷贝到/usr/local/bin中

亚洲城ca88 20

2 增加可执行权限

chmod +x apktool apktool.jar

反编译并查看java代码

1
解压后的文件夹中有很多文件。在Mac上我们需要用到dex2jar的是这三个东西(windows上对应用bat文件):

d2j-dex2jar.sh

d2j_invoke.sh

lib

亚洲城ca88 21

2 AndroidStudio 打包好的 APK文件 的后缀,需改为 .zip ,然后使用Dr.Unarchiver解压 。从解压的文件中找到 classes.dex 文件,并将其放入 dex2jar 同一目录下,如下:

亚洲城ca88 22

3 cmd中进入到dex2jar-2.0文件夹, 先修改权限,再反编译

chmod +x d2j-dex2jar.sh
chmod +x d2j_invoke.sh 
./d2j-dex2jar.sh classes.dex 

4
使用Finder->应用程序->JD-GUI.app,打开生成的classes-dex2jar.jar文件。

亚洲城ca88 23

亚洲城ca88 24

热身准备

首先我们需要一个APK,这里我自己写了一个,源码下载地址:http://download.csdn.net/detail/u012891055/9671973,打包成APK后下载到手机上。

它的主要功能是模拟邮箱激活,如果我们输入了错误的数据则无法通过激活。所以我们的目的很简单,就是让这个判断逻辑失效。

亚洲城ca88 25

反编译安装包

1
使用apktool命令反编译,d是decode解码的意思,-o是输出文件目录。/usr/local/bin中会生成demo文件夹。

apktool d /Users/administrator/Desktop/demo.apk -o
/Users/administrator/Desktop/demo

 如果提示demo文件夹已存在,则使用-f参数强制覆盖。

apktool d /Users/administrator/Desktop/demo.apk -f -o /Users/administrator/Desktop/demo

2 打开桌面上的demo文件夹。

smaili文件夹存放java类文件。Android系统有自己的虚拟机Dalvik(一个冰岛渔村名字),反编译后生成的java类文件的扩展名是.smali,而不是.class。

亚洲城ca88 26

主要源码说明:

第51行存储的正确的两个激活号码,通过:将账号密码隔开,如下

private static final String[] DUMMY_CREDENTIALS = new String[]{
            "foo@163.com:20135115",
            "bar@163.com:20135115"
};

现在只有激活码正确才能通过激活。

第331行是Execute函数,逻辑判断的部分。

    @Override
    protected void onPostExecute(final Boolean success) {
        mAuthTask = null;
        showProgress(false);

        if (success) {
            new AlertDialog.Builder(LoginActivity.this)
                    .setTitle("恭喜您")
                    .setMessage("成功激活!")
                    .show();
//                finish();
        } else {
            mPasswordView.setError(getString(R.string.error_incorrect_password));
            mPasswordView.requestFocus();
        }
    }

修改安装包

修改apktool反编译后的文件夹中的内容。res文件夹中直接替换,java代码需参考smali语法修改.smali文件。

反编译代码

dex2jar解压下来文件很多,在mac上我们需要用到dex2jar的是这三个东西(windows上对应用bat文件):

  • d2j_invoke.sh
  • d2j-dex2jar.sh
  • lib

亚洲城ca88 27

AndroidStudio打包好的APK文件的后缀,需改为.zip,然后解压。从解压的文件中找到classes.dex文件,并将其放入dex2jar同一目录下,如下:

亚洲城ca88 28

并在cmd中也进入到同样的目录,然后执行:

sh d2j-dex2jar.sh classes.dex

执行如下:

亚洲城ca88 29

然后我们会得到一个classes-dex2jar.jar文件,我们借助JD-GUI工具打开即可,打开如下:

亚洲城ca88 30

可以看到代码非常清晰,这样我们就可以看到整个APP的代码逻辑了。

重新打包

cmd中进入桌面,执行命令。b是build的意思。

apktool b demo -o myDemo.apk

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

反编译资源

apktool下载完成后有一个.sh文件和.jar文件,我们把APK放进来,如下:

亚洲城ca88 31

在cmd中进入apktool目录,执行命令:

sh apktool.sh apktool d FooApp.apk

d是decode的意思,表示我们要对FooApp解码,结果如下:

亚洲城ca88 32

然后你会惊喜的发现多了一个FooApp文件夹。

亚洲城ca88 33

主要目录说明:

  • AndroidManifest.xml:描述文件
  • res:资源文件
  • smail:反编译出来的所有代码,语法与java不同,类似汇编,是Android虚拟机所使用的寄存器语言

修改App icon

打开我们的描述文件,高清无码:

亚洲城ca88 34

可以看到我们的App
icon名称为ic_launcher,我们找到所有mipmap开头的文件夹,替换成下图即可:

亚洲城ca88 35

ic_launche

亚洲城ca88 36

在最后重新打包后我们的App
icon就会被修改了,不过在重新打包之前,我们还有最重要的一件事没有做,那就是修改激活码判断逻辑。

修改逻辑

我们通过源码或者JD-GUI查看反编译的代码可以看到激活码判断逻辑如下:

    @Override
    protected void onPostExecute(final Boolean success) {
        mAuthTask = null;
        showProgress(false);

        if (success) { 
        // 激活码正确
            new AlertDialog.Builder(LoginActivity.this)
                    .setTitle("恭喜您")
                    .setMessage("成功激活!")
                    .show();
//                finish();
        } else {
            mPasswordView.setError(getString(R.string.error_incorrect_password));
            mPasswordView.requestFocus();
        }
    }

所以我们只需要找到反编译后的if(success)的语句,并将其修改成if(!success)即可,如下:

if (success)//修改成if(!success)
{
...
} else {
...
}

这样我们就成功的颠倒了以前的逻辑,我们输入一个错误的激活码,就会被判断成正确的。挺简单的,是吧。

现在我们来动手修改:

  1. 打开smail里的LoginActivity$UserLoginTask.smali文件.

  2. 全局搜索if-eqz,通过AlertDialog关键字辅助定位,发现在第228行

    亚洲城ca88 37

  3. ok,就是这里了,然后将if-eqz修改成if-nez,他们对应Java的语法如下:

Smail 语法 Java 语法
if-eqz v0, if(v0 == 0)
if-nez v0, if(v0 != 0)

ok,大功告成,现在就可以重新打包了。关于smail语法,有兴趣的直接Google就行了。

重新打包

我们大概修改后两个地方,其实重新打包也十分简单,在cmd中执行以下命令即可:

sh apktool.sh b FooAPP -o NewFooApp.apk

其中b是build的意思,表示我们要将FooAPP文件夹打包成APK文件,-o用于指定新生成的APK文件名,这里新的文件叫作NewFooApp.apk。执行结果如下图所示:

亚洲城ca88 38

然后你会发现同级目录下生成了新的apk文件:

亚洲城ca88 39

但是要注意,这个apk现在还是不能安装的,因为我们没有对它进行签名,重新签名后它就是个名副其实的盗版软件了,大家一定要强烈谴责这种行为。

重新签名

重新签名也是很简单的,我直接用的一个已有签名文件,使用Android
Studio或者Eclipse都可以非常简单地生成一个签名文件。

在cmd中执行格式如下:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore 签名文件名 -storepass 签名密码 待签名的APK文件名 签名的别名

然后我们就可以用这个apk进行安装了,为了追求更快的运行速度,我们可以对其进行一次字节对齐,这里就不说了。

使用盗版APK

我们用NewFooApp.apk安装好盗版app后,发现图标变成了篮球,并且随便输入数据都能通过激活了:

亚洲城ca88 40

1

怎么样?总的来说还是挺有意思的吧,不过别用歪了。

参考链接:

Android安全攻防战,反编译与混淆技术完全解析(上)-
郭霖

Android安全技术解密与防范 –
周圣韬

Done

作者:
@biggergao
个人博客: Mr.码了戈壁

2016年06月29日

相关文章