1

我正在使用其 ELF 和 DWARF 信息获取程序的所有数据,并将 pin 工具连接到当前正在运行的进程——它是一种使用 Pin 工具的调试器。

为了从堆栈中获取局部变量,我正在使用可以从 Pin 访问的寄存器 EIP、EBP 和 ESP。

让我感到奇怪的是,当 pin 工具附加到进程时,我期望 EIP 指向正在运行的当前函数,但 EIP 指向的是 .PLT 部分。换句话说,如果在 Foo() 运行时 pin 工具被挂接到进程中,那么我期望 EIP 指向 Foo 函数内的某个地址。但是它指向 .PLT 部分的开头。

我需要知道的是进程当前所在的函数——有没有办法使用 .PLT 部分获取函数的地址?有没有其他方法可以从堆栈或使用 Pin 获取函数的地址?我希望我足够清楚,如果有任何问题,请告诉我。

4

1 回答 1

0

我可能不完全理解这里发生了什么......指令指针真的在 .plt 部分中还是你只是从 Pin 得到一个垃圾值?

您将正在读取的指令指针命名为 EIP,如果您在 64 位系统上运行,这可能会出现问题,是这样吗?您会看到指令指针寄存器在 32 位系统上是 32 位值,在 64 位系统上是 64 位值。所以 Pin 实际上为指令指针提供了 3 个 REG_* 名称:EIP、RIP 和 GBP。EIP 始终是寄存器的低 32 位一半,RIP 是 64 位值,而 GBP 是两者之一,具体取决于您的架构。在 64 位系统上请求 EIP 会给您带来垃圾,就像在 32 位系统上请求 RIP 一样。

否则,在谷歌上快速浏览一下就会给我这个。引用一点:

默认情况下,.plt 条目全部由链接器初始化,不指向正确的目标函数,而是指向动态加载器本身。因此,第一次调用任何给定函数时,动态加载程序会查找该函数并修复 .plt 的目标,以便下次使用此 .plt 插槽时,我们调用正确的函数。

更重要的是:

在将控制权转移给应用程序之前,可以指示动态加载程序将地址绑定到所有 .plt 插槽——这是通过在运行程序之前设置环境变量LD_BIND_NOW=1来完成的。例如,在调试程序时,这在某些情况下很有用。

希望有帮助。

于 2012-11-06T06:24:53.297 回答