在ntdll.dll的内部ZwCreateUserProcess中跳远

jca*_*cai 4 assembly winapi 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
Run Code Online (Sandbox Code Playgroud)

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

jmp far 0x33:0x74BE271E
Run Code Online (Sandbox Code Playgroud)

但是,当我踏上这个指令,奥利刚回来ntdll.ZwCreateUserProcessadd esp, 4通话之后(这是不是0x74BE271E).我给了一个断点retn 0x2C,我发现新进程是在执行期间以某种方式创建的add esp, 4.

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

nin*_*alj 5

jmp far 0x33:0x74BE271E` 
Run Code Online (Sandbox Code Playgroud)

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


Igo*_*sky 5

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

选择器 33h 是一个特殊的选择器,它覆盖了 4GB 内存空间,但设置为 x64 模式。跳转到 wow64cpu.dll 的 64 位(但仍然是用户模式)部分,它将 32 位 API 参数转换为 64 位参数并调用 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/