缓冲区溢出

扫码查看
MAC OS上 结果: 0 32 48
Win7 VS2005上:24 32 48

  1. #include "stdafx.h"
  2. #include <stdio.h>

  3. int main(int argc,char* argv)
  4. {
  5.    int var1=0;
  6.    char var2=0;
  7.    int var3=0;
  8.    char str_val1[]="24\n";
  9.    char str_val2[]="32\n";
  10.    char str_val3[]="48\n";
  11.    sscanf(str_val1,"%d",&var1);
  12.    sscanf(str_val2,"%d",&var2);
  13.    sscanf(str_val3,"%d",&var3);
  14.    printf("var1=%d,var2=%d,var3=%d\n",var1,var2,var3);
  15.    return 0;
  16. }
  17. /*
  18. 不同的编译器可能有不同的结果,加上优化选项也可能有不同的结果,之所以有这样的结果是因为
  19. 缓冲区溢出, sscanf(str_val2,"%d",&var2)中的var2是char,只占一个字节,当作为%d格式
  20. 的时候实际写了4个字节,声明的时候var1在var2前面,所以就把var1覆盖了3个字节,这和机器
  21. 堆栈的生长方向也有关,如果栈是向上生长的就没有这种效果,还和str_var的值有关,var1太大
  22. 就不会被覆盖完(不等于0),var2太大就会影响var1(值不一定),如果编译的时候加了优化选项
  23. (gcc -O),作为速度优化,编译器会把变量按机器字对齐,也没有这种效果,总之,缓冲区溢出这
  24. 种东西很麻烦,搞不清结果会是什么。
  25. */

缓冲区溢出-LMLPHP
如上图, 三个变量分配的起始地址分别为0x7fff5fbffb3c, 0x7fff5fbffb3b, 0x7fff5fbffb34


  1. /* 地址末两位 */
  2. 3C 3D 3E 3F var1 3C: 起始地址
  3. 38 39 3A 3B var2 3B: 起始地址
  4. 34 35 36 37 var3 34: 起始地址
  5. 第一:不明白为啥 var2不分配在38起始
  6. 第二:既然分配了在3B起始, 为啥前面的38,39,3A都留空了?
  7. 因为var3分配到了34

  8. 这样如果在var2地址,也就是3B处写入%d的数据,那么3B 3C 3D 3E都会被覆盖
  9. 所以var1也就为0了. VS2005并没有覆盖,可能需要一个较大的数才能覆盖



MAC OS 和Win7 VS2005上地址情况时类似的,如果var2写入四个字节都会覆盖var1,
但是奇怪的是两者输出结果并不一样,VS2005的并没有截图。






10-23 21:59
查看更多