Skip to main content
 首页 » 编程设计

compilation之ELF、PIE ASLR 以及介于两者之间的所有内容,特别是在 Linux 中

2024年11月01日27TianFang

在问我的问题之前,我想介绍一些我想确保我正确的技术细节:

  • 位置无关可执行文件 (PIE) 是一种无论加载到哪个内存地址都能够执行的程序,对吗?
  • ASLR(地址空间布局随机化)几乎说明为了保持地址静态,我们会以某种方式随机化它们,

  • 我读过专门在基于 Linux 和 Unix 的系统中,无论我们的代码是 PIE,如果是 PIE,所有跳转、调用和偏移都是相对的,因此我们没有问题,实现 ASLR 是可能的。
    如果不是,无论代码是可执行文件还是共享对象,代码都会以某种方式被修改并编辑地址。
    现在这让我问几个问题
  • 如果 ASLR 可以在不是 PIE 并且是可执行文件且不是共享/可重定位对象的代码中实现( 我知道重定位如何在可重定位对象中工作!!!! ),它是如何完成的? ELF 格式不应该包含说明代码部分中哪些是函数的部分,以便内核加载程序可以修改它,对吗? ASLR 应该是一个内核功能,例如,一个包含这些指令的可执行文件到底怎么可能。
    伪代码:
     inc_eax: 
      add eax, 5 
      ret 
     
     main: 
      mov eax, 5 
      mov ebx, 6 
      call ABSOLUTE_ADDRES{inc_eax} 
    
    内核可执行加载器如何知道如何更改
    地址,如果它们没有存储在 ELF 内的某个可重定位表中
    文件并且不是相对的以便将可执行文件加载到某些
    随机地址?
  • 假设我错了,为了实现 ASLR,你必须有一个
    PIE 可执行文件。所有段都是相对的。如何编译一个
    C++ OOP 代码并使其工作,例如,如果我有一些实例
    使用指向其结构中的虚拟表的指针的类,
    并且那个虚拟表应该保存绝对地址,因此我
    将无法为具有以下功能的 C++ 程序编译纯 PIE
    使用运行时虚拟表,再次 ASLR 是不可能的....
    我怀疑虚拟表会包含相对地址和
    每次调用都会有一个不同的虚拟表
    虚函数...
  • 我最后一个也是最不重要的问题是关于 ELF 和 PIE——是否有一些特殊的方法来检测 ELF 可执行文件是 PIE?我熟悉 ELF 格式,所以我怀疑有没有办法,但我可能错了。无论如何,如果没有办法,内核加载程序如何知道我们的可执行文件是否是 PIE,因此它可以在其上使用 ASLR。

  • 我把这一切都搞砸了,如果有人能在这里帮助我,我会很高兴的。

    请您参考如下方法:

    你的问题似乎是困惑和误解的大杂烩。

    A Position Independent Executable (PIE) is a program that would be able to execute regardless of which memory address it is loaded into, right?


    几乎。一个 PIE二进制通常不能在任意地址加载到内存中,因为它的 PT_LOAD段将有一些对齐要求(例如 0x400 或 0x10000)。但是如果在满足对齐要求的地址加载到内存中,它可以被加载并正确运行。

    ASLR (Address Space Layout Randomization) pretty much states that in order to keep addresses static we would randomize them in some manner,


    我无法以任何有意义的方式解析上述语句。
    ASLR 是一种随机化地址空间各个部分的技术,目的是使“已知地址”攻击更加困难。
    请注意,ASLR 早于 PIE二进制文件,并且在任何情况下都不需要 PIE .当引入 ASLR 时,它随机放置堆栈、堆和共享库。 (非 PIE )主要可执行文件的位置无法随机化。
    ASLR 被认为是成功的,因此扩展到也支持 PIE main 二进制文件,它实际上是一个特制的共享库(并且具有 ET_DYN 文件类型)。
    1. call ABSOLUTE_ADDRES{inc_eax} how would the kernel executable loader know how to change the addresses if > they aren't stored in some relocatable table

    简单:在 x86 上,没有到 call ABSOLUTE_ADDRESS 的指令-- 所有调用都是相对的。

    2 ... I wouldn't be able to compile a pure PIE for C++ programs that have usage of run time virtual tables, and again ASLR isn't possible..

    PIE二进制需要重定位,就像共享库一样。 PIE 中的虚拟表二进制文件的工作方式与它们在共享库中的工作方式完全相同: ld-linux.so.2更新 GOT (全局偏移表)在将控制转移到 PIE 之前二进制。

    3 ... is there some special way to detect an ELF executable is PIE


    简单: PIE二进制将 ELF 文件类型设置为 ET_DYN (非 PIE 二进制文件的类型为 ET_EXEC )。如果您运行 file a.outPIE可执行文件,你会看到它是一个“共享库”。