找到程序真正的入口(使用IDE追踪)
一、程序的真正入口
main或WinMain只是“语法规定的程序入口” 并不是“应用程序入口”。
我们使用VC++ 6.0 的栈回溯功能,找到main函数之前的代码。菜单View -> Debug Windows -> Call Stack 打开栈回溯窗口(快捷键 Alt + 7)。 
上图显示程序运行时调用了三个函数,分别为:KERNEL32.DLL、mainCRTStartup和main。 其中KERNEL32! 7C81776F 表示在系统库KERNEL32.dll中的地址7c81776f处调用了mainCRTStartup。
通过双击 mainCRTStartup,我们可以找到这个函数定义在 crt0.c 中,你可以在crt0.c中找到mainCRTStartup的源码。
下面是crt0.c中注释的摘抄:
/***
*crt0.c - C runtime initialization routine
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* This is the actual startup routine for apps. It calls the user's main
* routine [w]main() or [w]WinMain after performing C Run-Time Library
* initialization.
*
* With ifdefs, this source file also provides the source code for:
* wcrt0.c the startup routine for console apps with wide chars
* wincrt0.c the startup routine for Windows apps
* wwincrt0.c the startup routine for Windows apps with wide chars
*
*******************************************************************************/
这里说明了函数真正的入口
/***
*mainCRTStartup(void)
*wmainCRTStartup(void)
*WinMainCRTStartup(void)
*wWinMainCRTStartup(void)
*
*Purpose:
* These routines do the C runtime initialization, call the appropriate
* user entry function, and handle termination cleanup. For a managed
* app, they then return the exit code back to the calling routine, which
* is the managed startup code. For an unmanaged app, they call exit and
* never return.
*
* Function: User entry called:
* mainCRTStartup main
* wmainCRTStartup wmain
* WinMainCRTStartup WinMain
* wWinMainCRTStartup wWinMain
*
*Entry:
*
*Exit:
* Managed app: return value from main() et al, or the exception code if
* execution was terminated by the __except guarding the call
* to main().
* Unmanaged app: never return.
*
*******************************************************************************/
由于我安装的的VC++6.0不是完整版,未找到crt0.c。然后,我切换到vs2010下,找到了crt0.c,其中有这样一段定义:
#ifdef _WINMAIN_
#ifdef WPRFLAG
#define _tmainCRTStartup wWinMainCRTStartup
#else /* WPRFLAG */
#define _tmainCRTStartup WinMainCRTStartup
#endif /* WPRFLAG */
#else /* _WINMAIN_ */
#ifdef WPRFLAG
#define _tmainCRTStartup wmainCRTStartup
#else /* WPRFLAG */
#define _tmainCRTStartup mainCRTStartup
#endif /* WPRFLAG */
#endif /* _WINMAIN_ */
当然,如果你装了完整版的VC++6.0 应该与此不同。 不过,这些函数的目的总是为了:申请堆空间、初始化堆空间、获取环境变量、获取CommandLine、全局数据初始化、浮点寄存器初始化等。
二、修改程序入口
菜单Project -> Settings -> Link -> Output 在 Entry-point symbol中可以指定程序入口。

重新指定入口后,没有调用 mainCRTStartup 函数,直接就调用了入口函数MyEntry。 如下图: 
但是,由于没有调用mainCRTStartup函数,堆空间是没有初始化的,当使用堆空间时,程序会报错崩溃,如下图:

备注: 从Visual Studio 2003(VC7.0)开始,微软加入了防止缓冲区溢出的选项:/GS,编译器会在每个函数的栈内分配一个随机标记,而这个随机标记的种子数由应用程序入口的代码负责初始化。
http://my.oschina.net/huangsz/blog/286246
找到程序真正的入口(使用IDE追踪)的更多相关文章
- 如何找到程序的真正入口mainCRTStartup
相信大家都知道以为程序的入口为main函数,但是程序的真正的入口不是main而是mainCRTStartup,那么我们如何找到他的地址呢? 先用第一种方法,就是直接代码显示 #include<s ...
- [iOS] 使用xib作为应用程序入口 with IDE
[iOS] 使用xib作为应用程序入口 with IDE 在「使用xib做为应用程序入口 with Code」这篇文章中,介绍了如何透过写Code的方式,来使用xib做为应用程序的入口.但其实在Xco ...
- 可执行程序的入口点在那里?(强化概念:程序真正的入口是mainCRTstartup)
今天终于有时间来研究一下一个很大很大的工程编译成一个exe和若干dll后,程序是如果执行它的第一条指令的?操作系统以什么规则来找到应该执行的第一条指令(或说如何找到第一个入口函数的)? 我们以前写wi ...
- Linux上程序执行的入口--Main
main()函数,想必大家都不陌生了,从刚开始写程序的时候,大家便开始写main(),我们都知道main是程序的入口.那main作为一个函数,又是谁调用的它,它是怎么被调用的,返回给谁,返回的又是什么 ...
- MongoDB源码分析——mongod程序源码入口分析
Edit 说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他 ...
- 在纯C工程的main函数之前跑代码(手工找到程序入口点, 替换为我们自己的函数)
在main函数之前跑代码的方法 方法: 手工找到程序入口点, 替换为我们自己的函数 写测试程序 // test.cpp : Defines the entry point for the consol ...
- 用pyqt5做一个能python程序能插入图片的ide
之前只是放到github上了,现在一想应该开源,大家想继续做好这个ide的都能从这里起步. #注意在.py文件相同目录下放一个1.png做测试图片 #本质就是用html来实现图片 #写在前面的话:这个 ...
- [zhuan]Android程序的真正入口Application
http://blog.csdn.net/coding_or_coded/article/details/6602560 接触android已经有一段时间了,一直以为android程序的入口是配置文件 ...
- nstall-Package : 无法找到程序包“MySql.Data.Entity.EF6”
在vs2013中用MySQL+EF6时,会遇到版本的问题,解决方法一般如下: 1 Install-Package EntityFramework -Version 6.0.0然后Enter2 Inst ...
随机推荐
- 程序中使用事务来管理sql语句的执行,执行失败时,可以达到回滚的要求。
1.设置使用事务的SQL执行语句 /// <summary> /// 使用有事务的SQL语句 /// </summary> /// <param name="s ...
- C# 中根据datetime的值来计算属于本年的第几周,类似delphi中的weekoftheyear功能
/// <summary> /// 获得今天是今年的第几周 /// </summary> /// <param name="year">< ...
- 【转】LINUX下一款不错的网站压力测试工具webbench
原文链接:http://blog.csdn.net/xinqingch/article/details/8618704 安装: wget http://blog.s135.com/soft/linux ...
- python成长之路——第二天
cpython:c解释器 .pyc(字节码)——机器码 jpython :java解释器 java字节码 ironpython :C#解释器 C#字节码 .... 上面的:编译完之后 ...
- 练习 jquery+Ajax+Json 绑定数据 分类: asp.net 练习 jquery+Ajax+Json 绑定数据 分类: asp.net
练习 jquery+Ajax+Json 绑定数据
- 当webview遇到了Slidingmenu,webView出现卡白,解决方案
先介绍一下什么是SlidingMenu: Sliding Menu的是一种比较新的设置界面或配置界面效果,在主界面左滑或者右滑出现设置界面,能方便的进行各种操作.如Evernote.Google+.F ...
- arm: 使用结构体操作寄存器
使用结构体操作寄存器: //寄存器赋值和取值的时候,要注意寄存器的长度,有的寄存器的值只有8位. //还要注意,使用volatile修饰寄存器变量.volatile 参考http://www.cnbl ...
- 如何创建C++程序
下载Microsoft Visual C++ 6.0请点击这里:VC 6.0下载(包括中文版英文版)(支持Win7和XP) 首先,我们要进入Microsoft Visual C++集成开发环境(Int ...
- linux指令(目录类操作指令)
pwd 显示当前所在的工作目录 cd 目标目录 例如cd /boot/grub 从当前目录切换到某个目录 cd 切换到根目录 cd.. 切换到当前目录的上层目录 ls 显示当前目录下的内容 ...
- 【转】centOS上安装redis+phpredis2.2.4扩展
原文链接:http://www.cnblogs.com/xsi640/p/3756130.html 我原来的安装方式:http://www.cnblogs.com/wuling129/p/464738 ...