banner
lca

lca

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

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

image

IDA デバッガの選択#

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

image

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

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

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

image

ida デバッガオプション

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

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

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 位(操作结果中二进制中 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 = Jumps if greaterは、符号なしジャンプの対応する命令はJA、Jumps if aboveです。

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

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

image

この時、赤いブロックにジャンプします。最初に比較される文字は 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 デバッガを使用することで、動的デバッグと静的分析を行い、プログラムの構造と実行プロセスを深く理解できますが、この章ではソースプログラムを変更することはなく、デバッガ内でフラグレジスタの値を変更しただけです。

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