crackme#16 解説 著者:mom[Full_moon] さん(  ̄(工) ̄)ノ

今回の、#16はiniファイルに登録するパターンです。

OllyDBGを、起動して「crkme16.exe」を読込んでください。
「検索」→「ラベル一覧」(「Search for」→「Name(Label)」)で、ラベル一覧の一覧を、表示します。

「KERNEL32.GetPrivateProfileStringA」を選択して、「Enter」キーを押してください。
「References in crkme16:.text to KERNEL32.GetPrivateProfileStringA」というウィンドウが表示されます。

Address 004011CA call <JMP.&KERNEL32.GETPRIVATEPROFILESTRINGA>を選択して、「Enter」キーを押してください。

CPUウィンドウをよく見ると、

Address 004011C0 push crkme16.00403195 ; Key = "Serial"
Address 004011C5 push crkme16.0040318E ; Section = "Regist"


っと、iniファイルのキー名と、セクション名が分かります。

Address 004011CA call <JMP.&KERNEL32.GETPRIVATEPROFILESTR>; \GetPrivateProfileStringA ブレークポイントを設定して、「F9」キーで実行させます。

Address 004011B8 push esi ; IniFileName = "*:\****\crackme16.ini"


ってな感じで、iniファイルPathが入ってます。
「F8」キーでcallを飛ばし実行、「F7」キーを2回押して、コール先にリターンさせます。

Address 0040134E cmp eax,17 ← ここにリターンします。

読込んだ内容の長さをチェックしてます。

1度、これまでに分かった内容を整理します。
iniファイル名は、「crackme16.ini」

---------------------- ini内容 Start ----------------------

[Regist]

Serial=*********************** ←23(0x17)文字

----------------------- ini内容 End -----------------------


となります。

内容はこんな感じで、

[Regist]
Serial=1234567890ABCDEFGHIJKLM

エディターで、iniファイルを作って見ましょう。

「Ctrl」+「F2」で再起動させます。
そして、「F9」で実行。先程のブレークポイントで、止まります。

「F8」で、callを飛ばします。
そして、「F7」キーを何度か押して、

Address 0040135A call crkme16.004010D8 ← カーソルがここに来るまで実行させてください。

このcallの下に、test eax,eax っとチェックしてる記述があります。
「F7」を押して、callの中に入って見ましょう。

いろいろ、比較してますね。じっくりトレースしていきます。
「F7」キーを何度か押して、Address 004010E7 cmp [byte ds:esi],2D ← カーソルがここに来るまで実行させてください。

いま、実行中の行は、Address 004010E4 ~ 004010EC のループ中にあります。

Address 004010E4 add esi,6 ← ここで、esiレジスタを6づつカウントUPしています。
Address 004010E7 cmp [byte ds:esi],2D esiレジスタの示す文字が、0x2d(ASCII '-')かの比較です。
よって、Serial文字の6の倍数文字は、'-'となります。

右クリック→Follow in Dump→Memory Addressでダンプを表示させて、0x36→0x2dに変更します。
他も同様に、6の倍数文字目を、0x2dに変更します。
変更後の、フェークSerial文字は、「12345-7890A-CDEFG-IJKLM」となります。

「F7」キーを何度か押して、Address 004010EF cmp [byte ds:esi],30 ← カーソルがここに来るまで実行させてください。

いま、esiレジスタが示してる文字は、「IJKLM」となってます。
これは、フェークSerial文字の最後の5文字です。

まず、esiレジスタが示してる文字列の1文字の比較です。

Address 004010EF cmp [byte ds:esi],30
Address 004010F2 jb short crkme16.00401130
Address 004010F4 cmp [byte ds:esi],39
Address 004010F7 ja short crkme16.00401130

上記、4行が1文字目の比較です。
1文字目は、0x30(ASCII '0')~0x39(ASCII '9')の間ですね。
それ以外ですと、crkme16.00401130 にジャンプします。
それでは、[byte ds:esi]の部分を、0x30に変更します。

つぎに、「F7」キーを4回押して、Address 004010F9 cmp [byte ds:esi+1],41 ← カーソルがここに来るまで実行させてください。

