2012-06-17 14 views
6

私は1つのスタックオーバーフローの例で再生しています。この例は次のようになります。バッファオーバーフローのディレマ

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

} 

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

すべてのコードは、overflow.cというファイルにあります。 return_inputという脆弱な機能を持っています。特に30バイトのchar配列です。私は、出力以下にそれをコンパイルし、GDBに脆弱な機能を開けて得た:

(gdb) disas return_input 
0x08048464 <+0>: push %ebp 
0x08048465 <+1>: mov %esp,%ebp 
0x08048467 <+3>: sub $0x48,%esp 
0x0804846a <+6>: mov %gs:0x14,%eax 
0x08048470 <+12>: mov %eax,-0xc(%ebp) 
0x08048473 <+15>: xor %eax,%eax 
0x08048475 <+17>: lea -0x2a(%ebp),%eax 
0x08048478 <+20>: mov %eax,(%esp) 
0x0804847b <+23>: call 0x8048360 <[email protected]> 
0x08048480 <+28>: lea -0x2a(%ebp),%eax 
0x08048483 <+31>: mov %eax,(%esp) 
0x08048486 <+34>: call 0x8048380 <[email protected]> 
0x0804848b <+39>: mov -0xc(%ebp),%eax 
0x0804848e <+42>: xor %gs:0x14,%eax 
0x08048495 <+49>: je  0x804849c <return_input+56> 
0x08048497 <+51>: call 0x8048370 <[email protected]> 
0x0804849c <+56>: leave 
0x0804849d <+57>: ret  
End of assembler dump. 

あなたは私たちがhex48を予約関数プロローグ(12月72)からわかるように、ローカル変数のスタック上のバ​​イト。まず、脆弱な配列がスタック上で始まるアドレスを見つけようとしていました。私はそれが-0x2a(%ebp)だと思います、そうですか? Hex2aは小数点第4位です。私が理解しているように、スタックに保存されたEBPを上書きする前に42バイトを安全に書き込むことができます。

[email protected]:~/temp/ELF_reader$ ./overflow 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
Segmentation fault (core dumped) 

バッファをオーバーフローするのに十分な37バイトである方法:私はこの例を実行するときしかし、それは、セグメンテーションフォールトを取得する権利のみ37バイトに十分ですか?ローカルのchar配列が保存されたEBPから-42バイトの場合

+0

無関係ですが[この質問](http://stackoverflow.com/questions/9249315/what-is-gs-in-assembly)は*極端に*類似しています。 – huon

+0

Cでは、30バイトの配列に31バイトを書き込むだけで、その配列をオーバーフローさせることができます(未定義の動作が発生します)。 – pmg

答えて

6

関数の分解全体を見ることなくわかりにくいです。

しかし、私の推測によれば、-0xc(%ebp)に格納された%gs:0x14は、stack canaryである可能性があります。これは、スタックのコレクトが検出された場合にクリーンな終了を引き起こします。 したがって、この値は-0xc(%ebp)に格納されます。つまり、バッファのサイズは実際には30バイトになります。

+0

ありがとう、gccスタック保護なしで再コンパイルされたアセンブリコードでは、すべての値が正しく与えられます。 –

関連する問題