ASLR和PIE的区别

Bob*_*421 6 aslr

我不太确定了解 ASLR 和 PIE 之间的区别。

在我看来,ASLR 是一个操作系统选项,而 PIE 是一个编译选项。

那么, - 如果我在启用了 ASLR 的操作系统上运行无 PIE 程序会发生什么?- 如果我在禁用 ASLR 的操作系统上运行 PIE 程序会发生什么?

PIE 和 ASLR 是否适用于相同的事物(函数地址、库?)

谢谢

Obs*_*ian 6

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 程序会发生什么?

实际上,这不应该成为问题,因为这是随机布局操作系统本身分配的资源的问题。因此,要么您已经从中获得了一个指针,并且从您的角度来看没有任何变化,要么已经由系统来正确设置正确的寄存器,例如在运行进程之前设置堆栈时。

  • 我想知道的是,在 4 种可能的情况下,我的程序的函数地址是否位于同一位置(pie/aslr、no-pie/aslr、pie/no-aslr、no-pie/no-aslr) (6认同)