ichirin2501's diary

いっちりーん。

Crackmes.deやってみた

実際にやってみた問題はこれ。
http://crackmes.de/users/sunshine/sunshines_crackme_1/


これがLv1って、俺の頭が弱すぎるorz
以下はただのめも。

004013F0   > 0FBE9405 F4FDF>MOVSX EDX,BYTE PTR SS:[EBP+EAX-20C] ;Nameが格納
004013F8   . 83C0 01        ADD EAX,1
004013FB   . 03CA           ADD ECX,EDX  ;各文字を和を計算
004013FD   . 3BC7           CMP EAX,EDI
004013FF   .^7C EF          JL SHORT Crackme1.004013F0
00401401   > 83FF 03        CMP EDI,3  ;Nameが4文字以上かチェック
00401404   . 7E 36          JLE SHORT Crackme1.0040143C
00401406   . 8B85 F0FDFFFF  MOV EAX,DWORD PTR SS:[EBP-210]  ;Serialが格納
0040140C   . 83C0 FB        ADD EAX,-5
0040140F   . 83F8 03        CMP EAX,3  ;Serialが5〜8文字かチェック
00401412   . 77 28          JA SHORT Crackme1.0040143C
00401414   . A1 D8434000    MOV EAX,DWORD PTR DS:[4043D8]  ;data.keyの計算値
00401419   . 85C0           TEST EAX,EAX
0040141B   . 76 1F          JBE SHORT Crackme1.0040143C
0040141D   . 03C1           ADD EAX,ECX
0040141F   . 0385 ECFDFFFF  ADD EAX,DWORD PTR SS:[EBP-214]
00401425   . C785 F0FDFFFF >MOV DWORD PTR SS:[EBP-210],Crackme1.0040>
0040142F   . 3D B0104000    CMP EAX,Crackme1.004010B0  ;ここ重要
00401434   . 75 06          JNZ SHORT Crackme1.0040143C

Nameの各文字の和 + Serial + data.keyの計算値 == 0x004010B0 になれば良い。
問題はdata.keyの計算値なんだけど、まずdata.keyってファイルを用意する必要がある。

00401130  /$ 83EC 08        SUB ESP,8
00401133  |. 68 98314000    PUSH Crackme1.00403198
00401138  |. 50             PUSH EAX  ;EAXには文字列定数data.keyのアドレスが格納
00401139  |. 8D4C24 08      LEA ECX,DWORD PTR SS:[ESP+8]
0040113D  |. 51             PUSH ECX
0040113E  |. FF15 9C304000  CALL DWORD PTR DS:[<&MSVCR80.fopen_s>]   ;  MSVCR80.fopen_s
00401144  |. 83C4 0C        ADD ESP,0C
00401147  |. 85C0           TEST EAX,EAX ;正常終了したらEAXには0が入ってる
00401149  |. 74 06          JE SHORT Crackme1.00401151
0040114B  |. 33C0           XOR EAX,EAX
0040114D  |. 83C4 08        ADD ESP,8
00401150  |. C3             RETN
00401151  |> 8B1424         MOV EDX,DWORD PTR SS:[ESP]
00401154  |. 55             PUSH EBP
00401155  |. 56             PUSH ESI
00401156  |. 8B35 A8304000  MOV ESI,DWORD PTR DS:[<&MSVCR80.fseek>]  ;  MSVCR80.fseek
0040115C  |. 6A 02          PUSH 2                                   ; /whence = SEEK_END
0040115E  |. 6A 00          PUSH 0                                   ; |offset = 0
00401160  |. 52             PUSH EDX                                 ; |stream
00401161  |. FFD6           CALL ESI                                 ; \fseek
00401163  |. 8B4424 14      MOV EAX,DWORD PTR SS:[ESP+14]
00401167  |. 50             PUSH EAX                                 ; /stream
00401168  |. FF15 A4304000  CALL DWORD PTR DS:[<&MSVCR80.ftell>]     ; \ftell
0040116E  |. 8B4C24 18      MOV ECX,DWORD PTR SS:[ESP+18]
00401172  |. 6A 00          PUSH 0
00401174  |. 6A 00          PUSH 0
00401176  |. 51             PUSH ECX
00401177  |. 8BE8           MOV EBP,EAX
00401179  |. FFD6           CALL ESI
0040117B  |. 83C4 1C        ADD ESP,1C
0040117E  |. 83FD 0A        CMP EBP,0A  ;10文字以上のチェック
00401181  |. 73 16          JNB SHORT Crackme1.00401199
00401183  |. 8B5424 08      MOV EDX,DWORD PTR SS:[ESP+8]
00401187  |. 52             PUSH EDX                                 ; /stream
00401188  |. FF15 AC304000  CALL DWORD PTR DS:[<&MSVCR80.fclose>]    ; \fclose
0040118E  |. 83C4 04        ADD ESP,4
00401191  |. 5E             POP ESI
00401192  |. 33C0           XOR EAX,EAX
00401194  |. 5D             POP EBP
00401195  |. 83C4 08        ADD ESP,8
00401198  |. C3             RETN

