是否存在API调用或仅使用ntdll.dll
的任何其他类似方式在堆栈上分配内存?
我知道alloca()
会这样做,但我无法使用它,因为我只能使用ntdll.dll
中的函数。
谢谢!
答案 0 :(得分:2)
alloca是部分内部函数,由编译器实现。但在内部它会调用_alloca_probe_16
(对于x86)或__chkstk
(x64)以在栈上调用移动防护页面。这个函数的实现存在于alloca16.obj
和chkstk.obj
中,可以在VC
子文件夹中找到(其中exacly依赖于VC版本) - 您可以为链接过程添加此obj,甚至可以先将其转换到lib。同样在最新的WDK库中 - 存在ntdllp.lib
(不与ntdll.lib
混淆) - 它还包含所有实现需求(ntdll.dll
导出_chkstk
(对于x86)和{{1 (对于x64))
再次详细说明:
当您使用src代码编写
时 __chkstk
alloca(cb)
编译器在x86中生成
CL
和x64版本
mov eax,cb
call _alloca_probe_16 ; do actual stack allocation and probe
所以必须在某处实现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
,否则会出现链接错误 - 未解析的外部符号。
在最新的WDK版本中存在__chkstk
(注意ntdllp.lib
- 而不是p
),其中包含此实现。在这种情况下,您的PE将从ntdll.lib
导入__chkstk
或_alloca_probe
(此函数导出XP的最小值 - 这两个函数都指向相同的代码,只是别名)
另一个解决方案 - 在ntdll.dll
文件夹中可以找到VC
和alloca16.obj
- 您可以将此obj用作链接输入(或合并chkstk.obj
+ alloca16.obj
在单个lib文件中)。在这种情况下,您的PE将无需导入。
答案 1 :(得分:1)
您不需要依赖于体系结构,因为堆栈上的分配(通常)与体系结构无关。
如果您正在使用C99,那么您可以使用可变长度数组进行标准方法:https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
你只需写下这样的东西:
char mybuffer[my_size];
它将被分配到堆栈中。
答案 2 :(得分:1)
因为alloca
操纵堆栈指针,所以它不是真实的"功能,它是一个"编译器内在"。如果您编译使用alloca
汇编语言的函数,应该看到它直接转换为sub esp, NNN
而不是call alloca
。 (除了 sub esp, NNN
之外,可能还会调用函数。在这种情况下,您需要找出该函数的作用,它通常定义的位置,并安排为你的应用程序提供替代品。你已经跳过了各种不寻常的箍,只能使用NTDLL,这只是一个。)
如果您执行,请参阅call alloca
而不是sub esp, NNN
,这很可能意味着您的编译器只有alloca
的假实现< em> not 给你从堆栈分配的内存,你根本不应该使用它。