Windows进程创建过程详解(含PE文件加载)

news/2024/6/30 23:23:06

1.调用CreateProcessW打开指定可执行文件,并创建一个内存区对象。这里仅仅是打开exe文件,并没有将文件映射到内存中。打开exe是为了在后续创建进程的过程中从exe头部中读取一些环境配置。
2.调用ntdll.dll中的NtCreateProcessEx系统服务。该函数仅仅是一个内核层对外的门户,其实ntdll.dll中几乎所有的API都是一个空壳,ntdll.dll的本质就是用户层和内核层之间的一道屏障。而这道屏障就是负责保护内核层的,防止用户层直接控制内核层。ntdll.dll中的API会对用户输入的参数进行严格检测,防止对内核层造成破坏。
在这里插入图片描述

3.调用ntdll.dll中的NtCreateProcessEx之后,他会利用处理器的陷阱机制切换到内核模式下。之后在内核模式中的系统服务分发函数KiSystemService获得控制权,它利用当前线程指定的系统服务表,调用到执行体层的NtCreateProcessEx函数。这里需要注意的是ntoskrnl.dll中的执行体层,该层中包含了与ntdll.dll中API完全对应的一套Nt函数。而恰恰就是执行体中的这一套API才是真正的函数本体。
4.执行体层的NtCreateProcessEx被调用之后,系统开始正式在内核层创建进程。
5.创建EPROCESS对象,并初始化其中的域(这里的域表示的就是结构体中的成员或属性)。
6.创建初始的进程地址空间。
7.创建进程的句柄表。
8.调用KeInitializeProcess函数来初始化新进程对象的基本优先级、Affinity、进程页表目录和超空间的页帧号。
9.通过PspInitializeProcessSecurity函数初始化新进程的安全属性,主要是从父进程复制一个令牌。
10.设置新进程的优先级类别。
11.初始化新进程的句柄表。
12.初始化新进程的进程地址空间,该过程是通过调用MmInitializeProcessAddressSpace函数进行的。主要是读取exe文件中的部分属性对进程地址空间进行初始化。注意:这里还没有将exe加载到进程地址空间中。仅仅是读了些属性进行初始化用。
13.创建进程ID,利用ExCreateHandle函数在CID句柄表中创建一个进程ID项。
14.对这次进程的创建行为进行审计。审计就是类似于记录。
15.创建一个PEB,这里首次出现了进程环境快PEB。PEB是EPROCESS结构成员之一。
16.将新进程加入到全局的进程链表PsActiveProcessHead中。
17.调用ObInsertObject函数,把新进程对象插入到当前进程的句柄表中。这里的新进程对象就是EPROCESS结构对象。
18.设置进程的创建时间。并把新进程的句柄赋到ProcessHandle中,从而创建者可以获得新进程的句柄。
19.到目前为止,内核中的进程已经创建完毕,但进程本身是不具备执行能力的,进程仅仅只是一个执行环境,必须要创建一根线程来负责执行代码。
20.在创建初始线程之前,首先要构造一个栈以及一个可供运行的环境。初始线程的栈大小可以通过PE映像文件获取。
21.调用ntdll.dll中的NtCreateThread函数来创建线程。
22.和进程创建同理,线程创建最后也是由执行体层的NtCreateThread函数来完成。
23.创建ETHREAD对象,并初始化其中的域。
24.生成线程ID。
25.建立TEB线程环境块。
26.设置线程安全属性工作。
27.进程的初始线程的启动函数默认是kernel32.dll中的BaseProcessStart函数(非线程函数)。然而这里的线程不会立即执行,它会先处于挂起状态,等待进程完全初始化后才开始真正执行。
28.到目前为止内核部分的进程创建基本完成,但是从用户层的子系统角度来说,用户进程的创建才刚刚开始。
29.Kernel32.dll会给Windows子系统发送一个消息,消息的内容包括:进程和线程的句柄、进程创建者的ID等必要信息。
30.Windows子系统进程csrss.exe负责接收此消息。
31.保留一份句柄。
32.设定新进程的优先级类别。
33.在子系统中分配一个内部进程块。
34.设置新进程的异常端口,从而子系统可以接收到该进程中发生的异常。
35.对于正在被调试的进程,设置它的调试端口,从而子系统可以接收到该进程的调试事件。
36.分配并初始化一个内部线程块,并插入到进程的线程列表中。
37.窗口会话中的进程计数增加1。
38.设置进程的停机级别为默认级别。
39.将新进程插入到子系统的进程列表中。
40.分配并初始化一块内存供子系统的内核模式部分使用(W32PROCESS结构)。
41.显示应用程序启动光标。
42.到这时候,进程环境已经建立好了,其线程将要使用的资源也分配好了,Windows子系统已经知道并登记了此进程和线程。所以,初始线程被恢复执行,余下的初始化工作是初始线程在新进程的环境中完成的。
43.KiThreadStartup是新线程的启动例程,它调用PspUserThreadStartup函数,该函数中会将PE文件读取到内存中。
44.然后调用LdrInitializeThunk函数对PE映像加载器进行初始化。
45.初始化堆管理器
46.根据导入表加载DLL,并调用DLL的入口函数。
47.当LdrInitializeThunk返回到用户模式后,该线程开始执行应用程序指定的线程启动函数(BaseProcessStart)。
这里需要注意:Vista以后是BaseThreadInitThunk函数

