crackme#12 解析手引き

OllyDBGを、起動して「crkme12.exe」を読込んでください。
取りあえず1度「F9」キーで動かしてみましょう。

crackme #12のウィンドウが、表示されました。
今回のウィンドウでは、「未登録」と表示されてます。
では、OllyDBGを再スタートさせてください。

ここで少しプログラムを眺めて見ましょう。


00401000 > $ 6A 00 PUSH 0 ; /pModule = NULL
00401002 . E8 DF010000 CALL <JMP.&KERNEL32.GetModuleHandleA> ; \GetModuleHandleA
00401007 . A3 17304000 MOV DWORD PTR DS:[403017],EAX
0040100C . 6A 00 PUSH 0 ; /lParam = NULL
0040100E . 68 95104000 PUSH crkme12.00401095 ; |DlgProc = crkme12.00401095
00401013 . 6A 00 PUSH 0 ; |hOwner = NULL
00401015 . 6A 01 PUSH 1 ; |pTemplate = 1
00401017 . FF35 17304000 PUSH DWORD PTR DS:[403017] ; |hInst = NULL
0040101D . E8 88010000 CALL <JMP.&USER32.DialogBoxParamA> ; \DialogBoxParamA
00401022 . 50 PUSH EAX ; /ExitCode
00401023 . E8 B2010000 CALL <JMP.&KERNEL32.ExitProcess> ; \ExitProcess
00401028 . 55 PUSH EBP
00401029 . 8BEC MOV EBP,ESP
0040102B . 53 PUSH EBX
0040102C . 56 PUSH ESI
0040102D . 57 PUSH EDI
0040102E . 817D 0C 110100>CMP DWORD PTR SS:[EBP+C],111
00401035 . 75 0C JNZ SHORT crkme12.00401043
00401037 . 66:817D 10 EA0>CMP WORD PTR SS:[EBP+10],3EA
0040103D . 75 4D JNZ SHORT crkme12.0040108C
0040103F . EB 08 JMP SHORT crkme12.00401049
00401041 . EB 49 JMP SHORT crkme12.0040108C
00401043 > 837D 0C 10 CMP DWORD PTR SS:[EBP+C],10
00401047 . 75 0C JNZ SHORT crkme12.00401055
00401049 > 6A 00 PUSH 0 ; /Result = 0
0040104B . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040104E . E8 5D010000 CALL <JMP.&USER32.EndDialog> ; \EndDialog
00401053 . EB 37 JMP SHORT crkme12.0040108C
00401055 > 817D 0C 100100>CMP DWORD PTR SS:[EBP+C],110
0040105C . 75 2E JNZ SHORT crkme12.0040108C
0040105E . EB 06 JMP SHORT crkme12.00401066
00401060 . 41 62 6F 75 74>ASCII "About",0
00401066 > 68 60104000 PUSH crkme12.00401060 ; /lParam = 401060
0040106B . 6A 00 PUSH 0 ; |wParam = 0
0040106D . 6A 0C PUSH 0C ; |Message = WM_SETTEXT
0040106F . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401072 . E8 4B010000 CALL <JMP.&USER32.SendMessageA> ; \SendMessageA
00401077 . FF35 1B304000 PUSH DWORD PTR DS:[40301B] ; /lParam = 0
0040107D . 6A 01 PUSH 1 ; |wParam = 1
0040107F . 68 80000000 PUSH 80 ; |Message = WM_SETICON
00401084 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401087 . E8 36010000 CALL <JMP.&USER32.SendMessageA> ; \SendMessageA
0040108C > 5F POP EDI
0040108D . 5E POP ESI
0040108E . 5B POP EBX
0040108F . 33C0 XOR EAX,EAX
00401091 . C9 LEAVE
00401092 . C2 1000 RETN 10
00401095 . 55 PUSH EBP
00401096 . 8BEC MOV EBP,ESP
00401098 . 53 PUSH EBX
00401099 . 56 PUSH ESI
0040109A . 57 PUSH EDI
0040109B . 817D 0C 100100>CMP DWORD PTR SS:[EBP+C],110
004010A2 . 0F85 AC000000 JNZ crkme12.00401154
004010A8 . 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
004010AB . EB 0C JMP SHORT crkme12.004010B9
004010AD . 63 72 61 63 6B>ASCII "crackme #12",0
004010B9 > 68 AD104000 PUSH crkme12.004010AD ; /lParam = 4010AD
004010BE . 6A 00 PUSH 0 ; |wParam = 0
004010C0 . 6A 0C PUSH 0C ; |Message = WM_SETTEXT
004010C2 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004010C5 . E8 F8000000 CALL <JMP.&USER32.SendMessageA> ; \SendMessageA
004010CA . 6A 0A PUSH 0A ; /RsrcName = 10.
004010CC . FF35 17304000 PUSH DWORD PTR DS:[403017] ; |hInst = NULL
004010D2 . E8 DF000000 CALL <JMP.&USER32.LoadIconA> ; \LoadIconA
004010D7 . A3 1B304000 MOV DWORD PTR DS:[40301B],EAX
004010DC . FF35 1B304000 PUSH DWORD PTR DS:[40301B] ; /lParam = 0
004010E2 . 6A 01 PUSH 1 ; |wParam = 1
004010E4 . 68 80000000 PUSH 80 ; |Message = WM_SETICON
004010E9 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004010EC . E8 D1000000 CALL <JMP.&USER32.SendMessageA> ; \SendMessageA
004010F1 . 6A 00 PUSH 0 ; /hTemplateFile = NULL
004010F3 . 68 80000000 PUSH 80 ; |Attributes = NORMAL
004010F8 . 6A 03 PUSH 3 ; |Mode = OPEN_EXISTING
004010FA . 6A 00 PUSH 0 ; |pSecurity = NULL
004010FC . 6A 00 PUSH 0 ; |ShareMode = 0
004010FE . 68 00000080 PUSH 80000000 ; |Access = GENERIC_READ
00401103 . 68 00304000 PUSH crkme12.00403000 ; |FileName = "k12me.crk"
00401108 . E8 C7000000 CALL <JMP.&KERNEL32.CreateFileA> ; \CreateFileA
0040110D . 40 INC EAX
0040110E . 85C0 TEST EAX,EAX
00401110 . 74 40 JE SHORT crkme12.00401152
00401112 . A3 13304000 MOV DWORD PTR DS:[403013],EAX
00401117 . 6A 00 PUSH 0 ; /pFileSizeHigh = NULL
00401119 . FF35 13304000 PUSH DWORD PTR DS:[403013] ; |hFile = NULL
0040111F . E8 BC000000 CALL <JMP.&KERNEL32.GetFileSize> ; \GetFileSize
00401124 . A3 1F304000 MOV DWORD PTR DS:[40301F],EAX
00401129 . 83C0 08 ADD EAX,8
0040112C . F7E0 MUL EAX
0040112E . 40 INC EAX
0040112F . F7E0 MUL EAX
00401131 . 3D 99970000 CMP EAX,9799
00401136 . 75 0F JNZ SHORT crkme12.00401147
00401138 . 68 0A304000 PUSH crkme12.0040300A ; /Text = "登録済み"
0040113D . 6A 64 PUSH 64 ; |ControlID = 64 (100.)
0040113F . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401142 . E8 81000000 CALL <JMP.&USER32.SetDlgItemTextA> ; \SetDlgItemTextA
00401147 > FF35 13304000 PUSH DWORD PTR DS:[403013] ; /hObject = NULL
0040114D . E8 7C000000 CALL <JMP.&KERNEL32.CloseHandle> ; \CloseHandle
00401152 > EB 4D JMP SHORT crkme12.004011A1
00401154 > 817D 0C 110100>CMP DWORD PTR SS:[EBP+C],111
0040115B . 75 34 JNZ SHORT crkme12.00401191
0040115D . 66:817D 10 E80>CMP WORD PTR SS:[EBP+10],3E8
00401163 . 75 20 JNZ SHORT crkme12.00401185
00401165 . 6A 00 PUSH 0 ; /BeepType = MB_OK
00401167 . E8 50000000 CALL <JMP.&USER32.MessageBeep> ; \MessageBeep
0040116C . 6A 00 PUSH 0 ; /lParam = NULL
0040116E . 68 28104000 PUSH crkme12.00401028 ; |DlgProc = crkme12.00401028
00401173 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
00401176 . 6A 02 PUSH 2 ; |pTemplate = 2
00401178 . FF35 17304000 PUSH DWORD PTR DS:[403017] ; |hInst = NULL
0040117E . E8 27000000 CALL <JMP.&USER32.DialogBoxParamA> ; \DialogBoxParamA
00401183 . EB 1C JMP SHORT crkme12.004011A1
00401185 > 66:817D 10 E90>CMP WORD PTR SS:[EBP+10],3E9
0040118B . 75 14 JNZ SHORT crkme12.004011A1
0040118D . EB 08 JMP SHORT crkme12.00401197
0040118F . EB 10 JMP SHORT crkme12.004011A1
00401191 > 837D 0C 10 CMP DWORD PTR SS:[EBP+C],10
00401195 . 75 0A JNZ SHORT crkme12.004011A1
00401197 > 6A 00 PUSH 0 ; /Result = 0
00401199 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040119C . E8 0F000000 CALL <JMP.&USER32.EndDialog> ; \EndDialog
004011A1 > 5F POP EDI
004011A2 . 5E POP ESI
004011A3 . 5B POP EBX
004011A4 . 33C0 XOR EAX,EAX
004011A6 . C9 LEAVE
004011A7 . C2 1000 RETN 10
004011AA $-FF25 2C204000 JMP DWORD PTR DS:[<&USER32.DialogBoxParamA>] ; USER32.DialogBoxParamA
004011B0 $-FF25 18204000 JMP DWORD PTR DS:[<&USER32.EndDialog>] ; USER32.EndDialog
004011B6 $-FF25 24204000 JMP DWORD PTR DS:[<&USER32.LoadIconA>] ; USER32.LoadIconA
004011BC $-FF25 20204000 JMP DWORD PTR DS:[<&USER32.MessageBeep>] ; USER32.MessageBeep
004011C2 $-FF25 1C204000 JMP DWORD PTR DS:[<&USER32.SendMessageA>] ; USER32.SendMessageA
004011C8 $-FF25 28204000 JMP DWORD PTR DS:[<&USER32.SetDlgItemTextA>] ; USER32.SetDlgItemTextA
004011CE $-FF25 0C204000 JMP DWORD PTR DS:[<&KERNEL32.CloseHandle>] ; kernel32.CloseHandle
004011D4 $-FF25 08204000 JMP DWORD PTR DS:[<&KERNEL32.CreateFileA>] ; kernel32.CreateFileA
004011DA $-FF25 10204000 JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>] ; kernel32.ExitProcess
004011E0 $-FF25 04204000 JMP DWORD PTR DS:[<&KERNEL32.GetFileSize>] ; kernel32.GetFileSize
004011E6 $-FF25 00204000 JMP DWORD PTR DS:[<&KERNEL32.GetModuleHandleA>] ; kernel32.GetModuleHandleA


