一、程序的真正入口

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追踪)的更多相关文章

  1. 如何找到程序的真正入口mainCRTStartup

    相信大家都知道以为程序的入口为main函数,但是程序的真正的入口不是main而是mainCRTStartup,那么我们如何找到他的地址呢? 先用第一种方法,就是直接代码显示 #include<s ...

  2. [iOS] 使用xib作为应用程序入口 with IDE

    [iOS] 使用xib作为应用程序入口 with IDE 在「使用xib做为应用程序入口 with Code」这篇文章中,介绍了如何透过写Code的方式,来使用xib做为应用程序的入口.但其实在Xco ...

  3. 可执行程序的入口点在那里?(强化概念:程序真正的入口是mainCRTstartup)

    今天终于有时间来研究一下一个很大很大的工程编译成一个exe和若干dll后,程序是如果执行它的第一条指令的?操作系统以什么规则来找到应该执行的第一条指令(或说如何找到第一个入口函数的)? 我们以前写wi ...

  4. Linux上程序执行的入口--Main

    main()函数,想必大家都不陌生了,从刚开始写程序的时候,大家便开始写main(),我们都知道main是程序的入口.那main作为一个函数,又是谁调用的它,它是怎么被调用的,返回给谁,返回的又是什么 ...

  5. MongoDB源码分析——mongod程序源码入口分析

    Edit 说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他 ...

  6. 在纯C工程的main函数之前跑代码(手工找到程序入口点, 替换为我们自己的函数)

    在main函数之前跑代码的方法 方法: 手工找到程序入口点, 替换为我们自己的函数 写测试程序 // test.cpp : Defines the entry point for the consol ...

  7. 用pyqt5做一个能python程序能插入图片的ide

    之前只是放到github上了,现在一想应该开源,大家想继续做好这个ide的都能从这里起步. #注意在.py文件相同目录下放一个1.png做测试图片 #本质就是用html来实现图片 #写在前面的话:这个 ...

  8. [zhuan]Android程序的真正入口Application

    http://blog.csdn.net/coding_or_coded/article/details/6602560 接触android已经有一段时间了,一直以为android程序的入口是配置文件 ...

  9. nstall-Package : 无法找到程序包“MySql.Data.Entity.EF6”

    在vs2013中用MySQL+EF6时,会遇到版本的问题,解决方法一般如下: 1 Install-Package EntityFramework -Version 6.0.0然后Enter2 Inst ...

随机推荐

  1. 基于物品的协同过滤推荐算法——读“Item-Based Collaborative Filtering Recommendation Algorithms” .

    ligh@local-host$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.3 基于物品的协同过滤推荐算法--读"Item-Based ...

  2. 【剑指Offer学习】【面试题18 :树的子结构】

    题目:输入两棵二叉树A 和B.推断B 是不是A 的子结构. 二叉树结点的定义: /** * 二叉树的树结点 */ public static class BinaryTreeNode { int va ...

  3. Java线程(十):CAS

    前言 在Java并发包中有这样一个包,java.util.concurrent.atomic,该包是对Java部分数据类型的原子封装,在原有数据类型的基础上,提供了原子性的操作方法,保证了线程安全.以 ...

  4. 2014-7 Andrew Ng 自动化所报告听后感

    原文:http://blog.sina.com.cn/s/blog_593af2a70102uwhl.html 一早出发,8点20就赶到现场, 人越聚越多,Ng提前几分钟到达现场,掌声一片.    N ...

  5. hdu2289Cup(神坑题,精度+二分,以半径二分不能过,以高度为二分就过了)

    Problem Description The WHU ACM Team has a big cup, with which every member drinks water. Now, we kn ...

  6. 再见了acm

    2013年11月17日长沙区域赛我的最后一场区域赛. 忙碌了三年的acm要停下脚步,一时还无法接受. 这样一个结果有点无奈. 感谢队友,三年三支队伍五个队友,感谢你们.(每当写到这里时就总有点小忍不住 ...

  7. 使用zabbix监控nginx

    在zabbix agentd客户端上,查看nginx是否加载了--with-http_stub_status_module.因为zabbix监控nginx是根据 nginx的Stub Status模块 ...

  8. Android实现 再按一次退出 的三种方法 durationTime、timerTask 和Handler

    目前很多Android应用都会实现按返回键时提示“再按一次推退出” 在这篇文章中总结了各家的方法,一般都是监听Activity的onKeyDown 或者onBackPressed方法 方法一: 直接计 ...

  9. 开源框架ViewPagerIndicator的使用——TabPageIndicator

    1.导入Android-ViewPagerIndicator库文件 下载地址:https://github.com/JakeWharton/ViewPagerIndicator 2.布局文件     ...

  10. SUSAN检测算子

    USAN区域(核同值区):和核像素的灰度相同会相信的模板像素的区域. 利用这个区域的尺寸.重心.二阶矩等可以帮助检测图像的边缘和角点.利用USAN的面积作为特征可以起到增强边缘和角点的效果. 该方法不 ...