Radare2 调试 - 如何进入惰性导入函数?

逆向工程 调试 linux 雷达2 动态链接
2021-06-22 03:30:40

我有一个从外部库(共享对象)导入函数的 linux 二进制文件。这些函数是延迟加载的,当 rip 位于@main时不可用@entry当我进入这样一个函数(如call sym.imp.<function>)时,它进入 plt->got->linker->function。手动执行此操作(步入)非常耗时且不舒服。分析函数 ( aaa) 似乎都没有注册afl ~ <function>延迟加载库的任何函数 ( ),因此无法收集函数起始地址(直到链接器填充 plt/got)。

到目前为止,我想出的唯一方法是在 处中断call,查找dm(现在加载的)库的映射内存 ( ) 并添加函数的偏移量(通过预先直接/静态加载库收集)。这最终导致目标函数的起始地址。

即使这有效,我认为对于这样一个基本任务来说它仍然太复杂了,并且可能有一个更简单的方法。我记得 IDA/Windows 允许准备一个静态环境(加载二进制文件、库、添加注释、注释等),一旦进入调试器,初始化阶段(链接器)就会检测到准备好的库并要求使用/重载它们动态会话。在那里,您可以轻松地在函数上设置断点并且调试器成功停止。

问题是:如何在radare2 中不通过plt/got/linker 进入延迟加载的导入函数?

编辑:这是一个具体的例子:

r2 -d /usr/bin/rar
aaa
db sym.imp.__swprintf_chk
dc

然后你最终进入.plt(两次)然后进入map.usr_lib_ld_2.27.so.r_x + 50055.

1个回答

sym.imp.*符号都指向了plt这个打算。为了定位加载的模块/库的特定功能,您需要使用该dmi命令及其子命令。

按照您的示例,在以下步骤中,我将演示如何访问__swprintf_chk.

首先,在调试模式下打开一个二进制文件。我正在使用相同的二进制文件。

$ r2 -d /usr/bin/rar

Process with PID 8617 started...
= attach 8617 8617
bin.baddr 0x00400000
Using 0x400000
asm.bits 64
 -- This computer has gone to sleep.
[0x7f1f85401090]>

__swprintf_chklibc 的一部分,所以我们需要先将库加载到内存中。默认情况下,前radare2符libc被加载到内存中,以便让我们快速持续执行,直到我们达到使用该程序的入口点dcud ebug ç ontinue ü NTIL):

[0x7f1f85401090]> dcu entry0
Continue until 0x00403000 using 1 bpsize
hit breakpoint at: 403000

现在我们处于程序的入口点,我们可以简单地执行以下命令:

[0x00403000]> dmi libc __swprintf_chk
235 0x001335f0 0x7f1f845c35f0 GLOBAL   FUNC  162 __swprintf_chk

我们收到的地址__swprintf_chk0x7f1f845c35f0我们可以使用radare2的内部grep( ~)来只取这个值:

[0x00403000]> dmi libc __swprintf_chk~[2]
0x7f1f845c35f0

我们还可以使用dmi*以下命令将其打印为radare2 命令

[0x00403000]> dmi* libc __swprintf_chk
f sym.__swprintf_chk 162 0x7f1f845c35f0

如果你想执行命令,只需在它前面加上一个点:

[0x00403000]> .dmi* libc __swprintf_chk
[0x00403000]> f~sym.__swprintf_chk
0x7f1f845c35f0 162 sym.__swprintf_chk

如您所见,该地址被添加为名为“sym.__swprintf_chk”的标志。

如需更多帮助,您可以执行dmi?dm?阅读这些命令的帮助。
更多信息可以在我为 r2book 编写“内存映射”一章中找到。