banner
lca

lca

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

《ゼロから始めるIDAリバースエンジニアリング》学習ノート-10(IDAデバッガ)

image

IDA デバッガの選択#

ida は複数のデバッガをサポートしています。

image

ida がサポートするデバッガ

Local Windows debugger デバッガを選択します。

メニューバーのデバッガ - デバッガオプションを開くと、いくつかのデバッガの機能を設定できます。

image

ida デバッガオプション

デバッガインターフェース機能#

プロセスエントリポイントを一時停止にチェックを入れ、イベント条件を選択し、OK をクリックします。

image

以前の重要なコード jinx の名前を変更し、色を変更します。

image

変更後は以下のようになります。X キーを押して、この関数がどこで参照されているかを確認します:

image

参照ポイントに色を付けます。

image

0x00401243 でブレークポイントを設定し、この行にマウスを置き、右クリック - ブレークポイントを追加します。ブレークポイントを追加すると、赤い背景に変わります。

image

メニューバーのデバッガ - プロセスを開始(F9)を使用してデバッグを開始します。ローカルで実行可能ファイルをデバッグすると、以下の警告ウィンドウが表示されます。

image

注:

ローダーがプログラムを分析しているとき、プログラムはローカルで実行されませんが、デバッグは異なります。プログラムがウイルスや他の危険なマルウェアである場合は、特に注意が必要です。この場合、リモートデバッガ(REMOTE DEBUGGER)を使用して仮想マシン内でプログラムを実行する必要があります。

はいをクリックしてデバッグを続行します。

デバッガがエントリポイントで一時停止するように設定したため、以下の図のように、ida はエントリポイント(0x00401000)で一時停止します。

image

右上の汎用レジスタとフラグレジスタウィンドウを調整して、表示を確認します。

image

上の図では、これらのレジスタの値を見ることができます。正常に調整した後、メニューバーのウィンドウ - デスクトップを保存を開き、defaultオプションにチェックを入れて、デバッガのデフォルトウィンドウ設定として保存します。これにより、デバッガを実行する際にプログラムはデフォルト設定で実行され、必要に応じて変更も可能です。

汎用レジスタの下にスタックビューを配置できます。

image

左側と最下部は逆アセンブルおよび 16 進数ウィンドウです。

image

逆アセンブルビューの下には現在のメモリアドレスとファイルオフセット(FILE OFFSET)が表示されます。このオフセットは実行可能ファイルのオフセットを指します。

image

ida では、デフォルトで G キーはメモリアドレスに移動するショートカットキーです。G を押して 0x401389 を入力し、以前に設定したブレークポイントに移動します。

image

すべての静的分析、名前変更などの変更内容は保存されます。

image

メニューバーのビュー - サブビューを開く - セグメントを開くと、ローダーが 3 つのセグメントを読み込んだことがわかります。

image

0x401000 の code フィールドと、下の data および.idata フィールドが読み込まれます。これらのセグメントの変更はすべて保存されますが、それ以外の変更は保存されません。なぜなら、それらはデバッガによって読み込まれたセグメントであり、IDA データベースに保存されることはないからです。

上の図の L マークは、このプログラムがローダーとデバッガによって同時に読み込まれたことを示しています。静的分析を実施できるだけでなく、動的デバッグ中に静的分析の情報が失われることもありません。

以下にいくつかの小ツールバーを紹介します。

1、メニューバーの view(ビュー) - toolbars(ツールバー) - jump(ジャンプ)を選択し、デスクトップ保存機能を使用してデフォルトで有効に設定します。

image

戻るキーを押すと、以前のプログラムエントリポイントに戻ります。

image

メニューバーの debugger(デバッガ) - breakpoints(ブレークポイント) - breakpoint list(ブレークポイントリスト)で、すべてのプログラムブレークポイントを確認できます。

image

任意の場所をクリックすると、対応するブレークポイントにジャンプできます。

条件ジャンプ命令とフラグレジスタ#

現在、デバッガはプログラムエントリに到達し、2 つのブレークポイントが設定されており、F9 を押して実行を続けます。

image

