Back Crack Next Crack

クラック crkme02

今回はcrkme02.exeのクラックです。 OllyにロードしてF9で起動、どうやら前回と同じパス入力タイプですね。 とりあえず定石で攻めてみましょう GetWindowTextA か GetDlgItemTextA にBPをセットですね。 フェイクパスとして"ABCDEF"を入力し登録ボタンをクリック。 004011F5 でブレークしたらF8を1回押して "004011FA CMP EAX,8" のところでとめてください。 "CMP EAX,8" の説明をします。 CMPは比較の命令で、"EAX,8"となっているので"8とEAXの値を比較しろ"と言う意味になります。 比較の結果はゼロフラグに反映されます。 比較の結果が同じものであればフラグをセットします。 比較の結果が違うものであればフラグはリセットされます。 それではEAXの値を確認してください、6が入っていますね。 "CMP EAX,8" とあるので6と8は違うものですね、違うときはゼロフラグがリセットされます。 F8を1回押してリセットされるか見てみましょう、リセットされていますね(0 になっている)。 次に "004011FD JNZ SHORT 00401221"を説明します。 "JNZ"は "Jump not ZeroFlag" のことで、ゼロフラグが立っていない(リセット)ときにジャンプせよという命令です。 アレ?・・気づいた方はいますかね、前回やったジャンプ命令を覚えていますか? イコールじゃないときにジャンプするアレです、そう、JNEでしたね。 イコールじゃない(ゼロフラグがリセット)という条件では今回も同じですよね。 結論からいうとこの2つはまったく同じ命令です。 構文に意味を持たせるために違う表記が用意されていますが意味は同じです。 ジャンプ命令には表記は違うが意味は同じという命令がいくつかあります。 さて、はなしをJNZに戻しましょう。 今回はゼロフラグが立っていませんね、なので"00401221"へジャンプします。 ジャンプするかどうかF8を1回押してみてください、ジャンプしましたね。 ジャンプした先を見てみると、おや? 不正解ですの文字が見えますね。 F8を5回押してみてください、やはり"不正解です"のメッセージボックスが出てきてしまいました。 ということは先ほどのJNZ命令でジャンプしてはいけなかったみたいです。 ジャンプしないようにするには "CMP EAX,8"を実行したときにゼロフラグを立てなければなりませんね。 フラグを立てるためにはEAXに8が入ってなければなりません。 先ほどの"CMP EAX,8"のときには、EAXに6が入っていてゼロフラグが立ちませんでした。 さてどうやったらここを8に出来るのでしょう? 実はGetWindowTextA関数は取得した値の桁数をEAXに返します。 つまり入力したフェイクパスは"ABCDEF"で6桁だったのでEAXには6が入ったのです。 というわけで"ABCDEFGH"の8桁で再チャレンジしてみましょう。 F9を1回押して制御を戻し、フェイクパス"ABCDEFGH"を入力直し登録ボタンをクリック。 ブレーク後F8を1回押してEAXの値を確認、見事に8が入っていますね。 これで次のJNZ命令で飛ばなくてすみそうです、F8を2回押して確かめましょう、ハイ、ジャンプしませんね。 さて、"004011FF CALL crkme02.0040123A" に来ました。 CALLというのは呼び出しのことでいわゆるサブルーチンってやつです。 CALL 0040123A とあるので0040123Aへ移動すると考えてもらっていいです。 それではトレースしていきましょう、F8ではなくてF7を1回押してください。 F8とF7の違いは覚えていますか?、サブルーチンに入らないときはF8、入っていくときはF7でしたね。 今回はこのサブルーチン内の処理を見たいのでF7というわけです。 "0040123A XOR EAX,EAX" 上にやってきましたね。 XORは前回のANDと同じくビット演算の1つです。 XORの特徴は同じ値をXORすると0になることです。 ということは今回 XOR EAX,EAX の結果は0になりますね、結果はEAXに入ります。 それではEAXが0になるかF8を1回押してください、0になりましたね。 "0040123C MOV ESI,0040302C"上に来ました。 MOV命令はその名から察しが付くようにMoveのことですが、実際にはコピー(代入)しています。 "MOV ESI,0040302C"とあるので、0040302Cという値をESIへコピーしろという命令です。 画面を見るとわかりますが0040302Cにはフェイクパス"ABCDEFGH"が入っています、確認してみましょう。 Ollyの左下のダンプウィンドウで右クリック → Go to →Expression、40302Cと入れてEnter。 "0040302C 41 42 43 44 45 46 47 48 ABCDEFGH" 言語は全て数値で扱われているので 41 42 43・・・ (A,B,C・・)となっています。 ヘキサエディタで見てみればわかりますので暇なときにでも覚えてください。 F8を1回押してESIの値を見てください0040302Cが入ってますね。 次は"CMP BYTE PTR DS:[ESI],35"の説明です。 CMPは先ほどやった比較の命令ですね、 重要なのは"BYTE PTR DS:[ESI]"の"BYTE PTR"のところで、 これはメモリにアクセスするサイズを表しいます。 今回はBYTEとあるのでバイト単位でアクセスします。 DS:(データセグメント)については今は深く考えなくていいです。 メモリにアクセスするためのおまじないとでも考えておいてください。 [ESI]のカッコはメモリアクセスであることを表します。 つまり"CMP BYTE PTR DS:[ESI],35"は、 ESIアドレスに格納されている1バイトの値と、35を比較しろという命令になります。 今回は41と35を比較しているはずです。 重要なのは、メモリは値の大きさを判断することが出来ないので、 メモリにアクセス場合は必ずサイズを指定する必要があるというところです。 BYTEで1バイト、WORDで2バイト、DWORDで4バイトのサイズ指定になります。 その次のコードを見てみましょう"JNZ SHORT 00401271"とあるので比較が違った場合00401271へジャンプしますね。 ジャンプ先の00401271を見てみましょう"RET"とありますね、"Return" サブルーチンを抜けるという意味です。 このサブルーチンは004011FFから入ったので"00401204 TEST EAX,EAX"へ抜けます。 00401204 TEST EAX,EAX の次は"00401206 JE 00401221"となっているので、 TEST EAX,EAX の結果で分岐することが分かりますね。 ではEAXの値を確認しましょう、現在EAXは0になっていますね。 ということはTEST EAX,EAXの結果は0になってゼロフラグが立ちますので、 この次のJE命令でジャンプすることになりそうですね。 更にジャンプした先を見てみると、どうやら"不正解"になるようです。 ということは先のJE命令でジャンプしないようにしなければいけないようです。 ジャンプしないようにするには、その前の"TEST EAX,EAX"でゼロフラグが立たないようにしなければなりませんね。 サブルーチン内の処理をもう一度見直してみることにしましょう。 サブルーチン内を見てみるとやたらとJNZ命令が多いですね、しかもそのどれもが"00401271 RET"へジャンプしています。 更によく見てみると00401271へジャンプをしてしまうと"00401270 INC EAX"を実行することが出来ません。 INC EAXは"EAXの値を1増やせ"という命令です。 ここさえ通ればEAXに1が入りルーチンを抜けた先のTEST命令でゼロフラグを立たせないようにすることができます。 回りくどい説明でしたが、要はこのサブルーチンで入力したフェイクパスと正規のレジストパスを比較しています。 フェイクパスの1桁目から順に 5(35) E(45) H(48) 9(39) V(56) 3(33) Q(51) W(57) と比較していくので、 レジストパスは"5EH9V3QW"であることが判明しましたね。

今回のポイント "単純な桁チェックと固定パス"

Back Crack Next Crack

- XOR - XOR は2進化した数値の各桁を比較して値が違えば1に、同じ値なら0にします。 例1: 5 xor 3 = 6 101 (5) xor 11 (3) --------- 110 (6) 例2: 6 xor 3 = 5 ※再度おなじ値でXORすると元の値に戻る。 110 (6) xor 11 (3) ---------- 101 (5) 例3: 7 xor 7 = 0 ※両方とも同じ値でXORすると0になる。 111 (7) xor 111 (7) ---------- 000 (0)