Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5760655
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: C/C++

2007-12-24 15:09:07

今天swordlea在紫丁香上贴了一个题目:
发信人: SwordLea (飞刀李), 信区: C_and_CPP
标  题: 一个有趣题目,高手请进
发信站: 紫丁香社区 (Mon Dec 24 10:32:17 2007), 站内

话说是在VC6Debug环境下,要求填补一段代码,使输入与输出一致。

void test()
{
    int t;
    scanf("%d", &t);

   /*
   在这里填写代码……
   */
}

int main()
{
    int m;
    test();
    printf("%d", m);
}

   /*
   在这里填写代码……
   */
}

int main()
{
    int m;
    test();
    printf("%d", m);
}

许多人会说这个题目有错误,或者认为根本不可以实现。如果仔细
看一下题目中的暗示,就会有思路了。
--
    俺是个原始人,喜欢到处穷溜达。有天逛到一个黑不溜秋的地方,觉得很气闷,就说了
句“要有光!”然后大爆炸就开始了,时间就产生了,宇宙就初具规模了……

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 127.0.0.1]
无聊了,就做了一下:
可以使用类似于缓冲区溢出的方法,在test()中精确定位m,将输入赋给m即可。但是不同编
译器可能不一样,无法做一个通用的代码来实现。
发信人: fisherman (生命在于折腾), 信区: C_and_CPP
标  题: Re: 一个有趣题目,高手请进
发信站: 紫丁香社区 (Mon Dec 24 12:26:03 2007), 站内

fisherman:/home/wangyao# cat /proc/sys/kernel/randomize_va_space
1
fisherman:/home/wangyao# echo "0" > /proc/sys/kernel/randomize_va_space
fisherman:/home/wangyao# gcc-3.0 test.c -g
fisherman:/home/wangyao# gdb ./a.out
GNU gdb 6.6.90.20070912-debian
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x80484a9: file test.c, line 16.
(gdb) disassemble main
Dump of assembler code for function main:
0x080484a0 :    push   %ebp
0x080484a1 :    mov    %esp,%ebp
0x080484a3 :    sub    $0x8,%esp
0x080484a6 :    and    $0xfffffff0,%esp
0x080484a9 :    call   0x8048484
0x080484ae :   sub    $0x8,%esp
0x080484b1 :   pushl  -0x4(%ebp)
0x080484b4 :   push   $0x80485a0
0x080484b9 :   call   0x8048398
0x080484be :   add    $0x10,%esp
0x080484c1 :   leave
0x080484c2 :   ret
End of assembler dump.
(gdb) s
The program is not being run.
(gdb) r
Starting program: /home/wangyao/a.out
Failed to read a valid object file image from memory.

Breakpoint 1, main () at test.c:16
16          test();
(gdb) s
test () at test.c:6
6           scanf("%d", &t);
(gdb) p &t
$1 = (int *) 0xbffff554
(gdb) p t
$2 = 134513888
(gdb) p *0xbffff554
$3 = 134513888
(gdb) s
1
11      }
(gdb) p t
$4 = 1
(gdb) p *0xbffff554
$5 = 1
(gdb) s
main () at test.c:17
17          printf("%d", m);
(gdb) p m
$6 = 134513888
(gdb) p &m
$7 = (int *) 0xbffff564
(gdb) set *0xbffff564=*0xbffff554
(gdb) p m
$8 = 1
(gdb) p *0xbffff564
$9 = 1
(gdb) q
The program is running.  Exit anyway? (y or n) y

这样的话,就将输入的值赋给了m了。
这里,由于2.6.11之后的内核加入了虚拟地址变换,所以我们关掉randomize_va_space,不
关掉也是可以的,只不过每次地址总是变化,比较讨厌。
gcc-4.x版本的编译出来的代码看起来不是很清晰,使用的是gcc-3.0,不过原理是一样子的


【 在 fisherman (生命在于折腾) 的大作中提到: 】
: 可以使用类似于缓冲区溢出的方法,在test()中精确定位m,将输入赋给m即可。但是不同
编译器可能不一样,无法做一个通用的代码来实现。


--
每日至少抽一刻钟,解答邮件列表中初学者的问题,
每周至少抽两小时,整理新学知识将体验发表/分享出去,
    通过Blog/Wiki/MaiList/个人网站……
每旬至少抽四个小时, 来翻译自个儿喜爱的自由软件的文档,
每月至少抽八小时, 快乐的编程,推进自个儿的项目,
每年至少参加一次, 自由软件的活动,传播自由软件思想,


※ 来源:·紫丁香社区 lilacbbs.com·[FROM: 221.212.*.*]
按照上面的思路:
fisherman:/home/wangyao# cat test.c
#include
#include

void test ()
{
  int t;
  scanf ("%d", &t);

  /*
   *   
阅读(1844) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~