是否有 API 调用或任何其他类似方式,仅使用ntdll.dll
, 在堆栈上分配内存?
我知道alloca()
这样做,但我不能使用它,因为我只能使用ntdll.dll
.
谢谢!
是否有 API 调用或任何其他类似方式,仅使用ntdll.dll
, 在堆栈上分配内存?
我知道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 代码时
alloca(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
- not )。ntdll.lib
在这种情况下,您的 PE 将被导入__chkstk
或_alloca_probe
从中导入ntdll.dll
(此函数从 XP 导出的最小值 - 这两个函数都指向相同的代码,只是别名)
另一种解决方案 - 可以在VC
文件夹中找到alloca16.obj
-chkstk.obj
您可以将此 obj 用作链接输入(或在单个 lib 文件中合并alloca16.obj
+ )。chkstk.obj
在这种情况下,您的 PE 将毫无意义。
您不需要依赖于架构的东西,因为堆栈上的分配(通常)是独立于架构的。
如果您使用的是 C99,那么您有一个标准的方法,使用可变长度数组:https ://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
你会很简单地写这样的东西:
char mybuffer[my_size];
它将被分配在堆栈上。
因为alloca
操纵堆栈指针,它不是一个“真正的”函数,它是一个“编译器内在”。如果你编译一个使用alloca
汇编语言的函数,你应该看到它被直接翻译成sub esp, NNN
而不是call alloca
. (除了. 之外,可能还有对函数的调用。sub esp, NNN
在这种情况下,您需要找出该函数的作用,它通常定义的位置,并安排您的应用程序提供替代。您已经跳过了各种不寻常的箍只使用 NTDLL,这只是另外一个。)
如果你看到并且call alloca
no sub esp, NNN
,那很可能意味着你的编译器只有一个虚假的实现,alloca
它没有给你从堆栈分配的内存,你根本不应该使用它。