15

このコードがどのように機能するかはよくわかりません。

char shellcode[] = "\xbb\x00\x00\x00\x00"           
                   "\xb8\x01\x00\x00\x00"                  
                   "\xcd\x80";                  

int main()
{
    int *ret;
    ret = (int *)&ret + 2;
    (*ret) = (int)shellcode;
}

わかりました、私は知っています:

int *ret;

int のポインターを設定します。と:

ret = (int *)&ret + 2;

ret と 2 バイトのアドレスを設定します (と思います)。

しかし、これが何を意味するのかわかりません:

(int *)&ret

意味はわかるけど&ret意味がわからない(int *)&retshellcodeまた、 toの値を代入してシェルコードを実行するにはどうすればよいretですか?

更新:次の違いは何ですか:

(int *)&ret  + 2

と:

&ret + 2
4

1 に答える 1

17

「文字列」shellcodeには、何らかの機械コードが含まれています。

は、 へのポインタでint *ret;ある変数を定義します。retint

割り当てret = (int *)&ret + 2;は、それ自体の実際の場所 (またはアドレス) からret2 のサイズの場所を指します。intこれはスタック内のアドレスであり、おそらく関数の戻りアドレス ( main()) がスタックに格納されている場所です。

割り当て*ret = (int)shellcode;は、シェル コードのアドレスをリターン アドレスに割り当てます。したがって、main()関数が終了するとき、戻りアドレスはシェル コードであり、プログラムを正常に終了する代わりに、何をするかを行います。

キャストは多くの罪を覆い隠します。コードは、おそらくターゲット環境では正当化されますが、他の場所では必ずしも正当化されない、移植性のない多数の仮定を作成します。


&ret+2との違いは何(int *)&ret + 2ですか?

主にタイプします。これは、前述の多数の罪の 1 つです。 は、それ自体の型ではなく&ret、型int **( へのポインターへのポインター) を持ちます。すべての実際のマシンでは、キャストは、数値結果を変更することなく、コンパイラからの苦情 (間違った型のポインターを に割り当てることについて)を鎮めるだけです。intint *retsizeof(int *) == sizeof(int **)ret

于 2012-03-22T03:41:29.073 に答える