在这周,我发现我可以从 gdb 上调用 C 函数。这看起来很酷,因为在过去我认为 gdb 最多只是一个只读调试工具。
我对 gdb 能够调用函数感到很吃惊。正如往常所做的那样,我在 Twitter 上询问这是如何工作的。我得到了大量的有用答案。我最喜欢的答案是 Evan Klitzke 的示例 C 代码,它展示了 gdb 如何调用函数。代码能够运行,这很令人激动!
我(通过一些跟踪和实验)认为那个示例 C 代码和 gdb 实际上如何调用函数不同。因此,在这篇文章中,我将会阐述 gdb 是如何调用函数的,以及我是如何知道的。
关于 gdb 如何调用函数,还有许多我不知道的事情,并且,在这儿我写的内容有可能是错误的。
从 gdb 中调用 C 函数意味着什么?
在开始讲解这是如何工作之前,我先快速的谈论一下我是如何发现这件令人惊讶的事情的。
假如,你已经在运行一个 C 程序(目标程序)。你可以运行程序中的一个函数,只需要像下面这样做:
暂停程序(因为它已经在运行中)
找到你想调用的函数的地址(使用符号表)
使程序(目标程序)跳转到那个地址
当函数返回时,恢复之前的指令指针和寄存器
通过符号表来找到想要调用的函数的地址非常容易。下面是一段非常简单但能够工作的代码,我在 Linux 上使用这段代码作为例子来讲解如何找到地址。这段代码使用 elf crate。如果我想找到 PID 为 2345 的进程中的 foo 函数的地址,那么我可以运行 elf_symbol_value("/proc/2345/e