この時、crackme.exe プログラムが実行され、ターゲットプログラムの Help-register メニューバーにユーザー名とパスワードを入力します。

image

OK をクリックします。

image

上の図で、左側の点滅する赤い矢印はプログラムが続行するパスを示しています。この時、eax の値は 0x6c です。

image

0x6c を文字列に変換すると l になります。

image

image

上の図で、al レジスタは 0x41 と比較され、0x41(A)未満かどうかが判断されます。下の緑のコードブロックでは、al レジスタも 0x5a と比較されています。

asmconditionoperation
JAz=0 and c=0jump if above(もし大きければジャンプ)
JAEc=0jump if above or equal(もし大きいか等しければジャンプ)
JBc=1jump if below (もし小さければジャンプ)
JBEz=1 or c=1jump if below or equal(もし小さいか等しければジャンプ)
JCc=1jump if carry(もしキャリーならジャンプ)
JECXZecx=0jump if ecx is 0 (もし ecx が 0 ならジャンプ)
JEz=1jump if equal(もし等しければジャンプ)
JZz=1jump if zero(もしゼロならジャンプ)
JNEz=0jump if not equal(もし等しくなければジャンプ)
JNZz=0jump if not zero (もしゼロでなければジャンプ)
JO範囲を超えるjump if overflow
JP偶数の 1 ビット(操作結果の 2 進数中の 1 の個数、01110000)jump if parity
JPE偶数チェックjump if parity even
JNP偶数の 1 ビットがないjump if not parity
JPO奇数チェックjump if parity odd
JS符号ビットが 1jump if sign(もしフラグがあればジャンプ)
JNS符号ビットが 0jump if not sign(もしフラグがなければジャンプ)
JL/JNGE符号ビットとオーバーフローが同じjump if less or not greater/equal
JLE/JNGz=1 or 符号ビットとオーバーフローが同じjump if less or equal/not greater
JG/JNLEz=0 and 符号ビットとオーバーフローが同じjump is greater/not less or equal

条件ジャンプ命令とジャンプ条件

次に ida のフラグレジスタビューに移ります。以下の図のようになります。

image

表からわかるように、CF=0 の場合、ジャンプせず、プログラムは緑のコードブロックに進みます。では、この C フラグをトリガーする数学的条件は何でしょうか?

C フラグは、符号なし整数演算にエラーがあることを示す情報です。cmp 命令を結果を保存しない減算アルゴリズムと見なすと、0x6c - 0x41 = 0x2b、結果は正数です。もし al が 0x30 であれば、0x30 - 0x41 = -0x11になります。

image

-0x11 は負数であり、プログラムはそれに対応する 16 進数で実行を続けることしかできません。

image

上の図のように、-0x11 の 16 進数は 0xffffffef で、10 進数は 4294967279 です。この値は非常に大きく、0x30-0x41も正数にはなりません。

では、演算中に符号が考慮されているかどうかをどうやって知るのでしょうか。これは使用されるジャンプタイプによります。JB は符号なし数の比較後のジャンプ命令であり、対応する符号付き数の命令は JL です。

JB 命令を使用する場合、通常は符号なし整数が特定の値より小さいかどうかを検出するために使用されます。演算結果が借位を生じた場合、2 番目のオペランド(比較される数)が 1 番目のオペランド(比較数)より大きいことを示します。この場合、JB フラグは 1 になり、ジャンプが可能です。そうでなければ、演算結果が借位を生じなければ、JB フラグは 0 になり、条件を満たさず、ジャンプは行われません。

例:

mov al, 150    ;150をalに代入
cmp al, 255    ;alと255を比較
jb  smaller    ;もしalが255未満なら、smallerラベルにジャンプ
   ;他の操作を実行
   smaller:
   ;もしalが255以下なら、ここにジャンプ

この例では、al の値が 255 未満であれば、CF フラグは 1 になり、smaller ラベルにジャンプします。そうでなければ、al の値が 255 を超える場合、CF フラグは 0 になり、ジャンプせず、他の操作を実行します。(要するに、alが255未満であればジャンプ)

