crkme07
http://doomo.xyz/crack/crkme07.exe
実行
crkme07.exeを実行すると4つのテキストボックスが出てきて、シリアル番号的なものをを要求される。
解析
OllyDbgでcrkme07.exeを開く。アセンブリが表示されているウィンドウで右クリック->検索->ラベル名(現在のモジュール)をクリックする。
入力したシリアルが正しいかどうかを判定するには必ず入力テキストの情報を取得しなければならないので、そのあたりの処理に着目しよう。
GetWindowTextAが参照されているところでBPをセットして実行してみる。
1文字入力した瞬間にBPにぶつかる。多分半角数字以外のものが入力されていないかのチェックなのでいったんBPを外して適当なシリアルを全部入力する。
入力し終えたらもう一度GetWindowTextAのところにBPをセットして「登録」を押下。
.
.
.
ブレークポイントに引っかからない。
↑もう一度ラベル名を見てみる。テキストを取得する関数にはGetWindowTextのほかに、GetDlgItemIntが見つかった。
テキストを整数値に変換してそれを戻り値とする。今回の入力は数値だけなのでこれが怪しい。ここにBPを設置してもう一度実行してみる。
↑今度はちゃんと引っかかった。
↑まずこのへんの処理から。ループ構造になっている。
GetDlgItem関数で戻ってきた値(入力した整数値)をEBXが示すアドレス(0x40311C~)に格納する。そしてEBXを+2、ECXとEDXを+1してにECX > 4ならもう一度ループする。
ECXを+1するのはループカウンタ(Cのfor文の変数iみたいな)だから。
EDXはGetDlgItemInt関数を呼び出すときの引数として使われている。
004012BC . 52 PUSH EDX ; |ControlID
ControllIDは整数値に変換したいテキストの識別子なのでこれを+1することで次のテキストを取得できるという仕組み。
EBXを足すのはテキストを格納するアドレスをずらすため。
004012C5 . 66:8903 MOV WORD PTR DS:[EBX],AX
↑ここではワード長(32ビット)でデータを格納するので+2している。
無事ループを抜けるとEBXが指定したアドレスに整数1234(=0x04D2)が4つ分入ってる。
0x40311Dに格納されている数値をESIに代入。一つ目のテキストに入力した整数値だ。
その数値と0x66666667を乗算する。
IMUL関数はEAXの乗算の結果をEAXに格納するが、おさまりきらないときは上位ビットがEDXに格納される。
さらにEDXを2ビット分算術右ビットシフト(=÷4する)。
さらに0x1F(=31)ビットシフトしたものを加えた結果が
EDXが0x3E7ならOK。
0x66666667と掛け算して上位9~12ビットが0x03E7ならなんでもいいらしいので逆算してみる(計算過程は略)。1つめのテキストボックスには9990を指定すればいいことが分かった。
0x40311F(2番目のテキスト)に入力する値は0x270F(=9999)以下でなければならないことが分かる。(3番目のテキストも同様。)
このへんはよくわからない。読むのが嫌になるくらい長い。CMP命令も一番下に行くまでなくて、入力した数値から別の数値を作ってる感じ。
この問題を作った方も解説できないとのこと。
なので、こういうときはCMP命令周りを見てみるといいらしい。
004013B0 . 66:3BE8 CMP BP,AX
今、BPには4番目のテキストボックスの数値、AXには謎のメカニズムで生成された謎の数値が入っている(ここでは0x1732)。これが一致すればいいので4番目のテキストに0x1732(=5938)を入力する。
登録済と表示された。今回もいろいろ正解パターンがある。