[ZT]一个microsoft的.exe程序的启动过程

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

学习windows 编程从mfc角度来说可分为两部分那就是WinMain函数以前的,和WinMain函数以后的。前者涉及很多windows操作系统内部的知识,后者么看mfc源码就可以了。虽然大多数程序不需要你了解太多关于os加载应用程序这方面的知识,但我认为能较深入了解windows os的运行情况对程序员是很有帮助的。


最近我正在研究一个microsoft的.exe程序的启动过程,这也是以上所说的关于os如何加
载程序的知识,它包括进程创建,主线程 创建,PE文件加载,程序c运行时启动函数以及四种
main函数的调用等许多令我不得不静下心来好好思索的东东。从mfc编程角度来说,这些都是
不得见的,不过了解这些对程序员编制好的windows程序是有好处的。在平时的学习中中我有
很多疑点,到底在桌面双击一个exe程序,os调用的第一个函数是什么?甚至到现在我研究很
长时间后,还是得不到令我满意的答案。不过在学习的过程中我还是又说收获的,下面和大
家一起分享一下,我也把这段时间所学作一下总结。


要了解一个.exe程序的启动过程就不得不了解一下有关操作系统方面的知识,such as“
进程,线程,虚拟内存"的基本的知识。当然这里我就不详细介绍了,有兴趣的同学可以自己
去查一查这方面的资料。在未真正开始之前,先统一一下本文出现的一些名词的含义:
App.exe----------假定为应用mfc的AppWizard做出的一个SDI程序,App是它的名字。你
可以把它看为一个标准的"hello mfc!"程序。


PE------------不要以为它是“体育课”的缩写呦。它可是微软的标准win32可执行文件
.exe和动态链接库.dll的文件格式,它的english name是Portable Executable File Format。

下面可要正式开始了。
一个microsoft的.exe程序的启动方法有很多,这里我们以双击App.exe图标启动为例(
其他方法,我想也是一样的)。在补充一下,我所用的os是Windows2000Server,所以这里也
主要讨论win2000下的应用程序,过要涉及较多关于NT内核,毕竟微软主推win2000/winxp和
Unicode么。


一个microsoft的.exe程序的启动过程如下:
(1)当我们双击App.exe图标启动程序时,系统首先做什么呢,让我们先听一听侯捷是如何
说的吧“执行起来的App进程其实是shell调用CreateProcess激活的”----"深入浅出MFC se
cond edition" page39载。很多书上都是如是说的,shell又名“命令解释器”,是win32操
作系统基于浏览器的一个32位用户接口,它是一个多线程的好例子,屏幕上每一个文件夹浏
览窗口都是它的一个线程。它是操作系统引导时加载的系统进程,它具体表现为windows ex
plorer.exe。explorer.exe是所有用户应用程序的创造者。你完全可以将shell看成是所有应
用程序进程的父进程,就像桌面(desktop)可看成所有窗口的父窗口一样。shell的用途很多
,如启动应用程序,管理文件系统,将应用程序与相应文件相关联等等。我们常见的桌面上
的带有小箭头的快捷方式(shortcut)就是一个shell链接,shell负责管理一个叫"名字空间"
的类似文件系统似的“超文件系统”,它允许应用程序在任何地方在不知访问对象名字和位置
的前提下访问到这个对象,此类对象有:文件,目录,驱动器,打印机以及网络资源。而名
字空间就是shell把这些对象有层次组织起来的一个结构。名字空间为用户和应用程序提供了
一种可靠和高效的方法来访问和管理对象。好了不论它是什么,凡正它调用了CreateProcess,一切就从这里开始了。


(2)CreateProcess这个函数可作了不少工作。App进程由此诞生。当CreateProcess这个函
数被调用,系统就会创建一个“进程内核对象”。进程内核对象可以看作一个操作系统用来
管理进程的内核对象,它也是系统用来存放关于进程统计信息的地方(一个小的数据结构)
,其实它的真正创建者是一个叫NtCreateProcess的windows2000系统服务函数(也叫执行体服
务函数),他创建了进程内核对象供用户扩展。进程内核对象的初始使用计数为1。然后系统
为该进程创建4GB(=2^32)的虚拟地址空间(所谓虚拟就不是真的创建4GB的物理内存空间,这
些空间不是真在物理内存上).用于加载App.exe可执行文件和任何必要的dll文件的数据和代
码。


