这不会在系统调用期间发生。它发生在用户模式下。
WOW64 进程有两个用户模式堆栈 - 一个 32 位堆栈(您通常使用的堆栈)和一个 64 位堆栈。WOW64 ntdll 不进行系统调用。在本机 32 位 ntdll 将sysenter
(通过对 的间接调用SharedUserData!SystemCallStub
)的情况下,WOW64 ntdll 对wow64cpu!X86SwitchTo64BitMode
( call dword ptr fs:[0C0h]
)进行间接调用。
此函数使用一个特殊的选择器进行远跳,导致从 32 位模式切换到 64 位模式。然后 WOW64 层制作参数的副本,扩大任何必要的范围等,并继续进行真正的系统调用。
我敢打赌,您使用 32 位调试器来调试 WOW64 进程,而 32 位调试器不显示模式转换。它不能。但这仍然发生在用户模式下。
WOW64 上的任何最基本的来源都会告诉您,您应该能够自己猜测。这是迄今为止一个用户模式组件更合理的照顾模式转换,并保持内核仅64位,而不是具有32位和64位模式下的内核来处理系统调用。
MSDN 页面WOW64 实现细节实际上说明了这两件事:
进行系统调用的 32 位二进制文件不是使用 x86 系统服务调用序列,而是重建为使用自定义调用序列。这个调用序列对于 WOW64 拦截来说并不昂贵,因为它完全处于用户模式。当检测到自定义调用序列时,WOW64 CPU 转换回本机 64 位模式并调用 Wow64.dll。Thunking 在用户模式下完成,以减少对 64 位内核的影响,并降低 thunk 中可能导致内核模式崩溃、数据损坏或安全漏洞的错误的风险。thunk 从 32 位堆栈中提取参数,将它们扩展到 64 位,然后进行本地系统调用。
强调最后一句话是我的。它没有明确说明参数的提取和扩展是在单独的堆栈上完成的,但这并不是一个疯狂的猜测。