ここで、esiレジスタが示してる文字列の2文字の比較ですね。
範囲は、0x41(ASCII 'A')~0x5A(ASCII 'Z')です。
[byte ds:esi+1] を、0x41に変更します。

これ以降も、各文字の範囲をチェックしています。
3文字目は、0x61(ASCII 'a')~0x7a(ASCII 'z')
4文字目は、0x45(ASCII 'E')~0x55(ASCII 'U')
5文字目は、0x6b(ASCII 'k')~0x73(ASCII 's')
となってます。
3~5文字目も、範囲内の先頭文字に変更します。

変更後の、フェークSerial文字は、「12345-7890A-CDEFG-0AaEk」となります。
「Ctrl」+「F9」でリターンまで一気に実行します。
そして、「F7」でリターンします。

Address 0040135F test eax,eax ← ここで、今実行してきた、Serial文字の形式とSerial文字最後の5文字チェック結果を判定しています。
eaxレジスタが、0(ゼロ)の場合、下のジャンプ命令でジャンプし「登録情報に問題があります。」と表示されます。

今は、eaxレジスタは、1になっていると思いますので、気にせず進めます。

「F7」キーを何度か押して、
Address 0040136A call crkme16.004013E2 ; crkme16.004013E2 ← カーソルがここに来るまで実行させてください。

この下にも、test eax,eax 判定命令が記述されてます。
また「F7」キーを押して、callの中に入ります。
ここで、処理を追って下の方に行くと

Address 0040143A call <JMP.&KERNEL32.LSTRCMPA>; lstrcmpA の比較があります。

ここに、ブレーク・ポイントを仕掛けます。
あと、この処理もループの中なので、出口の

Address 0040144A mov ecx,3

ここにもブレーク・ポイントを仕掛けてください。

では、「F9」キーで実行させます。
lstrcmpAのBPで止まり、上には、

Address 00401438 push edi ; String2 = "JSmBC"
Address 00401439 push esi ; String1 = "12345"

と表示されてます。
String2 の方が正解Serialの1部です。

esiレジスタの示す文字列を、String2と同じに変更します。
「F9」で実行

Address 00401438 push edi ; String2 = "CLDuV"
Address 00401439 push esi ; String1 = "7890A"

これも、esiレジスタの示す文字列を、String2と同じに変更します。
「F9」で実行

Address 00401438 push edi ; String2 = "AGpFi"
Address 00401439 push esi ; String1 = "CDEFG"

これも、esiレジスタの示す文字列を、String2と同じに変更します。
「F9」で実行し、今度はループの出口、

Address 0040144A mov ecx,3 ← ここで止まります。

ここから、Address 00401454 loopd short crkme16.00401451 までのループで、lstrcmpAの結果を、orしてeaxレジスタの残していってます。
「F7」キーを何度か押して、Address 00401456 inc eax ← カーソルがここに来るまで実行させて下さい。

ここで、前のループの結果(eaxレジスタ)+1をしています。
今は、eaxレジスタ値は、0(ゼロ)なので、1になります。

「F7」キーを1度押して、

Address 00401457 test eax,eax ここで、eaxレジスタのチェックです。

気にせずに、「F7」キーを2回押してください。

Address 0040145B mov eax,1 ← ここで止まってます。

ここは、この処理の結果を設定しています。

では、「F7」キーを4回押して、コール元に返ります。

Address 0040136F test eax,eax ← ここで止まってます。

先程の処理の結果判定です。
またまた、気にせず、「F7」キーを2回押して

Address 00401373 push crkme16.00403000 ;"登録済み!" ← ここに来る事を確認してください。

**** 重要 ****

ここで、いろいろ変更を加えたフェークSerialを、メモしておきます。

0012FCF4 4A 53 6D 42 43 2D 43 4C 44 75 56 2D 41 47 70 46 JSmBC-CLDuV-AGpF
0012FD04 69 2D 30 41 61 45 6B i-0AaEk

これです。
あとは、「F9」を押して、「登録済み!」を確認してください。

次に、iniファイルに、正規Serialを入力して、再度、「登録済み!」になる事を確認してください。