【问题标题】:Why does the push instruction change the value of rsp? [duplicate]为什么 push 指令会改变 rsp 的值? [复制]
【发布时间】:2021-01-28 05:09:47
【问题描述】:

我正在检查 Ericksons Hacking: The Art of Exploitation 中的这段代码 sn-p:

void test_function(int a, int b, int c, int d) {
        int flag;
        char buffer[10];
        flag = 31337;
        buffer[0] = 'A';
}

int main() {
        test_function(1, 2, 3, 4); 
}
gcc -g stack_example.c

gdb -q ./a.out

gef➤list main


     0x555555555192 <main+0>         endbr64 
       0x555555555196 <main+4>         push   rbp
       0x555555555197 <main+5>         mov    rbp, rsp
     → 0x55555555519a <main+8>         mov    ecx, 0x4
       0x55555555519f <main+13>        mov    edx, 0x3
       0x5555555551a4 <main+18>        mov    esi, 0x2
       0x5555555551a9 <main+23>        mov    edi, 0x1
       0x5555555551ae <main+28>        call   0x555555555149 <test_function>
       0x5555555551b3 <main+33>        mov    eax, 0x0

我在 main 和 test_function 处设置断点。 当 break main 我得到以下输出:

gef➤  i r rsp rbp rip

    rsp            0x7fffffffdfc8      0x7fffffffdfc8
    rbp            0x0                 0x0
    rip            0x555555555192      0x555555555192 <main>
gef➤ x/8i $rip

       0x555555555192 <main>:   endbr64 
       0x555555555196 <main+4>: push   rbp
       0x555555555197 <main+5>: mov    rbp,rsp
       0x55555555519a <main+8>: mov    ecx,0x4
       0x55555555519f <main+13>:    mov    edx,0x3
       0x5555555551a4 <main+18>:    mov    esi,0x2
       0x5555555551a9 <main+23>:    mov    edi,0x1
       0x5555555551ae <main+28>:    call   0x555555555149 <test_function>

gef➤continue

现在,当我在 test_function 处中断时,寄存器包含:

gef➤  i r rsp rbp rip

    **rsp            0x7fffffffdfc0      0x7fffffffdfc0**
    **rbp            0x7fffffffdfc0      0x7fffffffdfc0**
    rip            0x55555555519a      0x55555555519a <main+8>

我的问题是,为什么在这些指令之后寄存器 rsp 从0x7fffffffdfc8 变为0x7fffffffdfc0

    0x555555555196 <main+4>         push   rbp
    0x555555555197 <main+5>         mov    rbp, rsp

【问题讨论】:

  • 因为 push 会将某些东西推入堆栈。
  • 是的,但为什么它改变了 8?我仍然缺少一些东西。
  • @MiroslavSavel 你知道“将东西推入堆栈”是什么意思吗?你知道rsp中的“sp”是什么意思吗?
  • 它指向栈顶?
  • @MiroslavSavel 记得 64 位是 8 字节,所以是的。 rsp 寄存器会减少您推送的字节数。

标签: c assembly x86-64


【解决方案1】:

指令push rbp 完成与sub rsp, 8; mov QWORD PTR[rsp], rbp; 相同的操作。它首先将堆栈指针 (rsp) 向上移动 8 个字节(这是因为 x86-64 中寄存器的大小是 8 个字节,即 64 位),然后将寄存器的值移动到它指向的内存位置。所以rsp的值,原来是0x7fffffffdfc8,变成了0x7fffffffdfc0,比原来少了8。

【讨论】:

  • sub 不是一个准确的解释,因为push 不会改变标志。 lea rsp, [rsp - 8] 更近了。
猜你喜欢
  • 2012-04-03
  • 1970-01-01
  • 2018-07-28
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2015-11-22
  • 1970-01-01
相关资源
最近更新 更多