私は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