我正在尝试堆栈粉碎以跟随我的安全文本。代码如下。现在,我有几个问题,在盯着这个看了几个小时后我无法自己调和,任何解释将不胜感激:
根据 System V x86_64 ABI ( http://www.x86-64.org/documentation/abi.pdf ),参数以相反的顺序被压入堆栈,但 6、5 和 4(c、b 和 a)似乎位于 0x7fffffffdf40,分别为 0x7fffffffdf44 和 0x7fffffffdf48。或者我在看 这是错误的,这些是实际值?我感到困惑的原因是堆栈在内存中向下增长,但是 large_string 首先被声明和初始化但似乎具有比 a、b 或 c (0x7fffffffde40) 更低的地址,如果这些是实际的内存位置。
如果调用 function() 的参数被压入栈中 0x7fffffffdf40 左右,那么返回地址不应该也被压入此处吗?我没有看到与似乎是返回地址的 4、5 或 6 相邻的任何内容,所以我认为这些是实际的变量内存位置?
也许以下内容相距不远?:main() 的框架位于 0x7fffffffdf40,function() 位于 0xfffffffde1c?
代码:
#include <stdio.h>
#include <string.h>
void function_1(char *str, int a, int b, int c){
char buffer[16] = "AAAAAAAAAAAAAAAA";
//
strcpy(buffer, str);
//
}
void function(char *ls, int a, int b, int c){
a -= 3;
b -= 3;
c -= 3;
function_1(ls, a, b, c);
}
int main(){
char large_string[256];
int i;
for(i = 0; i < 255; i++)
large_string[i] = 'A';
int a = 4, b = 5, c = 6;
function(large_string, a, b, c);
}
调试器跟踪信息:
Breakpoint 1, function_1 (str=0x7fffffffde40 'A' <repeats 200 times>..., a=1, b=2, c=3) at test.c:7
7 strcpy(buffer, str);
(gdb) print main
$1 = {int ()} 0x4005ab <main>
(gdb) print function
$2 = {void (char *, int, int, int)} 0x400573 <function>
(gdb) print function_1
$3 = {void (char *, int, int, int)} 0x40052d <function_1>
(gdb) x /500xg 0x7fffffffdd00
0x7fffffffdd00: 0x00007fffffffdd80 0x000000006562b026
0x7fffffffdd10: 0x0000000000000000 0x0000000000000001
0x7fffffffdd20: 0x00007ffff7ffe788 0x00007ffff7de4678
0x7fffffffdd30: 0x0000000000000000 0x00007fffffffdd70
0x7fffffffdd40: 0x00007ffff7ffa160 0x00007fffffffde80
0x7fffffffdd50: 0x00007ffff7ffa1d8 0x00007fffffffde70
0x7fffffffdd60: 0x0000000000000000 0x00007ffff7de3e9c
0x7fffffffdd70: 0x0000000000000000 0x00000000f63d4e2e
0x7fffffffdd80: 0x0000000000000001 0x0000000000000003
0x7fffffffdd90: 0x00007ffff7ff99c8 0x00007ffff7de4816
0x7fffffffdda0: 0x0000000000000000 0x00007fffffffdde0
0x7fffffffddb0: 0x00007ffff7a18d28 0x00007fffffffdef0
0x7fffffffddc0: 0x00007ffff7a251a8 0x0000000003d8f538
0x7fffffffddd0: 0x00007fffffffdee0 0x00000003f7ffeae8
0x7fffffffdde0: 0x0000000100000002 0x00007fffffffde40
0x7fffffffddf0: 0x4141414141414141 0x4141414141414141
0x7fffffffde00: 0x00007fffffffde30 0x00000000004005a9
0x7fffffffde10: 0x0000000100000000 0x0000000300000830
0x7fffffffde20: 0x0000000100000002 0x00007fffffffde40
0x7fffffffde30: 0x00007fffffffdf50 0x0000000000400606
0x7fffffffde40: 0x4141414141414141 0x4141414141414141
0x7fffffffde50: 0x4141414141414141 0x4141414141414141
0x7fffffffde60: 0x4141414141414141 0x4141414141414141
0x7fffffffde70: 0x4141414141414141 0x4141414141414141
0x7fffffffde80: 0x4141414141414141 0x4141414141414141
0x7fffffffde90: 0x4141414141414141 0x4141414141414141
0x7fffffffdea0: 0x4141414141414141 0x4141414141414141
0x7fffffffdeb0: 0x4141414141414141 0x4141414141414141
0x7fffffffdec0: 0x4141414141414141 0x4141414141414141
0x7fffffffded0: 0x4141414141414141 0x4141414141414141
0x7fffffffdee0: 0x4141414141414141 0x4141414141414141
0x7fffffffdef0: 0x4141414141414141 0x4141414141414141
0x7fffffffdf00: 0x4141414141414141 0x4141414141414141
0x7fffffffdf10: 0x4141414141414141 0x4141414141414141
0x7fffffffdf20: 0x4141414141414141 0x4141414141414141
0x7fffffffdf30: 0x4141414141414141 0x0041414141414141
---Type <return> to continue, or q <return> to quit---
0x7fffffffdf40: 0x0000000500000006 0x000000ff00000004
0x7fffffffdf50: 0x0000000000000000 0x00007ffff7a36ec5
0x7fffffffdf60: 0x0000000000000000 0x00007fffffffe038
0x7fffffffdf70: 0x0000000100000000 0x00000000004005ab
0x7fffffffdf80: 0x0000000000000000 0x9222f893ea203108
0x7fffffffdf90: 0x0000000000400440 0x00007fffffffe030
0x7fffffffdfa0: 0x0000000000000000 0x0000000000000000
0x7fffffffdfb0: 0x6ddd076c54e03108 0x6ddd17d536da3108
0x7fffffffdfc0: 0x0000000000000000 0x0000000000000000
0x7fffffffdfd0: 0x0000000000000000 0x0000000000400610
0x7fffffffdfe0: 0x00007fffffffe038 0x0000000000000001
0x7fffffffdff0: 0x0000000000000000 0x0000000000000000
0x7fffffffe000: 0x0000000000400440 0x00007fffffffe030
0x7fffffffe010: 0x0000000000000000 0x0000000000400469
0x7fffffffe020: 0x00007fffffffe028 0x000000000000001c
0x7fffffffe030: 0x0000000000000001 0x00007fffffffe359
0x7fffffffe040: 0x0000000000000000 0x00007fffffffe384
0x7fffffffe050: 0x00007fffffffe38f 0x00007fffffffe3a1
0x7fffffffe060: 0x00007fffffffe3b4 0x00007fffffffe3ca
0x7fffffffe070: 0x00007fffffffe3e0 0x00007fffffffe3f6
0x7fffffffe080: 0x00007fffffffe406 0x00007fffffffe411
0x7fffffffe090: 0x00007fffffffe461 0x00007fffffffe49a
0x7fffffffe0a0: 0x00007fffffffe4a6 0x00007fffffffe9c7
0x7fffffffe0b0: 0x00007fffffffe9f6 0x00007fffffffea27
0x7fffffffe0c0: 0x00007fffffffea33 0x00007fffffffea5e
0x7fffffffe0d0: 0x00007fffffffea73 0x00007fffffffebcc
0x7fffffffe0e0: 0x00007fffffffebe1 0x00007fffffffebec
0x7fffffffe0f0: 0x00007fffffffebfd 0x00007fffffffec27
0x7fffffffe100: 0x00007fffffffec42 0x00007fffffffec56
0x7fffffffe110: 0x00007fffffffec60 0x00007fffffffec71
0x7fffffffe120: 0x00007fffffffec88 0x00007fffffffecbc
0x7fffffffe130: 0x00007fffffffecc8 0x00007fffffffecd1
0x7fffffffe140: 0x00007fffffffece5 0x00007fffffffeced
0x7fffffffe150: 0x00007fffffffecff 0x00007fffffffed0e
0x7fffffffe160: 0x00007fffffffed33 0x00007fffffffed51
0x7fffffffe170: 0x00007fffffffed6c 0x00007fffffffed7e
---Type <return> to continue, or q <return> to quit---q
Quit
最佳答案
我不确定你从哪里得到的参数被压入堆栈。当然,有些论点是,但不是你的情况。四个参数,全部为 64 位或更小,在寄存器中传递。
您在堆栈上看到的参数不是传递给 function_1
的参数。它们是传递给 function
的参数,存储在堆栈中,因此它可以将它们传递给 function_1
。根据证据,我假设您在此处进行编译而没有进行优化,否则您根本看不到任何函数调用。
我相信您的其他误解可以立即得到解决。
关于C 堆栈帧跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37638037/