ELF、PIE ASLR 以及介于两者之间的所有内容,特别是在 Linux 中 [英] ELF, PIE ASLR and everything in between, specifically within Linux

查看:25
本文介绍了ELF、PIE ASLR 以及介于两者之间的所有内容,特别是在 Linux 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  • 位置独立可执行文件 (PIE) 是一种无论加载到哪个内存地址都能够执行的程序,对吗?

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

我读过专门在基于 Linux 和 Unix 的系统中,无论我们的代码是 PIE,还是 PIE,所有跳转、调用和偏移都是相对的,因此我们没有问题,实现 ASLR 是可能的.如果不是,无论代码是可执行文件还是共享对象,代码都会以某种方式被修改并编辑地址.

现在这让我问几个问题

  1. 如果 ASLR 可以在不是 PIE 且是可执行文件且不是共享/可重定位对象的代码中实现(我知道重定位在可重定位对象中是如何工作的!!!!),它是怎么做的?ELF 格式不应该包含任何说明代码部分中的函数的部分,以便内核加载程序可以修改它,对吗?ASLR 应该是一个内核功能,例如,一个包含这些指令的可执行文件到底怎么可能.

    伪代码:

     inc_eax:添加 eax, 5退主要的:移动轴,5mov ebx, 6调用绝对地址{inc_eax}

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

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

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

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

解决方案

您的问题似乎是混淆和误解的大杂烩.

<块引用>

位置无关可执行文件 (PIE) 是一种无论加载到哪个内存地址都能够执行的程序,对吗?

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

<块引用>

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

我无法以任何有意义的方式解析上述语句.

ASLR 是一种将地址空间的各个部分随机化的技术,以使已知地址"成为可能.攻击更难.

请注意,ASLR 早于 PIE 二进制文件,并且在任何情况下都不需要 PIE.当引入 ASLR 时,它随机放置堆栈、堆和共享库.(非PIE)主要可执行文件的位置无法随机化.

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

<块引用>

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

简单:在 x86 上,没有指令可以调用 ABSOLUTE_ADDRESS——所有调用都是相对的.

<块引用>

2 ...我将无法为使用运行时虚拟表的 C++ 程序编译纯 PIE,而且 ASLR 也是不可能的..

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

<块引用>

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

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

Before asking my question, I would like to cover some few technical details I want to make sure I've got correct:

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

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

I've read that specifically within Linux and Unix based systems, implementing ASLR is possible regardless of if our code is a PIE, if it is PIE, all jumps, calls and offsets are relative hence we have no problem. If it's not, code somehow gets modified and addresses are edited regardless of whether the code is an executable or a shared object.

Now this leads me to ask a few questions

  1. If ASLR is possible to implement within codes that aren't PIE and are executables AND NOT SHARED / RELOCATABLE OBJECT (I KNOW HOW RELOCATION WORKS WITHIN RELOCATABLE OBJECTS!!!!), how is it done? ELF format should hold no section that states where within the code sections are functions so the kernel loader could modify it, right? ASLR should be a kernel functionality so how on earth could, for example, an executable containing, for example, these instructions.

    pseudo code:

     inc_eax:
      add eax, 5
      ret
    
     main:
      mov eax, 5
      mov ebx, 6
      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 within the ELF file and aren't relative in order to load the executable into some random address?

  2. Let's say I'm wrong, and in order to implement ASLR you must have a PIE executable. All segments are relative. How would one compile a C++ OOP code and make it work, for example, if I have some instance of a class using a pointer to a virtual table within its struct, and that virtual table should hold absolute addresses, hence 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.... I doubt that virtual tables would contain relative addresses and there would be a different virtual table for each call of some virtual function...

  3. My last and least significant question is regarding ELF and PIE — is there some special way to detect an ELF executable is PIE? I'm familiar with the ELF format so I doubt that there is a way, but I might be wrong. Anyway, if there isn't a way, how does the kernel loader know if our executable is PIE hence it could use ASLR on it.

I've got this all messed up in my head and I'd love it if someone could help me here.

解决方案

Your question appears to be a mish-mash of confusion and misunderstanding.

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

Almost. A PIE binary usually can not be loaded into memory at arbitrary address, as its PT_LOAD segments will have some alignment requirements (e.g. 0x400, or 0x10000). But it can be loaded and will run correctly if loaded into memory at address satisfying the alignment requirements.

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

I can't parse the above statement in any meaningful way.

ASLR is a technique for randomizing various parts of address space, in order to make "known address" attacks more difficult.

Note that ASLR predates PIE binaries, and does not in any way require PIE. When ASLR was introduced, it randomized placement of stack, heap, and shared libraries. The placement of (non-PIE) main executable could not be randomized.

ASLR has been considered a success, and therefore extended to also support PIE main binary, which is really a specially crafted shared library (and has ET_DYN file type).

  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

Simple: on x86, there is no instruction to call ABSOLUTE_ADDRESS -- all calls are relative.

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 binary requires relocation, just like a shared library. Virtual tables in PIE binaries work exactly the same way they work in shared libraries: ld-linux.so.2 updates GOT (global offset table) before transferring control to the PIE binary.

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

Simple: a PIE binary has ELF file type set to ET_DYN (a non-PIE binary will have type ET_EXEC). If you run file a.out on a PIE executable, you'll see that it's a "shared library".

这篇关于ELF、PIE ASLR 以及介于两者之间的所有内容,特别是在 Linux 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