符号付きかどうかの比較は、その後の条件ジャンプ命令によって判断する必要があります。

符号なしジャンプ

符号説明フラグ
JE/JZ等しいかゼロの場合にジャンプzf
JNE/JNZ等しくないかゼロの場合にジャンプzf
JA/JNBEより大きいか、または以下でない場合にジャンプzf,cf
JB/JNAEより小さいか、または以上でない場合にジャンプcf
JBE/JNAより小さいか等しいか、または以上でない場合にジャンプcf,af

符号なしジャンプ

上の図の命令は符号を考慮していません。各ジャンプには対応する符号付きジャンプがあります。

符号説明フラグ
JE/JZ等しいかゼロの場合にジャンプzf
JNE/JNZ等しくないかゼロの場合にジャンプzf
JG/JNLEより大きいか、または以下でない場合にジャンプzf,sf,of
JGE/JNLより大きいか、または等しくないか、以下の場合にジャンプsf,of
JL/JNGEより小さいか、または等しくないか、以下の場合にジャンプsf,of
JLE/JNGより小さいか等しいか、または以上でない場合にジャンプzf,sf,of

符号付きジャンプ

上の 2 つの図において、JE(等しいかどうか)は両方の図に現れます。なぜなら、この特例では符号は重要ではなく、もし 2 つの数が等しければ、zf=1となり、フラグがトリガーされるからです。
符号付きジャンプの中でJG = より大きい場合にジャンプは、符号なしジャンプの中で対応する命令はJA、より大きい場合にジャンプです。

プログラムをデバッグしていると、ida は設定された各ブレークポイントで一時停止し、ループを実行します。各ループはターゲットプログラムに入力されたユーザー名の 1 文字を読み取り、0x41 と比較します。どの文字でも 0x41 未満であればエラーが表示されます。入力が lca の場合、各値は 0x41 より大きいため、エラーは表示されません。

数字を入力してみましょう。

image

この時、赤いブロックにジャンプします。つまり、jb がジャンプする場所です。最初に比較される文字は 2(0x32)であり、2 は確実に 0x41 より小さいです。

image

image

同時に C フラグがトリガーされ、CF=1 になります。なぜなら、0x32 - 0x41 の符号なし数の減算結果は負数であり、これが C フラグをトリガーします。

image

C フラグを右クリックし、Zero Value を選択して C フラグを 0 にします。

image

image

F9 を押してプロセスを続行すると、プログラムは 22lca の 2 文字目を読み取り、左側の赤い矢印が再び点滅し始めます。CF フラグを 0 に設定し続けると、その後の文字 lca はすべて 0x41 より大きくなり、フラグはトリガーされず、プログラムは左側の赤い矢印を進みます。

文字の検出が完了すると、プログラムは最後のジャンプに到達します。

image

上の図の cmp 命令は eax と ebx を比較し、jz は比較が等しいかどうかを判断します。符号なしで、プログラムは赤いブロックに進みます。なぜなら、これらの 2 つのレジスタは等しくないからです。

image

等しくないため、zf フラグはトリガーされません。

image

もし手動で zf フラグをトリガーし、ジャンプ方向を変更すると、プログラムは緑のブロックに進み、登録成功が表示されます。

image

image

SET IP#

set ip はデバッガモードでのみ使用できます。

時には、ジャンプを直接変更するのではなく、マウスを実行したいコードブロックに移動し、右クリックして SET EIP を選択することもできます。

0x40124c で set eip を設定すると、プログラムは 0x40124c から実行を開始します。

image

注:7.7 でこの操作を行うと、複数回実行した後に以下のエラーが表示されます。

image

「不正な命令を実行しようとしました」というメッセージが表示されます。

image

image

エラーメッセージはメモリが書き込み不可であることを示しており、読み取る内容が範囲を超えている可能性があります。

まとめ#

IDA デバッガを使用することで、動的デバッグと静的分析を行い、プログラムの構造と実行プロセスを深く理解することができますが、この章ではソースプログラムを変更することはなく、デバッガ内でフラグレジスタの値を変更しただけです。

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