免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 紫牧
打印 上一主题 下一主题

[函数] 一个面试题,说是考函数调用方式 [复制链接]

论坛徽章:
0
31 [报告]
发表于 2007-09-09 09:08 |只看该作者
这里面看的函数调用溢出的设法!

论坛徽章:
0
32 [报告]
发表于 2007-09-09 09:58 |只看该作者
原帖由 naihe2010 于 2007-9-9 00:44 发表


请问VC6-DEBUG编译,有什么特点吗?我感觉GCC不是这样处理的。

跟踪了一下,发现要写成(&t)[8] = t 才能实现功能。

gcc保持16字节栈对齐,所以在在分配空间时会大一些;vc6则是按照实际长度4字节对齐。确实,再看下去头大了。

论坛徽章:
0
33 [报告]
发表于 2007-09-09 10:01 |只看该作者
原帖由 紫牧 于 2007-9-8 21:29 发表

WINXP,VC6,结果如下
212651

  大哥,怎么会是这个结果呢?


C:\>cl 1.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

1.c
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:1.exe
1.obj

C:\>1
1
In test(),t=1 and &t=0012FF70.
In main(),m=1 and &t=0012FF7C.
C:\>

论坛徽章:
0
34 [报告]
发表于 2007-09-09 10:14 |只看该作者
原帖由 Cyg07 于 2007-9-9 10:01 发表

  大哥,怎么会是这个结果呢?


C:\>cl 1.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

1 ...

上面那个结果是在VC IDE中DEBUG模式下编译的结果
下面这个是在VC IDE中RELEASE模式下编译的结果
1
In test(),t=1 and &t=0013FF78.
In main(),m=4223216 and &t=0013FF80.
试了下在命令行方式下编译,结果是正确的,和你的一样
1
In test(),t=1 and &t=0013FF70.
In main(),m=1 and &t=0013FF7C.
好奇怪,说DEBUG和RELEASE不一样还能接受,怎么在IDE环境下和命令行下编译出来的结果不一样呢,是不是IDE环境下的编译选项影响了呢?

论坛徽章:
0
35 [报告]
发表于 2007-09-09 10:19 |只看该作者
release版本对空间做了优化处理。
我在命令行下加了 /O1参数编译

C:\>cl 1.c /O1
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

1.c
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:1.exe
1.obj

C:\>1
1
In test(),t=1 and &t=0012FF70.
In main(),m=4227312 and &m=0012FF7C.

论坛徽章:
0
36 [报告]
发表于 2007-09-09 10:23 |只看该作者
原帖由 Solidus 于 2007-9-9 01:43 发表
我觉得没啥必要在继续了,除非在插入代码的部分获得ebp的地址(函数被调用后-4的esp),否则用纯C没啥好办法了,因为这个本身就跟编译器有关了,没法预测泛用了

支持大哥的看法;如果有兴趣的话使用一些调试器(OllyDBG,softice,rdb)跟踪下就很清晰了!

论坛徽章:
0
37 [报告]
发表于 2007-09-09 10:26 |只看该作者
我这怎么是可以的呢--?
D:\>cl 1.c /o1
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

1.c
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:1.exe
/out:1.exe
1.obj

D:\>1
1
In test(),t=1 and &t=0013FF70.
In main(),m=1 and &m=0013FF7C.

论坛徽章:
0
38 [报告]
发表于 2007-09-09 10:34 |只看该作者
利用偏移的方式获取m并不可靠,
最可靠的方法是直接读取指令值,然后进行分析

论坛徽章:
0
39 [报告]
发表于 2007-09-09 10:45 |只看该作者
原帖由 mik 于 2007-9-9 10:34 发表
利用偏移的方式获取m并不可靠,
最可靠的方法是直接读取指令值,然后进行分析

能详细说说么?

论坛徽章:
0
40 [报告]
发表于 2007-09-09 10:53 |只看该作者
原帖由 紫牧 于 2007-9-9 10:45 发表

能详细说说么?


直接读出类似以下的代码段:

... ...
mov eax, [ebp - 4]
push eax
push offset string
call printf


分析 mov eax, [ebp - 4] 这句代码,获取 [ebp -4]
再得到原来的 ebp 值,自然就准确无误的设置 m 值, 不用理会哪个编译器如何做对齐,填补
不过这个方法对机器指令要熟悉
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP