这篇文章上次修改于 308 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

前言

假定你已经完成下面的操作,那么现在要实际开始操作了

  • termux + lldb的环境准备好了
  • 写好了dump上下文的lldb脚本

2023的补充

最新版的termux中lldb已经是16版本了,根据反馈可能出现image list只有几个库的情况,请尝试改为使用remote方式

步骤

首先在PC上进入termux的环境中(root用户)

记得要进入/data/data/com.termux/files/home执行命令,并且dump脚本也放到这个目录,以确保能正常读写文件

绿洲 v4.5.6为例(64位),目标是com.weibo.xvideo.NativeApis函数

通过frida hook RegisterNative,可以得到其native函数位于liboasiscore.so + 0x116CC

先查看其主进程pid

ps -ef | grep oasis

然后执行lldb进入lldb交互界面

再执行attach {pid}附加到主进程

这个时候APP会被暂停,此时再按c即可恢复运行

恢复运行后我们依然可以执行命令,这点相比gdb要好很多,gdb附加真的很慢而且只能在暂停的时候执行命令(?)

有时候会遇到这样的信号,这个时候APP就突然暂停了

通过下面的命令查看信号处理设置

process handle SIGSEGV

输出如下

NAME         PASS   STOP   NOTIFY
===========  =====  =====  ======
SIGSEGV      true  true   true

那么可以在刚附加的时候就把这个信号PASS动作设置为true,STOP动作设置为false,这样可以避免APP突然暂停

process handle SIGSEGV -p true -s false

如果其他APP存在反调试,可能会发SIGQUIT SIGSTOP SIGKILL之类的信号

暂停的时候可以打调用栈看看,说不定能找到反调试信息

可以用下面的命令查看目标so的基址信息

image list -o -f liboasiscore.so

这里只是演示下,lldb可以直接通过下面的命令实现对模块名+偏移的断点设置,相比gdb的操作方便得多

breakpoint set -s liboasiscore.so -a 0x116CC

现在断点下好了,将APP切换到后台,再进入APP就能触发s函数的调用

如果前面没有载入脚本,那么先通过下面的命令载入

command script import lldb_dumper.py

然后执行dumpctx命令即可开始dump上下文

提前做了过滤,所以不会太花时间

最后脚本会将dump好的内容打包

如果是用的ttyd+浏览器远程,那现在可以使用lsz命令直接下载文件,如果是adb方式,记得手动pull出来

现在就完成了dump上下文了

这里还没有结束

查看liboasiscore.so + 0x116CC的反汇编代码,可以看到这样的代码

v35 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);

对应的汇编是MRS X8, #3, c13, c0, #2

也就是在获取TPIDR_EL0这个系统寄存器,有关说明可以参考下面的文章

还有哪些系统寄存器?请参考

不过我们只需要获取到TPIDR_EL0就足以应付后续的模拟执行了

为了能稳妥的模拟执行,必须拿到这个寄存器的值,经过实践,发现无法直接在最开始断点的时候就拿到

只能在执行完MRS这条指令之后去获取x8的值

所以还需要在MRS的下一行断点,也就是liboasiscore.so + 0x116F4

breakpoint set -s liboasiscore.so -a 0x116F4

下完断点后按c执行,等断在0x116F4,然后通过register read x8读取TPIDR_EL0的值,记录下来

注意,不一定都是把值赋给x8,请结合实际情况确定是哪个寄存器

现在才算是完成上下文dump了

如果要结束附加进程,建议使用下面的命令(最好取消断点,再按c让APP恢复运行)

process detach

直接quit也能退,但是会导致APP崩溃或者无响应,不建议