c - 无法理解格式字符串利用代码

标签 c

我在阅读 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 的十六进制表示),即在 4 个地址之上当前 %esp。我也努力盯着汇编代码看,但我想我无法理解堆栈上的字符串操作。

最佳答案

在进入 snprintf 时,堆栈具有以下内容:

0xbfd257d0:     0xxxxxxxxx      0xxxxxxxxx      0xxxxxxxxx      0x080484d5
0xbfd257e0:     0xbfd25800      0x00000200      0xbfd25a00      0x00000000
0xbfd257f0:     0x00000000      0x00000000      0x00000000      0x00000000
0xbfd25800:     0x00000000      0x00000040      0xb7f22f2c      0x00000000
0xbfd25810:     0x00000000      0x00000000      0x00000000      0x00000000

0xbfd25800 -> target (initially 0x00000000 0x00000040 ...)
...        -> garbage
0xbfd257e8 -> pointer to buffer
0xbfd257e4 -> 512
0xbfd257e0 -> pointer to target
0xbfd257df -> return address

targetsnprintf 开始使用其单词作为参数之前被 snprintf 的结果覆盖:它首先写入“AAAA”(0x41414141 ) 在 0xbfd25800,然后“%x”读取 0xbfd257ec 的值并将其写入 0xbfd25804,...,然后“%x”读取 0xbfd25800(0x41414141)的值并将其写入 0xbfd25814,...

关于c - 无法理解格式字符串利用代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6930352/

相关文章:

c - C 中字符串数组出现元素重复的问题

c - Union 的位域使用

c - 以零为条件的 If 语句

c - 如何在 C 中静态断言浮点是 IEEE-754?

c - 如何跨多个函数使用goto

c - 自动 assembly 循环级分析

c - 调用 openssl::i2d_X509 后释放输出缓冲区的正确方法是什么?

c - gcc -O3 选项如何使运行速度如此之快?

c - char如何存储两个数字?

c++ - Arduino有平台宏吗?