【发布时间】: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寄存器会减少您推送的字节数。