基本的に私が利用している機能はこれです:
int getbufn()
{
char buf[512];
Gets(buf);
return 1;
}
メインプログラムを実行すると、関数は5回実行され、bufの場所が変わるたびに、%ebpの場所も変わります。私がすることになっているのは、特定の16進値(たとえば0xFFFFFFFF)を変数に配置することです。メインプログラムは、その変数が存在するかどうかを毎回チェックします。そうである場合は、5回すべてが完了し、プログラムが静かに終了するまで、再度実行されます。
私が抱えている問題は、16進値のチェックの直前に、定数である別の値、たとえば0x12345678のチェックがあることです。0x12345678が破損していて、そこにない場合、プログラムが爆発します。
0x12345678が-0x10(%ebp)に格納されていることがわかったので、%ebpに基づいており、毎回%ebpのアドレスを知っていますが、エクスプロイトを機能させることができるのは初めてです。これを行うには、基本的に496バイトをnopsledし、このマシンコードをバイト形式にします。
mov 0xFFFFFFFF, %eax
movl address old ebp, %ebp
push correct return adress in function main
ret
これは最終的に5ワードになり、リターンロングのバイトになります。これを0x313131で埋めて、6ワードの長さにします。この時点で、私のエクスプロイト文字列は520バイトの長さであり、これはバッファが%ebpを下回っている正確な量です。したがって、古いebpのアドレスと、nopsled内のどこかにアドレスを追加して、%ebpの現在の値とリターンを上書きします。 getbufnのアドレス。
問題は、プログラムが2回目に実行されるときに、%ebpが前のアドレスよりも0x10低いアドレスにあるため、%ebpを破損しない方法が機能せず、mainが0x12345678が-0x10(%ebp)にないことを検出することです。%ebpを破損しないようにするにはどうすればよいですか?