我不太确定了解 ASLR 和 PIE 之间的区别。
在我看来,ASLR 是一个操作系统选项,而 PIE 是一个编译选项。
那么, - 如果我在启用了 ASLR 的操作系统上运行无 PIE 程序会发生什么?- 如果我在禁用 ASLR 的操作系统上运行 PIE 程序会发生什么?
PIE 和 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"
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但会阻止将代码移动到已编译的位置之外的其他位置。如果您需要这样做,则必须编写一些代码,首先将 EIP 的当前值加载到 EAX 中,然后添加当前位置和目标数据之间的差异。
当您手工完成时,它会使开发过程稍微复杂化,但它也增加了大量的开销,使程序更大、速度更慢,这很快就会成为小型微处理器上的问题。
然而,在 x86 架构和其他现代计算机上,它并不真正可见,因为指令集已经优化为尽可能与位置无关,并且因为我们拥有 MMU 的优势,它使计算机能够在同一虚拟中运行每个进程。地址。
甚至在此之前,即使在实模式下,我们也有段寄存器。这使得程序员能够以 16 字节的粒度将东西基本上移动到他们想要的任何地方。
然而,在编译共享库时,这一点变得至关重要,因为所有共享库都应该在同一进程寻址空间中可见(并且实际上应该是程序的一部分)。
那么,如果我在启用了 ASLR 的操作系统上运行 no-PIE 程序会发生什么?
实际上,这不应该成为问题,因为这是随机布局操作系统本身分配的资源的问题。因此,要么您已经从中获得了一个指针,并且从您的角度来看没有任何变化,要么已经由系统来正确设置正确的寄存器,例如在运行进程之前设置堆栈时。