免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 5216 | 回复: 21
打印 上一主题 下一主题

一道关于段错误笔试题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-10 21:29 |只看该作者 |倒序浏览
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    int i = 1;
    char buf[4];

    strcpy(buf, "AAAA");
    printf("%d\n", i);

    return 0;
}

a) When compiled and executed on x86, why does this program usually not
    output what the programmer intended?

strcpy拷贝结束符('\0')时 因为buf大小为4字节,覆盖了i的最低字节(之前是1) 变为0;
所以输出结果是0


b) Name several ways in which the security problem that causes this
program not to output what the programmer intended can be prevented
WITHOUT changing the code.

但是这道题就不会了, 翻译是不是这样
找出几种可以解决引起上面程序没有按程序员意向输出的安全隐患的预防方法,且不用改变源码(就是上面那程序)

e文差不知道翻译对不对,

求方法(因为我除了该代码(比如说把buf改为buf[5]),就没有别的办法了)

论坛徽章:
0
2 [报告]
发表于 2010-06-10 22:13 |只看该作者

  1. 执行strcpy(buf, "AAAA");前
  2. 栈:
  3.      buf   ->  ?
  4.      buf+1 ->  ?
  5.      buf+2 ->  ?
  6.      buf+3 ->  ?
  7.      i     ->  1

  8. 执行strcpy(buf, "AAAA");后
  9. 栈:
  10.      buf   ->  'A'
  11.      buf+1 ->  'A'
  12.      buf+2 ->  'A'
  13.      buf+3 ->  'A'
  14.      i     ->  0
复制代码
第二个问有点像脑筋急转弯,得想想。

论坛徽章:
0
3 [报告]
发表于 2010-06-10 22:19 |只看该作者
不太明白,为什么x86上会出现这种情况呢

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
4 [报告]
发表于 2010-06-10 22:23 |只看该作者
第二题很有歧义啊……prevent应该是阻止,那么是只是输出1就好了,还是要求同时语义也正确?如果是预防的话,这种代码报错或者报警告就算预防了。而且change the code是全部不许改还是main不许改呢?

论坛徽章:
0
5 [报告]
发表于 2010-06-10 22:26 |只看该作者
不让改源码意思就是从编译入手吧

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
6 [报告]
发表于 2010-06-10 22:29 |只看该作者
应该能通过插入guard的方式来解决,不知道有没有某个编译器选项可以做到的……

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
7 [报告]
发表于 2010-06-10 22:32 |只看该作者
gcc有个-fstack-check的选项,不过只能报错不能prevent(我觉得有改正的含义)。唯一的改正方法恐怕只有加大缓冲区或者在复制的时候采用指定长度的复制。

论坛徽章:
0
8 [报告]
发表于 2010-06-10 22:44 |只看该作者
回复 7# starwing83


gcc -fstack-protector-all 试过了,生成的汇编代码里i和buf还是连续的(x86 & x86_64),这种错没有破坏堆栈,只改了局部变量,堆栈保护功能查不出来的。

我的思路是让编译器生成代码时,让i成为寄存器变量,不分配展空间的话,strcpy就能破坏栈框,就能检查出来了。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
9 [报告]
发表于 2010-06-10 22:47 |只看该作者
?我用了-fstack-check选项就检查出来了啊……

gcc -fstack-check test.c

寄存器变量的话……邪恶地:-Dint=register\ int不知道行不行……

论坛徽章:
0
10 [报告]
发表于 2010-06-10 22:48 |只看该作者
第二题很有歧义啊……prevent应该是阻止,那么是只是输出1就好了,还是要求同时语义也正确?如果是预防的话 ...
starwing83 发表于 2010-06-10 22:23



   应该是全部不许改吧



gcc有个-fstack-check的选项,不过只能报错不能prevent(我觉得有改正的含义)。唯一的改正方法恐怕只有加大 ...
starwing83 发表于 2010-06-10 22:32



    gcc的-fstack-check的选项是不是你上面说的插入guard的方式
   不是的话,插入guard的方式是指什么?

   我查了下你说的-fstack-check的选项
   GCC 对内存错误的检查主要依靠 3 个选项: -fstack-check -fbounds-check -fstack-protector-all
   GCC 4.1 以上支持-fstack-protector-all 选项 可以防止缓冲区溢出攻击,也可以利用此选项来检查代码是否有缓冲区溢出的错误
我现在去试试这几个选项
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP