【问题标题】:Why does push EBX result in pop ESI为什么 push EBX 会导致 pop ESI
【发布时间】:2019-06-14 22:05:10
【问题描述】:

我拿起了《实用逆向工程》这本书,在第 14 页(x86 汇编)上有以下示例:

mov eax, 0AAAAAAAh
mov ebx, 0BBBBBBBh
push eax
push ebx
pop esi
pop edi

现在,我将 eax 和 ebx 推入堆栈,但我弹出堆栈的 esi 和 edi。这是为什么?我以为我会推送和弹出相同的寄存器。

【问题讨论】:

  • 你可以弹出到任何你想要的寄存器(或内存)。堆栈不会跟踪值是如何到达那里的。这个技巧通常出现在针对大小优化的利用代码中,而不是使用更多字节的mov
  • 啊啊! pop esi 告诉 pop 的目的地。我认为您必须指定要弹出的内容。但现在我发现这毫无意义,因为您只能弹出堆栈顶部的内容。谢谢!
  • 是的,push/pop/call/ret 与普通的内存存储/加载非常相似,除了那些指令隐式使用 esp 值作为“栈顶指针”,因此很自然地将它们用于“LIFO” "(后进先出)类型的队列。但是您应该能够识别它背后的简单内存操作(尽管比尝试通过 sub esp,4 mov [esp],eax 而不是 push eax 来复制它更原子)
  • @Jester:它仅在 x86-64 长模式下保存字节以复制 64 位寄存器,例如 push rbx / pop rdi(1 + 1 字节)与 mov rdi, rbx(3 字节:REX +操作码 + modrm)。在 32 位代码中,复制带有 mov esi,ebx 的寄存器仍然只有 2 个字节。也许您正在考虑将寄存器设置为一个小的立即数,例如 push 1 / pop eax(2 + 1 个字节)与 mov eax, 1(5 个字节,因为没有可用的 mov r/m32,sign_extended_imm8 编码)。
  • 你推送的是值,而不是寄存器。这些值通常来自来自寄存器,但即使这样也不是必需的。您在此处弹出 寄存器。

标签: assembly x86


【解决方案1】:

您不推送寄存器,而是推送这些寄存器中保存的。在这种情况下,值来自寄存器eaxebx。寄存器本身保持在原来的位置(CPU 内部的某个位置)。

您可以将这些值弹出到任何寄存器中,例如此处的esiedi。这仅取决于您的代码中的哪个位置以及您需要这些值的寄存器。

有时您只想从堆栈中清除几个值。那你可以做

pop esi   ; or whatever register is not in use at the moment
pop esi    

这不会影响任何其他寄存器。(当然,您也可以简单地更改堆栈指针,但这是另一个话题。)

【讨论】:

    【解决方案2】:

    push — 压栈

    push 指令将其操作数放在内存中硬件支持的堆栈的顶部。具体来说,push 首先将 ESP 减 4,然后将其操作数放入地址 (%esp) 处的 32 位位置的内容中。 ESP(堆栈指针)由于 x86 堆栈向下增长而通过 push 递减 - 即堆栈从高地址增长到低地址。

    pop — 从栈中弹出

    pop 指令将 4 字节数据元素从硬件支持的堆栈顶部移除到指定的操作数(即寄存器或内存位置)中。它首先将位于内存位置 (%esp) 的 4 个字节移动到指定的寄存器或内存位置,然后将 ESP 递增 4。

    查看更多详情:push / pop explanation

    【讨论】:

      【解决方案3】:

      当您pop 堆栈时,寄存器操作数只接收堆栈顶部的值。只要相同数量的字节被压入和弹出,栈是平衡的,不管字节去哪里。您不一定需要将 pop 返回到之前的 pushed 值的来源相同的位置。

      例如,此代码使用当前在eax 中的任何内容加载寄存器ecx,而不会错位堆栈:

      push eax
      pop ecx
      

      您还可以通过手动调整堆栈指针来执行有效的“无操作数”pop

      push eax
      ...
      add esp, 4 ; Discard 32-bits on top of stack 
      ; Stack is now balanced (assuming the intermediate instructions did not misalign the stack)
      

      【讨论】:

        猜你喜欢
        • 2013-11-22
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-07
        相关资源
        最近更新 更多