我正在尝试了解格式字符串错误是如何工作的,并尝试自己探索它。
这是一个简单的程序:
#include"stdio.h"
#include"string.h"
struct mystruct{
char buf[32];
int num;
};
typedef struct mystruct *mys;
void myfunction2(){
struct mystruct struct1;
mys p1 = &struct1;
p1->num = 43981;
strcpy(p1->buf,"caaaaaaaaaaaaaaaaaaaaaaaaaaaaac"); // there are 31 characters in order to fit the \0
printf("%x %x %x %x %x %x %x %x %x %x %x %x");
}
int main(int argc, char *argv[]){
myfunction2();
return 0;
}
输出:
61616161 61616163 61616161 ff78bf10 ff7b6040 61616163 61616161 61616161 61616161 abcd fffedfb0 fffee000
“ff78bf10 ff7b6040”在那里做什么?为什么“61616163”(十六进制的“caaa”)不在字符串的开头和结尾,而是在随机位置?
我希望在字符串的开头和结尾看到
61616163
。
我还预计会出现 63616161
,因为它以 c 开头并以 c 结尾。
我没想到会在字符串字节中间看到随机的东西。
printf("%x %x %x %x %x %x %x %x %x %x %x %x");
要求 printf
打印 12 个 unsigned int
值,但不向其传递这些值。在典型情况下,在没有优化和其他因素干扰的情况下,printf
仍然会从参数应该已传递的位置检索值。
很可能,在您的 C 实现中,前几个参数将在 CPU 寄存器中传递,其余参数将在堆栈上传递。所以
printf
从这些地方获取值。它们保存程序中早期操作剩余的数据。 printf
正在打印此数据,并且它的信息量不是特别大。