C-仅使用ntdll的堆栈分配

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

是否有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.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
和no
sub-esp,NNN
,这很可能意味着您的编译器只有一个
alloca
的伪实现,它没有给您从堆栈分配的内存,您根本不应该使用它。

因为
alloca
操作堆栈指针,所以它不是“真实的”函数,它是“编译器固有的”。如果您将使用
alloca
的函数编译为汇编语言,您应该看到它直接被翻译为
sub esp,NNN
,而不是
call alloca
。(除了
子esp,NNN
之外,可能还有对函数的调用。在这种情况下,您需要了解该函数的功能,它通常在哪里定义,并安排您的应用程序提供替代。您已经经历了各种不寻常的困难,只使用NTDLL,这只是一个。)

如果您确实看到
call alloca
和no
子esp,NNN
,这很可能意味着您