3

私の質問は、スタックの割り当て、パディング、および配置に関連しています。次の関数について考えてみます。

void func(int a,int b)
{
    char buffer[5];
}

アセンブリレベルでは、関数は次のようになります。

pushl   %ebp
movl    %esp, %ebp
subl    $24, %esp

スタック上の24バイトがどのように割り当てられているか知りたいです。charbuffer[5]に16バイトが割り当てられていることを理解しています。なぜ余分な8バイトが使われるのか、そしてそれらがどのように割り当てられるのかわかりません。上記のリンクの一番上の答えは、それがretとleaveのためであると言っています。誰かがそれを拡張してくれませんか?

スタック構造は次のようになっていると思います。

[bottom] b , a , return address , frame pointer , buffer1 [top]

しかし、私は単純なバッファオーバーフローを書き込んでいて、リターンアドレスを変更しようとしているため、これは間違っている可能性があります。しかし、何らかの理由で差出人住所は変更されていません。スタックに何か他のものがありますか?

4

2 に答える 2

5

余分なスペースにはいくつかの理由があります。1つは、変数の整列用です。2つ目は、スタックをチェックするためのパディングを導入することです(通常、スペースのリリースビルドではなくデバッグビルド)。3つ目は、レジスターまたはコンパイラーによって生成された一時変数を一時的に保管するための追加のスペースを確保することです。

C呼び出しシーケンスでは、通常行われる方法は、引数をスタックにプッシュする一連のプッシュ命令があり、呼び出し命令を使用して関数を呼び出すことです。呼び出し命令は、リターンアドレスをスタックにプッシュします。

関数が戻ると、呼び出し元の関数はプッシュされた引数を削除します。たとえば、関数(これはC++プログラムを備えたVisualStudio 2005)の呼び出しは次のようになります。

push    OFFSET ?pHead@@3VPerson@@A      ; pHead
call    ?exterminateStartingFrom@@YAXPAVPerson@@@Z ; exterminateStartingFrom
add esp, 4

これは、変数のアドレスをスタックにプッシュし、関数を呼び出し(関数名はC ++ごとにマングルされます)、呼び出された関数が戻った後、スタックポインターに使用されるバイト数を追加して、スタックを再調整します。住所。

以下は、呼び出された関数のエントリ部分です。これは、ローカル変数用にスタックにスペースを割り当てることです。エントリ環境を設定した後、スタックから関数の引数を取得することに注意してください。

push    ebp
mov ebp, esp
sub esp, 232                ; 000000e8H
push    ebx
push    esi
push    edi
lea edi, DWORD PTR [ebp-232]

関数が戻ると、基本的にスタックを関数が呼び出されたときの位置に戻します。各関数は、スタックが戻る前に、スタックに加えた変更をクリーンアップする責任があります。

pop edi
pop esi
pop ebx
add esp, 232                ; 000000e8H
pop ebp
ret 0

差出人住所を変更しようとしているとのことです。これらの例からわかるのは、リターンアドレスがスタックにプッシュされた最後の引数の後にあることです。

これは、関数呼び出しの規則に関する簡単な説明です。Intelアセンブラ命令に関するこのドキュメントも参照してください。

Visual Studio 2005でいくつかの例の作業を行うと、次のコードを実行すると、この例の関数の戻り値にアクセスできるようになります。

void MyFunct (unsigned short arg) {
    unsigned char  *retAddress = (unsigned char *)&arg;
    retAddress -=4;
    printf ("Return address is 0x%2.2x%2.2x%2.2x%2.2x\n", retAddress[3], retAddress[2], retAddress[1], retAddress[0]);
}

このWindows32ビットアドレス指定のコールアセンブラ命令は、リターンアドレスが下位バイトから上位バイトに格納されるバイト順序でリターンアドレスを配置しているように見えることに注意してください。

于 2012-09-03T19:07:01.650 に答える
3

余分なスペースはスタックの配置用であり、通常はパフォーマンスを向上させるために行われます。

于 2012-09-03T18:36:44.877 に答える