使用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);
}
答案 0 :(得分:1)
此GLIBC_2.3
东西是在链接期间引入的(编译器对Glibc版本一无所知)。清单中的.rename
注释是IDA构件。 (IDA文档是否提供有关它们的任何信息?)
您看到的@
符号表示symbol versions,@@
指定将外部(在本例中为Glibc)对该符号的引用绑定到的默认版本。
使用ELF时,链接器支持符号版本。符号版本为 仅在使用共享库时有用。动态链接器可以使用 符号版本以在运行时选择功能的特定版本 可能已与较早版本的程序链接的程序 共享库。
因此,在装入时,ld.so
决定要在程序中将引用绑定到哪个符号。也许这就是.rename
的意思。
使用GNU工具链,绑定决定实际上可以延迟到运行时为止。在我的平台(x86_64-linux-gnu)上,memcpy是 IFUNC 。您可以通过查看readelf -s /lib/libc.so.6 | grep IFUNC.*memcpy
这样的glibc符号来检查是否适合您。但是,从理论上讲,如果不运行代码,IDA不会知道最终的目的地,因此ifuncs在这里可能无关紧要。为了进行更简洁的实验,您可以测试不是ifuncs的其他libc函数。