我有一个从外部库(共享库)导入函数的linux二进制文件。该函数是延迟加载的,当rip在@main@entry时不可用。当我进入这样的功能(如call sym.imp.<function>)时,它进入plt-> got-> linker-> function。手动(逐步)执行此操作非常耗时且不舒服。分析函数(aaa)似乎都没有注册延迟加载库的任何函数(afl ~ <function>),因此无法收集函数的起始地址(直到链接器填充plt / got为止)。 >到目前为止,我发现的唯一方法是在call处中断,查找(已加载)库的映射内存(dm)并添加函数的偏移量(通过预先直接/静态加载库来收集)。最终导致目标函数的起始地址。

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

编辑:
这是一个具体示例: .plt

评论

能否请您分享您的二进制文件并指向特定位置。这样,我们将能够为您提供最佳答案。

我添加了一个示例。

#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_chk是libc的一部分,因此我们需要首先将库加载到内存中。默认情况下,radare2在将libc加载到内存之前会中断,因此让我们快速继续执行直到使用dcu到达程序的入口点为止(调试继续直到):

[0x7f1f85401090]> dcu entry0
Continue until 0x00403000 using 1 bpsize
hit breakpoint at: 403000
进入程序的入口点,只需执行以下命令:我们可以使用radare2的内部grep(__swprintf_chk)仅采用此值: />
[0x00403000]> dmi libc __swprintf_chk
235 0x001335f0 0x7f1f845c35f0 GLOBAL   FUNC  162 __swprintf_chk


如果要执行该命令,只需在命令前加上一个点:

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


地址被添加为名为“ sym .__ swprintf_chk”的标志。

要获得更多帮助,可以执行0x7f1f845c35f0~并阅读这些命令的帮助。
更多信息,请参见“我为r2book写的“内存映射”一章。