crackme #12 ではバージョン情報を確認していただけば分かるように、今回は[キーファイル] を作成しなければいけません。
キーファイルをまだ作ってないのでウィンドウに「未登録」と表示されているのは当然ですね。
逆アセリストを上から順に眺めていくと、何か怪しい所がありますね・・・。

キーファイル形式のソフトはあまり見ないですが、このタイプの場合はまず、CreateFileAを探すことで解決できます。
まず CreateFileA で ファイルオープンハンドルを得なければならないからです。
逆アセリストに

004010F1 . 6A 00 PUSH 0 ; /hTemplateFile = NULL
004010F3 . 68 80000000 PUSH 80 ; |Attributes = NORMAL
004010F8 . 6A 03 PUSH 3 ; |Mode = OPEN_EXISTING
004010FA . 6A 00 PUSH 0 ; |pSecurity = NULL
004010FC . 6A 00 PUSH 0 ; |ShareMode = 0
004010FE . 68 00000080 PUSH 80000000 ; |Access = GENERIC_READ
00401103 . 68 00304000 PUSH crkme12.00403000 ; |FileName = "k12me.crk"
00401108 . E8 C7000000 CALL <JMP.&KERNEL32.CreateFileA> ; \CreateFileA

という所がありました。

その中で、

00401103 . 68 00304000 PUSH CRKME12.00403000 ; |FileName = "k12me.crk"
00401108 . E8 C7000000 CALL <JMP.&KERNEL32.CreateFileA> ; \CreateFileA

