4

私はubuntu 12.04および64ビットマシンで作業しています。私はバッファオーバーフローに関する良い本を読んでいました.1つの例で遊んでいると、1つの奇妙な瞬間が見つかりました.

私はこの本当に単純なCコードを持っています:

 void getInput (void){ 
    char array[8];    
    gets (array); 
    printf("%s\n", array); 

 }   
 main() { 
    getInput();    
    return 0;    
 }

ファイルoverflow.cで

32ビットフラグでコンパイルします。本のすべての例は32ビットマシンを想定しているため、次のようにします

 gcc -fno-stack-protector -g -m32 -o ./overflow ./overflow.c

コードでは char 配列は 8 バイトしかありませんでしたが、逆アセンブルを見ると、その配列はスタックに保存された EBP から 16 バイト離れた位置にあることがわかったので、次の行を実行しました。

 printf "aaaaaaaaaaaaaaaaaaaa\x10\x10\x10\x20" | ./overflow

そして得た:

 aaaaaaaaaaaaaaaaaaaa 
 Segmentation fault (core dumped)

次に、コアファイルを開きました:

 gdb ./overflow core
 #0  0x20101010 in ?? ()
 (gdb) info registers
 eax            0x19    25
 ecx            0xffffffff  -1
 edx            0xf77118b8  -143583048
 ebx            0xf770fff4  -143589388
 esp            0xffef6370  0xffef6370
 ebp            0x61616161  0x61616161
 esi            0x0 0
 edi            0x0 0
 eip            0x20101010  0x20101010

ご覧のように、EIP は実際に私が望んでいた新しい価値を手に入れました。しかし、この0x08048410のような有用な値を入れたいとき

 printf "aaaaaaaaaaaaaaaaaaaa\x10\x84\x04\x08" | ./overflow

プログラムはいつものようにクラッシュしますが、EIP レジスタの値を観察しようとすると、奇妙なことが起こります。

 #0  0xf765be1f in ?? () from /lib/i386-linux-gnu/libc.so.6
 (gdb) info registers
 eax            0x61616151  1633771857
 ecx            0xf77828c4  -143120188
 edx            0x1 1
 ebx            0xf7780ff4  -143126540
 esp            0xff92dffc  0xff92dffc
 ebp            0x61616161  0x61616161
 esi            0x0 0
 edi            0x0 0
 eip            0xf765be1f  0xf765be1f

突然、EIP がこの 0xf765be1f のように見え始め、0x08048410 のようには見えません。実際、この崩れた EIP 値を取得するには、0 から始まる任意の 16 進数値を入力するだけで十分であることに気付きました。なぜこれが起こるのか知っていますか?私が64ビットマシンを使用しているからですか?

UPD

コメントの皆さんが詳細を求めました。これは getInput 関数の逆アセンブリです。

 (gdb) disas getInput
 Dump of assembler code for function getInput:
    0x08048404 <+0>:    push   %ebp
    0x08048405 <+1>:    mov    %esp,%ebp
    0x08048407 <+3>:    sub    $0x28,%esp
    0x0804840a <+6>:    lea    -0x10(%ebp),%eax
    0x0804840d <+9>:    mov    %eax,(%esp)
    0x08048410 <+12>:   call   0x8048310 <gets@plt>
    0x08048415 <+17>:   lea    -0x10(%ebp),%eax
    0x08048418 <+20>:   mov    %eax,(%esp)
    0x0804841b <+23>:   call   0x8048320 <puts@plt>
    0x08048420 <+28>:   leave  
    0x08048421 <+29>:   ret 
4

3 に答える 3

3

のコード0x08048410が実行され、 の領域にジャンプした可能性があり0xf765be1fます。

このアドレスには何がありますか? 関数 (libC?) だと思いますので、そのアセンブリ コードを調べて、それが何をするかを確認できます。

また、成功した実行では、EIP ではなく EBP をオーバーランすることができたことにも注意してください。EBP には が含まれ0x61616161aaaaEIP には が含まれ0x20101010ます\n\n\n。破損した EBP が間接的に EIP を破損したようです。
オーバーランを 4 バイト長くしてみると、リターン アドレスもオーバーランするはずです。

于 2012-06-20T09:06:29.457 に答える
1

これはおそらく、最新のOS(Linuxは少なくともWindowsについては知りません)と最新のlibcには、スタックで見つかったコードの実行を許可しないメカニズムがあるためです。

于 2012-06-20T07:45:29.607 に答える
0

バッファ オーバーフローは未定義の動作を引き起こしているため、何かが起こる可能性があります。何が起こるかを理論化することは無駄です。

于 2012-06-20T07:51:03.303 に答える