【文章标题】: 我的第一个破解
【文章作者】: coldpine
【作者邮箱】: coldpinehe@sina.com
【软件名称】: crackme1.exe
【软件大小】: 200kb
【下载地址】: http://www.crackmes.de
【加壳方式】: 无
【编写语言】: vc++
【使用工具】: od
【操作平台】: win XP
【作者声明】: 这是我第一次写这种破文,有错误的地方,请指点,另外如果有人已经写过了的话,
请通知我删除
用od加载,对GetWindowTextA函数下断点,很容易断在下面
下面是主要程序段
004014C5 |. FF15 D0024300 CALL DWORD PTR DS:[<&USER32.GetWindow>; \GetWindowTextA
004014CB |. 3BF4 CMP ESI, ESP
004014CD |. E8 EE1D0000 CALL crackme1.004032C0
004014D2 |. 8BF4 MOV ESI, ESP
004014D4 |. 68 EB030000 PUSH 3EB ; /ControlID = 3EB (1003.)
004014D9 |. 8B45 08 MOV EAX, DWORD PTR SS:[EBP+8] ; |
004014DC |. 50 PUSH EAX ; |hWnd
004014DD |. FF15 CC024300 CALL DWORD PTR DS:[<&USER32.GetDlgIte>; \GetDlgItem
004014E3 |. 3BF4 CMP ESI, ESP
004014E5 |. E8 D61D0000 CALL crackme1.004032C0
004014EA |. 8945 9C MOV DWORD PTR SS:[EBP-64], EAX
004014ED |. 8BF4 MOV ESI, ESP
004014EF |. 6A 14 PUSH 14 ; /Count = 14 (20.)
004014F1 |. 8D4D A0 LEA ECX, DWORD PTR SS:[EBP-60] ; |
004014F4 |. 51 PUSH ECX ; |Buffer
004014F5 |. 8B55 9C MOV EDX, DWORD PTR SS:[EBP-64] ; |
004014F8 |. 52 PUSH EDX ; |hWnd
004014F9 |. FF15 D0024300 CALL DWORD PTR DS:[<&USER32.GetWindow>; \GetWindowTextA
004014FF |. 3BF4 CMP ESI, ESP
00401501 |. E8 BA1D0000 CALL crackme1.004032C0
00401506 |. E8 FFFAFFFF CALL crackme1.0040100A
0040150B |. 85C0 TEST EAX, EAX
0040150D |. 74 4D JE SHORT crackme1.0040155C
0040150F |. 6A 0A PUSH 0A
00401511 |. 8D45 E0 LEA EAX, DWORD PTR SS:[EBP-20]
00401514 |. 50 PUSH EAX
00401515 |. 8D4D C0 LEA ECX, DWORD PTR SS:[EBP-40]
00401518 |. 51 PUSH ECX
00401519 |. E8 0AFBFFFF CALL crackme1.00401028
0040151E |. 83C4 04 ADD ESP, 4
00401521 |. 50 PUSH EAX ; |Arg1
00401522 |. E8 49A00000 CALL crackme1.0040B570 ; \crackme1.0040B570
00401527 |. 83C4 0C ADD ESP, 0C
0040152A |. 50 PUSH EAX
0040152B |. 8D55 A0 LEA EDX, DWORD PTR SS:[EBP-60]
0040152E |. 52 PUSH EDX
0040152F |. E8 6C1F0000 CALL crackme1.004034A0
00401534 |. 83C4 08 ADD ESP, 8
00401537 |. 85C0 TEST EAX, EAX
00401539 75 1F JNZ SHORT crackme1.0040155A
0040153B |. 8BF4 MOV ESI, ESP
0040153D |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
0040153F |. 68 4CA04200 PUSH crackme1.0042A04C ; |lolmuckis crackme #1\ncoded 2006 by mucki
00401544 |. 68 34A04200 PUSH crackme1.0042A034 ; |make a keygen ;-)
00401549 |. 8B45 08 MOV EAX, DWORD PTR SS:[EBP+8] ; |
0040154C |. 50 PUSH EAX ; |hOwner
0040154D |. FF15 D4024300 CALL DWORD PTR DS:[<&USER32.MessageBo>; \MessageBoxA
00401553 |. 3BF4 CMP ESI, ESP
00401555 |. E8 661D0000 CALL crackme1.004032C0
0040155A |> EB 44 JMP SHORT crackme1.004015A0
0040155C |> 6A 0A PUSH 0A
0040155E |. 8D4D E0 LEA ECX, DWORD PTR SS:[EBP-20]
00401561 |. 51 PUSH ECX
00401562 |. 8D55 C0 LEA EDX, DWORD PTR SS:[EBP-40]
00401565 |. 52 PUSH EDX
00401566 |. E8 B3FAFFFF CALL crackme1.0040101E //用户名处理函数,
将每个字母变成大写的字母,将ascii码值乘以157a-1,再求和
0040156B |. 83C4 04 ADD ESP, 4
0040156E |. 50 PUSH EAX ; |Arg1
0040156F |. E8 FC9F0000 CALL crackme1.0040B570 ; \crackme1.0040B570 //将数字除以A求余,商继续除以A求余
//依次到最后就是最后的序列号
00401574 |. 83C4 0C ADD ESP, 0C
00401577 |. 50 PUSH EAX
00401578 |. 8D45 A0 LEA EAX, DWORD PTR SS:[EBP-60]
0040157B |. 50 PUSH EAX
0040157C |. E8 1F1F0000 CALL crackme1.004034A0 //比较字符串函数
00401581 |. 83C4 08 ADD ESP, 8
00401584 |. 85C0 TEST EAX, EAX
00401586 |. 75 18 JNZ SHORT crackme1.004015A0 //爆破点,关键跳转
00401588 |. 8BF4 MOV ESI, ESP
0040158A |. 68 1CA04200 PUSH crackme1.0042A01C ; /now make a keygen!
0040158F |. 8B4D 9C MOV ECX, DWORD PTR SS:[EBP-64] ; |
00401592 |. 51 PUSH ECX ; |hWnd
00401593 |. FF15 D8024300 CALL DWORD PTR DS:[<&USER32.SetWindow>; \SetWindowTextA
00401599 |. 3BF4 CMP ESI, ESP
0040159B |. E8 201D0000 CALL crackme1.004032C0
004015A0 |> 5F POP EDI
004015A1 |. 5E POP ESI
004015A2 |. 5B POP EBX
004015A3 |. 81C4 A4000000 ADD ESP, 0A4
004015A9 |. 3BEC CMP EBP, ESP
004015AB |. E8 101D0000 CALL crackme1.004032C0
004015B0 |. 8BE5 MOV ESP, EBP
004015B2 |. 5D POP EBP
004015B3 \. C3 RET
004015B4 CC INT3
//将用户名的小写字母转化为大写字母
00403320 /$ 55 PUSH EBP
00403321 |. 8BEC MOV EBP, ESP
00403323 |. 83EC 0C SUB ESP, 0C
00403326 |. C745 F8 00000>MOV DWORD PTR SS:[EBP-8], 0
0040332D |. 833D 00DF4200>CMP DWORD PTR DS:[42DF00], 0
00403334 |. 75 47 JNZ SHORT crackme1.0040337D
00403336 |. 8B45 08 MOV EAX, DWORD PTR SS:[EBP+8]
00403339 |. 8945 F4 MOV DWORD PTR SS:[EBP-C], EAX
0040333C |. EB 09 JMP SHORT crackme1.00403347
0040333E |> 8B4D F4 /MOV ECX, DWORD PTR SS:[EBP-C]
00403341 |. 83C1 01 |ADD ECX, 1
00403344 |. 894D F4 |MOV DWORD PTR SS:[EBP-C], ECX
00403347 |> 8B55 F4 MOV EDX, DWORD PTR SS:[EBP-C]
0040334A |. 0FBE02 |MOVSX EAX, BYTE PTR DS:[EDX] //取出每一个字母的ascii码值
0040334D |. 85C0 |TEST EAX, EAX
0040334F |. 74 24 |JE SHORT crackme1.00403375
00403351 |. 8B4D F4 |MOV ECX, DWORD PTR SS:[EBP-C]
00403354 |. 0FBE11 |MOVSX EDX, BYTE PTR DS:[ECX]
00403357 |. 83FA 61 |CMP EDX, 61 //判断是不是小写字母
0040335A |. 7C 17 |JL SHORT crackme1.00403373
0040335C |. 8B45 F4 |MOV EAX, DWORD PTR SS:[EBP-C]
0040335F |. 0FBE08 |MOVSX ECX, BYTE PTR DS:[EAX]
00403362 |. 83F9 7A |CMP ECX, 7A //
00403365 |. 7F 0C |JG SHORT crackme1.00403373
00403367 |. 8B55 F4 |MOV EDX, DWORD PTR SS:[EBP-C]
0040336A |. 8A02 |MOV AL, BYTE PTR DS:[EDX]
0040336C |. 04 E0 |ADD AL, 0E0 //将每个acsii码值加224D
0040336E |. 8B4D F4 |MOV ECX, DWORD PTR SS:[EBP-C]
00403371 |. 8801 |MOV BYTE PTR DS:[ECX], AL //小写转大写字母
00403373 |>^ EB C9 \JMP SHORT crackme1.0040333E //循环
00403375 |> 8B45 08 MOV EAX, DWORD PTR SS:[EBP+8] //无字母的话就跳出在此,将转换的大写字母放在ax中
00403378 |. E9 99000000 JMP crackme1.00403416
0040337D |> 6A 01 PUSH 1
0040337F |. 6A 00 PUSH 0
00403381 |. 6A 00 PUSH 0
00403383 |. 6A 00 PUSH 0
00403385 |. 6A FF PUSH -1
00403387 |. 8B55 08 MOV EDX, DWORD PTR SS:[EBP+8]
0040338A |. 52 PUSH EDX
0040338B |. 68 00020000 PUSH 200
00403390 |. A1 00DF4200 MOV EAX, DWORD PTR DS:[42DF00]
00403395 |. 50 PUSH EAX
00403396 |. E8 753B0000 CALL crackme1.00406F10
0040339B |. 83C4 20 ADD ESP, 20
0040339E |. 8945 FC MOV DWORD PTR SS:[EBP-4], EAX
004033A1 |. 837D FC 00 CMP DWORD PTR SS:[EBP-4], 0
004033A5 |. 75 02 JNZ SHORT crackme1.004033A9
004033A7 |. EB 5C JMP SHORT crackme1.00403405
004033A9 |> 6A 62 PUSH 62 ; /Arg4 = 00000062
004033AB |. 68 78A14200 PUSH crackme1.0042A178 ; |strupr.c
004033B0 |. 6A 02 PUSH 2 ; |Arg2 = 00000002
004033B2 |. 8B4D FC MOV ECX, DWORD PTR SS:[EBP-4] ; |
004033B5 |. 51 PUSH ECX ; |Arg1
004033B6 |. E8 F51B0000 CALL crackme1.00404FB0 ; \crackme1.00404FB0
004033BB |. 83C4 10 ADD ESP, 10
004033BE |. 8945 F8 MOV DWORD PTR SS:[EBP-8], EAX
004033C1 |. 837D F8 00 CMP DWORD PTR SS:[EBP-8], 0
004033C5 |. 75 02 JNZ SHORT crackme1.004033C9
004033C7 |. EB 3C JMP SHORT crackme1.00403405
004033C9 |> 6A 01 PUSH 1
004033CB |. 6A 00 PUSH 0
004033CD |. 8B55 FC MOV EDX, DWORD PTR SS:[EBP-4]
004033D0 |. 52 PUSH EDX
004033D1 |. 8B45 F8 MOV EAX, DWORD PTR SS:[EBP-8]
004033D4 |. 50 PUSH EAX
004033D5 |. 6A FF PUSH -1
004033D7 |. 8B4D 08 MOV ECX, DWORD PTR SS:[EBP+8]
004033DA |. 51 PUSH ECX
004033DB |. 68 00020000 PUSH 200
004033E0 |. 8B15 00DF4200 MOV EDX, DWORD PTR DS:[42DF00]
004033E6 |. 52 PUSH EDX
004033E7 |. E8 243B0000 CALL crackme1.00406F10
004033EC |. 83C4 20 ADD ESP, 20
004033EF |. 85C0 TEST EAX, EAX
004033F1 |. 75 02 JNZ SHORT crackme1.004033F5
004033F3 |. EB 10 JMP SHORT crackme1.00403405
004033F5 |> 8B45 F8 MOV EAX, DWORD PTR SS:[EBP-8]
004033F8 |. 50 PUSH EAX
004033F9 |. 8B4D 08 MOV ECX, DWORD PTR SS:[EBP+8]
004033FC |. 51 PUSH ECX
004033FD |. E8 1E3A0000 CALL crackme1.00406E20
00403402 |. 83C4 08 ADD ESP, 8
00403405 |> 6A 02 PUSH 2 ; /Arg2 = 00000002
00403407 |. 8B55 F8 MOV EDX, DWORD PTR SS:[EBP-8] ; |
0040340A |. 52 PUSH EDX ; |Arg1
0040340B |. E8 E0250000 CALL crackme1.004059F0 ; \crackme1.004059F0
00403410 |. 83C4 08 ADD ESP, 8
00403413 |. 8B45 08 MOV EAX, DWORD PTR SS:[EBP+8]
00403416 |> 8BE5 MOV ESP, EBP
00403418 |. 5D POP EBP
00403419 \. C3 RET
//分析: 将每个字母的大写ascii码值乘以157a再减一求和,再将和乘以A,加上一个数就是
计算序列号的数了(加上的这个数我不会分析,里面很多浮点计算看不懂,希望大虾指点)
00401211 |> /8B55 FC /MOV EDX, DWORD PTR SS:[EBP-4]
00401214 |. |83C2 01 |ADD EDX, 1
00401217 |. |8955 FC |MOV DWORD PTR SS:[EBP-4], EDX
0040121A |> |8B45 FC MOV EAX, DWORD PTR SS:[EBP-4]
0040121D |. |3B45 F0 |CMP EAX, DWORD PTR SS:[EBP-10] //与输入的位数比较,少就继续取字母
00401220 |. |7D 3C |JGE SHORT crackme1.0040125E
00401222 |. |8B4D 08 |MOV ECX, DWORD PTR SS:[EBP+8]
00401225 |. |034D FC |ADD ECX, DWORD PTR SS:[EBP-4]
00401228 |. |33D2 |XOR EDX, EDX
0040122A |. |8A11 |MOV DL, BYTE PTR DS:[ECX] //依次取出每一个大写字母的ASCii码值
0040122C |. |83FA 20 |CMP EDX, 20
0040122F |. |74 2B |JE SHORT crackme1.0040125C
00401231 |. |8B45 08 |MOV EAX, DWORD PTR SS:[EBP+8]
00401234 |. |0345 FC |ADD EAX, DWORD PTR SS:[EBP-4]
00401237 |. |33C9 |XOR ECX, ECX
00401239 |. |8A08 |MOV CL, BYTE PTR DS:[EAX]
0040123B |. |894D F4 |MOV DWORD PTR SS:[EBP-C], ECX
0040123E |. |8B55 F4 |MOV EDX, DWORD PTR SS:[EBP-C]
00401241 |. |69D2 7A150000 |IMUL EDX, EDX, 157A //将ascii值乘157a
00401247 |. |8955 F4 |MOV DWORD PTR SS:[EBP-C], EDX
0040124A |. |8B45 F4 |MOV EAX, DWORD PTR SS:[EBP-C]
0040124D |. |83E8 01 |SUB EAX, 1 //乘积减一
00401250 |. |8945 F4 |MOV DWORD PTR SS:[EBP-C], EAX
00401253 |. |8B4D F8 |MOV ECX, DWORD PTR SS:[EBP-8]
00401256 |. |034D F4 |ADD ECX, DWORD PTR SS:[EBP-C]
00401259 |. |894D F8 |MOV DWORD PTR SS:[EBP-8], ECX
0040125C |>^\EB B3 \JMP SHORT crackme1.00401211
//通过上述计算出来的数字再除以A求余,再用商除以A求余,依次下去就是序列号
0040B5EF |> /8B45 08 /MOV EAX, DWORD PTR SS:[EBP+8]
0040B5F2 |. |33D2 |XOR EDX, EDX
0040B5F4 |. |F775 10 |DIV DWORD PTR SS:[EBP+10] //将数字除以A之后的商继续除以A连续如此保存每次除A之后的余数
//组成序列号
0040B5F7 |. |8955 F4 |MOV DWORD PTR SS:[EBP-C], EDX
0040B5FA |. |8B45 08 |MOV EAX, DWORD PTR SS:[EBP+8]
0040B5FD |. |33D2 |XOR EDX, EDX
0040B5FF |. |F775 10 |DIV DWORD PTR SS:[EBP+10]
0040B602 |. |8945 08 |MOV DWORD PTR SS:[EBP+8], EAX
0040B605 |. |837D F4 09 |CMP DWORD PTR SS:[EBP-C], 9
0040B609 |. |76 16 |JBE SHORT crackme1.0040B621
0040B60B |. |8B55 F4 |MOV EDX, DWORD PTR SS:[EBP-C]
0040B60E |. |83C2 57 |ADD EDX, 57
0040B611 |. |8B45 FC |MOV EAX, DWORD PTR SS:[EBP-4]
0040B614 |. |8810 |MOV BYTE PTR DS:[EAX], DL
0040B616 |. |8B4D FC |MOV ECX, DWORD PTR SS:[EBP-4]
0040B619 |. |83C1 01 |ADD ECX, 1
0040B61C |. |894D FC |MOV DWORD PTR SS:[EBP-4], ECX
0040B61F |. |EB 14 |JMP SHORT crackme1.0040B635
0040B621 |> |8B55 F4 |MOV EDX, DWORD PTR SS:[EBP-C]
0040B624 |. |83C2 30 |ADD EDX, 30
0040B627 |. |8B45 FC |MOV EAX, DWORD PTR SS:[EBP-4]
0040B62A |. |8810 |MOV BYTE PTR DS:[EAX], DL
0040B62C |. |8B4D FC |MOV ECX, DWORD PTR SS:[EBP-4]
0040B62F |. |83C1 01 |ADD ECX, 1
0040B632 |. |894D FC |MOV DWORD PTR SS:[EBP-4], ECX
0040B635 |> |837D 08 00 |CMP DWORD PTR SS:[EBP+8], 0
0040B639 |.^\77 B4 \JA SHORT crackme1.0040B5EF
//比较序列号函数
0040157C |. E8 1F1F0000 CALL crackme1.004034A0
004034A0 /$ 8B5424 04 MOV EDX, DWORD PTR SS:[ESP+4] //输入的序列号
004034A4 |. 8B4C24 08 MOV ECX, DWORD PTR SS:[ESP+8] //算出的序列号
004034A8 |. F7C2 03000000 TEST EDX, 3
004034AE |. 75 3C JNZ SHORT crackme1.004034EC
004034B0 |> 8B02 /MOV EAX, DWORD PTR DS:[EDX] //输入的序列号的前四位的
// acii码值
004034B2 |. 3A01 |CMP AL, BYTE PTR DS:[ECX] //比较第一位
004034B4 75 2E JNZ SHORT crackme1.004034E4 //是继续,否则玩完
004034B6 |. 0AC0 |OR AL, AL
004034B8 |. 74 26 |JE SHORT crackme1.004034E0
004034BA |. 3A61 01 |CMP AH, BYTE PTR DS:[ECX+1] //比较第二位
004034BD |. 75 25 |JNZ SHORT crackme1.004034E4
004034BF |. 0AE4 |OR AH, AH
004034C1 |. 74 1D |JE SHORT crackme1.004034E0
004034C3 |. C1E8 10 |SHR EAX, 10 //将第三位第四位移至al ah中
004034C6 |. 3A41 02 |CMP AL, BYTE PTR DS:[ECX+2] //比较第三位
004034C9 |. 75 19 |JNZ SHORT crackme1.004034E4
004034CB |. 0AC0 |OR AL, AL
004034CD |. 74 11 |JE SHORT crackme1.004034E0
004034CF |. 3A61 03 |CMP AH, BYTE PTR DS:[ECX+3] //比较第四位
004034D2 |. 75 10 |JNZ SHORT crackme1.004034E4
004034D4 |. 83C1 04 |ADD ECX, 4 //取正确序列号第四字节以后的字母
004034D7 |. 83C2 04 |ADD EDX, 4 //取输入序列号的第四字节以后的字母
004034DA |. 0AE4 |OR AH, AH
004034DC |.^ 75 D2 \JNZ SHORT crackme1.004034B0 //取完了没有,没有继续循环再比较
总结:
算法分析:
第一步: 将用户的输入的用户名转化为大写字母
然后将每个字母的ascii码值乘以157a并
将结果减一,最后将每个字母的计算结果
相加,再将和乘以A得到一个数
第二步: 计算一个数,和第一步的数值相加(对不起
,这个数值的计算方法看不懂,好像有很多浮点
计算,希望高手指点)
第三步: 将第二步相加的结果除以A,得到商和余数
商继续除以A得到商和余数,依次将所有的余数
组在一起就是序列号啦!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课