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

时间:2019-11-23 19:58:22

标签: assembly emu8086

我是一个新的汇编程序员,我想知道是否有一种方法可以完全清理堆栈 (来自所有函数参数和函数指针) 预先感谢

1 个答案:

答案 0 :(得分:2)

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

但是请确保可以在返回之前覆盖args在堆栈上。在大多数调用约定中,堆栈args由被调用方“拥有”,因此无论如何它们都可以将它们用作本地var。

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

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

但是请记住:回信地址不是有价值的信息。您要返回的代码已经可以通过call +0找到自己的地址了; pop ax仅调用其自身的功能之一。


在现代x86上,有 种方法来制作受保护的飞地。例如,SGX是为此而设计的,而SMM (System Management Mode)也为此而设计。甚至在内核之外。

或者在保护模式下,您可能在不同的特权域之间进行呼叫。通常是用户空间调用内核。 通过让内核使用单独的专用内核堆栈来避免信息泄漏。在多线程系统中,为了安全起见,这是必需的,否则在内核使用时,另一个用户空间线程会修改堆栈内存,控制内核返回地址。

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