(3)下面概述一下系统的加载器(可称为loader)是如何加载这些东东的。首先了解一下系
统为该进程创建4GB的虚拟地址空间是如何分配的,对于win2000/winxp来说,默认情况下每
个用户进程可以占有2GB的私有地址空间;操作系统占有剩余的2GB空间。
在32位x86系统上,
从0x00000000到0x7fffffff的空间中存放着 应用程序代码,全局变量,每个线程堆栈,dll
代码。
从0x80000000到0xc0000000的空间中存放着 内核和执行体,HAL(硬件抽象层),引导驱动程序

从0xc0000000到0xc0800000的空间中存放着 进程页表和超空间。
从0xc0800000到0xffffffff的空间中存放着 系统高速缓存,分页缓冲池,非分页缓冲池。
首先,CreateProcess打开应用程序文件(.exe),它先扫描该文件的文件头,该文件头里含有文
件能运行在那个环境之下,如果是win32环境,系统就直接加载文件的代码和数据并输入(im
port)该文件执行所需的dll函数。如果不是win32环境比如时os/2的.exe则先加载相应的环境
子系统,载由该环境加载该文件的代码和数据以及该文件执行所需的dll函数。至于系统是如
何知道文件的代码和数据以及该文件执行所需的dll函数所在的位置就需要你了解一下PE文件
格式了,其实也很简单,PE文件拥有很多sections,数据和代码都放在不同的section里面,
文件执行所需的dll也放在单独的section(.idata)里,这里就不详述了。而且在加载过程中涉
及到有关虚拟内存,内存映射文件等很多较深的知识,我会在以后的系列文章中详细专题论
述的。


(4)进程加载代码和数据完毕后,就开始创建线程来执行进程空间内的代码。进程是静态的
,它只是线程的容器。一个进程至少因该有一个线程(main thread),其它线程都是主线程通
过调用CreateThread函数创建的。线程也是核心对象,他的实际创建者是一个叫NtCreateTh
read的windows2000系统服务函数。一个线程其实只是一个线程核心对象和两个堆栈(一个核
心堆栈,用于线程运行在核心态;一个用户堆栈,用于线程运行在用户态),线程与进程类似
,也拥有线程核心对象计数和线程句柄,这里不详述。线程用于描述进程中的运行路径。每
当进程被初始化时,系统就要创建一个主线程。该线程与c/c++运行时库的启动代码一道开始
运行,启动代码则调用进入点函数(就是我们的main函数,它也是主线程的进入点函数),并
且继续运行直到进入点函数返回并且c/c++运行时库的启动代码调用ExitProcess为止。每个
线程都有自己的入口点函数,主线程入口点函数名字必须是main,wmain,WinMain或wWinMain
.而其他的线程入口点函数名字可使用任何名字。每个线程函数必须有一个返回值,它将作为
线程的退出代码。对于主线程来说,这个返回值将传给c/c++运行时库的启动函数。


