0

クラスに対していくつかのバイナリ分析を行う必要があり、プログラムの1つで立ち往生しています。いくつかのブレークポイントとdisasを設定すると、次のようになります。

Dump of assembler code for function main:
    0x080484e2 <+0>:    push   %ebp
    0x080484e3 <+1>:    mov    %esp,%ebp
    0x080484e5 <+3>:    sub    $0x48,%esp
    0x080484e8 <+6>:    and    $0xfffffff0,%esp
    0x080484eb <+9>:    mov    $0x0,%eax
    0x080484f0 <+14>:   sub    %eax,%esp
    0x080484f2 <+16>:   cmpl   $0x1,0x8(%ebp)
    0x080484f6 <+20>:   jg     0x8048504 <main+34>
    0x080484f8 <+22>:   movl   $0x7,(%esp)
 => 0x080484ff <+29>:   call   0x804833c <exit@plt>
    0x08048504 <+34>:   mov    0xc(%ebp),%eax
    0x08048507 <+37>:   add    $0x4,%eax
    0x0804850a <+40>:   mov    (%eax),%eax
    0x0804850c <+42>:   mov    %eax,(%esp)
    0x0804850f <+45>:   call   0x804832c <atoi@plt>
    0x08048514 <+50>:   mov    %eax,-0x10(%ebp)
    0x08048517 <+53>:   cmpl   $0xd,-0x10(%ebp)
    0x0804851b <+57>:   jne    0x804853b <main+89>
    0x0804851d <+59>:   lea    -0x38(%ebp),%eax
    0x08048520 <+62>:   mov    %eax,(%esp)
    0x08048523 <+65>:   call   0x8048414 <makebuf>
    0x08048528 <+70>:   lea    -0x38(%ebp),%eax
    0x0804852b <+73>:   mov    %eax,0x4(%esp)
    0x0804852f <+77>:   movl   $0x804863b,(%esp)
 ** 0x08048536 <+84>:   call   0x804831c <printf@plt>
    0x0804853b <+89>:   movl   $0x1,(%esp)
    0x08048542 <+96>:   call   0x804833c <exit@plt>
End of assembler dump.

(printf @ pltへの呼び出しの場所の横にある星で編集しました)。私には、exit()を呼び出して文字列を作成し、その文字列を出力してから、別のexit()を実行するプログラムのように見えます。この最初のexit()の呼び出しをバイパスできれば、チャレンジへの答えが出力されると思います。NOPを実行するための呼び出しが発生する場所を設定するためにこれを行う正しい方法はありますか?もしそうなら、NOPのオペコードは何ですか?0x0と0x00000000に設定してみました。どんな助けでも大歓迎です!ありがとう。

4

5 に答える 5

3

線を見て

0x080484f2 <+16>:   cmpl   $0x1,0x8(%ebp)
0x080484f6 <+20>:   jg     0x8048504 <main+34>

プログラムに最初の出口をスキップさせる方法を確認する - インジェクションの必要はない

于 2012-08-29T20:08:21.427 に答える
1

次の行があるため、必ずしも終了するとは限りません。

cmpl   $0x1,0x8(%ebp)

この行では、プログラムはこの関数の最初の引数の値を 1 でチェックし、1 より大きい場合はジャンプします。
また、ここでprintfのフォーマットを見たい場合はprintf "%s", 0x804863b、gdbで入力できます。
更新 :
このプロシージャがメインの場合、0x8($ebp)いわゆる argc が含まれます。これは、プログラムの入力数です。したがって、プログラムを実行しているときに必要なことは、プログラムに入力を与えることです。のように./a.out blah。また、gdb
に入力してこの値を確認することもできます。x/2wx $esp

于 2012-08-29T20:16:24.060 に答える
1

おそらく、終了する呼び出しを単に NOP アウトしたくないでしょう。今回はそれを回避できるかもしれませんが、exit の両方の呼び出しで、呼び出しの前に終了コードをスタックに配置しています。プログラムの残りの部分に応じて、これらのスタック値が使用される場合と使用されない場合があります。

したがって、オプションは、MOV と CALL の両方を NOP アウトするか、ジャンプを常に希望どおりに強制するかのいずれかです。

または、最善の方法は、どのパラメーターが目的の動作をさせるかを正確に把握することです。

また、x86 の標準 NOP オペコードは 0x90 です。

于 2012-08-29T20:21:12.660 に答える
1

これが宿題に関するものである場合は、何が許可されているかを知っておく必要があります。

パッチ適用が許可されている場合、オペコードを jg から jng に変更するのが最善の方法です。インテルのマニュアルを調べて、何を変更する必要があるかを確認する必要がありますが、通常は 1 バイトになります。

パッチが許可されていない場合は、比較対象の変数を設定する関数を見つけ、その関数を別の値に設定する方法を見つけなければなりません。

于 2012-08-29T20:47:31.203 に答える
0

0x90 は x86 の NOP 命令です。したがって、0x90 は 1 つの NOP 命令、0x9090 は 2 つの NOP 命令、0x90909090 は 4 つの NOP 命令になります。

call 0x804833c命令の長さを注意深く確認してください。4バイトの長さだとは思いません。

于 2012-08-29T20:06:09.397 に答える