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 函数。
使用 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 函数。