コンピュータシステムの爆弾実験への深い理解
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. 実験的洞察
<スパン の使用は スイッチの分岐構造は、操作のための別の位置のための別の位置にジャンプする別の数値の入力によると、最終的に結果を得る。まず、入力された数値の範囲を分析し、異なる入力でジャンプする正確な位置を決定します。
関連
-
Mysql がエラーを報告 オペランドには 1 つのカラムが含まれている必要があります。
-
よくある例外の問題と解決策
-
react error TypeError: 未定義のプロパティ 'setState' を読み取ることができません。
-
不具合ログ】Prologでコンテンツが許可されていないエラー発生
-
error unable to access jarfile Solution
-
コンパイラーエラーです。ISO C++は型がない***の宣言を禁じています。
-
中に内部エラーが発生しました。「Javaツーリングの初期化」中に内部エラーが発生しました。
-
Oracle の例外 ORA-01861 を解決する: リテラルが形式文字列に一致しません。
-
VS2019 MFCのデバッグエラーです。C1083 インクルードファイルが開けません。"afxwin.h" を開けません。そのようなファイルやディレクトリはありません
-
NullPointerException
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
libc++abi.dylib: NSException タイプの捕捉されない例外で終了するエラー
-
メールサーバーの問題点まとめ
-
Python update pip error: EnvironmentErrorのため、パッケージをインストールできませんでした。[WinError 5] アクセスが拒否されました
-
linux error ttyname failed: デバイスに不適切な ioctl Solution
-
ArrayAdapter がリソース ID に TextView を要求する問題を解決する方法
-
ローカルプロジェクトをgitlabにアップロードする
-
S_ISREG およびその他いくつかの共通マクロ .
-
json文字列のダブルクォートが&quotになるのですが、どうすれば解決できますか?
-
Androidアプリケーション開発 - ビープ音とバイブレーションによる警告の実装
-
Assert.assertNotNull() で null 判定 Assertion