这道题是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解密一下就出来了。

123456789 | from Crypto.Cipher import AESiv = '122B157F2BAED2A6ACF7158807CF4F3C'.decode('hex')enc = '47FE6CEEA092F9A72A73B3763613701A'.decode('hex')cryptor = AES.new(iv,AES.MODE_ECB)dec = cryptor.decrypt(enc)print dec |
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
总结
作为第一次安卓动态调试,很多地方还做的很生疏,但收获也是很多的。