在64位x86平台上比较PIE、PIC代码和可执行文件有什么区别?

oxf4rvwz  于 2023-06-21  发布在  其他
关注(0)|答案(1)|浏览(305)

测试是在Ubuntu 12.04 64位。x86架构。
我对位置无关可执行文件(PIE)和位置无关代码(PIC)的概念感到困惑,我猜它们不是正交的。
这是我的快速实验。

gcc -fPIC -pie quickSort.c -o a_pie.out
gcc -fPIC      quickSort.c -o a_pic.out
gcc                           a.out

objdump -Dr -j .text a.out > a1.temp
objdump -Dr -j .text a_pic.out > a2.temp
objdump -Dr -j .text a_pie.out > a3.temp

我有以下发现。

    • A.a. out包含一些PIC代码,但只有**在libc prologue和epilogue函数中抵抗,如下图所示:
4004d0:       48 83 3d 70 09 20 00    cmpq   $0x0,0x200970(%rip)        # 600e48 <__JCR_END__>

在我的简单快速排序程序的汇编指令中,我没有找到任何PIC指令。

    • B.a_pic. out包含PIC代码,我没有找到任何非PIC**指令...在我的quicksort程序的指令中,所有全局数据都是通过PIC指令访问的,如下所示:
40053b:       48 8d 05 ea 02 00 00    lea    0x2ea(%rip),%rax        # 40082c <_IO_stdin_used+0x4>
    • C.a_pie. out包含与a_pic. out语法相同的指令。但是,a_pie. out的. text**部分的内存地址范围为0x630到0xa57,而a_pic. out的同一部分的范围为0x400410到0x400817。

有谁能给我解释一下这些现象吗?尤其是发现C。再次,我真的很困惑PIE与。PIC,不知道如何解释发现C..

zkure5ic

zkure5ic1#

我对位置无关可执行文件(PIE)和位置无关代码(PIC)的概念感到困惑,我猜它们不是正交的。
PIEPIC之间唯一的真实的区别是,您可以在PIC中插入符号,但不能在PIE中插入符号。除此之外,它们几乎是等同的。
您可以阅读有关符号插入here的信息。
C. a_pie.out包含与a_pic. out语法相同的指令。但是,a_pie.out的.text部分的内存地址范围为0x 630到0xa 57,而a_pic.out的同一部分的范围为0x 400410到0x 400817。
PIE二进制文件只是作为一个共享库进行链接,因此它的默认加载地址(第一个LOAD段的.p_vaddr)为零。期望的是,某些东西会将这个二进制文件从零页重新定位,并将其加载到某个随机地址。
另一方面,一个非PIE的可执行文件总是被加载到它的linked-at地址。在Linux上,x86_64二进制文件的默认地址是0x400000,因此.text的地址与此不远。

相关问题