C - 仅使用ntdll进行堆栈分配

时间:2016-12-13 18:25:57

标签: c winapi stack allocation ntdll

是否存在API调用或仅使用ntdll.dll的任何其他类似方式在堆栈上分配内存?

我知道alloca()会这样做,但我无法使用它,因为我只能使用ntdll.dll中的函数。

谢谢!

3 个答案:

答案 0 :(得分:2)

alloca是部分内部函数,由编译器实现。但在内部它会调用_alloca_probe_16(对于x86)或__chkstk(x64)以在栈上调用移动防护页面。这个函数的实现存在于alloca16.objchkstk.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文件夹中可以找到VCalloca16.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 给你从堆栈分配的内存,你根本不应该使用它。