如何解决堆栈安全问题组装



我是一个新的汇编程序员,我想知道是否有办法完全清理堆栈 (来自所有函数参数和函数指针( 提前致谢

> emu8086 模拟真实模式。 没有安全感;所有代码都以完全权限运行,以接管整个计算机。 你必须信任你的来电者;调用方可以在调用之前反汇编函数的机器代码,甚至对其进行修改。

但可以肯定的是,您可以在返回之前覆盖堆栈上的参数。 在大多数调用约定中,堆栈参数由被调用方"拥有",因此他们可以将它们用作本地变量。

但是,不,如果不将目标地址留在内存或寄存器中,就不可能跳到某个地方pop cx/零返回地址/jmp cx可以让您在覆盖内存中的返回地址后模拟ret,但随后它会在寄存器中。

我想也许您可以在 FLAGS 中设置TF(单步模式陷阱标志(,并使用调试中断处理程序在再次禁用 TF 之前执行某些操作(例如返回地址为零(。 但是调试异常帧推送包含该返回地址的 CS:IP,并且从带有iret的调试异常返回

将但请记住:退货地址不是有价值的信息。 您要返回的代码可能已经找到了自己的地址,call +0;pop ax只是调用它自己的函数之一。


在现代 x86 上,有一些方法可以制作受保护的飞地。例如,SGX就是为此而设计的,而SMM(系统管理模式(也是"外部"甚至内核。

或者在保护模式下,您可能在不同的权限域之间进行调用。 通常是用户空间调用内核。您可以通过让内核使用单独的私有内核堆栈来避免信息泄漏。对于多线程系统的安全性是必需的,否则另一个用户空间线程会在内核使用它时修改堆栈内存,从而控制内核返回地址。

为避免系统调用中的信息泄漏;保留所有寄存器,但包含返回值或归零的寄存器除外。 这样,您就不能在寄存器中保留任何内核临时数据。 而且由于您根本没有使用用户空间堆栈,因此这不是问题。

最新更新