はGDB

2017-01-19 8 views
0

でリターンアドレスを見つけることができません私は(ちょうどデバッグ目的)Cにそのプログラムを書いた:はGDB

void return_input(void) 
{ 
    char array[10]; 

    gets(array); 
    printf("%s\n", array); 
} 

main() 
{ 
    return_input(); 

    return 0; 

}

私はスタックオーバーフローで実験されており、それ以来私は働いています64ビットマシンの私はその後、gdbでのプログラムをデバッグ

gcc -m32 -mpreferred-stack-boundary=2 -ggdb overflow.c -o overflow 

でそれをコンパイルし、return_input機能を分解し、私が得た:

0x0804841b <+0>: push %ebp 
    0x0804841c <+1>: mov %esp,%ebp 
    0x0804841e <+3>: sub $0xc,%esp 
    0x08048421 <+6>: lea -0xa(%ebp),%eax 
    0x08048424 <+9>: push %eax 
    0x08048425 <+10>: call 0x80482e0 <[email protected]> 
    0x0804842a <+15>: add $0x4,%esp 
    0x0804842d <+18>: lea -0xa(%ebp),%eax 
    0x08048430 <+21>: push %eax 
    0x08048431 <+22>: call 0x80482f0 <[email protected]> 
    0x08048436 <+27>: add $0x4,%esp 
    0x08048439 <+30>: nop 
    0x0804843a <+31>: leave 
    0x0804843b <+32>: ret 

これは、リターンアドレスが0x0804843bされるべきであるとマーク(または、それはないですか?)ESPを調べるときしかし、にブレークポイントを設定した後(x/20x $espと(これは、64ビットマシン上でプログラムをコンパイルした32ビットであることを覚えています)返品先住所を見つけることができません:

0xffffd400: 0xffffd406 0x080481ec 0x08048459 0x00000000 
    0xffffd410: 0xffffd418 0x08048444 0x00000000 0xf7e195f7 
    0xffffd420: 0x00000001 0xffffd4b4 0xffffd4bc 0x00000000 
    0xffffd430: 0x00000000 0x00000000 0xf7fb0000 0xf7ffdc04 
    0xffffd440: 0xf7ffd000 0x00000000 0xf7fb0000 0xf7fb0000 

返品先住所が表示されないのはなぜですか?長い質問を申し訳ありません。ありがとうございます。

+0

あなたが取得した文字列はどれくらいフェッチされましたか?リターンアドレスを上書きするのは、悪意のあるコードを実行するためにバッファオーバーフローを使用する方法とまったく同じです... – StoryTeller

+0

@StoryTeller私はすでに質問で言及したとおりです。私は、取得で休憩を設定し、まだ何も入力していない。問題は返信先が表示されないことです –

+0

@StoryTellerその点について詳しく説明できますか? –

答えて

2

0x0804843bは「ret」です。あなたはそれを「リターンアドレス」と混同しているようです。戻りアドレスは、呼び出し関数で実行する次の命令のアドレスです。特にこのコードの場合:

0x08048425 <+10>: call 0x80482e0 <[email protected]> 
    0x0804842a <+15>: add $0x4,%esp 

リターンアドレスは0x0804842aです。

今、正確に何をしたのか不明です。あなたが指定した通りにコンパイルすると、「ブレーク・アゲイン」+「ラン」がうまく動作します。あなたは "内"の取得からregsを投げていると確信していますか?

(gdb) disassemble return_input 
Dump of assembler code for function return_input: 
    0x0804843b <+0>: push %ebp 
    0x0804843c <+1>: mov %esp,%ebp 
    0x0804843e <+3>: sub $0xc,%esp 
    0x08048441 <+6>: lea -0xa(%ebp),%eax 
    0x08048444 <+9>: push %eax 
    0x08048445 <+10>: call 0x8048300 <[email protected]> 
    0x0804844a <+15>: add $0x4,%esp 

これは命令を取得する必要があります。

0x0804844d <+18>: lea -0xa(%ebp),%eax 
    0x08048450 <+21>: push %eax 
    0x08048451 <+22>: call 0x8048310 <[email protected]> 
    0x08048456 <+27>: add $0x4,%esp 
    0x08048459 <+30>: nop 
    0x0804845a <+31>: leave 
    0x0804845b <+32>: ret  
End of assembler dump. 

(gdb) break gets 
Breakpoint 1 at 0x8048300 
(gdb) run 
[..] 
Breakpoint 1, 0xf7e3a005 in gets() from /lib/libc.so.6 
(gdb) x/20x $esp 
0xffffd160: 0x00000001 0xf7fa3000 0xffffd180 0x0804844a 

ここでは4位です。

0xffffd170: 0xffffd176 0x0804820c 0x08048479 0x00000000 
0xffffd180: 0xffffd188 0x08048464 0x00000000 0xf7df15a6 
0xffffd190: 0x00000001 0xffffd224 0xffffd22c 0x00000000 
0xffffd1a0: 0x00000000 0x00000000 0xf7fa3000 0xf7ffdbe4 
(gdb) 
+0

私はここで3つの質問を持っています:1)戻りアドレスが、関数から戻った後に実行される次の命令のアドレスでない場合は、それは何ですか?2)セグメンテーションフォルトを取得するために、どのアドレスをオーバーフローする必要がありますか? 3) 'x/20x $ esp'コマンドで' ret'アドレスを見つけることができないのはなぜですか? –

+0

1.最初にダンプしているスタック状態は何ですか? 2.戻りアドレスが保存されている場所を上書きする必要があります。 3.なぜあなたは 'ret'の住所を探していますか?どこにbtしましたか?一般的には、テーマに関する古典を読むことをおすすめします:http://phrack.org/issues/49/14.html –