首页
社区
课程
招聘
[旧帖] [求助]高手请进!一道看似简单,其实很复杂的面试题目的思索! 0.00雪花
发表于: 2012-10-5 20:55 2859

[旧帖] [求助]高手请进!一道看似简单,其实很复杂的面试题目的思索! 0.00雪花

2012-10-5 20:55
2859
提问:这段程序是一个很古老的面试题目的测试,原始帖子在:http://bbs.pediy.com/showthread.php?t=104954
以下程序运行后,老是出错。可能是堆栈平衡问题。不过release版本还是不报错的,比较少了很多检查。不知道什么,请各位大侠指点。

#include<stdio.h>
extern "C" int __cdecl mainCRTStartup(void);
void print()
{
  #pragma comment(linker, "/entry:print")
        #pragma comment(linker, "/SECTION:.text,ERW")
  #pragma comment(lib, "msvcrt.lib")
  int mainCRTStartup();
  void main();
  
  __asm
  {
    MOV EAX, OFFSET main
    MOV BYTE PTR[EAX], 0xB8 //MOV EAX, 0x
    MOV DWORD PTR[EAX+1], OFFSET SHOWSTRING //将printf语句地址放在eax+1处
    MOV WORD PTR[EAX+5], 0xE0FF // JMP EAX:FFE0
  }
  
  mainCRTStartup();
  __asm
  {
    ret
  }

SHOWSTRING:
  printf("hello,world!\n");
}
void main()
{
}
我认为这个程序的执行流程是这样的:
首先执行print函数处(这个函数是关键):
执行到以下代码
__asm
  {
    MOV EAX, OFFSET main
    MOV BYTE PTR[EAX], 0xB8 //MOV EAX, 0x
    MOV DWORD PTR[EAX+1], OFFSET SHOWSTRING //将printf语句地址放在eax+1处
    MOV WORD PTR[EAX+5], 0xE0FF // JMP EAX:FFE0
  }
时,即将mov eax,OFFSET SHOWSTRING与jmp eax指令码写到main函数地址处。之后执行mainCRTStartup();这个crt启动函数显然会调用我们的名为main的函数。于是就执行了SHOWSTRING处的代码,之后mainCRTStartup();内部做一些清理性工作则会退出这个启动函数。然后,我们返回
__asm
  {
    ret
  }
这样就退出的print函数。我想,是不是此时返回时,栈顶作为返回地址的数据不和谐,让eip指向了一段不和谐的代码。于是乎不和谐的事情就出现了。要是这样,应该怎样做呢?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 11
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
VC 6 编译了下  debug 版本不报错啊    楼主 你的执行流程分析错了 。。。。
  程序进入 入口 改写了 main 函数之后 调用 mainCRTStartup ,然后带有main 然后直接从 main 里面跳到 printf 处执行 执行后 退出 入口函数  由于入口函数尾部会恢复堆栈平衡 相等于退出了 mainCRTStartup 然后执行 mainCRTStartup 的下一条语句 也就是 ret 退出入口函数
2012-10-6 01:32
0
游客
登录 | 注册 方可回帖
返回
//