avatar

Catalog
Android程序分析入门(破解程序)

前言

前面的篇章中做好了Android程序分析的准备工作,编写了一个可以用来破解的入门程序,配置了右键命令行的快捷键以及逆向分析需要用到的工具Apktool和AndroidKiller。本篇就来用这些工具对Android程序进行一次简单的破解。

破解入手

我们之前编写的程序是一个简单的注册的页面程序,没有后台的,可以专门用来破解上手。也算是比较基础的破解类型。在正式破解之前,我们先捋一捋破解思路。如果有过Windows平台逆向破解经验的小伙伴就会这样想:

  1. 将程序拖进OllyDbg
  2. 注册程序 -> 注册失败,并留意注册失败时弹出的字符串
  3. 在OllyDbg中搜索相关字符串
  4. 找到分支执行语句并修改执行流程
  5. 完成暴破

这的确是一个非常连贯且合理的思路,但是Android程序并不像Windows上的exe程序一样,可以直接拖进调试器进行调试并修改。所以在对Android程序破解时步骤会有所变化:

  1. 对apk文件进行反编译
  2. 分析apk文件
  3. 修改Smali文件
  4. 将修改后的程序重新编译,并签名

下面,我们就按照这些步骤,对程序进行逆向破解吧。

反编译

  1. 首先找到我们之前的apk文件,在我们编写好的Android程序项目中的地址位于:

    Code
    1
    项目名\app\build\outputs\apk\debug
  2. 右键在当前目录打开命令行,输入如下指令

    Code
    1
    apktool d app-debug.apk -o outdir_dbg

    这时apktool会将apk文件进行反编译,并输出到outdir_dbg文件中,如图所示

  3. 这样,我们反编译部分的工作就完成了

程序分析

  1. 这里首先我们需要下载一个工具,git bash,这部分在前一篇忘记提了,不过安装过程也很简单,进入官网下载后自行安装。一般情况下安装时它会要求添加到右键快捷键的,如果没有的话,就按照添加右键命令行的方法添加到注册表即可。

  2. 根据编写程序时的运行结果来看 我们需要搜索Register Failed字符串,然后找到其在程序中的所在位置,接着向上回溯,找到条件分支语句的地方,进行修改,便可完成暴破

  3. 有了思路后,开始实践,根据Android程序的特性,通常情况下,字符串硬编码到源码中,也可能引用自res/values目录下的string.xml文件中,所以我们决定对整个目录进行搜索,查找”Register Failed”字符串出现的位置,在对apk进行反汇编的目录中,右键Git Bash Here,键入如下指令:

    Code
    1
    grep -r "Register Failed" outdir_dbg/
    可以发现,仅有一处,并且的确位于res/values目录下的string.xml文件中
  4. 根据结果我们可以发现“Register Failed”这个字符串的值对应的Id是unsuccess,可以推测unsuccess有可能作为引用出现在反汇编代码中的某一处,所以接下来输入指令:

    Code
    1
    grep -r "unsuccess" outdir_dbg/
    结果显示有3处出现unsuccess,其中一处是第三步出现的;另外两处可以看出unsuccess只不过是个变量名,其值为0x7f0b002b。所以这个值,就有可能会是代码中引用代表"Register Failed"的值。
  5. 根据上一步的推测,继续搜索0x7f0b002b的值,输入如下指令:

    Code
    1
    grep -r "0x7f0b002b" outdir_dbg/
    根据结果,发现“0x7f0b002b”这个值出现了3次,值得关注的一处位于MainActivity$MyListener.smali这个文件中,有点Android正向开发经验都知道,一般来说MainActivity.java用于一个Android程序的主体功能的实现,而smali文件对应的就是Java文件编译完再反编译回来的文件。下面一个部分,将主要关注该文件。

修改Smali文件

  1. 找到MainActivity$MyListener.smali文件,路径位于:

    Code
    1
    项目名\app\build\outputs\apk\debug\outdir_dbg\smali\com\droider\crackme_0x1
  2. 用AndroidKiller打开该文件(也可以用别的文本编译器,例如010Editor),并定位到指令

    smali
    1
    const v7, 0x7f0b002b

    的位置,观察前后程序 我们可以发现,0x7f0b002b这个代表着“Register Failed”这个字符串的语句位于cond_1这个执行分支中,并且该执行分支,会将该参数传入Toast.makeText函数中执行,可以猜测,这部分就属于执行失败时要执行的地方。向上观察,有一个条件判断语句

    smali
    1
    if-ne v6, v1, :cond_1

    该语句当条件判断成立时会跳转到cond_1执行,也就是执行失败的分支。这就是突破口,我们可以修改这行条件判断语句,改为

    smali
    1
    if-eq v6, v1, :cond_1

    这样语句判断的条件相反,也就不那么容易跳转到执行失败的分支了,修改后代码如下:

    修改完Smali文件后,这时就只剩下最后一步了

重新编译并签名

  1. 修改完smali文件后,回退到最初反编译的那个文件夹,右键进入命令行,输入如下指令:

    Code
    1
    apktool b outdir_dbg

    这里是通过apktool将我们修改后的文件夹重新编译成apk文件,编译后生成的文件位于目录:

    Code
    1
    outdir_dbg\dist

    这里有一个很大的坑,我之前最早进行实验的时候,就是重新编译时总是失败主要原因是apktool的版本不对,我的电脑Java的版本是13.0.1apktool版本是2.4.1,在这个条件下是可以重新编译成功的,其它情况就不一定了。

  2. 在重新编译完后,生成了app-debug.apk文件,此时该文件是不能拖进Android虚拟机运行的,原因是我们修改了原本的apk文件,需要重新签名。这时我们利用AndroidKiller进行签名就行了。

    步骤是:打开AndroidKiller -> 工具 -> APK签名 -> 将app-debug拖入 -> 选择签名AndroidKiller -> 执行

    执行结束后效果如下: 此时在刚刚的文件夹中会生成一个新的文件apk-debug_sign.apk,这是已经签名过的程序,可以拖入虚拟机中运行

  3. 我们将apk-debug_sign.apk文件拖进虚拟机安装并运行,这时可以发现,无论我们输入什么用户名和校验码时,都会 弹出”Register Succeed”,原因是我们修改了程序的执行流程,使得在原本执行打印”Register Failed”情况变成了相反的情况。

  4. 至此,便完成了此次程序的整个的破解流程

小结

本篇结束,Android逆向算是开了一个头,然而接下来的更新却可能遥遥无期。首先Windows内核部分,在驱动篇结束后,将和Android逆向部分穿插更新,接下来要到APC机制了,APC机制非常繁琐,而且需要逆向大量函数,这一篇章花费一个月都更不完也是有可能的。另一个,最近公司有Python开发的需求,加上最近使用Frida进行hook时,需要用到Python和JavaScript,虽说以前用过一段时间,也很久没用了,最近需要花点时间复习下,也会顺便更新几期Python以及JavaScript相关的内容。再之后,可能才轮到Android的Smali语法部分的更新,总的来说,5月接下来会更加忙碌了。

参考资料

《Android软件安全权威指南》 —— 丰生强

Author: cataLoc
Link: http://cataloc.gitee.io/blog/2020/05/11/Android%E7%A8%8B%E5%BA%8F%E5%88%86%E6%9E%90%E5%85%A5%E9%97%A8-%E4%B8%8B/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