我正在尝试了解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如何创建流程。
答案 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/