【问题标题】:Why "symbol@GOT" is not permitted on pie binary?为什么 pie 二进制文件中不允许使用“symbol@GOT”?
【发布时间】:2018-11-20 13:33:51
【问题描述】:

这里是示例汇编文件,test.s

.global main  
main:  
 mov __progname@GOT, %eax         // failed to compile
 mov __progname@GOT(%ebx), %eax   //succeed to compile

我尝试使用-pie 标志编译它,但失败了。

$ gcc -pie -o test test.s
osboxes@osboxes:/mnt/hgfs/VM_Shared/Reassemblabla/src$ gcc -pie -o test test.s
/usr/bin/ld: /tmp/ccPGMLlH.o: direct GOT relocation R_386_GOT32X against `__progname' without base register can not be used when making a shared object
/usr/bin/ld: failed to set dynamic section sizes: File format not recognized
collect2: error: ld returned 1 exit status

错误说,在 pie 二进制中,只能使用基址寄存器访问GOT 条目。

问题。
我不知道为什么编译器会像上面那样抱怨。
更具体地说,为什么在 pie 二进制文件中不允许使用 __progname@GOT 寻址?



我的看法。
Loader 在 pie 二进制文件的加载时间内知道__progname@GOT 的地址。

因此,加载程序可以在加载时简单地将该地址写入__progname@GOT 的位置。
这就是装载机可以做的。

所以我不明白为什么编译器坚持像
mov __progname@GOT(%ebx), %eax 这样的寄存器相对访问。

【问题讨论】:

  • Loader 通常不会写入代码部分,因为这会破坏跨进程的共享,这对库很重要。它对可执行文件不是特别有用,但由于 PIE 是建立在相同功能之上的,因此不允许这样做。
  • @Jester 但是......当我们使用直接内存访问时,加载程序会写入代码部分。例如,当我们使用mov MY_SYMBOL, %eax 之类的指令并将其编译为饼图二进制文件时,MY_SYMBOL 的地址直到加载时才固定。在这种情况下,加载程序在加载时将MY_SYMBOL的地址写入<.text>部分。
  • 是的,从技术上讲这是可能的,但 GOT 的全部意义在于避免代码中的重定位。如果您可以接受搬迁,则不需要 GOT,只需使用您展示的简单搬迁即可。
  • @Jester 哦,这很有意义。是的,你是对的。我们使用 GOT 来避免代码中的重定位,而使用 relocaion 访问 GOT 部分很奇怪……就像自相矛盾。感谢您的评论!
  • 有趣的问题。这个source 有一条关于 GOT 地址对于 PIC 未知的评论。我不知道为什么共享库会出现这种情况,本地 GOT 是已知的。也许他们在谈论另一个模块的 GOT?还允许使用 lea(记录在 ABI 中)。最后,似乎算法的描述是骗人的,.got 部分的 end 被减去。我现在想不出任何原因。

标签: linux assembly x86 position-independent-code got


【解决方案1】:

PIE 应该使用 pc 相对寻址; ia32 在这方面很糟糕,所以您需要执行以下操作:

    call thunk
    add  $_GLOBAL_OFFSET_TABLE__, %eax
    mov  __progname@GOT(%eax), %eax
    ret
thunk:
    mov (%esp), %eax
    ret

从这个程序地址到 _GLOBAL_OFFSET_TABLE__ 的通知偏移量被计算为引用 GOT。因此,程序可以在任何地址加载(而不是链接或定位),并且会找到 GOT 和所有变量,因为相对偏移量是相同的。 作为参考,上面的amd64版本是这样的:

mov    __progname(%rip), %rax
ret

请注意,这两个都保持文本“纯”......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-30
    • 2020-09-25
    • 2023-03-07
    • 2022-01-20
    • 2017-07-18
    • 2012-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多