是否有API调用或任何其他类似的方式(只使用ntdll.dll )来分配堆栈上的内存?
我知道alloca()会这样做,但我不能使用它,因为我只能使用来自ntdll.dll的函数。
谢谢!
发布于 2016-12-13 18:32:23
alloca是部分内禀函数,由编译器实现。但在内部,它调用_alloca_probe_16 (用于x86)或__chkstk(x64),用于在堆栈上向下移动保护页面。这个函数的实现存在于alloca16.obj和chkstk.obj中,它们可以在VC子文件夹中找到(在这些子文件夹中完全依赖于VC版本)--您可以为链接进程添加这个obj,甚至可以首先将它转换为lib。另外,在最新的WDK库中
同样,在更多细节中:
当您使用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 -而不是ntdll.lib)。在本例中,PE将从__chkstk或_alloca_probe中导入ntdll.dll (此函数如何从XP导出最小值-这两个函数都指向相同的代码,只是别名)
另一种解决方案--在VC文件夹中可以找到alloca16.obj和chkstk.obj --您可以使用这个obj作为链接输入(或者在单个lib文件中合并alloca16.obj + chkstk.obj )。在这种情况下,您的PE将没有什么重要的。
发布于 2016-12-13 18:33:29
您不需要依赖于体系结构的东西,因为堆栈上的分配(通常)与体系结构无关。
如果您使用的是C99,那么可以使用可变长度数组( https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html )来执行此操作。
你只需写这样的东西:
char mybuffer[my_size];它将被分配到堆栈上。
发布于 2016-12-13 18:43:19
因为alloca操作堆栈指针,所以它不是“真正的”函数,而是“编译器内在的”。如果将使用alloca编译成汇编语言的函数编译成汇编语言,则应该看到它是直接转换为sub esp, NNN而不是call alloca的。(除了sub esp, NNN之外,还可能调用一个函数。在这种情况下,您需要了解该函数的功能,它通常是在哪里定义的,并安排您的应用程序提供替代功能。您已经跳过了各种不寻常的循环,只使用NTDLL,这只是另外一个。)
如果您确实看到了call alloca而没有sub esp, NNN,这很可能意味着您的编译器只有一个假的alloca实现,它没有为您分配从堆栈中分配的内存,因此您根本不应该使用它。
https://stackoverflow.com/questions/41128061
复制相似问题