Assembly 内翻前推

Assembly 内翻前推,assembly,x86,nasm,Assembly,X86,Nasm,当调用发生时,我的理解是调用方的地址被推送到堆栈上,当执行ret时,它跳转到堆栈中弹出的值 如果我推一个值,但忘记弹出它,会发生什么?ret是否会简单地从堆栈中弹出它期望的返回地址,并被堆栈顶部的实际值严重弄错?例如: Function: mov ax, "A" push ax ret call Function 此外,我对普莎和波帕也有同样的疑惑。如果我在push之后推送一个值,那么popa现在在弹出它使用的寄存器数量时是否使用该值,将原始的第一个寄存器保留在堆栈上

当调用发生时,我的理解是调用方的地址被推送到堆栈上,当执行ret时,它跳转到堆栈中弹出的值

如果我推一个值,但忘记弹出它,会发生什么?ret是否会简单地从堆栈中弹出它期望的返回地址,并被堆栈顶部的实际值严重弄错?例如:

Function:
    mov ax, "A"
    push ax
    ret

call Function

此外,我对普莎和波帕也有同样的疑惑。如果我在push之后推送一个值,那么popa现在在弹出它使用的寄存器数量时是否使用该值,将原始的第一个寄存器保留在堆栈上,并将每个寄存器恢复为寄存器+1的值?

堆栈只是一个内存,它无论如何都不会被键入,您始终可以推送一个寄存器并弹出另一个寄存器

ret只是ip寄存器中的一个pop,因此push/ret是实现jmp的一种低效方法。没有任何魔法能与上一次通话相匹配


您甚至可以在不使用push的情况下更改堆栈上的数据,只需使用esp或ebp指针进行更改即可。并确保您可以意外覆盖回信地址。导致程序意外覆盖返回地址是恶意软件使用的一种众所周知的技术。

堆栈只是一个内存,它无论如何都不会被键入,您可以推一个寄存器,然后弹出另一个寄存器

ret只是ip寄存器中的一个pop,因此push/ret是实现jmp的一种低效方法。没有任何魔法能与上一次通话相匹配


您甚至可以在不使用push的情况下更改堆栈上的数据,只需使用esp或ebp指针进行更改即可。并确保您可以意外覆盖回信地址。恶意软件使用的一种众所周知的技术就是导致程序意外覆盖返回地址。

这正是您所说的。请注意,您可以在调试器中尝试这些操作。您完全正确。仅供参考,这就是调用约定通常同时使用堆栈指针(如esp)和ebp的原因。你可以在这里读更多的内容:正如你所说的。请注意,您可以在调试器中尝试这些操作。您完全正确。仅供参考,这就是调用约定通常同时使用堆栈指针(如esp)和ebp的原因。您可以在此处阅读更多内容: