打印字符串字节时出现随机内容?格式字符串漏洞测试疑问
格式字符串漏洞探究疑问解答
测试代码
#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"); // 共31个字符,以适配终止符\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
输出中的随机值来源
你调用的printf只提供了格式字符串,没有传入对应%x的参数,它会直接从栈上读取额外的随机数据。printf的工作逻辑是:根据格式符%x,从栈帧里依次取出4字节(32位系统下)数据打印。当格式符数量超过传入的参数数量时,它会继续往栈的更高地址(当前栈指针上方的区域)读取,这些区域可能是之前函数调用残留的栈数据、保存的寄存器值、栈帧返回地址或者未初始化的栈内存,所以看起来是随机值。
字符串内容位置与预期不符的原因
为什么没看到
63616161:你使用的是小端序系统(绝大多数x86/x86_64设备都是),4字节数据打印时会低字节在前。字符串开头的c(0x63)后面跟着三个a(0x61),内存里的存储顺序是0x63 0x61 0x61 0x61,printf按4字节读取后会倒序输出成61616163,而非大端序的63616161——这是你对字节序的误解导致的预期偏差。为什么字符串内容出现在“随机”位置:
struct1是栈上的局部变量,栈的具体布局由编译器决定。printf在没有参数时,从自身栈帧的位置开始往后读取数据,而struct1的buf和num在栈上的位置,与printf读取的起始位置之间,可能隔着printf自身的栈帧数据(比如返回地址、保存的寄存器),所以输出中间会夹杂随机栈数据,buf里的内容也就被分散在不同位置。另外你设置的p1->num = 43981转十六进制是0xabcd,输出里的abcd就是这个值的打印结果,也能佐证栈读取的顺序。
内容的提问来源于stack exchange,提问作者Mateusz
相关产品推荐
相关产品推荐