(5)c/c++运行时库的启动函数它其实是一个程序的真正调用的第一个函数,它是在程序链
接时由链接程序选择相应的启动函数并加到程序的开始处。c/c++运行时库有四个版本的启动
函数,他们分别对应不同类型的应用程序。比如,需要ANSI字符和字符串的GUI应用程序的启
动函数是WinMainCRTStartup,其对应的进入点函数是
WinMain,需要Unicode字符和字符串的GUI应用程序的启动函数是wWinMainCRTStartup,其对应
的进入点函数是wWinMain,而需要ANSI字符和字符串的CUI应用程序(如控制台console程序)的应用程序的启动
函数是mainCRTStartup,对应的入口点函数为main;需要Unicode字符和字符串的CUI应用程序
(如控制台console程序)的应用程序的启动函数为wmainCRTStartup,对应的入口点函数为wmain;c/c++运行时库的启动函数的功能如下:
以wWinMainCRTStartup(大多数运行在windows2000下的应用程序的启动函数都是它)为例。它
负责:
*检索指向新进程的完整命令行指针;
*检索指向新进程的环境变量的指针;
*对c/c++运行时的全局变量进行初始化;
*对c运行期的内存单元分配函数(比如malloc,calloc)和其他低层I/O例程使用的内存栈进
行初始化。
*为C++的全局和静态类调用构造函数。
当这些初始化工作完成后,该启动函数就调用wWinMain函数进入应用程序的执行。
当wWinMain函数执行完毕返回时,wWinMainCRTStartup启动函数就调用c运行期的exit()函
数,将返回值
(nMainRetVal)传递给它。之后exit()便开始收尾工作:
*调用由_onexit()函数调用和注册的任何函数。
*为C++的全局和静态类调用析构函数;
*调用操作系统的ExitProcess函数,将nMainRetVal传递给它,这使得操作系统能够撤销进
程并设置它的exit 代码。


(6)至此启动函数的任务完成,至于中间wWinMain函数的运行过程看看mfc源码即可。不过我还要提一下,wWinMain函数其实只是调用了mfc的AfxWinMain()函数,而一切的真正代码的运
行也是从AfxWinMain()开始的。
以上只是粗略将一下一个microsoft的.exe程序的启动过程,其中有很多深奥的知识我只是提了一下,有些知识在以后的文章中还会陆续提到的。

INCA_ProF脚本教程 一、首先INCA软件是当前主流标定开发软件之一,尤其在动力系统控制器的标定中应用非常广泛;与此同时ProF编程脚本是INCA软件提供各种实用功能之一,使用者可根据需求编写ProF脚本语言对ECU闪存编程等各种自定义操作。 二、然而ProF脚本语言在ETAS的官网或其他网络上并没有专门的使用教程,通常只有ETAS技术支持人员提供的ProF Documentation文档或少量可参考的Demo案例,然而ProF Documentation文档仅涉及ProF语言的函数的操作说明,没有从全局的框架上介绍Pro 阅读详情

相关推荐

基于Joplin和Joplin Server搭建私有云笔记

我们知道,多端同步功能是笔记工具最重要的功能。只有实现了多端同步,我们才能在工作电脑和手机之间无缝切换笔记体验。Joplin 在同步上得不错,支持 Dropbox、OneDrive 和 AWS s3(当然国内都没法用),支持 WebDAV 协议,也支持自家的 Joplin Server。 本文介绍如何在自己的服务器上搭建 Joplin Server,并配置好 Joplin Desktop 的同步功能。 前置条件 安装docker 创建 Joplin Server 配置文件 创建配置文件,~/docke

代码时光 1万+

Windows系统下22个整洁的代码编辑器推荐

用于Windows代码编辑器有很多,但似乎其中只有少数是真正值得使用的。毕竟,你需要一段时间的使用,所有的设置和调整来满足您的设计需要,所以你最好找到一个你喜欢的!今天奉献给大家22个 windows代码编辑器,,你可以免费下载这些编辑器 Notepad++ http://notepad-plus.sourceforge.net v 5.3.2 | Free 这可能是...

weixin_33816946的博客 359

YOLOv8【第十一章:视频追踪与流处理篇·第6节】BoT-SORT 改进:结合相机运动补偿(CMC)提升追踪稳定性!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏。该专栏系统复现并梳理全网各类 YOLOv8 改进与实战案例(当前已覆盖分类 / 检测 / 分割 / 追踪 / 关键点 / OBB 检测等方向),坚持持续更新 + 深度解析,质量分长期稳定在 97 分以上,可视为当前市面上 覆盖较全、更新较快、实战导向极强 的 YOLO 改进系列内容之一。

**My Coding Family** 648

windowsmarkdown安装与应用

安装markdown 此次安装的是python版本的markdown,所以需要先安装python。 安装python 下载地址: http://www.python.org/ftp/python/2.7.2/python-2.7.2.msi直接运行安装即可。 安装mark

