回答您问题的第 2 部分:根据您正在制作的系统调用,您可能必须将一个值放入esp
(作为 arg 数组)。如果这是 shellcode 的结尾,那么你很好。但是,如果 shell 代码还有更多内容,而您碰巧做了 apush
并且碰巧指向了其余 shellcode 中的esp
某个地方,那么您可能会遇到麻烦(因为此时您将编写自己的指令)。sub $0x99, %esp
一个简单的解决方法是在 shellcode 的开头做一些事情。
编辑(回应评论)
也许我误解了你的问题。当您说“堆栈溢出”时,我认为您的意思是缓冲区溢出。如果我假设正确,请继续阅读。假设您确实在谈论经典的破坏堆栈类型的利用(根据您链接到的图片似乎就是这种情况),那么您正在用nop
雪橇填充缓冲区,shellcode
最后覆盖返回指针。外壳代码是“位置无关代码”。这意味着它是一系列指令,无论寄存器、标志等的当前状态如何,都可以执行。
通常,(这也是您发布的链接描述它的方式)您用 nop 填充缓冲区,然后是 shellcode,最后是指向 nop 雪橇中某处的返回地址。执行指令时ret
,地址 in%esp
被弹出%eip
并%esp
增加 4(在 x86 中)。问题是,如果你的 shellcode 有多个指令,这会产生递减push
的副作用。如果你有足够的它们并且你的shellcode一直在最后(即与返回地址相邻),那么你最终可能会用指令覆盖你的shellcode。 %esp
push
所以,要真正回答你的问题。不,没有“机制”可以将你的 shellcode 与“它的堆栈”分开。这是因为您的 shellcode 本身没有堆栈。请记住,它是与位置无关的代码。无论机器状态如何,它都必须能够运行。任何需要进行的堆栈管理都必须由 shellcode 本身执行。这就是为什么如果代码中有很多语句,我建议sub $0x99, %esp
在 shellcode 的开头使用a。push
另一种选择是确保返回地址(%esp-4
将指向)和您的 shellcode 之间有足够的空间。