缓冲区溢出与字节对齐

有学生给我看了如下代码。

-------------  original source code ----------------------------------------

// Sina blog has bug, always stop me from pasting "% s" for formating a string

#include <stdio.h>  
#include <string.h>
#define LEN 3   
int main() 
    
     char str1[LEN] = "\0";     
     char str2[LEN] = "\0";       
     strcpy(str1,"11");
     strcpy(str2,"222222");

    
     printf(" % 10s   ADDR(str1)=%u\n", str1,(unsigned int)(void*)str1); // Sinablog bug    
     printf(" % 10
  ADDR(str2)=%u\n", str2,(unsigned int)(void*)str2);       

     return 0;
}

----------------------------------------------------------------------------

问我,为何在VC6.0中执行结果为

            22   ADDR(str1)=1245052
        222222   ADDR(str2)=1245048

 

    这实际上是字节对齐和缓冲溢出的综合结果。str1,str2两个字符数组都是3个字节大小,

VC编译缺省4字节对齐,str2, str1地址相差4个字节,即比3大的4倍数最小是4,故有:

                 ADDR(str1) = ADDR(str2) + 4,

strcpy(str2,"222222")缓冲溢出后改写了str1, 导致str1被改写成"22".

    事实上,在codepad.org ( actually GCC, also tried GCC 4.5.c under cygwin)上执行结果为

           222   ADDR(str1)=3210942681
        222222   ADDR(str2)=3210942678

 

同样的缓冲区溢出因为没有字节对齐(ADDR(str1)-ADDR(str2) == 3)而导致不同的输出。

此外,VC中因为4字节对齐,导致的缓冲区溢出只占用了本程序的合法空间,所以此时仍旧

是“安全的”,而codepad.org上的GCC因为没有4字节对齐,输入222222后,因为要在

str2+6加个0(即str1+3)加个0,已再次缓冲溢出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值