CreateFileAで参照されているキーファイルのファイル名は「k12me.crk」かなと予想がつきます。
では、もう少し下まで見てみましょう。


00401117 . 6A 00 PUSH 0 ; /pFileSizeHigh = NULL
00401119 . FF35 13304000 PUSH DWORD PTR DS:[403013] ; |hFile = NULL
0040111F . E8 BC000000 CALL <JMP.&KERNEL32.GetFileSize> ; \GetFileSize
00401124 . A3 1F304000 MOV DWORD PTR DS:[40301F],EAX
00401129 . 83C0 08 ADD EAX,8
0040112C . F7E0 MUL EAX
0040112E . 40 INC EAX
0040112F . F7E0 MUL EAX
00401131 . 3D 99970000 CMP EAX,9799


0040111F . E8 BC000000 CALL <JMP.&KERNEL32.GetFileSize> ; \GetFileSize

ここでファイルサイズを取得してる見たいです。

00401124 . A3 1F304000 MOV DWORD PTR DS:[40301F],EAX

取得したファイルサイズを EAX に入れてます。

00401129 . 83C0 08 ADD EAX,8

EAX + 8  → EAX で EAX に8を足しています。

0040112C . F7E0 MUL EAX

EAX × EAX → EAX に 入れてます。

0040112E . 40 INC EAX

EAX + 1  → EAX で EAX に1を足しています。

0040112F . F7E0 MUL EAX

EAX × EAX → EAX に 入れてます

00401131 . 3D 99970000 CMP EAX,9799

ファイルサイズを計算して0x9799(38809;10進)とEAXを比較しています。

以上の事からキーファイルのファイル名は「k12me.crk」で間違いないようです。
ファイルサイズを計算して0x9799(38809;10進)と同じになるように逆算してみましょう。

先ほどの38809 の 平方根 は 197 です。
次に 197-1=196 ですね。
196 の 平方根は 14 です。
次は 14-8=6 で ファイルサイズが 「6」となりました。

ではテキストエディタで、ファイル名は「k12me.crk」、ファイルサイズが6byte(半角英数6文字)の
キーファイルを作成して見ましょう。


作成したら、OllyDBGを「F9」でスタートさせてください。
「登録済み」 となれば成功です。

今回のcrackme #12では単純にファイルサイズ(文字数)だけの比較だけなので、
このように噛み砕いてしまえば解かりやすくなります。