进程的创建过程
什么是进程?
一个exe文件能算是进程吗?
不能,因为这是死的程序,也就是在内存中没有他的位置,他只是在磁盘中,当双击运行后,他在内存中展开,才算真正的进程
例如
打开资源管理器,这些就是进程,有名字,有唯一的PID等
进程提供程序所需的资源,如:数据、代码等
进程就好比是一个装修好的房子,提供各种家具,而住在房子里的人就好比线程,来使用这些资源,目前不涉及线程相关的内容
那到底进程长啥样?
我们用OD来附加一个正在运行的程序,或者说是进程
随便附加一个,然后点击Memory模块,这些就是进程提供的数据与代码,可以发现,最开始是从0x10000,开始的,怎么不从0开始?
每一个进程都有自己的4GB虚拟空间,而0~64K,即0000~0xFFFF
通常情况下是不会使用的,然后我们拉到最后
看到最后的地址是0x7FFE0000,欸不是有4GB吗,咋到这儿就结束了?
从0x80000000到0xFFFFFFFF之间这个被称作高2G,是给内核程序用的
所以,每一个进程都有自己的4GB虚拟空间,实际上说的是只有低2G才属于当前进程,因为高2G是共享的
在所以,每一个进程都有自己的4GB虚拟空间,这句话只是看起来是这样的
总之可以用一张表来展示
分区 |
x86 32位Windows |
空指针赋值区 |
0x00000000 ~ 0x0000FFFF |
用户模式区 |
0x00010000 ~ 0x7FFEFFFF |
64KB禁入区 |
0x7FFF0000 ~ 0x7FFFFFFF |
内核 |
0x80000000 ~ 0xFFFFFFFF |
就像一张空头支票一样,名义上是4GB,实际却不是
倘若真的是4GB,那这么多进程,那内存不就炸了吗
这里解释一下为什么0000~0xFFFF是64KB
16进制的每一个数都是0~F共16个数,这里有四位,所以就是16的4次方,即16^4 = 65536,也就是排列组合的问题,然后知道1KB = 2^10B,所以65536/(2^10)= 64
所以称为64KB,其他的同理
在上面进程中,可以注意到,这些数据好像都是一块一块的,并且格式都差不多
这些进程,不是由一个文件组成的,而是由一堆相同类型文件组成的,那这个类型是什么呢,就是PE文件结构,PE文件的讲解,还请观看其他大佬的文章
这里可以看看,点击上面E模块,就在M模块的左边
这些就是PE文件,这些就是进程所提供的资源,可以理解成这些都是封装好了的资源
所以,进程就是由一堆PE文件所组成的
进程的创建步骤
1.任何进程都是别的进程创建的:会用到win API CreateProcess()函数
2.进程的创建过程
- 映射exe文件
- 创建内核对象EPROCESS
- 映射系统DLL(ntdll.dll)
- 创建线程内核对象ETHREAD
- 系统启动线程
- 映射DLL(ntdll.LdrlnitializeThunk)
- 线程开始执行
①:映射exe文件,在图中的用户区域
②:创建内核对象,每一个进程对象都有一个,这里不用深究,知道就行
③:映射系统DLL(ntdll.dll),任何一个exe文件都会用到系统的dll,也就是ntdll.dll
④:创建线程内核对象,创建进程的时候必须要创建至少一个线程,因为进程只是提供资源,而线程才是使用资源,没有线程,则该进程是没有意义的
⑤-1:映射DLL,启动之前还要映射dll,至于是什么,上面说过的一堆PE文件,就是映射这些(不一定只有dll),学了PE就知道了
总结
- 进程是由一堆PE文件组成的
- 进程只提供资源,不管如何使用
- 线程才是使用进程提供的资源