在PIE二进制文件中,代码段在执行过程中发生更改。为什么会这样?

时间:2018-10-04 06:26:48

标签: assembly x86 binary loader position-independent-code

由于PIE二进制文件的性质, 绝对 地址无法访问二进制文件中的所有数据。
因此,有两种方式 相对

访问数据

两种方式

  1. 在执行过程中, loader 会在GOT条目中加载数据的位置。
    并以二进制方式访问该地址。

  2. 使用_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的权限。


问题:

  1. 为什么会这样? 为什么编译器选择使用这种奇怪的方式,而不是使用 两种方式
  2. 这是 pie 二进制文件中的常见情况吗?

1 个答案:

答案 0 :(得分:0)

与位置无关的可执行文件由编译器和链接器的结合工作产生,而不仅仅是链接器。在您的情况下,您传递了GCC已经汇编的代码,可能不是编译器使用PIE标志生成的代码。

链接器不是生成相对的加载和存储指令的链接器,编译器会这样做,并且链接器确保正确放置正确的重定位段等等。