gpt4 book ai didi

c - 栈, esp 寄存器

转载 作者:太空宇宙 更新时间:2023-11-04 01:13:03 28 4
gpt4 key购买 nike

我从一本书中复制了这段代码。在每条评论中,我都放了一个数字,然后问你与该数字评论的代码行相关的问题(1、2、3、4)。希望没事。

1) ESP 指向这些缓冲区值。为什么我们在这里看不到“A”的 0x41????

2) ESP 指向标志变量内存,必须包含 31337,即十六进制的 0x7a69。为什么它包含这个数字 0xbffff89c ???

3) 指向前一个堆栈帧指针,在这种情况下包含正确的地址。

4) 返回地址。也正确。

5) 参数。也正确的值。

那么在 1) 和 2) 中会发生什么?是填充吗?

非常感谢你。

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);
}


GDB debug session
Breakpoint 2, test_function (a=1, b=2, c=3, d=4) at stack_example.c:5
5 flag = 31337;
(gdb) i r esp ebp eip
esp 0xbffff7c0 0xbffff7c0
ebp 0xbffff7e8 0xbffff7e8
eip 0x804834a 0x804834a <test_function+6>
(gdb) disass test_function
Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
0x08048355 <test_function+17>: leave
0x08048356 <test_function+18>: ret
End of assembler dump.
(gdb) print $ebp-12
$1 = (void *) 0xbffff7dc
(gdb) print $ebp-40
$2 = (void *) 0xbffff7c0
(gdb) x/16xw $esp
0xbffff7c0: 0x00000000 0x08049548 0xbffff7d8 0x08048249 // 1
0xbffff7d0: 0xb7f9f729 0xb7fd6ff4 0xbffff808 0x080483b9 // 1
0xbffff7e0: 0xb7fd6ff4 // 1
0xbffff89c // 2
0xbffff808 // 3
0x0804838b // 4
0xbffff7f0: // 4
0x00000001 0x00000002 0x00000003 0x00000004 // 5




reader@hacking:~/booksrc $ gcc -g stack_example.c
reader@hacking:~/booksrc $ gdb -q ./a.out
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) disass main
Dump of assembler code for function main():
0x08048357 <main+0>: push ebp
0x08048358 <main+1>: mov ebp,esp
0x0804835a <main+3>: sub esp,0x18
0x0804835d <main+6>: and esp,0xfffffff0
0x08048360 <main+9>: mov eax,0x0
0x08048365 <main+14>: sub esp,eax
0x08048367 <main+16>: mov DWORD PTR [esp+12],0x4
0x0804836f <main+24>: mov DWORD PTR [esp+8],0x3
0x08048377 <main+32>: mov DWORD PTR [esp+4],0x2
0x0804837f <main+40>: mov DWORD PTR [esp],0x1
0x08048386 <main+47>: call 0x8048344 <test_function>
0x0804838b <main+52>: leave
0x0804838c <main+53>: ret
End of assembler dump
(gdb) disass test_function()
Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
0x08048355 <test_function+17>: leave
0x08048356 <test_function+18>: ret
End of assembler dump
(gdb)

最佳答案

'A'31337 是文字。他们没有理由被放在堆栈上。

如果您打印出该代码块的反汇编以准确查看编译器发出的内容,您会更感兴趣。然后您可以在运行时交叉检查您的堆栈包含的内容。

鉴于您的函数没有副作用,它可以优化为空操作。

这是我在我更熟悉的环境中使用您的代码得到的结果:

Breakpoint 1, test_function (a=1, b=2, c=3, d=4) at t.c:4
4 flag = 31337;
(gdb) disass test_function
Dump of assembler code for function test_function:
0x080483a4 <+0>: push %ebp
0x080483a5 <+1>: mov %esp,%ebp
0x080483a7 <+3>: sub $0x10,%esp
=> 0x080483aa <+6>: movl $0x7a69,-0x4(%ebp)
0x080483b1 <+13>: movb $0x41,-0xe(%ebp)
0x080483b5 <+17>: leave
0x080483b6 <+18>: ret
End of assembler dump.
(gdb) display $ebp
2: $ebp = (void *) 0xffffcd70
(gdb) display $esp
3: $esp = (void *) 0xffffcd60
(gdb) x/16xw $esp
0xffffcd60: 0xf7e7dcdd 0xf7fa7324 0xf7fa6ff4 0x00000000
0xffffcd70: 0xffffcd88 0x080483e1 0x00000001 0x00000002
0xffffcd80: 0x00000003 0x00000004 0xffffcdf8 0xf7e66cc6
0xffffcd90: 0x00000001 0xffffce24 0xffffce2c 0x00000001

除了 ASM 语法之外,与您的情况不同的是,我的编译器在堆栈上保留了较少的松弛部分,仅此而已。

因此,在您的情况下,文字最终出现在指令流 中,而不是出现在堆栈中。局部变量的堆栈地址和内容(解释为 32 位整数,注意字节顺序):

(gdb)  x/1xw $ebp-4
0xffffcd6c: 0x00000000
(gdb) x/1xw $ebp-0xe
0xffffcd62: 0x7324f7e7

现在让我们分配给flag:

(gdb) n
5 buffer[0] = 'A';
(gdb) x/8xw $esp
0xffffcd60: 0xf7e7dcdd 0xf7fa7324 0xf7fa6ff4 0x00007a69
0xffffcd70: 0xffffcd88 0x080483e1 0x00000001 0x00000002
(gdb) x/1xw $ebp-4
0xffffcd6c: 0x00007a69
(gdb) x/1xw $ebp-0xe
0xffffcd62: 0x7324f7e7

很好,正确的堆栈槽已更新($ebp-4 x/8xw 第 1 行的最后 32 位槽)。

然后让我们设置buffer的第一项:

(gdb) n
6 }
(gdb) x/4x $ebp-0xe
0xffffcd62: 0x41 0xf7 0x24 0x73
(gdb) x/8xw $esp
0xffffcd60: 0xf741dcdd 0xf7fa7324 0xf7fa6ff4 0x00007a69
0xffffcd70: 0xffffcd88 0x080483e1 0x00000001 0x00000002
(gdb) x/1xw $ebp-4
0xffffcd6c: 0x00007a69
(gdb) x/1xw $ebp-0xe
0xffffcd62: 0x7324f741

又好了。当以 32 位整数形式查看时,字节顺序让事情看起来有点奇怪,但如果逐字节查看它,它看起来很好。

关于c - 栈, esp 寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7806681/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com