由于PIE二进制文件的性质, 绝对 地址无法访问二进制文件中的所有数据。
因此,有两种方式 相对
两种方式
在执行过程中, loader 会在GOT
条目中加载数据的位置。
并以二进制方式访问该地址。
使用_GLOBAL_OFFSET_TABLE
位置计算数据地址,并对其进行访问。
但是,我看到了另一种相对访问数据的方法。
在下面的二进制文件中,二进制文件更改了<.text>
部分的代码。
很奇怪。
.global main
main:
push stderr
我将其编译为饼图二进制文件。
jiwon@jiwon$ gcc -fPIE -pie -o test test.s
jiwon@jiwon$ objdump -D test_pie | grep "<main>" -A5
000005c0 <main>:
5c0: ff 35 00 00 00 00 pushl 0x0
5c6: 66 90 xchg %ax,%ax
5c8: 66 90 xchg %ax,%ax
5ca: 66 90 xchg %ax,%ax
如您在上面的反汇编中所见,push stderr
被组装成pushl 0x0
。
And ..当我执行二进制文件时,
pwndbg> disass /r main
Dump of assembler code for function main:
=> 0x004005c0 <+0>: ff 35 48 18 40 00 push DWORD PTR ds:0x401848
0x004005c6 <+6>: 66 90 xchg ax,ax
0x004005c8 <+8>: 66 90 xchg ax,ax
0x004005ca <+10>: 66 90 xchg ax,ax
<。text>部分更改为指向stderr
!
我认为这很奇怪,因为<.text>
部分在一般应用中具有-WX
权限。
但是在这种情况下,<.text>
是RWX
的权限。
问题:
答案 0 :(得分:0)
与位置无关的可执行文件由编译器和链接器的结合工作产生,而不仅仅是链接器。在您的情况下,您传递了GCC
已经汇编的代码,可能不是编译器使用PIE
标志生成的代码。
链接器不是生成相对的加载和存储指令的链接器,编译器会这样做,并且链接器确保正确放置正确的重定位段等等。