【发布时间】:2011-02-09 14:42:23
【问题描述】:
我一直在阅读一个可以覆盖其返回地址的函数。
void foo(const char* input)
{
char buf[10];
//What? No extra arguments supplied to printf?
//It's a cheap trick to view the stack 8-)
//We'll see this trick again when we look at format strings.
printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n% p\n\n"); //%p ie expect pointers
//Pass the user input straight to secure code public enemy #1.
strcpy(buf, input);
printf("%s\n", buf);
printf("Now the stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
}
有人建议这就是堆栈的样子
foo的地址=00401000
我的堆栈如下所示:
00000000
00000000
7FFDF000
0012FF80
0040108A
00410EDE
问题:
-。为什么作者随意选择倒数第二个值作为 foo() 的返回地址?
-。值是从底部还是从顶部添加到堆栈中?
- 除了函数返回地址,我显然在堆栈上看到的其他值是什么?即为什么不填零
谢谢。
【问题讨论】:
-
这取决于您使用的 CPU(系列),也取决于 ABI。您可能应该适当地标记您的问题,以便清楚您在这里谈论的是什么(我猜是 Linux 或 Windows 上的 x86 ?)。
-
这也取决于编译器。较新版本的 Visual Studio 和 GCC 对堆栈重新排序以使此类攻击更加困难。如果
buf位于返回地址之后,则需要一个缓冲区underflow 来覆盖返回地址。而且下溢的情况要少得多。