日期:2014-05-17 浏览次数:21134 次
转载请注明出处
Q: 在windows下,调用CreateProcess这个API来创建进程,它内部究竟做了什么?
A: 对于操作系统,一般肯定是分层的。内核将处理最终的创建进程操作,但是它的上层可能有一些模块,进行一些参数合法性判断或者为了可移植考虑的判断。windows同样不例外。看看windows下面内核上面的模块:
不妨先写一个CreateProcess的程序,通过逆向工程得到内部调用的东西。
Q: 如下代码:
编译成CreateProcessDemo.exe, 运行:
可以看出,它正确地创建了进程。
A: 下面我们将找出哪个模块包含CreateProcessA函数。进入VS的命令行工具,
使用如下命令dumpbin.exe /all CreateProcessDemo.exe > d:\dumpbin_createprocessdemo.txt得到所有dump的信息,找到如下信息:
可以看出,CreateProcessA是在KERNEL32.DLL中被引用的。
Q: 现在我们可以在kernel32.dll中查看CreateProcessA的调用关系了?
A: 是的。使用ida,打开系统目录下面的kernel32.dll, 并查找CreateProcessA函数的位置:
可以在靠近最后的时候发现调用CreateProcessInternalA例程。
Q: 继续查找CreateProcessInternalA例程的内部实现,它最终会调用CreateProcessInternalW来实现。继续查找CreateProcessInternalW的实现,发现它最终会调用NtCreateUserProcess例程(在xp下,会调用NtCreateProcessEx).此例程不在kernel32.dll中,它在哪里?
A: 正如上面的图示描述,它以nt开头,它在ntdll.dll中。同样适用ida打开ntdll.dll, 找到NtCreateUserProcess的实现:
Q: ZwCreateUserProcess是什么,好像和NtCreateUserProcess是一样的?
A: 仅仅在ntdll.dll中来说,依照上面的截图,它们是一致的;可是在内核中,它们不完全一致。Nt开头的例程会进行访问权限和参数合法性判断,而Zw不会,Zw它可以由内核模式代码直接使用;同时,调用Zw开头的例程会将先前的模式改变为内核模式,而使用Nt开头的例程不能。
Q: 刚刚所说的用户模式是如何进入内核模式的?
A: 上面的ntdll.dll中执行依然是用户模式,NtCreateUserProcess通过向eax传入中断号, edx传入7FFE0300H为参数地址来进行系统调用,进入内核模式。它的内部实现为: