banner
lca

lca

真正的不自由,是在自己的心中设下牢笼。

《ゼロから始めるIDAリバースエンジニアリング》学習ノート-7(フロー制御)

image

1、無条件ジャンプ命令 JMP#

EIP(ポインタレジスタ)は次に実行される命令を指し、実行が完了すると EIP は次の命令を指します。EIP(ポインタレジスタ)内の値は、各命令の実行後に自動的に更新され、次に実行される命令のアドレスを指します。アセンブリ言語のいくつかのジャンプ命令(例えば JMP、JE、JNE など)は EIP の値を修正することができ、指定されたアドレスにジャンプして実行することができます。

JMP A命令の中で、A はプログラム作者が期待する無条件ジャンプのメモリアドレスです。

image

jmp short 命令

JMP SHORT命令は 2 バイトの短距離ジャンプ命令で、前方または後方にのみジャンプできます。最初のバイト EB はジャンプオペコード(OPCODE)です。ジャンプの方向は 2 番目のバイトの値によって決まります。このジャンプには距離制限があります。

image

jmp short 命令の機械語を表示

上の図では、EB は jmp のオペコードであり、この命令は命令の終了後 5 バイト前方にジャンプします。ターゲットアドレスを計算するには、下の図の方法を使用します。命令の開始アドレス➕命令自体の長さ(2 バイト)➕2 番目のバイトのジャンプ距離(5 バイト)。

image

ジャンプ位置の計算

short のジャンプ距離:最大の前方ジャンプ距離は 0x7f です。

注:ida は機械語を表示します

メニューバー Options-General 設定で、Number of opcode bytes (graph) の値を 12(10)に変更します。デフォルトは 0 です。

image

注:データベーススナップショット機能

逆アセンブル中にプログラムにいくつかの変更を加えると、既に認識された関数が中断されます。データベーススナップショットを使用すると、以前の状態に戻すことができ、問題が発生したときに修正方法がわからない場合にこの機能を使用できます。

image

スナップショットに名前を付ける

image

スナップショットをロードするには、View-Database snapshot manager を選択します。

image

すべてのスナップショットリストと作成日を確認できます。

image

実験 2 ジャンプの 2 番目のバイトを 05 から 7f に変更

ida の patch byte 機能を使用して 05 を 7f に変更します。

image

image

image

実験2 05を7fに変更

image

実験2 変更後のアセンブリビュー 上の図から、左側の矢印が示すように、プログラムはここで0x4013a5に前方ジャンプします。

image

image

次に 0x7f を 0x80 に変更します。

image

0x80 に変更すると、プログラムは後方にジャンプします。以前の 0x7f は最も遠い前方ジャンプであり、したがって 0x80 は最も遠い後方ジャンプです。

image

Python は数値から前方または後方のジャンプを判断しないため、-0x80 を表す dword を入力する必要があります。つまり、0xffffff80です。計算結果は0xffffffffとビットごとの AND 演算を行い、32 ビットを超えるビットはクリアされるため、0x4012a6という値が得られます。

もし 0xff を 2 番目のバイトのジャンプ距離として使用すると、これは最小のジャンプ距離 - 1 であり、上の図からわかるように、最終的に 0x401325 にジャンプします。つまり、1 バイトジャンプしました。

さらに 1 バイト戻ると、命令の 2 番目のバイトを fe に変更すると、最終的に起点位置に戻り、無限ループが形成されます。

image

もし 2 番目のバイトを fd に変更すると、命令の末尾から 3 バイト戻ると、最終的に 0x401323 にジャンプします。

image

image

短距離ジャンプを使用すると、現在のアドレスの近くでのみジャンプでき、すべてのアドレスにジャンプすることはできません。したがって、プログラムは長距離ジャンプを使用します。

image

上の図にはいくつかの長距離ジャンプが表示されており、図の loc はその命令が一般的な命令であることを示しています。

image

上の図は長距離ジャンプであり、0x4026ae から 0x4029b3 までの距離は短距離ジャンプの作用範囲を超えています。

image

ジャンプ範囲計算公式は次のとおりです:終点命令の開始アドレス - 開始命令の開始アドレス - 5

5 はジャンプ命令の長さであり、結果は 0x300、つまり長距離ジャンプ命令のオペコード E9 の後の dword です。

image

2、条件ジャンプ命令#

CMP A,B # AとBを比較し、比較結果に基づいて異なる操作を実行

image

条件ジャンプ命令

上の図では、CMP は eax と ebx を比較します(レジスタの減算)。もしそれらが等しい場合、結果は 0 となり、フラグレジスタ(EFLAGS)の Z フラグまたはゼロフラグがトリガーされ、JZ 命令がこのフラグを検出してジャンプします。Z フラグがトリガーされると、上の図の緑色の矢印の経路が実行され、トリガーされない場合は青色の矢印の経路が実行されます。

16 進数ASM説明
74 or 0F84JE等しい場合はジャンプ
75 or 0F85JNE等しくない場合はジャンプ
77 or 0F87JA大きい場合はジャンプ
7CJL小さい場合はジャンプ
7DJGE小さくない場合はジャンプ
7EJLE小さいか等しい場合はジャンプ
7FJG大きいか等しい場合はジャンプ
80JOオーバーフローの場合はジャンプ
81JNOオーバーフローしない場合はジャンプ
82JB/JNAE小さい場合はジャンプ
83JNB/JAE小さくない場合はジャンプ
86JNA/JBE大きくないか等しい場合はジャンプ
88JS符号が負の場合はジャンプ
89JNS符号が正の場合はジャンプ
8CJL/JNGE小さい場合はジャンプ
8DJGE/JNL小さくない場合はジャンプ
8EJLE/JNG小さいか等しい場合はジャンプ
8FJG/JNLE大きいか等しい場合はジャンプ

JMP と NOP を除いて、残りは比較結果に基づいて実行される条件ジャンプ命令です。

3、CALL と RET 命令#

  • CALL 命令は関数を呼び出すために使用されます。
  • RET 命令はこの関数を呼び出した命令の次の命令に戻るために使用されます。

下の図には CALL 呼び出し命令があり、プログラムは0x4013d8にジャンプしてこの関数を実行します。(0x4013d8のアドレスの前のsub_はここが関数であることを示しています)CALL 命令は戻りアドレス0x40123dをスタックに保存します。

image

call 命令の例

この関数をダブルクリックすると、次の位置にジャンプし、関数の具体的な内容は次のとおりです:

image

0x4013d8 関数の具体的な内容

上の図のように、関数が完了すると ret 命令が実行され、スタックに保存された戻りアドレス 0x4012d にジャンプします。これはこの関数を呼び出した命令の次の命令です。

image

戻りアドレス

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。