という感じで、data.keyファイルには7 10文字以上のデータがないと弾かれる。そして、
その7 10文字以上のデータを使って以下の計算を行い、4043D8に結果を入れる。

004011ED  |. 8B35 D8434000  MOV ESI,DWORD PTR DS:[4043D8]
004011F3  |> 8B4424 14      /MOV EAX,DWORD PTR SS:[ESP+14]
004011F7  |. 8A0407         |MOV AL,BYTE PTR DS:[EDI+EAX]
004011FA  |. 8AC8           |MOV CL,AL
004011FC  |. 80E1 01        |AND CL,1
004011FF  |. 3ACB           |CMP CL,BL
00401201  |. 74 08          |JE SHORT Crackme1.0040120B
00401203  |. 83C6 01        |ADD ESI,1
00401206  |. 84DB           |TEST BL,BL
00401208  |. 0F94C3         |SETE BL
0040120B  |> D0E8           |SHR AL,1
0040120D  |. 8AD0           |MOV DL,AL
0040120F  |. 80E2 01        |AND DL,1
00401212  |. 3AD3           |CMP DL,BL
00401214  |. 74 08          |JE SHORT Crackme1.0040121E
00401216  |. 83C6 01        |ADD ESI,1
00401219  |. 84DB           |TEST BL,BL
0040121B  |. 0F94C3         |SETE BL
0040121E  |> D0E8           |SHR AL,1
00401220  |. 8AC8           |MOV CL,AL
00401222  |. 80E1 01        |AND CL,1
00401225  |. 3ACB           |CMP CL,BL
00401227  |. 74 08          |JE SHORT Crackme1.00401231
00401229  |. 83C6 01        |ADD ESI,1
0040122C  |. 84DB           |TEST BL,BL
0040122E  |. 0F94C3         |SETE BL
00401231  |> D0E8           |SHR AL,1
00401233  |. 8AD0           |MOV DL,AL
00401235  |. 80E2 01        |AND DL,1
00401238  |. 3AD3           |CMP DL,BL
0040123A  |. 74 08          |JE SHORT Crackme1.00401244
0040123C  |. 83C6 01        |ADD ESI,1
0040123F  |. 84DB           |TEST BL,BL
00401241  |. 0F94C3         |SETE BL
00401244  |> D0E8           |SHR AL,1
00401246  |. 8AC8           |MOV CL,AL
00401248  |. 80E1 01        |AND CL,1
0040124B  |. 3ACB           |CMP CL,BL
0040124D  |. 74 08          |JE SHORT Crackme1.00401257
0040124F  |. 83C6 01        |ADD ESI,1
00401252  |. 84DB           |TEST BL,BL
00401254  |. 0F94C3         |SETE BL
00401257  |> D0E8           |SHR AL,1
00401259  |. 8AD0           |MOV DL,AL
0040125B  |. 80E2 01        |AND DL,1
0040125E  |. 3AD3           |CMP DL,BL
00401260  |. 74 08          |JE SHORT Crackme1.0040126A
00401262  |. 83C6 01        |ADD ESI,1
00401265  |. 84DB           |TEST BL,BL
00401267  |. 0F94C3         |SETE BL
0040126A  |> D0E8           |SHR AL,1
0040126C  |. 8AC8           |MOV CL,AL
0040126E  |. 80E1 01        |AND CL,1
00401271  |. 3ACB           |CMP CL,BL
00401273  |. 74 08          |JE SHORT Crackme1.0040127D
00401275  |. 83C6 01        |ADD ESI,1
00401278  |. 84DB           |TEST BL,BL
0040127A  |. 0F94C3         |SETE BL
0040127D  |> D0E8           |SHR AL,1
0040127F  |. 24 01          |AND AL,1
00401281  |. 3AC3           |CMP AL,BL
00401283  |. 74 08          |JE SHORT Crackme1.0040128D
00401285  |. 83C6 01        |ADD ESI,1
00401288  |. 84DB           |TEST BL,BL
0040128A  |. 0F94C3         |SETE BL
0040128D  |> 83C7 01        |ADD EDI,1
00401290  |. 3BFD           |CMP EDI,EBP
00401292  |.^0F82 5BFFFFFF  \JB Crackme1.004011F3
00401298  |. 8935 D8434000  MOV DWORD PTR DS:[4043D8],ESI