// Before Vista
VOID
BaseThreadStart(
    IN LPTHREAD_START_ROUTINE lpStartAddress,
    IN LPVOID lpParameter
)

在这里插入图片描述

// Vista+
VOID 
BaseThreadInitThunk(
    IN DWORD LdrReserved, 
    IN LPTHREAD_START_ROUTINE lpStartAddress, 
    IN LPVOID lpParameter
);

在这里插入图片描述
而其中的lpStartAddress传入的就是EP入口地址。

48.至此,进程已经完全建立起来了,并正式开始执行用户空间的代码。


http://www.niftyadmin.cn/n/2663404.html

相关文章

面向对象:你怎么还不到我身边来,走到哪里迷路了嘛

各位男生如果看到合适的女生,但自己 “下不了手”,请可劲地介绍给你还单着的亲朋好友 ^_^小帖士1)单身男生和女生都有机会加入面向对象,点击 “阅读原文” 可以开始试用~2)加入面向对象平台后,有…

Google将要推出网络硬盘GDrive?!

之前Google推出 Page Creator,因为拥有100MB空间,所以也算是一个官方的小小的 网络硬盘了。可惜的是它的空间不支持断点续传,因此上传容易下载有点不方便(建议使用FlashGet下载)。不管怎样,Google的本意并不…

高通卖专利起家终成3G时代霸主

高通卖专利起家终成3G时代霸主[more]没有工厂,仅凭借专利授权就能跻身世界500强,在通信巨头高通的美国总部中,你只要稍加留心就能发现高通取得这样“奇迹”的原因。高通专利墙在高通总部,矗立着几面“专利墙” 。高通将自己的每一…

如何让网页产生渐变效果

如何让网页产生渐变效果 网页产生渐变效果不一定非要什么FLASH其实原理非常简单,META标签中就带有动态滤镜的功能。本站的这种效果其实就是用了meta标签而没有做其他任何修改。 你可以把以下这两段加到你的HTML的META头中,再看看效果:-&#…

线程同步—线程锁

一、原子访问:Interlocked系列函数 可以保证一个值的操作是一个原子操作。实际的代码执行过程如下: //C代码: g_x;//汇编: MOV EAX, [g_x] INC EAX MOV [g_X], EAX从上面的代码可以看出,即便是单条C代码,…

为什么Google比Yahoo!成功

先来看一下一项最新的搜索 市场调查结果(by Nielsen//NetRatings),如左图所示,搜索市场的前三名依然是Google、Yahoo!及MSN,它们的市场占有率(美国)分别是48.2%、22.2%、11%。耐人寻味的是&…

搞事情!英伟达最便宜 AI 新硬件,仅 99 美元

(给技术最前线加星标,每天看技术热点)原创整理:技术最前线(ID: TopITNews)参考:Engadget 和 Nvidia一般来说,复杂的人工智能不适合微型电脑一类的自制设备,因为微型电脑几乎不能处理基本功能之外…

微软更新太复杂 美夏令时间转换IT人员耗时大

微软更新太复杂 美夏令时间转换IT人员耗时大[more]4月29日国际报道 美国日光节约时间(夏令时间)调整中,企业发现准备过程既复杂又耗时,尤其对微软Windows电子邮件与服务器软件而言更是如此。依照新法规规定,今年美国的日光节约时间(daylight …