瑞星卡卡安全论坛技术交流区系统软件 MFC代码分析03:深层理解应用程序的启动和装入

1   1  /  1  页   跳转

MFC代码分析03:深层理解应用程序的启动和装入

MFC代码分析03:深层理解应用程序的启动和装入

MFC代码分析02:初探MFC程序消息处理机制


在学C语言的时候,我们的教材告诉我们,应用程序的入口是main函数。如果接触过Windows编程,开篇一定也会告诉你,Windows程序有一个WinMain函数,它作为Windows程序的入口。是这样吗?我们不妨讨论讨论。

问题一:应用程序库何时装入?先于主函数,还是后于主函数?
问题二:用户全局变量到底是什么?它在什么时候开始它的生命周期?
问题三:对于Windows平台下的程序,和对于其他平台下程序,初始化过程一样吗?

要解释这些问题,有些难度,我们不妨考虑一下如何进行解释。我们首先借助MFC的一个全局变量theApp入手去了解整个过程。


引用:

什么是theApp对象?
该对象被许多介绍MFC框架的书籍称为组织整个程序的纽带

我们在此对象初始化处设置一个断点,我们可以发现其整个初始化过程:
CObject构造函数 --> CCmdTarget构造函数 --> CWinThread构造函数 --> CWinApp构造函数 --> 自身构造函数
这不是重点,我们关注的是,他初始化以后,程序到底运行到何处。我们惊奇的发现,当对象初始化完毕后,程序返回到一个名为_initterm的函数中,并且继续进行整个表(_PVFV)的遍历。这个是什么表呢?它凭什么先于用户全局变量出现?
我们继续跟踪其上层调用,我们发现了一个巨型的函数,名为wmainCRTStartup或者mainCRTStartup。在其代码中,我们惊奇的发现了对main和WinMain函数的调用!!!难道main和WinMain函数真的不是应用程序的真正入口?是的,的确不是!

我们把目标锁定到这个所谓的wmainCRTStartup或者mainCRTStartup函数上,看看它到底是何方神圣!

我们在其开头插入断点,重新跟踪程序的运行。不出所料,程序首先走到了该函数的开头(实际上程序首先做的是全局变量的初始化,这些全局变量不是用户程序定义的全局变量)。
我们发现除了栈变量的初始化后,进行的是一个检查托管模式的操作。实际上我们可以看到,此处是在检查其PE头。(我们可以推测,如果非Windows平台下程序,第一步还会不会还是检查他的PE头呢?呵呵)
紧接着的就是设置其应用程序类型,这就是所谓的GUI程序还是控制台程序。实际上这里使用宏实现的,根据一个宏,判断设置为什么模式,判断出现在预处理阶段,与运行时的判断无关。
后面紧跟的操作是初始化这个可爱的_PVFV表,跟着的就是保存C库传递矩阵,加载C库里的运行时初始化程序。再后面进行命令行参数的设置,浮点数的装载,精度的设置。
下面就到了我们一开始讲到的函数_initterm的调用了。不过此处仅仅是对C++的初始化。
初始化完成后,装入结束运行函数。接着又进入了_initterm函数。我们可以看到,实际上在这里进行的是应用程序的初始化,也就是说,用户编写的应用程序从此处开始生效!在此函数中,完成对全局变量和函数表的初始化。
接下来,接收应用程序参数,自然而言后面跟着的就是参数的检查。
进行了一系列操作,终于等到了所谓的主函数调用。当然,此处包含了一系列异常的捕获。从此处开始,真正走入了用户编写的指令部分。

上面罗罗嗦嗦讲了这么多,总结一下,大致流程如下:


引用:

检查托管模式(check_managed_app):实际在检查其PE头
设置应用程序类型(GUI界面的应用程序 or 控制台应用程序)
初始化函数表
保存C库传递矩阵
设置浮点除参数
运行时初始化程序(_RTC_Initialize)
设置命令行参数
装载浮点数
精度设置
C++初始化(_initterm)
注册终止函数(atexit)
初始化运行环境(_initterm):包含初始化用户全局变量
获取应用程序参数
检查输入串
转向主函数(main or winmain)



用户系统信息:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322)
最后编辑天下奇才 最后编辑于 2008-09-29 11:01:58

一点点的激情,一点点的执着,让我一步一步的走入了自己梦寐以求的行业。从一个学校里年少轻狂的孩子,成为了一名信息安全的研发工程师。从只知道写代码,真正开始慢慢的去思考、设计和实现一种技术、一种算法、一个模块、一个软件乃至一个系统。
人生本来就该不断的追求梦想,不断的跨过一个又一个不可能穿越的鸿沟。别人看来,我很疯狂,但我笑了,人生能有几回疯?真正疯狂的人是不计后果的向前冲的,至少我还不是。我所想的,只是别人不敢想的。我所做的,只是别人不敢做的。一个一个虚无缥缈的事物,都必须是有一个一个疯狂的人逐渐的具体和完善。但愿我是这样的人,我只愿做这样的人。
分享到:
gototop
 

回复:MFC代码分析03:深层理解应用程序的启动和装入(编辑中)

留空

一点点的激情,一点点的执着,让我一步一步的走入了自己梦寐以求的行业。从一个学校里年少轻狂的孩子,成为了一名信息安全的研发工程师。从只知道写代码,真正开始慢慢的去思考、设计和实现一种技术、一种算法、一个模块、一个软件乃至一个系统。
人生本来就该不断的追求梦想,不断的跨过一个又一个不可能穿越的鸿沟。别人看来,我很疯狂,但我笑了,人生能有几回疯?真正疯狂的人是不计后果的向前冲的,至少我还不是。我所想的,只是别人不敢想的。我所做的,只是别人不敢做的。一个一个虚无缥缈的事物,都必须是有一个一个疯狂的人逐渐的具体和完善。但愿我是这样的人,我只愿做这样的人。
gototop
 
1   1  /  1  页   跳转
页面顶部
Powered by Discuz!NT