免费注册 查看新帖 |

Chinaunix

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

aix中,变量怎么会这样? [复制链接]

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-08 14:22 |只看该作者 |正序浏览
int main()
{
   char b[5];
   strcpy(b,"Hello,Aix");
   printf("b is %s",b);
}

b is Hello,Aix

运行上面竟然不会报错??怎么会这样?难道aix帮这个变量增加了空间?

论坛徽章:
0
31 [报告]
发表于 2008-05-13 00:16 |只看该作者
原帖由 chenzhanyiczy 于 2008-5-8 15:33 发表
我从来不敢这么自信,即使能达到你这样的水平。没错,这个问题是很低级,但自己也是从这样的错误中锻炼出来的

测试时链接efence库, 能保证一旦越界必core dump. 测试完毕后重新链接即可.

论坛徽章:
0
30 [报告]
发表于 2008-05-11 22:30 |只看该作者
原帖由 zx_wing 于 2008-5-11 19:56 发表

我告诉你这种BUG怎么调。
当你的系统出现异常的时候,用调试器从出错的地方一个函数一个函数的往前跟,你会最终会发现在有一点上某个内存地址的值异常了。在这个地址上停一个写断点。重新运行你的程序,当溢 ...

这个方法真是不错。还没有试过这样调试的。以后可以试试!:wink:

论坛徽章:
0
29 [报告]
发表于 2008-05-11 19:56 |只看该作者
原帖由 chenzhanyiczy 于 2008-5-8 14:55 发表
假设一个上几万行得程序,虽然有这个bug,但测试时,都是输出正确得结果,那没可能还要一个个去检查吧

我告诉你这种BUG怎么调。
当你的系统出现异常的时候,用调试器从出错的地方一个函数一个函数的往前跟,你会最终会发现在有一点上某个内存地址的值异常了。在这个地址上停一个写断点。重新运行你的程序,当溢出覆盖到这个地址时,写断点就停住了,你就可以找到溢出的地方。
不仅是几万行的程序,上百万行的程序也是这么调的。

论坛徽章:
0
28 [报告]
发表于 2008-05-11 19:39 |只看该作者
定义字符数组时,我也验证过几种unix系统(包括linux)都会按4的倍数分配空间。
但是写出这样的代码,说明还是新新新手

论坛徽章:
0
27 [报告]
发表于 2008-05-10 20:21 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
26 [报告]
发表于 2008-05-09 22:34 |只看该作者
上面的错了,理论上会覆盖返回地址,但是gcc的编译器通常会自作多情。比如
#include <stdio.h>

void foo(void)
{
   char b[5];
   
   strcpy(b,"Hello,Aix");
   printf("b is %s",b);
}

int main(int argc, char *argv[])
{
   foo();

   return 0;
}
对应的汇编是:
        .file        "a.c"
        .text
LC0:
        .ascii "Hello,Aix\0"
LC1:
        .ascii "b is %s\0"
.globl _foo
        .def        _foo;        .scl        2;        .type        32;        .endef
_foo:
        pushl        %ebp
        movl        %esp, %ebp
        subl        $24, %esp;b只有5个字节却要分给他24个字节的保留空间;而其当我把5改成25后,这里的24变成了40
        subl        $8, %esp
        pushl        $LC0
        leal        -24(%ebp), %eax
        pushl        %eax
        call        _strcpy
        addl        $16, %esp
        subl        $8, %esp
        leal        -24(%ebp), %eax
        pushl        %eax
        pushl        $LC1
        call        _printf
        addl        $16, %esp
        leave
        ret
        .def        ___main;        .scl        2;        .type        32;        .endef
.globl _main
        .def        _main;        .scl        2;        .type        32;        .endef
_main:
        pushl        %ebp
        movl        %esp, %ebp
        subl        $8, %esp
        andl        $-16, %esp
        movl        $0, %eax
        movl        %eax, -4(%ebp)
        movl        -4(%ebp), %eax
        call        __alloca
        call        ___main
        call        _foo
        movl        $0, %eax
        leave
        ret
        .def        _printf;        .scl        2;        .type        32;        .endef
        .def        _strcpy;        .scl        2;        .type        32;        .endef


因为栈sp指针的东西总是要是4的倍数的,所以我把第12行的$24改成了$8之后,编译这个汇编文件的到的可执行文件输出是:
C:\EP_Backup>a
b is ?@
C:\EP_Backup>

我实在WindowsXP 上用MingW带的gcc编译的

论坛徽章:
0
25 [报告]
发表于 2008-05-09 22:19 |只看该作者
void foo()
{
   char b[5];
   strcpy(b,"Hello,Aix");
   printf("b is %s",b);
}

int main()
{
   foo();
   return 0;
}

这样试一下,
字符串应该就会覆盖到返回低地址了

[ 本帖最后由 sanbiangongzi 于 2008-5-9 22:25 编辑 ]

论坛徽章:
0
24 [报告]
发表于 2008-05-09 20:38 |只看该作者
会不会溢出是编译器决定的,跟AIX有什么关系

论坛徽章:
0
23 [报告]
发表于 2008-05-09 10:34 |只看该作者
原帖由 safedead 于 2008-5-8 18:28 发表
以前在C/C++看过一篇关于字符串常量的老生常谈文字
据说AIX默认允许覆盖字符串常量

比如
char *a = "abcd";
char *b = "efgh";
strcpy(a, b);
是允许的

如果真的是这样
移植起来就会要人命


编译时候指定 -qro 就可以
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP