找到程序真正的入口(使用IDE追踪)
2016-02-22 23:06
267 查看
一、程序的真正入口
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
相关文章推荐
- <Docker + Bamboo + Saltstack持续集最佳实践 > 本周三晚在线公开课
- 关于org-page的坑
- Intent
- 4. 对list进行sort
- ThinkPHP3.2.3 Nginx 下 URL_MODEL 的配置
- 深入理解java中的package关键字 http://blog.csdn.net/lindir/article/details/8067732
- CentOS搭建SVN服务器
- SetColumnInfo、GetRowInfo、RecalcLayout
- MVC5 Bundles发布到IIS失效问题解决方案
- 【基础技术】Java基础那些事儿系列-成员变量与局部变量
- 带dos调试窗口的win32程序
- 使用Python统计深圳市公租房申请人省份年龄统计
- 错误票库
- 出现error .so: undefined reference to 的解决办法
- nanomsg的使用与分析
- iOS Facebook 最新最简单快速分享方法
- React Native学习笔记-1:JSC profiler is not supported.
- ubuntu安装和使用appium遇到的问题解决方案
- spring类型自动转换——@InitBinder和Converter
- Maven-010-maven 编译报错:Failure to ... in ... was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced.