【发布时间】:2011-08-03 17:09:17
【问题描述】:
我在阅读this 文章时遇到了这段代码,显示了格式字符串的利用。
#include <stdio.h>
int main(void)
{
char secret[]="hack.se is lame";
char buffer[512];
char target[512];
printf("secret = %pn",&secret);
fgets(buffer,512,stdin);
snprintf(target,512,buffer);
printf("%s",target);
}
使用以下输入执行它
[root@knark]$ ./a.out
secret = 0xbffffc68
AAAA%x %x %x %x %x %x %x //Input given
AAAA4013fe20 0 0 0 41414141 33313034 30326566
- [root@knark]$
到目前为止,我所了解的是%x 的序列将继续打印当前%esp 以上地址的值(我假设堆栈正在向下向较低地址增长)。
我无法理解的是给定的输入存储在buffer 数组中,该数组与当前%esp 的距离不能小于 512 字节。那么,输出怎么会在 4 个%x 之后包含41414141(AAAA 的十六进制表示),即正好在当前%esp 的 4 个地址之上。我也努力盯着汇编代码看,但我想我无法跟踪堆栈上字符串的操作。
【问题讨论】:
-
我不明白你的命令调用。
~/research/paper是可执行文件吗?我会理解./myprog < inputdata或cat inputdata | ./myprog,但我不明白你在做什么。 -
好的,我明白了。执行
a.out,打印secret = 0xbffffc68,然后等待用户输入。对我来说,这只是将输入回显到最后一行的屏幕,然后退出。~/research/paper只是一个 shell 提示符。 -
@kerrek SB:我很抱歉。为了更清楚,我已将其删除。
-
我没有得到并且需要测试的是
fgets如何从标准输入读取超过 'AAAA' 字节。它应该达到 EOF 而不是实际读出 512 个字节吗?我的意思是当它读取标准输入时,它是否应该得到一个以空结尾的字符串然后是 EOF? -
@Mr. Shickadance:如果遇到换行符,fgets 最多将接下来的 n-1 个字符读取到缓冲区中。
标签: c