好的,所以在问我的问题之前,我想介绍一些技术细节,我想确保我做对了:
位置无关可执行文件 - PIE,是一个无论加载到哪个内存地址都能执行的代码,对吗?
ASLR ------地址空间布局随机化,几乎说明为了保持地址静态,我们会以某种方式随机化它们,
我已经在基于Linux和Unix的系统中特别阅读了实现ASLR是可能的,无论我们的代码是PIE,如果它是PIE,所有跳转,调用和偏移是相对的,因此我们没有问题 如果不是,则编写一些代码,无论代码是可执行文件还是共享对象,都会编辑修改地址并编辑地址....
对......现在这让我提出几个问题
如果ASLR可以在不属于PIE和的代码中实现 是可执行文件而不是共享/可重定位对象(我知道如何 重新安置工作在可重新定位的对象中!!!! )它是怎么回事 完成?,精灵格式应该没有任何部分说明在哪里 代码部分是函数,因此内核加载器可以修改 对的? ASLR应该是一个内核功能,所以实际上如何 可以是例如包含例如这些的可执行文件 说明
伪代码:
inc_eax:
add eax, 5
ret
main:
mov eax, 5
mov ebx, 6
call ABSOLUTE_ADDRES{inc_eax}
内核可执行加载器如何知道如何更改 地址,如果它们没有存储在精灵内的某个可重定位表中 文件并不是相对的,以便将可执行文件加载到某些文件中 随机地址?
我们说我错了,为了实施ASLR,你必须有一个 PIE可执行文件,所有段都是相对的,如何编译一个 C ++ OOP代码并使其工作,例如,如果我有一些实例 一个类使用指向其结构中的虚拟表的指针, 并且该虚拟表应该包含绝对地址,因此我 将无法为具有的C ++程序编译纯PIE 使用运行时虚拟表,再次ASLR是不可能的.... 我怀疑虚拟表是否包含相对地址和 对于某些人来说,每次调用会有一个不同的虚拟表 虚函数......
关于ELF和PIE,我最后一个也是最不重要的问题是 检测ELF可执行文件的一些特殊方法是PIE?,我是 熟悉ELF格式,所以我怀疑除了我之外还有其他方法 可能是错的,无论如何,如果没有内核的方式 加载器知道我们的可执行文件是否是PIE因此它可以使用ASLR
我已经把这一切搞砸了,如果有人能在这里帮助我,我会喜欢它,提前谢谢
答案 0 :(得分:10)
你的问题似乎是一种混乱和误解的混乱。
位置无关可执行文件 - PIE,是一个无论加载到哪个内存地址都能执行的代码,对吗?
几乎。 PIE
二进制文件通常无法在任意地址加载到内存中,因为其PT_LOAD
段将具有一些对齐要求(例如0x400或0x10000)。但它可以加载,如果在满足对齐要求的地址加载到内存中,它将正确运行。
ASLR ------地址空间布局随机化,几乎说明为了保持地址静态,我们会以某种方式随机化它们,
我无法以任何有意义的方式解析上述陈述。
ASLR是一种随机化地址空间各部分的技术,以使“已知地址”攻击更加困难。
请注意,ASLR 早于 PIE
二进制文件,并且不以任何方式要求PIE
。引入ASLR时,它随机放置堆栈,堆和共享库。 (非PIE
)主要可执行文件的位置无法随机化。
ASLR被认为是成功的,因此扩展为也支持PIE
主二进制文件,它实际上是一个特制的共享库(并且具有ET_DYN
文件类型)。
- 醇>
call ABSOLUTE_ADDRES{inc_eax}
如果>内核可执行加载器如何知道如何更改地址?它们不存储在一些可重定位的表中
简单:在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
,则会看到它是“共享库”。