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

笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述记录一次安卓动态调试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的文件夹

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

文章图片

此次我们动态调试所需要的是android_server。
记录一次安卓动态调试lib库

文章图片

通过各种方法,把它放到/system/bin/目录下,并给予执行权限
记录一次安卓动态调试lib库

文章图片

然后在电脑上执行adb shell,输入su拿到root权限后再输入andoird_server
记录一次安卓动态调试lib库

文章图片

看到Listening on port #23946...
再开一个命令行窗口,输入 adb forward tcp:23946 tcp:23946进行端口转发。
【记录一次安卓动态调试lib库】
记录一次安卓动态调试lib库

文章图片

至此,准备工作就完成了。
IDA连接调试在手机端打开待调试的crackme
在x86的ida下,选择如下菜单
记录一次安卓动态调试lib库

文章图片

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

文章图片

点击OK。
找到待调试的应用:
记录一次安卓动态调试lib库

文章图片

点击OK,等待片刻后进入调试界面。
记录一次安卓动态调试lib库

文章图片

由于要等待so解密,所以我们打开这一项
记录一次安卓动态调试lib库

文章图片

勾上这里
记录一次安卓动态调试lib库

文章图片

点击运行让程序跑起来。
记录一次安卓动态调试lib库

文章图片

手机端随便输入一些东西后点击确定,发现IDA成功断下。
出现这个直接点OK跳过
记录一次安卓动态调试lib库

文章图片

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

文章图片

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

文章图片

手动按f8从linker走到libart.so(我调试用的手机是安卓5.1的)
记录一次安卓动态调试lib库

文章图片

在Modules里找到libtutu.so
记录一次安卓动态调试lib库

文章图片

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

文章图片

发现代码已经解密了。
记录一次安卓动态调试lib库

文章图片

可以按F5看看
记录一次安卓动态调试lib库

文章图片

一切正常。
方法一:静态分析
记录一次安卓动态调试lib库

文章图片

这些明显是函数指针,我们双击过去,按c转换成代码,再回来按f5。
记录一次安卓动态调试lib库

文章图片

上面有个未知作用的函数,我们一层层点进去看,发现是strlen。
记录一次安卓动态调试lib库

文章图片

稍微重命名一下,我们可以看出就是一个AES_ECB模式的加密
记录一次安卓动态调试lib库

文章图片

IV和enc都有了,直接用python解密一下就出来了。
记录一次安卓动态调试lib库

文章图片

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


flag:6ae379eaf3ccada5
方法二:纯动态调试既然都已经开始动态调试了,为什么还要劳烦我们去分析代码呢?总有人会这样想。
也算是锻炼一下动态的能力,我们现在用纯动态的方法来做。
首先,如果你脱完壳直接f9开跑的话,你会发现程序结束了,因为这个so里有一个叫做antiDebug的函数
记录一次安卓动态调试lib库

文章图片

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

文章图片

我们不用去管这个函数内部到底干了什么,我们只要直接将这个函数在段首ret掉,这样下面的所有代码都不会被执行了。
记录一次安卓动态调试lib库

文章图片

我们掏出插件keypatch,ctrl+alt+k
记录一次安卓动态调试lib库

文章图片

改成POP {R4-R7,PC}
记录一次安卓动态调试lib库

文章图片

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

文章图片

这样这个antiDebug就被patch掉了。
我们还发现这个so中自带了decrypt函数。
我们来到check函数,找到这一段。
记录一次安卓动态调试lib库

文章图片

我们要把原来的AES128_ECB_encrypt)(input, & IV, & enc_out)改成AES128_ECB_decrypt)(enc_right, & IV, & enc_out),这样enc_out里保存的就是我们所需要的flag了。
这里,我们发现我们需要的enc_right保存在R6寄存器里
记录一次安卓动态调试lib库

文章图片

所以我们patch这两句
记录一次安卓动态调试lib库

文章图片

重新f5,现在变成了我们所希望的样子
记录一次安卓动态调试lib库

文章图片

用f2下好断点,f9运行
记录一次安卓动态调试lib库

文章图片

enc_out是在R7寄存器里,此时的R7为FFABD2A4
记录一次安卓动态调试lib库

文章图片

在数据窗口我们按G键,跳转到FFABD2A4
记录一次安卓动态调试lib库

文章图片

成功得到flag:6ae379eaf3ccada5
总结作为第一次安卓动态调试,很多地方还做的很生疏,但收获也是很多的。
原文:大专栏   记录一次安卓动态调试lib库


    推荐阅读