Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 大会如何知道在哪里返回?_Assembly_X86 - Fatal编程技术网

Assembly 大会如何知道在哪里返回?

Assembly 大会如何知道在哪里返回?,assembly,x86,Assembly,X86,我目前正试图了解IA32体系结构中的组装。在运行缓冲区溢出攻击代码之前,我一直认为我理解了堆栈结构,该代码将返回地址推到堆栈顶部,然后返回。然后,令我惊讶的是,程序返回到我推到堆栈上的那个地址。我最初认为基指针将用于返回,因为它正好位于返回地址的旁边。但是,我没有触碰基本指针。那么,汇编如何知道返回到哪里呢 谢谢。ret指令只是弹出堆栈顶部的任何内容,并将其用作返回地址。没有什么新奇的事情发生。如果您没有跟踪堆栈大小,并且在堆栈顶部不是正确的返回地址的上下文中碰巧在错误的时间执行ret,则您有一

我目前正试图了解IA32体系结构中的组装。在运行缓冲区溢出攻击代码之前,我一直认为我理解了堆栈结构,该代码将返回地址推到堆栈顶部,然后返回。然后,令我惊讶的是,程序返回到我推到堆栈上的那个地址。我最初认为基指针将用于返回,因为它正好位于返回地址的旁边。但是,我没有触碰基本指针。那么,汇编如何知道返回到哪里呢


谢谢。

ret指令只是弹出堆栈顶部的任何内容,并将其用作返回地址。没有什么新奇的事情发生。如果您没有跟踪堆栈大小,并且在堆栈顶部不是正确的返回地址的上下文中碰巧在错误的时间执行ret,则您有一个错误。

ret指令只会弹出堆栈顶部的内容,并将其用作返回地址。没有什么新奇的事情发生。如果您没有跟踪堆栈大小,并且在堆栈顶部不是正确的返回地址的上下文中在错误的时间执行ret,那么您就有一个bug。

x86有几种返回方法

最简单的是RET指令。这将从堆栈中获取当前地址,并将其放入EIP和voila中

因为x86体系结构是CISC,所以它也有扩展的特性,所以您有一个带有大小参数的RET。此命令用于在返回后运行ADD到堆栈后替换基本RET指令:

RET 16
-- becomes
RET
ADD 16, esp
这允许您在返回的同时编写一条指令来取消参数变量。在这种情况下,调用约定非常重要,因为调用方负责在堆栈上添加参数变量,而被调用方将它们从堆栈中删除

因为x86处理器附带所谓的段,所以有一条RET指令将从堆栈中检索段和IP地址。您现在每天都不在常规程序中使用此指令,因为内存模型足够大,可以避免它,但它是可用的。这被称为远网

此外,英特尔处理器支持4级保护,因此内核可以受到用户程序无法访问的保护,而驱动程序也可以驻留在单独的保护级别中,以避免驱动程序损坏内核。RET指令也可用于在这些级别之间切换。再次在堆栈上找到信息

最后,对于中断处理程序也有一个特殊情况。在一个标准程序中,你永远看不到那些只在内核中使用的程序。每当处理器产生中断时,就会调用一个特殊的处理程序。该处理程序必须返回特殊的IRET指令中断返回。这一个也从堆栈中获取数据,但是它保存了更多的信息,比如寄存器和状态标志

ESP -> +-------+
       |  ...  |  <-- local variables
EBP -> |  ...  |  <-- previous frame pointer (EBP)
       |  ...  |  <-- registers that cannot be modified are saved here
       |  EIP  |  <-- IP address saved by CALL instruction
       |  ...  |
       |  ...  |  <-- parameters to your function
       +-------+
       |  ...  |  <-- local variables of caller
EBP -> |  ...  |  <-- previous frame pointer (EBP)
       .........

x86有几种返回方法

最简单的是RET指令。这将从堆栈中获取当前地址,并将其放入EIP和voila中

因为x86体系结构是CISC,所以它也有扩展的特性,所以您有一个带有大小参数的RET。此命令用于在返回后运行ADD到堆栈后替换基本RET指令:

RET 16
-- becomes
RET
ADD 16, esp
这允许您在返回的同时编写一条指令来取消参数变量。在这种情况下,调用约定非常重要,因为调用方负责在堆栈上添加参数变量,而被调用方将它们从堆栈中删除

因为x86处理器附带所谓的段,所以有一条RET指令将从堆栈中检索段和IP地址。您现在每天都不在常规程序中使用此指令,因为内存模型足够大,可以避免它,但它是可用的。这被称为远网

此外,英特尔处理器支持4级保护,因此内核可以受到用户程序无法访问的保护,而驱动程序也可以驻留在单独的保护级别中,以避免驱动程序损坏内核。RET指令也可用于在这些级别之间切换。再次在堆栈上找到信息

最后,对于中断处理程序也有一个特殊情况。在一个标准程序中,你永远看不到那些只在内核中使用的程序。每当处理器产生中断时,就会调用一个特殊的处理程序。该处理程序必须返回特殊的IRET指令中断返回。这一个也从堆栈中获取数据,但是它保存了更多的信息,比如寄存器和状态标志

ESP -> +-------+
       |  ...  |  <-- local variables
EBP -> |  ...  |  <-- previous frame pointer (EBP)
       |  ...  |  <-- registers that cannot be modified are saved here
       |  EIP  |  <-- IP address saved by CALL instruction
       |  ...  |
       |  ...  |  <-- parameters to your function
       +-------+
       |  ...  |  <-- local variables of caller
EBP -> |  ...  |  <-- previous frame pointer (EBP)
       .........

汇编是一种语言。它什么都不知道。CALL将EIP寄存器值推送到堆栈上。RET恢复它。如果你的书没有解释这一点,那就另找一本书,非常基本
返回时不使用EBP基指针。返回地址是堆栈顶部的任何值。EBP只是一个“助手”,子例程可以使用它来更容易地查找参数和本地堆栈变量Assembly是一种语言。它什么都不知道。CALL将EIP寄存器值推送到堆栈上。RET恢复它。如果你的书没有解释这一点,那就另找一本书,这是非常基本的东西。返回时不使用EBP基指针。返回地址是堆栈顶部的任何值。EBP只是一个“助手”,子例程可以使用它来更容易地查找参数和局部堆栈变量