映射内存的可执行文件和dll
当一个线程调用CreateProcess的时候,系统会执行以下步骤:
- 系统会先确定CreateProcess所指定的可执行文件的所在位置。如果找不到文件,那么CreateProcess会返回FALSE。、
- 系统创建一个内核对象EProcess
- 系统为新进程创建一个私有的地址空间
- 系统预定一个足够大的地址空间来容纳.exe文件。PE文件中有指定的预定位置。默认情况下,.exe文件的基地址为0x00400000,构建exe代码时,可以通过/BASE链接器开关,来指定一个预定地址。
- 系统会对地址空间的区域进行标注,表明该区域的后备物理储存器来自磁盘上的exe文件,而不是页交换文件。
当系统把.exe文件映射到进程的地址空间之后,会访问.exe文件中的一个段,这个段列出了一些DLL文件,它们包含该.exe文件调用的函数。然后系统会调用LoadLibrary来加载每个dll,如果载入的DLL中还需要其他的DLL,
系统也会同样的调用LoadLibrary来加载DLL,系统加载DLL的时候,会执行以下操作:
- 系统会预定一块足够大的地址空间区域来容纳DLL文件。预定的地址空间区域已经在DLL文件中指出。默认情况下X86平台的DLL的基地址为0x10000000,x64平台上是0x00400000.但是,只需在构建DLL文件时使用/BASE链接器开关,就能指定一个预定地址。
- 如果系统无法在DLL文件中指出的预定基地址处预定区域,原因有两种①该位置已经被其他的DLL后者exe占用 ②区域不够大。这个时候系统会尝试在其他位置加载DLL。 如果系统无法加载DLL到指定的位置,那么有可能就是DLL中不包括重定位信息,那么系统就无法在其他位置加载DLL。
- 系统会对地址空间区域进行标注,表明该区域的后备物理存储器时来自磁盘上的DLL文件,而并非来自系统的页交换文件。如果由于Windows不能将DLL载入到指定的位置而进行重定向的话,系统还会另外的进行i标注,表明DLL中的一部分物理存储器被映射到了页交换文件中。
内存映射文件
要使用内存映射文件,需要执行三个步骤:
- 创建或打开一个文件内核对象,该对象标识内存映射文件的那个磁盘文件。 CreateFile
- 创建了一个文件映射内核对象来告诉系统该文件的大小以及访问权限。 CreateFileMapping
- 告诉系统把文件映射对象的部分或者全部映射到进程的地址空间中去。 MapViewOfFile
- .................................................
- 取消进程地址空间对文件内核对象的映射。 UnmapViewOfFile
- 关闭文件映射对象 CloseHandle
- 关闭文件内核对象 CloseHandle