【发布时间】:2019-02-18 12:59:57
【问题描述】:
我不太清楚 ASLR 和 PIE 之间的区别。
在我看来,ASLR 是一个操作系统选项,而 PIE 是一个编译选项。
所以, - 如果我在启用了 ASLR 的操作系统上运行 no-PIE 程序会发生什么? - 如果我在禁用了 ASLR 的操作系统上运行 PIE 程序会发生什么?
PIE 和 ASLR 是否适用于相同的事物(函数地址、库?)
谢谢
【问题讨论】:
标签: aslr
我不太清楚 ASLR 和 PIE 之间的区别。
在我看来,ASLR 是一个操作系统选项,而 PIE 是一个编译选项。
所以, - 如果我在启用了 ASLR 的操作系统上运行 no-PIE 程序会发生什么? - 如果我在禁用了 ASLR 的操作系统上运行 PIE 程序会发生什么?
PIE 和 ASLR 是否适用于相同的事物(函数地址、库?)
谢谢
【问题讨论】:
标签: aslr
ASLR实际上是操作系统有目的采用的一种策略,主要是为了规避缓冲区溢出等某些攻击,有时是为了更好地全局使用整个内存。主要目标是使不同资源的位置变得不可预测。
PIE 或 PIC 然而,与 CPU 指令集相当相关,当您编写汇编代码时,这个问题尤其重要。简而言之,CPU 所做的基本上就是在某些地址读取数据,进行简单的算术和逻辑运算,在其他地址写入数据并在代码中进行跳转。
由于许多原因,编写固定位置代码比独立代码更容易,但它也很大程度上取决于您正在编译的 CPU,尤其是微控制器。
例如,如果您需要从内存中读取较长的数据范围,您将加载一个指向该范围开头的基址寄存器,然后对其进行索引。 但是这个范围的地址将在编译时确定,因此是固定的。在以下示例中,值“1005”将加载到 EAX
USE32
ORG 1000h
00001000 B8 05 10 00 00 MOV EAX,data
00001005 48 65 6C 6C 6F data: DB "Hello"
这工作得很好,但可以防止将代码移动到其他位置而不是为其编译的位置。如果您需要这样做,则必须编写一些代码,首先将 EIP 的当前值加载到 EAX 中,然后添加当前位置和目标数据之间的差异。
手工操作会使开发过程稍微复杂化,但也会增加大量开销,使程序变得更大更慢,这很快就会成为小型微处理器的问题。
然而,在 x86 架构和其他现代计算机上,它并不真正可见,因为指令集已经优化为尽可能与位置无关,并且因为我们拥有 MMU 的优势,它使计算机能够以相同的虚拟地址。
甚至在那之前,即使在实模式下,我们也有段寄存器。这使程序员能够以 16 字节的粒度将事物基本上移动到他们想要的任何地方。
但是,在编译共享库时它变得至关重要,因为它们都应该在同一个进程寻址空间中可见(并且实际上应该是程序的一部分)。
那么,如果我在启用了 ASLR 的操作系统上运行无 PIE 程序会发生什么?
实际上,这应该不是问题,因为这是随机布置操作系统本身分配的资源的问题。因此,要么您已经从中获得了一个指针,并且从您的角度来看没有任何变化,要么它已经由系统正确设置正确的寄存器,例如在运行进程之前设置堆栈时。
【讨论】: