g++4.8的堆栈内容
Stack content for g++4.8
我写了一段简单的代码来测试缓冲区溢出:
#include <stdio.h>
#include <string.h>
using namespace std;
int f(int x, int y, char *s){
char buf[4];
strcpy(buf,s);
return 0;
}
int main(int argc, char** argv){
f(2,3,argv[1]);
return 0;
}
然后用gdb(g++4.8.4)编译并查看其执行情况
g++ -g -fno-stack-protector -o bo bo.c
gdb bo
...
b f
r "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
p $rbp // 0x7fffffffdc90
p $rsp // 0x7fffffffdc70
x/20xw $rsp
0x7fffffffdc70: 0xffffe0ef 0x00007fff 0x00000003 0x00000002
0x7fffffffdc80: 0xffffdcb0 0x00007fff 0x00000000 0x00000000
0x7fffffffdc90: 0xffffdcb0 0x00007fff 0x00400585 0x00000000
0x7fffffffdca0: 0xffffdd98 0x00007fff 0x00000000 0x00000002
0x7fffffffdcb0: 0x00000000 0x00000000 0xf7a36ec5 0x00007fff
我的理解是,堆栈向下生长到较低的地址,但看起来这个堆栈帧(从0x7fffffffdc90 - 0x7fffffffdc90
)正在向上生长:参数向上推(s,y,然后x)。为什么?
看起来返回地址(0x00400585)是先推送的。但是后续单词的含义是什么?他们是:
- 是否保存
$rbp$
- 接下来的两个单词是什么
要查看调用f
后堆栈会发生什么,请在gdb:中调用反汇编程序
(gdb) disas
Dump of assembler code for function f(int, int, char*):
0x000000000040052d <+0>: push %rbp
0x000000000040052e <+1>: mov %rsp,%rbp
0x0000000000400531 <+4>: sub $0x20,%rsp
0x0000000000400535 <+8>: mov %edi,-0x14(%rbp)
0x0000000000400538 <+11>: mov %esi,-0x18(%rbp)
0x000000000040053b <+14>: mov %rdx,-0x20(%rbp)
0x000000000040053f <+18>: mov -0x20(%rbp),%rdx
0x0000000000400543 <+22>: lea -0x10(%rbp),%rax
0x0000000000400547 <+26>: mov %rdx,%rsi
0x000000000040054a <+29>: mov %rax,%rdi
=> 0x000000000040054d <+32>: callq 0x400410 <strcpy@plt>
0x0000000000400552 <+37>: mov $0x0,%eax
0x0000000000400557 <+42>: leaveq
0x0000000000400558 <+43>: retq
在调用strcpy
之前,堆栈看起来像(我使用64位格式化而不是32位):
(gdb) x/6xg $rsp
0x7fffffffddb0: 0x00007fffffffe297 0x0000000200000003
0x7fffffffddc0: 0x00007fffffffddf0 0x0000000000000000
0x7fffffffddd0: 0x00007fffffffddf0 0x0000000000400585
所以你可以看到:
0x0000000000400585
—函数f
的返回地址- 就在它旁边
0x00007fffffffddf0
-由0x000000000040052d <+0>: push %rbp
推送到堆栈上 - 接下来的4个值通过
0x0000000000400531 <+4>: sub $0x20,%rsp
- 您可以看到参数
2
和3
在调用strcpy
之前保存在堆栈上(0x0000000200000003
-因为int
只有4字节长)
您还可以从反汇编中推导出堆栈上的其他值。
堆栈的顶部在开头(地址0x7fffffffddb0
),地址变大(例如第三行的0x7fffffffddd0
),因此您可以看到堆栈确实向下增长,但gdb显示为上下颠倒。
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- 你能重载对象变量名本身返回的内容吗
- 如何将内容数组写入文本文件?
- 试图让变量检查数组中的某些内容
- initializer_list中字符串的内容为何为空
- 如何正确显示此堆栈的内容?
- 作者在解释C 中的堆栈和堆时犯了一个错误,或者我正在误读某些内容
- 如何从C++中清除 lua 堆栈中的所有内容
- 无法从堆栈中检索所有内容
- 如何决定堆栈上的内容
- 为什么我无法检查堆栈上的内容
- 如何在不在堆栈上创建任何内容的情况下打印数组的内容
- 捕获堆栈溢出的内容
- 在qt中更改不同堆栈小部件页面中的菜单栏内容
- 如何将内容从一个堆栈移动到另一个堆栈
- std::vectors中的vector取消分配其shared_ptr内容(堆栈实体对象的使用不正确?)
- main函数之前的堆栈内容
- 比较队列和堆栈的内容
- Valgrind几乎对所有内容都给出了错误(警告:客户端切换堆栈?)
- g++4.8的堆栈内容