是否有仅使用 ntdll.dll
的 API 调用或任何其他类似方式在堆栈上分配内存?
我知道 alloca()
会这样做,但我不能使用它,因为我只能使用 ntdll.dll
中的函数。
谢谢!
最佳答案
alloca 是部分内在函数,由编译器实现。但在内部它调用 _alloca_probe_16
(对于 x86)或 __chkstk
(x64) 将保护页面向下移动到堆栈中。此函数的实现存在于 alloca16.obj
和 chkstk.obj
中,它们可以在 VC
子文件夹中找到(完全依赖于 VC 版本)-您可以为链接过程添加此 obj,甚至可以先将其转换为 lib。也在最新的 WDK 库中 - 存在 ntdllp.lib
(不要与 ntdll.lib
混淆) - 它也包含所有需要的实现(ntdll.dll
导出 _chkstk
(对于 x86)和 __chkstk
(对于 x64))
再次详细说明:
当你写src代码时
分配(cb)
CL
x86 编译器生成
mov eax,cb
call _alloca_probe_16 ; do actual stack allocation and probe
在 x64 版本中
mov ecx,eax
add rcx,0Fh
cmp rcx,rax
ja @@0
mov rcx,0FFFFFFFFFFFFFF0h
@@0:
and rcx,0FFFFFFFFFFFFFFF0h
mov rax,rcx
call __chkstk ; probe only
sub rsp,rax ; actual stack allocation
因此 _alloca_probe_16
和/或 __chkstk
必须在某处实现,否则您会遇到链接错误 - 未解析的外部符号。
在最新的 WDK 版本中存在包含此实现的 ntdllp.lib
(注意 p
- 而不是 ntdll.lib
)。在这种情况下,您的 PE 将从 ntdll.dll
导入 __chkstk
或 _alloca_probe
(此函数从 XP 导出最小值 - 这两个函数都是重点到相同的代码,只是别名)
另一个解决方案 - 在 VC
文件夹中可以找到 alloca16.obj
和 chkstk.obj
- 你可以使用这个 obj 作为链接输入(或将 alloca16.obj
+ chkstk.obj
合并到单个 lib 文件中)。在这种情况下,您的 PE 将毫无意义。
关于C - 仅使用 ntdll 的堆栈分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41128061/