jizha的专栏 7689

五款优秀的编辑器 --适合程序员使用

1,Notepad++ 比windows的记事本更好的一个编辑器,完全免费开源,可以实现不同编程语言语法加亮,可定制性很强; 2,Emacs 完成开源免费,跨平台,深受高级编程人员喜爱。对于使用UNIX/LINUX的人来说应该很熟悉; 3,UltraEdit 功能也挺强大的,收费,并且费用不低,支持的编程语言讲法加亮不多; 4,TextMade ...

gotyou 703

Windows核心编程:探索虚拟内存

作者:shenzi链接:http://blog.csdn.net/shenziWindows核心编程:探索虚拟内存1.系统信息     操作系统中有许多值是由系统所运行的主机决定的,如页面大小和分配粒度等。我们应该在进程初始化时取得这些值,然后在代码中使用它们。GetSystemInfo函数用来取得与主机相关的值:

shenzi的天空 5127

一个microsoft.exe程序文件的启动过程

重庆邮电大学 pppz(Java学生) 852

explore进程和linux,解析Svchost.exe和Explorer.exe两大系统进程(zt)

在本文中我们将着重介绍一下Windows系统的Svchost.exe和Explorer.exe两种进程,作为Windows系统中两种重要的进程,下面我们就来看看他们的特点以及在各个操作系统中的应用。Explorer在Windows系列的操作系统中,运行时都会启动一个名为Explorer.exe的进程。这个进程主要负责显示系统桌面上的图标以及任务栏,它在不同的系统中有不同的妙用。Explorer在W...

weixin_42541463的博客 512

win2000:ntoskrnl.exe 文件丢失解决一例

今天windows 2000启动出了点问题如下:下列档案遗漏或损毁,无法启动 Windows NT: Winnt_root\System32\Ntoskrnl.exe 请重新安装一份上列档案的拷贝。解决过程:1,google了ntoskrnl.exe,查找到微软的解决方法.不过,没有试,看着和我的解决方式不一样.如果哪位有出现此类问题,可以试一下.http://support.microsoft.

Robert's Log 3070

解析Svchost.exe和Explorer.exe两大系统进程(zt)

在本文中我们将着重介绍一下Windows系统的Svchost.exe和Explorer.exe两种进程,作为Windows系统中两种重要的进程,下面我们就来看看他们的特点以及在各个操作系统中的应用。Explorer  在Wind...

congsikuai0611的博客 159

WORD不能打开了,提示winword.exe出错(还有EXCEL)

在一次不正常退出WORD后,就不能再打开了,提示winword.exe程序出现错误,即将关闭,并创建错误日志,要求重启,后来重启也一样。重装安装OFFICE也不行? 解决方法以: 可能由于不正常退出造成C:\Documents and Settings\你的用户名\Application Data\Microsoft\Templates\NORMAL.DOT文件损坏了,一般删除,再次进入WOR

Robert's Log 2万+

Svchost.exe进程的功能以及相关知识大揭秘(zt)

Svchost.exe进程的功能以及相关知识大揭秘(文档类别:C++) 2004-10-8  在基于NT内核的Windows操作系统家族中,Svchost.exe一个非常重要的进程。很多病毒、木马驻留系统与这个进程密切相关,因此深入了解该进程是非常有必要的。本文主要介绍Svchost进程的功能,以及与该进程相关的知识。Svchost进程概述微软对“Svchost进程”的定义是:Svchost.e

2067

Manifest相关[ZT]

