CreateProcess的做了什么
BOOL CreateProcess(
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo, // startup information
LPPROCESS_INFORMATION lpProcessInformation // process information
);
1、创建内核对象
用户层 内核层
CreateProcess NtCreateProcess
高2G中的一块内存
0x10 0x812356 0 句柄表,刚创建时是空的
如果这个刚刚被创建的进程,里面的线程用创建了其他的内核对象
注意:进程是一个空间的概念,而线程才是真正执行的代码
比如:
CreateProcess CreateMutex
CreateThread CreateFile
CreateEvent CreateFileMapping
...
高2G中的一块内存
内核对象的句柄表
0x0 0x812345 0 为了安全,不会给客户端返回
0x1 0x834567 1 真正的地址,而是一个编号
0x2 0x8XXXXX 0
0x3 0x8..... 1
0x4 0x8..... 1
2、分配4GB的虚拟空间(Windows 32位)
0x00000000 - 0x0000FFFF NULL指针使用
int* pnSomeInteger = (int*)malloc(sizeof(int));
*pnSomeInteger = 5;
0x00010000 - 0x7FFFFFFF 用户区
1、将EXE拉伸,存储到指定的位置
1000000 2、遍历EXE导入表,将需要用到的DLL拉伸存储到
指定位置,如果位置被占用,换的地方,并通过
DLL的重定位表,修复全局遍历.
2000000 3、DLL如果引用了其他的DLL 递归第二步
4、修复EXE/DLL中的IAT表
5、创建线程、设置线程CONTEXT 开始执行
内核:
0x80000000 - 0xFFFFFFFF
3、创建进程的主线程
当进程的空间创建完毕,EXE与导入表中的DLL都正确加载完毕后,会创建一个线程 当线程得到CPU的时候,程序就正开始指向了,EIP的初始值设定为:ImageBase+OEP
HANDLE CreateThread(
PSECURITY_ATTRIBUTES psa,
DWORD cbStack,
PTHREAD_START_ROUTINE pfnStartAddr,
PVOID pvParam,
DWORD fdwCreate,
PDWORD pdwThreadID);
当进程创建成功后,会将进程句柄、主线程句柄、进程ID以及主线程ID存储在 typedef struct _PROCESS_INFORMATION
{
HANDLE hProcess; //进程句柄
HANDLE hThread; //主线程句柄
DWORD dwProcessId; //进程ID
DWORD dwThreadId; //线程ID
} PROCESS_INFORMATION; 也就是,CreateProcess的最后一个 OUT 参数
到此,整个进程创建结束了.