PowerPC64 导入重命名

PowerPC64 imports rename

使用 powerpc64-linux-gnu-gcc 编译 .c 文件会产生以下二进制文件:

.text:00000000100007F4 # .rename _00000017.plt_call.memcpy__GLIBC_2.3, "_00000017.plt_call.memcpy@@GLIBC_2.3"
.text:00000000100007F4
.text:00000000100007F4 # =============== S U B R O U T I N E =======================================
.text:00000000100007F4
.text:00000000100007F4 # void *00000017_plt_call_memcpy__GLIBC_2_3(void *dest, const void *src, size_t n)
.text:00000000100007F4                         _00000017.plt_call.memcpy__GLIBC_2.3:
.text:00000000100007F4 .set arg_28,  0x28
.text:00000000100007F4
.text:00000000100007F4 std       r2, arg_28(r1)
.text:00000000100007F8 ld        r12, (memcpy_plt - 0x10027F00)(r2) # memcpy
.text:00000000100007FC mtctr     r12
.text:0000000010000800 ld        r2, (qword_10020158 - 0x10027F00)(r2)
.text:0000000010000804 bctr
.text:0000000010000804 # End of function _00000017.plt_call.memcpy__GLIBC_2.3

我不明白 .rename _00000017.plt_call.memcpy__GLIBC_2.3 是从哪里来的,为什么要从 memcpy 重命名?

给出此结果的代码示例:

int main()
{
    char* buf = (char*)calloc(25, sizeof(char));
    char* buf1 = (char*)calloc(25, sizeof(char));
    memcpy(buf, buf1, 25);
}

这个 GLIBC_2.3 东西是在链接过程中引入的(编译器对你的 Glibc 版本一无所知)。清单中的 .rename 评论是 IDA 神器。 (IDA 文档是否介绍了它们?)

您看到的 @ 标志表示 symbol versions@@ 指定默认版本,外部(在本例中为 Glibc)引用绑定到此符号。

The linker supports symbol versions when using ELF. Symbol versions are only useful when using shared libraries. The dynamic linker can use symbol versions to select a specific version of a function when it runs a program that may have been linked against an earlier version of the shared library.

因此,关于程序中的引用将绑定到哪个符号的决定最终由 ld.so 在加载时做出。也许这就是 .rename 的意思。

使用 GNU 工具链,绑定决定实际上可以延迟到 运行 时间。在我的平台 (x86_64-linux-gnu) 上,memcpy 是一个 IFUNC。您可以通过查看 glibc 的符号来检查您是否属于这种情况 readelf -s /lib/libc.so.6 | grep IFUNC.*memcpy。但理论上,如果没有 运行 代码,IDA 将不知道最终目的地,因此 ifunc 在这里可能无关紧要。不过,为了更清晰的实验,您可以测试其他不是 ifunc 的 libc 函数。