1. ホーム

コンピュータシステムの爆弾実験への深い理解

2022-02-08 03:05:53

I. 実験の目的

この実験では、アセンブリコードを読み解く能力を向上させ、学習することで gdbデバッギングツール。

II. 実験用リソース

<スパン ラボコースホームページからダウンロード 爆弾のzipアーカイブです。実験環境は、仮想マシン内のlinuxです。

iii. 実験に必要な条件と準備

<1> この実験は、アセンブリプログラムとそのデバッグ方法に慣れるための実験である。 

<2> 実験には2つのファイル bomb (実行ファイル) と bomb.c (cソースファイル) が含まれます。 

<3>gdb ツールでアセンブリコードを逆アセンブルし、c ファイルと組み合わせて、各レベルのエントリ関数を探し出す。 

アセンブリコードを解析して、各フェーズでブートストラップが "explode_bomb" セグメントにジャンプする場所を見つけ、ジャンプが成功する条件を解析し、これを突破口にコマンドラインにどの文字を入力すればそのレベルをパスできるかを見つける。 

<5> この実験では、通常レベル6つと隠しレベル1つの合計7つのレベルがあります。最低でも6つのレベルをクリアする必要があります。

1. linuxシステム上で直接ブラウザでラボコースのネットワークにログインし、爆弾実験に関連するフォルダをダウンロードする。実行ファイルbomb、C言語ファイルをデスクトップに配置する。


2. cd+Desktop は、desktop フォルダに行き、bomb をディスアセンブルして 1.txt ファイルにあるアセンブリコードを取得します。


2. ファイルを実行しようとした。パーミッションがないことを示し、正常に実行されないことを発見し、以下の情報を確認することで回避策を見いだしました。


選択された bomb->properties->permissions->select ファイルをプログラムとして実行することを許可する。


IV. 実験課題

フェーズ1

1. アイデア分析・概略設計

<1> 最初の数行は、スタックを開いているところです。

スタックに %ebp ebp をプッシュする

mov %esp,%ebp ebp がスタックの先頭のとき、esp は常に先頭の要素を指します。

Sub $0x18,%espは新しい空間のセクションを開く

<2> <explode_bomb> にジャンプするスニペットを探してください。


<スパン 前方検索 <explode_bomb> の条件: <string_not_equal> つまり、2つの文字列の内容が同じでない場合。

比較する2つの文字列は

即時カウント 0x804a15cアドレスの内容と、入力したい文字列の0x8(% ebp)。

2. gdbを使ってアドレス0x804a15cの内容を調べ、パス文の取得を行う

実験的洞察

<スパン アセンブリコードを見てみると、その呼び出しが <string_not_equal> 関数では、入力は文字列と推定でき、アドレス0x804a15cに対応する値をx/sで文字列の形で見て、レベルをパスするように入力します。文字列比較関数は、2つの文字列を比較し、その結果を%eaxに格納し、最終的に%eaxの値を決定する関数である。

フェーズ2

1. アイデア分析・概略設計


このコードの中に、いくつかの の呼び出しは、関数 を以下の場所で使用します。

<1> 8048d7f call 804910b<read_six_numbers>

という名前のコールがあります。 read_six_numbers は、入力された6つの数字を読み込むための関数です。

0804910b <read_six_numbers>:

スタックに %ebp : %ebp をプッシュします。

mov %esp,%ebp : %esp にスタックの先頭の現在アドレスを保持させる、つまり %ebp を指すようにします。

sub $0x28,%esp: 現在の関数のためのスタックフレームを開く

mov 0xc(%ebp),%eax

lea 0x14(%eax),%edx

mov %edx,0x1c(%esp): 6番目の番号を保存します。

lea 0x10(%eax),%edx

mov %edx,0x18(%esp): 5番目の数字を保存します。

lea 0xc(%eax),%edx

mov %edx,0x14(%esp): 4番目の数字を保存する

lea 0x8(%eax),%edx

mov %edx,0x10(%esp): 3番目の数値を保存します。

lea 0x4(%eax),%edx

mov %edx,0xc(%esp): 2番目の数字を保存する

mov %eax,0x8(%esp): 最初の数値を保存します。

movl $0x804a232,0x4(%esp)です。

<2> 8048d90 で <explode_bomb> を呼び出してください。

スタックオープン段階

6つの数字で読み取る


の最初の数字を配置します。 -0x20(%ebp) と最初の数値の大きさを 0 と比較し、等しければ続行、等しくなければ爆発します。2番目の数値は -0x1c(%ebp) にあり、2番目の数値の大きさを 1 と比較します。 もし等しければ続行し、そうでなければ爆弾が爆発します。つまり、最初に入力する数値が0で、2番目の数値が1であることを確認することができます。


<スパン アドレスを入れる -0x18(%ebp)->%ebx

