Windows 上的系统调用使用的隐藏堆栈是什么?

逆向工程 视窗 记忆 内存转储 系统调用 虚拟内存
2021-06-18 02:23:19

我注意到在 Windows 7 x64 WOW64 上的用户模式中有一个内存区域在系统调用期间会发生变化。它位于地址空间的相当低的位置,具有堆栈的特征,即它以一个大的保留区、一个页面保护和几页 R/W 开始。只有一个线程在运行,而且它有自己的堆栈,所以我认为它没有连接。

例如,如果我调用 NtQueryVirtualMemory,这是一个相当恒定的系统调用,因为它应该只填充一个结构而不修改地址空间的任何其他内容,即使如此,内存区域也会随着一些分散在各处的更改而更新。有没有人有关于这是什么的任何信息?它是用户模式下内核的某种暂存空间吗?

我还注意到,当有两个线程时,还会有另一个这样的隐藏区域,所以它可能是每个线程。

任何有关 Windows 标准内存布局的文档都会很棒。

2个回答

这不会在系统调用期间发生。它发生在用户模式下。

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 位,然后进行本地系统调用。

强调最后一句话是我的。它没有明确说明参数的提取和扩展是在单独的堆栈上完成的,但这并不是一个疯狂的猜测。

您可以使用内核调试器并在该区域上设置硬件断点以捕获对其的访问(内核访问不能被用户模式调试器捕获)。希望这会给你一些线索。