0 0

谁能解释下C语言的strcpy的这个溢出问题呢3

const char * src = "hello";
char dest[1];

strcpy(dest,src);
printf("%s\n",src);
printf("%s\n",dest);

结果是:
             (空行)
hello


问题补充:
我的编译器是vc6,32位机器
C 
2009年9月17日 16:43

3个答案 按时间排序 按投票排序

0 0

我现在没有VC6的编译器了……楼主可以参考这篇文章设置VC6输出汇编文件:http://www.codeproject.com/KB/recipes/compout.aspx
然后阅读输出的汇编来分析。或者把输出的汇编贴到这边来问也好。其实看着汇编来分析很容易,我上面也给出例子了 ^ ^

2009年9月18日 14:34
0 0

JavaEye的语法高亮插件bug又把代码的头两列给吃掉了……可恶
我上面的代码里第16行开头是LOOP:,头两个字母被吃了……

2009年9月17日 23:10
0 0

楼主用的是什么编译器,版本是多少,用了什么编译参数?这些都会影响到结果……

例如说我在x86上用VC9,编译参数为/O2,得到的运行结果就是输出两行hello然后报错。
它编译出来的main函数是这样的:

  ; 在栈上申请char dest[1]的空间。
  ; 虽然它只有1字节,但栈空间都是按字长分配的,每次分配至少一个DWORD,
  ; 所以push任意一个寄存器正好达到esp -= 4
  ; 而dest的起始位置是esp + 3
  push ecx
  
  ; 现在栈的状况是:
  ; 假设esp当前值为S1,则
  ; S1 + 3等于dest的起始地址
  ; S1 + 4开始的DWORD是main的返回地址
  ; 再下面就是前一个栈帧的内容了
  
  ; 以下是strcpy的展开
  ; 循环计数器清零
  xor  eax, eax
LOOP:
  ; 把src字符串里的下标为eax的字节复制到cl
  mov  cl , byte ptr [eax + &src]
  ; 把那个字节再从cl复制到dest的下标为eax的位置
  mov  byte ptr [esp + eax + 3], cl
  ; 检查是否遇到字符串结尾的'\0'
  test cl, cl
  ; 还没到结尾就继续循环
  jne  LOOP
  ; strcpy结束
  
  ; 循环结束后,dest[0]为'h',
  ; 而dest[1]到dest[4]正好跟原本保存返回地址的那个DWORD重叠了,
  ; 所以返回地址被改写为"ello"对应的整数,在little-endian的x86上
  ; "ello"对应的是0x6F6C6C65
  
  ; 调用printf("%s\n", src)
  push &src
  push &format_string
  call &printf
  
  ; 注意C标准库的函数的调用序列是cdecl,由调用方做栈平衡,
  ; 现在栈的状况是:
  ; 假设esp当前值为S2,则S2 == S1 + 4*2(因为push了两次,每次+4)
  ; 则dest的起始地址为S1 + 3 == S2 + 11
  
  ; 调用printf("%s\n", dest)
  ; 将dest的地址加载到eax中
  lea  eax, dword ptr [esp + 0bh]
  push eax
  push &format_string
  call &printf
  
  ; 返回值清0
  xor  eax, eax
  ; 恢复栈平衡
  add  esp, 014h
  ; 返回
  ret


如果用GCC的话,栈的布局会有点不同。GCC 3.x和GCC 4.x都会在栈上放所谓的“cookie”,位于每个返回地址的“上面”。所以溢出后的表现会跟VC的不同。楼主可以自己试试去阅读汇编解决疑惑 ^ ^

2009年9月17日 23:08

