珍しくちょっとした技術系の記事になります。
eagle0wlさん(@eagle0wl)のcrackmeを使用させていただきました。
技術向上を目的とした記事になります。
クラックする方法は様々ありますが、Cheat Engineという動的デバッガを使用してクラックしてみます。
Cheat EngineでCrackMeしてみた
CrackMeで自分の技術力を確かめたり、向上が可能です。
パズルを解くような感覚で楽しいのでやってみました。
注意:記事の内容はすべて自己責任でお願いします。
殴り書き感ありますが、わからない場合C言語の勉強などをしてから見ると理解ができると思います。
crackmeのダウンロード
下記のHPからダウンロードしました。
http://www.mysys.org/eagle0wl/
「eagle0wl’s crackme VOL.01 ver1.02」というリンクですね。
crkme01.exeを解く
まずはデバッガを使わずに動作確認します。
入力欄にテキトーな文字を入力したり空にした状態で登録ボタンを押すと、「不正解です!」というメッセージが表示されました。
私は「入力欄の文字列と何かの文字列を比較しているんだな」と考えました。
とりあえず、該当の比較処理を探します。
WindowsAPIの「MessageBoxA関数」に移動します。これはメッセージボックスを表示する関数です。
returnのところにブレークポイントを設置します。具体的には「ret 0010」の「MessageBoxA+1B」のアドレスです。
設置したら、登録ボタンを押してメッセージボックスを表示させます。そして閉じます。すると引っかかります。F7のStepで返ります。どうやら、アドレス: 0040121C でメッセージボックスの関数を呼び出していたようです。
この関数呼出は「不正解です!」の場合のものです。つまり、「正解です!」のようなメッセージボックスを呼出すアドレスもあるはずです。(予想)
というか、予想していた「比較」の処理があるはずです。
ありました。je crkme01.exe+1226 ってやつですね。(ちなみにcrkme01.exeは 00400000 から始まってます。)
あとは、この処理をjmp とか jneに書き換えれば、「正解です!」と表示されます。
入力欄に入力する正しい文字列を知りたいのなら、比較命令の上を見れば良いです。
lstrcmp関数を使っている場所がありますね。その上にpushがありますが、これが引数です。
というか、右のCommentに答えが書いてありますね…。Cheat Engine便利。
Ctrl + V で表示・非表示の切り替えができます。
crkme02.exe
crkme01.exeと同じ方法です。
ただ、01とは比較処理が異なっています。
lstrcmp関数が見当たりません。ブレークポイント設置しても引っかかりませんでした。
MessageBoxAのretから呼び出し元を特定して解析してみると、
004011FD の jne 00401221 という命令で 00401221 にジャンプしていたようです。
つまり「cmp eax,08」という命令でFalseだったということです。Falseという表現はよくない気もしますが。
「cmp eax,08」は何かな?と考えましたが、感覚で文字数チェックかなと思いました。確認すべくcmp命令のところでブレークポイント設置。入力欄には、5文字を入れて登録ボタンを押します。するとEAXは00000005になっていました。
「cmp eax,08」の上には『GetWindowText』という関数を呼び出しているようです。なんだろこれ?
戻り値
関数が成功すると、コピーされた文字列の文字数が返ります( 終端の NULL 文字は含められません)。タイトルバーやテキストがない場合、タイトルバーが空の場合、および hWnd パラメータに指定したウィンドウハンドルまたはコントロールハンドルが無効な場合は 0 が返ります。拡張エラー情報を取得するには、 関数を使います。
つまり、まず1つめの比較処理は「文字数チェック」です。
ふるいをかけたイメージですね。
文字数チェックしたあとは、文字列の比較をすると予想がつきます。
しかし、先ほど書いたようにlstrcmpなどの文字列比較関数を使ってません。どういうチェックをしているのでしょうか。
8文字入力した場合はjneでジャンプせずに「0040123A」をCallしています。なので「0040123A」を見てみると、cmp→jneの命令が繰り返されています。もう1文字ずつ比較しているんだなとわかります。
「mov esi,0040302C」この命令で、esiに入力した文字列が入ります。
esi = 1文字目
esi+1 = 2文字目…
となってます。
下のcmp命令の第2オペランドの16進数が答えになります。
cmp byte ptr [esi],35
jne crkme02.exe+1271
cmp byte ptr [esi+01],45
jne crkme02.exe+1271
cmp byte ptr [esi+02],48
jne crkme02.exe+1271
cmp byte ptr [esi+03],39
jne crkme02.exe+1271
cmp byte ptr [esi+04],56
jne crkme02.exe+1271
cmp byte ptr [esi+05],33
jne crkme02.exe+1271
cmp byte ptr [esi+06],51
jne crkme02.exe+1271
cmp byte ptr [esi+07],57
jne crkme02.exe+1271
inc eax
ret
つまり、答えは 5EH9V3QW になります。(ドラッグして選択してください。)
改ざん方法は色々ありますが、どこかの命令を「call 00401208」とでもすれば良いでしょう。なにを入力しても正解ですと表示されます。
また、気が向いたら続きをかくかも。
コメント
え..えーと… は…はっかー…はんたーい