これはアーキテクチャとコンパイラ フラグに大きく依存するため、ここで 1 つのことを指摘して「これに違いない」と言うのは不可能です。ただし、役立つと思われるヒントをいくつか紹介できます。
まず、スタック境界について考えます。-mpreferred-stack-boundary=X
GCC へのフラグについて聞いたことがあるかもしれません。そうでない場合は、基本的に、スタック上の値をそれぞれ 2 Xバイトにすることをコンパイラに指示します。コンパイラは、これらの値がスタックにできるだけ収まるようにプログラムを最適化しようとします。一方、 などの GCC 修飾子__packed__
を使用すると、コンパイラはスタック内のデータを可能な限り密に収めようとします。
スタックプロテクターもあります。基本的に、GCC はダミーの値をスタックに配置し、バッファー オーバーフローがプログラムのセグメンテーション違反以外に害を及ぼさないようにします (これは楽しいことではありませんが、攻撃者が命令ポインターの制御を追跡するよりはましです)。これは簡単に試すことができます。GCC の最近のバージョンを使用して、ユーザーにバッファをオーバーフローさせます。プログラムが「スタック破壊が検出されました、終了しました」という行に沿ったメッセージで終了することに注意してください。を使用してプログラムをコンパイルしてみてください-fno-stack-protector
。スタックに割り当てられたローカル メモリはおそらく少なくなります。
最後に、cdecl 呼び出し規則がどのように機能するかについて、あなたが誤解している小さな詳細がいくつかあります。引数は、関数を呼び出す前にスタックにプッシュされます。つまり、引数はスタックのメモリの上位にあることを意味します (スタックはメモリの下位に成長することに注意してください)。以下は、3 つの引数を必要とし、2 つのローカル整数変数を割り当てる関数の非常に単純化された例です。
# First we push three arguments on the stack in reverse order as they
# appear in C. The values don't matter here.
pushl $0xc
pushl $0xb
pushl $0xa
# A CALL instruction comes in here to get in the function. The return
# address is placed on the stack.
# Assume we are in the function now. This function first saves the base
# pointer, then sets the base pointer to the address in the stack pointer.
pushl %ebp
movl %esp, %ebp
# Now we can allocate our local variables. We need 8 bytes of space for
# those 2 integer variables (note that this is an extremely simplified
# example that doesn't consider what I just told you above).
subl $0x8, %esp
# Let's just put 1 and 2 in those variables.
movl $0x1, -4(%ebp)
movl $0x2, -8(%ebp)
# We're done. Put a return value in EAX, then restore the stack- and
# base pointers.
movl $0x0, %eax
movl %ebp, %esp
popl %ebp
ret
基本的に、スタックは次のようになります。
16(%ebp) -> Argument 3
12(%ebp) -> Argument 2
8(%ebp) -> Argument 1
4(%ebp) -> Return address
%ebp -> Old %ebp pushed on the stack by function
-4(%ebp) -> Local variable 1
-8(%ebp) -> Local variable 2
つまり、ローカル変数のみがベース ポインターよりも下位のメモリに存在します。正直なところ、スタック上のローカル変数のサイズに影響を与える可能性のあるものが他にもいくつかありますが、含めるのを忘れていましたが、これが少し役立つことを願っています. プログラムをハッキングし続けると、それがわかるでしょう。:)