提问:这段程序是一个很古老的面试题目的测试,原始帖子在: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指向了一段不和谐的代码。于是乎不和谐的事情就出现了。要是这样,应该怎样做呢?
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!