上記のアセンブリコードをC言語に直したのが以下のコード
data.keyファイルの中身は 1111111 と仮定して配列に格納してる。
最初の0xEF,0xBB,0xBFは固定値。

void passcode(void){
	unsigned char pass[] = {0xef,0xbb,0xbf,'1','1','1','1','1','1','1'};
	unsigned int eax,ebx,ecx,edx,esi,edi;
	unsigned int ebp = sizeof(pass)/sizeof(pass[0]);
	ebx = edi = esi = 0;
	for(;;){
		eax = pass[edi];
		ecx = eax&1;
		if( ecx!=ebx ){
			esi++;
			ebx = !ebx;
		}
		eax >>= 1;
		edx = eax&1;
		if( edx!=ebx ){
			esi++;
			ebx = !ebx;
		}
		eax >>= 1;
		ecx = eax&1;
		if( ecx!=ebx ){
			esi++;
			ebx = !ebx;
		}
		eax >>= 1;
		edx = eax&1;
		if( edx!=ebx ){
			esi++;
			ebx = !ebx;
		}
		eax >>= 1;
		ecx = eax&1;
		if( ecx!=ebx ){
			esi++;
			ebx = !ebx;
		}
		eax >>= 1;
		edx = eax&1;
		if( edx!=ebx ){
			esi++;
			ebx = !ebx;
		}
		eax >>= 1;
		ecx = eax&1;
		if( ecx!=ebx ){
			esi++;
			ebx = !ebx;
		}
		eax >>= 1;
		eax = eax&1;
		if( eax!=ebx ){
			esi++;
			ebx = !ebx;
		}
		edi++;
		if( edi<ebp )continue;
		else         break;
	}
	printf("%x\n",esi);
}

というわけで、てきとーに
Name : aaaa
Serial : 400f08
data.keyの中身 : 1111111

として、Congrats!

追記:
0xEF,0xBB,0xBFは固定値 とか、
0040117E |. 83FD 0A CMP EBP,0A ;7文字以上のチェック
とか、疑問を持ちつつ、スルーして書いちゃったけど、
テキストファイルのバイナリ覗いたら、0xEF,0xBB,0xBFが先頭にありました。
ということは…フォーマットか!
調べてみると、BOM付きUTF-8 でした。