记录一次安卓动态调试lib库

前言

这道题是iscc 2017中的安卓第二题,所有的算法都在lib库中,而lib库又是加了壳的,所以就用动态调试解决吧。第一次动态调试安卓,就写的详细一些吧。

文中用到

1.能正常运行这个crackme的手机一部,需要root(本人手上的主力机是安卓7.1的就运行不了)
2.IDA一个
3.IDA神级插件Keypatch
4.安卓调试adb
5.python
6.这个crackme

题目链接

链接:http://pan.baidu.com/s/1kVLYYOJ 密码:e2tj

解析

准备

首先在手机上安装这个crackme,这个不需要多说。

通过jeb的逆向,发现所有与题目解题相关的代码都在libtutu.so中。ida直接载入会发现这个so是被加密的。

那就开始动态调试。

在ida的目录下有一个叫dbgsrv的文件夹

此次我们动态调试所需要的是android_server。

通过各种方法,把它放到/system/bin/目录下,并给予执行权限

然后在电脑上执行adb shell,输入su拿到root权限后再输入andoird_server

看到Listening on port #23946...

再开一个命令行窗口,输入 adb forward tcp:23946 tcp:23946进行端口转发。

至此,准备工作就完成了。

IDA连接调试

在手机端打开待调试的crackme

在x86的ida下,选择如下菜单

点击OK。

找到待调试的应用:

点击OK,等待片刻后进入调试界面。

由于要等待so解密,所以我们打开这一项

勾上这里

点击运行让程序跑起来。

手机端随便输入一些东西后点击确定,发现IDA成功断下。

出现这个直接点OK跳过

直接apply

断在linker

手动按f8从linker走到libart.so(我调试用的手机是安卓5.1的)

在Modules里找到libtutu.so

双击check

发现代码已经解密了。

可以按F5看看

一切正常。

方法一:静态分析

这些明显是函数指针,我们双击过去,按c转换成代码,再回来按f5。

上面有个未知作用的函数,我们一层层点进去看,发现是strlen。

稍微重命名一下,我们可以看出就是一个AES_ECB模式的加密

IV和enc都有了,直接用python解密一下就出来了。

1
2
3
4
5
6
7
8
9
from Crypto.Cipher import AES
iv = '122B157F2BAED2A6ACF7158807CF4F3C'.decode('hex')
enc = '47FE6CEEA092F9A72A73B3763613701A'.decode('hex')
cryptor = AES.new(iv,AES.MODE_ECB)
dec = cryptor.decrypt(enc)
print dec
#6ae379eaf3ccada5

flag:6ae379eaf3ccada5

方法二:纯动态调试

既然都已经开始动态调试了,为什么还要劳烦我们去分析代码呢?总有人会这样想。

也算是锻炼一下动态的能力,我们现在用纯动态的方法来做。

首先,如果你脱完壳直接f9开跑的话,你会发现程序结束了,因为这个so里有一个叫做antiDebug的函数

我们不用去管这个函数内部到底干了什么,我们只要直接将这个函数在段首ret掉,这样下面的所有代码都不会被执行了。

我们掏出插件keypatch,ctrl+alt+k

改成POP {R4-R7,PC}

这样这个antiDebug就被patch掉了。

我们还发现这个so中自带了decrypt函数。

我们来到check函数,找到这一段。

我们要把原来的AES128_ECB_encrypt)(input, &IV, &enc_out)改成AES128_ECB_decrypt)(enc_right, &IV, &enc_out),这样enc_out里保存的就是我们所需要的flag了。

这里,我们发现我们需要的enc_right保存在R6寄存器里

所以我们patch这两句

重新f5,现在变成了我们所希望的样子

用f2下好断点,f9运行

enc_out是在R7寄存器里,此时的R7为FFABD2A4

在数据窗口我们按G键,跳转到FFABD2A4

成功得到flag:6ae379eaf3ccada5

总结

作为第一次安卓动态调试,很多地方还做的很生疏,但收获也是很多的。