C-仅使用ntdll的堆栈分配
是否有API调用或任何其他类似方式,仅使用C-仅使用ntdll的堆栈分配,c,winapi,stack,allocation,ntdll,C,Winapi,Stack,Allocation,Ntdll,是否有API调用或任何其他类似方式,仅使用ntdll.dll,在堆栈上分配内存 我知道alloca() 谢谢 alloca是部分固有函数,由编译器实现。但在内部,它调用\u alloca\u probe\u 16(对于x86)或\u chkstk(x64)以在堆栈上向下移动保护页。此函数的实现存在于alloca16.obj和chkstk.obj中,可在VC子文件夹中找到(具体取决于VC版本)-您可以为链接进程添加此obj,甚至可以先将其转换为lib。同样在最新的WDK库中-存在ntdllp.li
ntdll.dll
,在堆栈上分配内存
我知道alloca()
谢谢 alloca是部分固有函数,由编译器实现。但在内部,它调用\u alloca\u probe\u 16
(对于x86)或\u chkstk
(x64)以在堆栈上向下移动保护页。此函数的实现存在于alloca16.obj
和chkstk.obj
中,可在VC
子文件夹中找到(具体取决于VC版本)-您可以为链接进程添加此obj,甚至可以先将其转换为lib。同样在最新的WDK库中-存在ntdllp.lib
(不要与ntdll.lib
混淆)-它还包含实现的所有需要(ntdll.dll
导出\u chkstk
(对于x86)和\u 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
因此,必须在某个地方实现\u alloca\u probe\u 16
和/或\u chkstk
,否则您会遇到链接错误-未解析的外部符号
在最新的WDK版本中存在包含此实现的ntdllp.lib
(请注意p
-而不是ntdll.lib
)。在这种情况下,您的PE将从ntdll.dll
导入\u chkstk
或\u alloca\u probe
(此函数从XP导出的最小值-这两个函数指向相同的代码,只是别名)
另一种解决方案-在VC
文件夹中可以找到alloca16.obj
和chkstk.obj
-您可以使用此obj作为链接输入(或在单个lib文件中合并alloca16.obj
+chkstk.obj
)。在这种情况下,您的PE将不具有任何导入功能。alloca是部分固有函数,由编译器实现。但在内部,它调用\u alloca\u probe\u 16
(对于x86)或\u chkstk
(x64)以在堆栈上向下移动保护页。此函数的实现存在于alloca16.obj
和chkstk.obj
中,可在VC
子文件夹中找到(具体取决于VC版本)-您可以为链接进程添加此obj,甚至可以先将其转换为lib。同样在最新的WDK库中-存在ntdllp.lib
(不要与ntdll.lib
混淆)-它还包含实现的所有需要(ntdll.dll
导出\u chkstk
(对于x86)和\u 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
因此,必须在某个地方实现\u alloca\u probe\u 16
和/或\u chkstk
,否则您会遇到链接错误-未解析的外部符号
在最新的WDK版本中存在包含此实现的ntdllp.lib
(请注意p
-而不是ntdll.lib
)。在这种情况下,您的PE将从ntdll.dll
导入\u chkstk
或\u alloca\u probe
(此函数从XP导出的最小值-这两个函数指向相同的代码,只是别名)
另一种解决方案-在VC
文件夹中可以找到alloca16.obj
和chkstk.obj
-您可以使用此obj作为链接输入(或在单个lib文件中合并alloca16.obj
+chkstk.obj
)。在这种情况下,您的PE将不再重要。您不需要依赖于体系结构的东西,因为堆栈上的分配(通常)与体系结构无关
如果您使用的是C99,您有一种标准的方法,即使用可变长度数组:
你可以简单地写下这样的话:
char mybuffer[my_size];
它将被分配到堆栈上。您不需要依赖于架构的东西,因为堆栈上的分配(通常)与架构无关
如果您使用的是C99,您有一种标准的方法,即使用可变长度数组:
你可以简单地写下这样的话:
char mybuffer[my_size];
它将被分配到堆栈上。因为alloca
操作堆栈指针,它不是一个“实”函数,而是一个“编译器内部函数”。如果您将使用alloca
的函数编译为汇编语言,您应该看到它直接被翻译为sub esp,NNN
,而不是call alloca
。(除了子esp,NNN
之外,可能还有对函数的调用。在这种情况下,您需要了解该函数的功能,它通常在哪里定义,并安排您的应用程序提供替代。您已经经历了各种不寻常的困难,只使用NTDLL,这只是一个。)
如果确实看到callalloca
和nosub-esp,NNN
,这很可能意味着您的编译器只有一个alloca
的伪实现,它没有给您从堆栈分配的内存,您根本不应该使用它。因为alloca
操作堆栈指针,所以它不是“真实的”函数,它是“编译器固有的”。如果您将使用alloca
的函数编译为汇编语言,您应该看到它直接被翻译为sub esp,NNN
,而不是call alloca
。(除了子esp,NNN
之外,可能还有对函数的调用。在这种情况下,您需要了解该函数的功能,它通常在哪里定义,并安排您的应用程序提供替代。您已经经历了各种不寻常的困难,只使用NTDLL,这只是一个。)
如果您确实看到call alloca
和no子esp,NNN
,这很可能意味着您