相关推荐

    C语言源程序的缓冲区溢出漏洞分析及解决方案

    ### C语言源程序的缓冲区溢出漏洞分析及解决方案 #### 概述 缓冲区溢出一直是黑客攻击的重要手段之一,特别是在C/C++程序中尤为常见。这是因为C/C++提供了许多可以直接访问内存底层的函数,如果程序员未能妥善处理...

    C语言程序设计中的缓冲区溢出问题

    ### C语言程序设计中的缓冲区溢出问题 #### 背景介绍 缓冲区溢出是一种常见的安全漏洞,尤其在C语言程序设计中尤为突出。C语言作为一种强大的、灵活的编程语言,在系统软件开发和应用软件开发中都有广泛应用。但...

    c语言缓冲区溢出攻击原理案例视频讲解

    在IT安全领域,缓冲区溢出(Buffer Overflow)是一种常见的软件漏洞,主要存在于C语言及其类似编程语言中。本教程通过视频形式详细讲解了C语言程序的运行时结构以及缓冲区溢出攻击的原理。 首先,C语言程序的运行时...

    缓冲区溢出源码 C语言

    在这个环境下,开发者可以使用C++编译器创建和调试C语言代码,包括涉及缓冲区溢出问题的程序。 **3. 源码分析** 在提供的源码文件中,`wallet.*`、`walletDlg.*`、`Direct.cpp`、`StdAfx.cpp`等文件可能包含了程序...

    C语言 strcpy和memcpy区别详细介绍

    需要注意的是,`strcpy`不会检查目标缓冲区`dest`是否有足够的空间容纳整个源字符串,因此在使用时必须确保目标缓冲区足够大,否则可能导致内存溢出,这是一种常见的安全问题。 举一个简单的例子: ```c char str1...

    缓冲区溢出教程及配套代码

    总的来说,这个教程将帮助学习者全面理解缓冲区溢出的机制,掌握C语言和汇编中的关键知识点,熟悉相关工具的使用,提高安全编程的意识,对于软件开发人员和网络安全爱好者来说是一份宝贵的资源。通过深入学习和实践...

    《你必须知道的495个C语言问题》

    《你必须知道的495个C语言问题》的出版填补了这一空白。许多知识点的阐述都是其他资料中所没有的,弥足珍贵。 涵盖C99标准 目录 ~第1章 声明和初始化 1 基本类型 1 1.1 我该如何决定使用哪种整数类型? 1  ...

    C语言中溢出错误分析和防范.pdf

    《C语言中溢出错误分析和防范》这篇文章探讨了C语言编程中常见的溢出错误及其防范策略。溢出错误是由于程序在分配的内存空间之外写入数据导致的,这通常发生在栈溢出、堆溢出、BSS溢出和格式化串溢出等场景。 1. **...

    你必须知道的495个C语言问题(完整版)

    "你必须知道的495个C语言问题(完整版)"涵盖了C语言学习中的各种重要概念、难点和常见问题,旨在帮助程序员深入理解和熟练掌握这门语言。以下是基于这个主题的几个关键知识点: 1. **基本语法**:C语言的基础包括...

    12个有趣的C语言面试题

    答案:上面代码里的问题在于函数gets()的使用,这个函数从stdin接收一个字符串而不检查它所复制的缓存的容积,这可能会导致缓存溢出。这里推荐使用标准函数fgets()代替。 gets()函数的使用是unsafe的,它不检查缓存...

    C语言源程序的缓冲区溢出漏洞分析及解决方案.pdf

    【C语言源程序的缓冲区溢出漏洞分析及解决方案】 缓冲区溢出是C语言编程中常见的安全漏洞,主要发生在程序处理数据时,当向固定大小的缓冲区写入超过其容量的数据时,超出的数据会覆盖相邻内存区域,可能导致程序...

    c语言实现歌词社区

    在本项目中,"c语言实现歌词社区"是一个利用C语言编写的系统,旨在创建一个互动的歌词分享和管理平台。这个系统具有用户和管理员两种角色,分别有不同的权限和功能,为用户提供了一个集歌词上传、下载和编辑于一体的...

    C语言写字符串函数及任意个数求和

    C语言标准库中的`strcpy`函数用于将一个字符串复制到另一个字符串中。我们也可以自定义一个函数来实现相同的功能。例如,可以创建一个名为`my_strcpy`的函数,接受两个字符指针参数,然后逐个字符地将源字符串复制...

    <C语言常见问题聚>

    《C语言常见问题聚》是针对C语言编程中经常遇到的问题和难点进行汇集的资源,主要面向初学者和有一定基础的开发者。C语言作为计算机科学的基础语言,其简洁、高效的特点使得它在软件开发领域占有重要地位。然而,...

    strcpy 解析,很有用

    因此,在调用`strcpy`时,可能会导致缓冲区溢出的问题,因为源字符串比目标数组能容纳的字符多。 接下来是第二个示例: ```c void test2() { char string[10], str1[10]; int i; for (i = 0; i ; i++) { str1[i...

    strcpy和strncpy区别

    然而,这同时也带来了潜在的风险:如果`dest`的长度不足以容纳完整的`src`字符串,那么`strcpy`操作会导致缓冲区溢出,这是C语言中常见的安全问题之一。 ### strncpy函数详解 与`strcpy`不同,`strncpy`函数提供了...

Global site tag (gtag.js) - Google Analytics