(转载:http://blog.csdn.net/wengyb/archive/2009/07/09/4335138.aspx)“应用程序配置不正确,程序无法启动”详细举例(vc2008 sp1) http://hi.baidu.com/fairysky/blog/item/130dda13db7b050a5aaf53be.html内容我就不copy了,大家可以自己去看,总来说产生这个问题的原因可

Augusdi的专栏 1770

SHELL操作(ZT)

第一章 Windows Shell是什么一个操作系统外壳的不错的定义是它是一个系统提供的用户界面,它允许用户执行公共的任务,如访问文件系统,导出执行程序,改变系统设置等。MS-DOS有一个Command.COM扮演着这个角色。然而Windows已经有了图形界面环境,他的外壳程序也就必然是图形方式的。在Windows95以前,默认的Windows Shell就是程序管理器。     

肉丝的盘子 1800

[ZT]批处理详细教程

zt:http://www.vmware.cn前言最近对于批处理技术的探讨比较热,也有不少好的批处理程序发布,但是如果没有一定的相关知识恐怕不容易看懂和理解这些批处理文件,也就更谈不上自己动手编写了,古语云:“授人以鱼,不如授人以渔。”因为网上好像并没有一个比较完整的教材,所以抽一点时间写了这片 >给新手朋友们.也献给所有为实现网络的自由与共享而努力的朋友们.批处理文件是无格式的文本文件,它包含一

Robert's Log 700

EVC学习笔记 ZT

一、资源以及开发工具的获得 1.微软CE开发资源 (1)首页 http://msdn.microsoft.com/embedded/downloads/ce.net/default.aspx (2)eMbedded Visual Tools 3.0 - 2002 Edition http://www.microsoft.com/downloads/details.aspx?famil...

weixin_30852419的博客 86

(ZT) 解决VS2008编译的程序在某些机器上运行提示“由于应用程序配置不正确,应用程序未能启动”的问题

original url from: http://www.cnblogs.com/wondering/archive/2009/08/29/1556392.htmlVC9编译的程序在没有装过VC9(确切的说是.Net Framework3.5)的机器上运行时,如果提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。”这个错误,那 么就说明该程序动态链接了VC9的运行时库,(如果还用到了MFC,那么可能动态链接了VC9的MFC库,同理还有ATL库),以及缺少对应的 m

博客标题不能为空 2711

以色列人发现的IE 0day (ZT)

以色列人发现的IE 0day (ZT) 测试成功,会运行计算器只是利用起来有点 ... ...这个漏洞是由于微软IE浏览器启动“Print Table of Links”时引起的跨站***(Cross-Zone Scripting ) 如果启用了 "Print Table of Links",在打印一个网页的时候,能够导致执行任意代码。 1.选择“Print Table of Lin...

weixin_34248023的博客 114

Clickonce部署初体验(ZT)

我们经常要面对的是对开发模式的选择,比如C/S模式和b/s模式。现在,很多人都似乎比较喜欢选择B/S模式进行web的开发,这其中的原因是很多的。但其中一点很重要的原因,那就是因为B/S开发的话,部署非常之容易,因为这样很容易实现"瘦客户端",客户端只需要使用浏览器就可以运行应用了。但B/S模式下开发的WEB应用,也有其不足之处,主要是由于功能实现起来,是没办法和传统的C/S模式下的winfo...

weixin_30952103的博客 86

[ZT]软件开发成功 12 法则

by Joel Spolsky The Joel Test: 软件开发成功 12 法则 作者: Joel Spolsky 译: 李国华 Frank Li 编辑: 孙雯辰 Rosemary Sun 2000年8月9日 有没有听说过SEMA?这可是衡量一个软件开发组好坏的很深奥的系统。别介,等一下!别按那个联接! 给你六年你也搞不清这玩意。所以我自己随便攒了一套衡量系统,信不信由你,这系统,三分钟就可

l1t的专栏 1193

[ZT]MSSQL占用内存过大的解决方法

Normal 0 7.8 磅 0 2 <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimS

Robert's Log 1376

[ZT]Windows2003 设置

2004-11-4 1:36:24  水冷天下 h2ol  出处:一、windows server 2003 3790版本识别RTM=release to manufacture (公开发行批量生产)是给硬件制造商的版本!是送去压盘的,不是拿去卖的。OEM=Original Equipment Manufacturer只能全新安装, 和RTM差不多,只是称呼不同而已。RTL=retail(零售)正

Robert's Log 591
上一篇: [ZT]MISRA的C编程规范
YODOYODO
博客等级 码龄18年 3粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值