<スパン アドレスの設定 -0x8(%ebp)->%esi

eax は %ebp オフセット 24(0x18 の 10 進数)に対するアドレスを保持し、これが %eax に -4、つまり %ebp オフセット 28 に対するアドレ スを保持します。

add -0x8(%ebx),%eax ebp に対してオフセット 28 と 32 にあるメモリ内の数値、つまり最初の数値 0、2 番目の数値 1 を加算して 3 番目の数値 1 とし、%eax に格納します。

esiはループ終了条件であり、%ebpの値を4加算しています。つまり、2番目と3番目の数値を加算して4番目の数値とし、3番目と4番目の数値を加算して5番目の数値とし、4番目と5番目の数値を加算して6番目の数値とするのです。このアセンブリコードは、まず最初の2つの数値の値を決定し、ループすることによって、その後に続く数値がその前の2つの数値の和に等しくなるようにして、この6つの数値を決定しているのである。

2.  パス文の取得

ループが終了するので、入力される6つの数値は 0 1 1 2 3 5

この6つの数字を入力すると、パス

2.  実験的洞察

まず最初の2つの数字を決定し、この部分は比較的簡単です、次に-0x8(%ebx),%eaxを追加します、2つの数字を追加し、結果は%eaxに保存されます、%esi制御ループ、%ebx=%ebx+4、操作に参加している二つの数字のアドレスを変更します。

フェーズ3

1. アイデア分析・概略設計

<1>The stack building process(スタック構築プロセス

 8048ea1: 55 push %ebp

 8048ea2: 89 e5 mov %esp,%ebp

 8048ea4: 83 ec 28 sub $0x28,%esp

<2>

 8048ea7: 8d 45 f0 lea -0x10(%ebp),%eax

 8048eaa: 89 44 24 0c mov %eax,0xc(%esp)

 8048eae: 8d 45 f4 lea -0xc(%ebp),%eax

 8048eb1: 89 44 24 08 mov %eax,0x8(%esp)

 8048eb5: C7 44 24 04 3e A2 04 movl $0x804a23e,0x4(%esp)

 8048ebc: 08

 8048ebd 8b 45 08 mov 0x8(%ebp),%eax

 8048ec0: 89 04 24 mov %eax,(%esp)

これらの手順が実行された後のスタックです。

<3> 呼び出し関数 isoc99_sscanf@plt

関数を呼び出した後に eax>1, jump, otherwise detonate, presumably eax is the return value of the function isoc99_sscanf@plt, then more than one number needs to be entered.

<4> 番号を入力する

おそらく、この2つのアセンブリ記述に基づき、最初に入力された数値は、アドレス -0xc(%ebp) で、7より大きくない。

<5> スイッチ部

入力 switch文で、入力された数字によって、gdbを使って閲覧する特定のアドレスにジャンプします。

を gdb で使用します。 p/x *(int *) (0x804a1a0+4*入力された数字)で、すべての入力のジャンプアドレスを確認することができます。

<スパン リストの下に進むと、最初に入力された数値は、以下の値でなければならないことがわかります。 5、2番目の数値は%eaxの数値と等しくなければならない、つまり、最初に入力された数値に基づいて別のアドレスにジャンプして新しい値を生成し、%eaxの数値はこの数値と等しくなければならない、という関係があるのです。

ジャンプアドレスから2番目の数値を計算する。

i=0のとき0x8048f12にジャンプする

8048f1e: 2d 5a 03 00 00 sub $0x35a,%eax

 8048f23: 05 ef 02 00 00 $0x2ef,%eax を追加します。

 8048f28: 2d 16 02 00 00 sub $0x216,%eax

 8048f2d: 05 16 02 00 00 追加 $0x216,%eax

 8048f32: 2d 16 02 00 00 sub $0x216,%eax

 8048f37: 05 16 02 00 00 追加 $0x216,%eax

 8048f3c: 2d 16 02 00 00 sub $0x216,%eax

計算された2番目の数値は次のようになります。 147

 8048f41: eb 0a jmp 8048f4d <phase_3+0xac>// アドレスへジャンプ 8048f4d

このアセンブリコードでは、最初に入力される数値は、以下の値であることが必要です。 5

i=1のとき0x8048f19にジャンプする

これらの記述から算出される最初の数値は 最初の数値を1としたとき、2番目の数値は-641となるはずである

計算演算を行った後、アドレスにジャンプして 8048f4d、つまり最初に入力された数値が5より大きいことはありえない。

2. 結果の取得

3.  実験的洞察

<スパン の使用は スイッチの分岐構造は、操作のための別の位置のための別の位置にジャンプする別の数値の入力によると、最終的に結果を得る。まず、入力された数値の範囲を分析し、異なる入力でジャンプする正確な位置を決定します。