在ntdll.dll的内部ZwCreateUserProcess中跳远

时间:2012-12-02 18:33:21

标签: winapi assembly process

我正在尝试了解Windows API如何创建进程,因此我可以创建一个程序来确定无效的exes失败的位置。我有一个调用kernel32.CreateProcessA的程序。在OllyDbg中,调用kernel32.CreateProcessInternalA,调用kernel32.CreateProcessInternalW,调用ntdll.ZwCreateUserProcess。这个功能是:

mov eax, 0xAA
xor ecx, ecx
lea edx, dword ptr [esp+4]
call dword ptr fs:[0xC0]
add esp, 4
retn 0x2C

所以我跟着调用fs:[0xC0],其中包含一条指令:

jmp far 0x33:0x74BE271E

但是当我执行此指令时,Olly只是在通话后的ntdll.ZwCreateUserProcess处回到add esp, 4(不在0x74BE271E)。我在retn 0x2C处设置了一个断点,我发现在执行add esp, 4期间以某种方式创建了新进程。

所以我假设跳远有一些魔法。我尝试将CS​​寄存器更改为0x33,将EIP更改为0x74BE271E,而不是实际执行远跳,但这只是在几条指令后给了我一个访问冲突。这里发生了什么?我需要能够深入研究这个ZwCreateUserProcess的抽象,以弄清楚Windows如何创建流程。

3 个答案:

答案 0 :(得分:5)

jmp far 0x33:0x74BE271E` 

跳跃正在进入内核。 0x33是一个特殊的段选择器,指向某种x86门;这会触发上下文切换到内核。

答案 1 :(得分:4)

您缺少的部分是内核部分。您将要附加内核模式调试器并进入ZwCreateUserProcess的内核端代码以查看如何创建该进程。您还应该看看第5章"流程,线程和工作" Windows Internals第5版或第6版。该章详细介绍了流程创建。

答案 2 :(得分:3)

实际上,该跳转不会进入内核,而是切换到WoW64的x64用户模式子系统(Win64上的Win32)。

选择器33h是一个特殊选择器,覆盖4GB内存空间,但设置为x64模式。跳转到wow64cpu.dll的64位(但仍然是用户模式)部分,它将32位API参数转换为64位API并在64位ntdll.dll中调用API(是的,你有两个在WoW64过程中)。反过来,ntdll会调用进入内核的真实系统调用。

这里有一些链接更详细地描述了这种机制。您还可以通过搜索“天堂之门”这个词来找到更多信息。

http://rce.co/knockin-on-heavens-gate-dynamic-processor-mode-switching/

http://wasntnate.com/2012/04/heavens-gate-64-bit-code-in-32-bit-file/