1

ntdll.dllのみを使用してスタックにメモリを割り当てるAPI 呼び出しまたは別の同様の方法はありますか?

私はそれを知っalloca()ていますが、からの関数しか使用できないため、使用できませんntdll.dll

ありがとう!

4

3 に答える 3

2

alloca は部分的に組み込み関数であり、コンパイラによって実装されます。ただし、内部的には_alloca_probe_16(x86 の場合) または__chkstk(x64) を呼び出して、ガード ページをスタックに移動します。この関数の実装は、サブフォルダー (VC バージョンに正確に依存する場所) に存在し、そこにあります。この obj をリンク プロセスに追加するか、最初に lib に変換することもできますalloca16.obj。最新のWDKライブラリにも存在します(と混同しないでください)-実装に必要なすべてのものが含まれています(エクスポート(x86の場合)および(x64の場合))chkstk.objVCntdllp.libntdll.libntdll.dll_chkstk__chkstk


もう一度詳細に:

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- not )。ntdll.libこの場合、PE は import__chkstkまたは_alloca_probefromになりますntdll.dll(この関数は XP から最小限の方法でエクスポートされます - この関数は両方とも同じコードを指し、単にエイリアスです)

別の解決策 -VCフォルダー内で見つけることができalloca16.objchkstk.obj- この obj をリンク入力として使用できます (またはalloca16.obj+chkstk.objを単一の lib ファイルにマージします)。この場合、PE は何もインポートされません。

于 2016-12-13T18:32:23.543 に答える
1

スタック ポインターを操作するためalloca、"実際の" 関数ではなく、"コンパイラ組み込み関数" です。allocaアセンブリ言語を使用する関数をコンパイルすると、ではなくに直接変換されることわかります。(に加えて関数の呼び出しがあるかもしれません。その場合、その関数が何をするのか、通常はどこで定義されているのかを調べ、アプリケーションが代替を提供するように手配する必要があります。あなたはすでにあらゆる種類のものを飛び越えています。 NTDLL だけを使用する異常なフープの、これはちょうど 1 つです。)sub esp, NNNcall allocasub esp, NNN

と no表示される場合は、コンパイラがスタックから割り当てられたメモリを提供しない偽の実装しかないことを意味する可能性が非常に高く、まったく使用しないでくださいcall allocasub esp, NNNalloca

于 2016-12-13T18:43:19.563 に答える
1

スタックへの割り当ては(一般に)アーキテクチャに依存しないため、アーキテクチャに依存するものは必要ありません。

C99 を使用している場合は、可変長配列を使用してこれを行う標準的な方法があります: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

次のように簡単に書くことができます。

char mybuffer[my_size];

そして、スタックに割り当てられます。

于 2016-12-13T18:33:29.777 に答える