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

时间:2016-07-04 16:37:12

标签: compilation linker elf aslr

好的,所以在问我的问题之前,我想介绍一些技术细节,我想确保我做对了:

位置无关可执行文件 - PIE,是一个无论加载到哪个内存地址都能执行的代码,对吗?

ASLR ------地址空间布局随机化,几乎说明为了保持地址静态,我们会以某种方式随机化它们,

我已经在基于Linux和Unix的系统中特别阅读了实现ASLR是可能的,无论我们的代码是PIE,如果它是PIE,所有跳转,调用和偏移是相对的,因此我们没有问题 如果不是,则编写一些代码,无论代码是可执行文件还是共享对象,都会编辑修改地址并编辑地址....

对......现在这让我提出几个问题

  1. 如果ASLR可以在不属于PIE和的代码中实现 是可执行文件而不是共享/可重定位对象(我知道如何 重新安置工作在可重新定位的对象中!!!! )它是怎么回事 完成?,精灵格式应该没有任何部分说明在哪里 代码部分是函数,因此内核加载器可以修改 对的? ASLR应该是一个内核功能,所以实际上如何 可以是例如包含例如这些的可执行文件 说明

    伪代码:

    inc_eax:
     add eax, 5
     ret
    
    main:
     mov eax, 5
     mov ebx, 6
     call ABSOLUTE_ADDRES{inc_eax}
    

    内核可执行加载器如何知道如何更改 地址,如果它们没有存储在精灵内的某个可重定位表中 文件并不是相对的,以便将可执行文件加载到某些文件中 随机地址?

  2. 我们说我错了,为了实施ASLR,你必须有一个 PIE可执行文件,所有段都是相对的,如何编译一个 C ++ OOP代码并使其工作,例如,如果我有一些实例 一个类使用指向其结构中的虚拟表的指针, 并且该虚拟表应该包含绝对地址,因此我 将无法为具有的C ++程序编译纯PIE 使用运行时虚拟表,再次ASLR是不可能的.... 我怀疑虚拟表是否包含相对地址和 对于某些人来说,每次调用会有一个不同的虚拟表 虚函数......

  3. 关于ELF和PIE,我最后一个也是最不重要的问题是 检测ELF可执行文件的一些特殊方法是PIE?,我是 熟悉ELF格式,所以我怀疑除了我之外还有其他方法 可能是错的,无论如何,如果没有内核的方式 加载器知道我们的可执行文件是否是PIE因此它可以使用ASLR

  4. 我已经把这一切搞砸了,如果有人能在这里帮助我,我会喜欢它,提前谢谢

1 个答案:

答案 0 :(得分:10)

你的问题似乎是一种混乱和误解的混乱。

  

位置无关可执行文件 - PIE,是一个无论加载到哪个内存地址都能执行的代码,对吗?

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

  

ASLR ------地址空间布局随机化,几乎说明为了保持地址静态,我们会以某种方式随机化它们,

我无法以任何有意义的方式解析上述陈述。

ASLR是一种随机化地址空间各部分的技术,以使“已知地址”攻击更加困难。

请注意,ASLR 早于 PIE二进制文件,并且不以任何方式要求PIE。引入ASLR时,它随机放置堆栈,堆和共享库。 (非PIE)主要可执行文件的位置无法随机化。

ASLR被认为是成功的,因此扩展为也支持PIE主二进制文件,它实际上是一个特制的共享库(并且具有ET_DYN文件类型)。

  
      
  1. call ABSOLUTE_ADDRES{inc_eax}   如果>内核可执行加载器如何知道如何更改地址?它们不存储在一些可重定位的表中
  2.   

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

  

2 ...我无法为使用运行时虚拟表的C ++程序编译纯PIE,并且再次无法使用ASLR ..

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

  

3 ...有一些特殊的方法来检测ELF可执行文件是PIE

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