网游难民 发表于 2006-8-25 00:19:18

HappyTown's crackme算法分析

【文章标题】: HappyTown's crackme算法分析
【文章作者】: 网游难民
【作者主页】: www.chinapyg.com
【软件名称】: HappyTown's crackme
【软件大小】: 5.50
【下载地址】: 本地
【编写语言】: MASM32 / TASM32
【操作平台】: win xp
【软件介绍】: 一个不错的crackme
【作者声明】: 为庆祝PYG官方论坛2006.8.25以全新模式运作,,并开放注册一天而发~~激动ing~~
--------------------------------------------------------------------------------
【详细过程】
一,PEID查壳,为MASM32 / TASM32,运行,随便输入用户名,注册码,没有反映~~
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
二,下几个常用API断点,没有断下来,用eXeScope打开文件。(直接查找字符串也可以,这里只是介绍种方法)
1.用资源察看器eXeScope察看其Check(或注册)按钮所对应的资源ID号为1006,转换成16进制即3EE,前面加0后即03EE。
2.用W32DASM载入,点击查找-查找文本-03EE。来到004011C6,看到cmp ax,03EE。这就是点Check按钮后,代码执行的地方。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
三.用OD载入,找到4011C6处,在下面的4011D0处下断。
004011CA|. /0F85 3B010000 JNZ CrackMe_.0040130B
004011D0|. |68 43204000   PUSH CrackMe_.00402043                   ;在这里下断
004011D5|. |E8 E8FEFFFF   CALL CrackMe_.004010C2                   ; \CrackMe_.004010C2
004011DA|. |8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
004011DD|. |6A 05         PUSH 5
004011DF|. |FF75 FC       PUSH DWORD PTR SS:[EBP-4]
004011E2|. |E8 B1FEFFFF   CALL CrackMe_.00401098
004011E7|. |6A 0D         PUSH 0D
004011E9|. |50            PUSH EAX
004011EA|. |E8 92FEFFFF   CALL CrackMe_.00401081
004011EF|. |68 47204000   PUSH CrackMe_.00402047                   ; /Arg1 = 00402047 ASCII "d:\"
004011F4|. |E8 C9FEFFFF   CALL CrackMe_.004010C2                   ; \CrackMe_.004010C2
004011F9|. |8945 F8       MOV DWORD PTR SS:[EBP-8],EAX
004011FC|. |FF75 F8       PUSH DWORD PTR SS:[EBP-8]
004011FF|. |FF75 FC       PUSH DWORD PTR SS:[EBP-4]
00401202|. |E8 A8FEFFFF   CALL CrackMe_.004010AF
00401207|. |6A 05         PUSH 5
00401209|. |50            PUSH EAX
0040120A|. |E8 89FEFFFF   CALL CrackMe_.00401098
0040120F|. |6A 0D         PUSH 0D
00401211|. |50            PUSH EAX
00401212|. |E8 6AFEFFFF   CALL CrackMe_.00401081
00401217|. |FF75 F8       PUSH DWORD PTR SS:[EBP-8]                ; /Arg2
0040121A|. |FF75 FC       PUSH DWORD PTR SS:[EBP-4]                ; |Arg1
0040121D|. |E8 34FEFFFF   CALL CrackMe_.00401056                   ; \CrackMe_.00401056
00401222|. |8945 F0       MOV DWORD PTR SS:[EBP-10],EAX
00401225|. |68 80000000   PUSH 80                                  ; /Count = 80 (128.)
0040122A|. |68 04314000   PUSH CrackMe_.00403104                   ; |Buffer = CrackMe_.00403104
0040122F|. |68 EC030000   PUSH 3EC                                 ; |ControlID = 3EC (1004.)
00401234|. |FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
00401237|. |E8 FC000000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
0040123C|. |8945 F4       MOV DWORD PTR SS:[EBP-C],EAX             ;得到注册名位数
0040123F|. |837D F4 04    CMP DWORD PTR SS:[EBP-C],4
00401243|. |73 04         JNB SHORT CrackMe_.00401249            ;位数要大于4
00401245|. |C9            LEAVE
00401246|. |C2 1000       RETN 10
00401249|> |68 04314000   PUSH CrackMe_.00403104
0040124E|. |E8 E3FDFFFF   CALL CrackMe_.00401036                   ;用户名ASCII逐位相乘--算法CALL1
00401253|. |6A 01         PUSH 1
00401255|. |50            PUSH EAX
00401256|. |E8 26FEFFFF   CALL CrackMe_.00401081                   ;EAX中的值循环左移一位--算法CALL2
0040125B|. |0B45 F0       OR EAX,DWORD PTR SS:[EBP-10]             ;   与63A4C7FC逻辑或
0040125E|. |25 FFFFFF0F   AND EAX,0FFFFFFF                         ;保留后七位
00401263|. |8945 EC       MOV DWORD PTR SS:[EBP-14],EAX
00401266|. |33C9          XOR ECX,ECX
00401268|. |33D2          XOR EDX,EDX
0040126A|. |8D35 00304000 LEA ESI,DWORD PTR DS:
00401270|. |8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]
00401273|> |8945 EC       /MOV DWORD PTR SS:[EBP-14],EAX
00401276|. |6A 10         |PUSH 10                                 ; /10入栈
00401278|. |50            |PUSH EAX                              ; |Arg1
00401279|. |E8 82FDFFFF   |CALL CrackMe_.00401000                  ; \取出EAX中的最后一位---算法CALL3
0040127E|. |8BC8          |MOV ECX,EAX
00401280|. |8D3D 73204000 |LEA EDI,DWORD PTR DS:
00401286|. |8A0439      |MOV AL,BYTE PTR DS:[ECX+EDI]            ;取出表(71362de9f8ab45c)中为数对应的数字
00401289|. |8806          |MOV BYTE PTR DS:[ESI],AL
0040128B|. |8B45 EC       |MOV EAX,DWORD PTR SS:[EBP-14]         ;把EAX中取最后一位前的数值防入EAX中
0040128E|. |6A 04         |PUSH 4                                  ; /Arg2 = 00000004
00401290|. |50            |PUSH EAX                              ; |Arg1
00401291|. |E8 86FDFFFF   |CALL CrackMe_.0040101C                  ; \EAX的值除4--算法CALL4
00401296|. |8945 EC       |MOV DWORD PTR SS:[EBP-14],EAX
00401299|. |0BC0          |OR EAX,EAX
0040129B|. |74 04         |JE SHORT CrackMe_.004012A1            ;检测EAX是否为0,为0则跳
0040129D|. |46            |INC ESI
0040129E|. |47            |INC EDI
0040129F|.^|EB D2         \JMP SHORT CrackMe_.00401273
004012A1|> |68 00010000   PUSH 100                                 ; /Count = 100 (256.)
004012A6|. |8D85 ECFEFFFF LEA EAX,DWORD PTR SS:[EBP-114]         ; |
004012AC|. |50            PUSH EAX                                 ; |Buffer
004012AD|. |68 ED030000   PUSH 3ED                                 ; |ControlID = 3ED (1005.)
004012B2|. |FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004012B5|. |E8 7E000000   CALL <JMP.&user32.GetDlgItemTextA>       ; \取得注册码位数
004012BA|. |0BC0          OR EAX,EAX
004012BC|. |75 04         JNZ SHORT CrackMe_.004012C2            ;检查有没有填写注册码
004012BE|. |C9            LEAVE
004012BF|. |C2 1000       RETN 10
004012C2|> |68 00304000   PUSH CrackMe_.00403000                   ; /把上面循环取的的数字连在一起即为注册码
004012C7|. |8D85 ECFEFFFF LEA EAX,DWORD PTR SS:[EBP-114]         ; |
004012CD|. |50            PUSH EAX                                 ; |String1
004012CE|. |E8 53000000   CALL <JMP.&kernel32.lstrcmpA>            ; \lstrcmpA
004012D3|. |0BC0          OR EAX,EAX
004012D5|. |75 18         JNZ SHORT CrackMe_.004012EF            ;关键跳转
004012D7|. |6A 40         PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004012D9|. |68 08214000   PUSH CrackMe_.00402108                   ; |Title = "Congratulations"
004012DE|. |68 F9204000   PUSH CrackMe_.004020F9                   ; |Text = "GOOD JOB, MAN!"
004012E3|. |FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hOwner
004012E6|. |E8 59000000   CALL <JMP.&user32.MessageBoxA>         ; \MessageBoxA
004012EB|. |C9            LEAVE
004012EC|. |C2 1000       RETN 10
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
算法CALL1:
00401036/$55            PUSH EBP
00401037|.8BEC          MOV EBP,ESP
00401039|.8B75 08       MOV ESI,DWORD PTR SS:[EBP+8]
0040103C|.FC            CLD
0040103D|.33D2          XOR EDX,EDX
0040103F|.B8 01000000   MOV EAX,1
00401044|>0FB60E      /MOVZX ECX,BYTE PTR DS:[ESI]
00401047|.46            |INC ESI
00401048|.0BC9          |OR ECX,ECX
0040104A|.74 06         |JE SHORT CrackMe_.00401052
0040104C|.F7E1          |MUL ECX
0040104E|.03C2          |ADD EAX,EDX
00401050|.^ EB F2         \JMP SHORT CrackMe_.00401044------------循环求用户名的ASCII码的乘积放入EAX中
00401052|>C9            LEAVE
00401053\.C2 0400       RETN 4
00401056/$55            PUSH EBP

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
算法CALL2:
00401081/$55            PUSH EBP
00401082|.8BEC          MOV EBP,ESP
00401084|.53            PUSH EBX
00401085|.56            PUSH ESI
00401086|.57            PUSH EDI
00401087|.8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]
0040108A|.8D55 0C       LEA EDX,DWORD PTR SS:[EBP+C]
0040108D|.8A0A          MOV CL,BYTE PTR DS:[EDX]               ;给CL赋值1
0040108F|.D3C0          ROL EAX,CL                               ;循环左移一位
00401091|.5F            POP EDI
00401092|.5E            POP ESI
00401093|.5B            POP EBX
00401094|.C9            LEAVE
00401095\.C2 0800       RETN 8

+++++++++++++++++++++++++++++++++++++++++++++++
算法CALL3:
00401000/$55            PUSH EBP
00401001|.8BEC          MOV EBP,ESP
00401003|.83C4 FC       ADD ESP,-4
00401006|.53            PUSH EBX
00401007|.56            PUSH ESI
00401008|.57            PUSH EDI
00401009|.33D2          XOR EDX,EDX
0040100B|.8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]
0040100E|.8B4D 0C       MOV ECX,DWORD PTR SS:[EBP+C]               ;把十赋给ECX,
00401011|.F7F9          IDIV ECX
00401013|.8BC2          MOV EAX,EDX                                 ;把原EAX的最后一位给EAX
00401015|.5F            POP EDI
00401016|.5E            POP ESI
00401017|.5B            POP EBX
00401018|.C9            LEAVE
00401019\.C2 0800       RETN 8
++++++++++++++++++++++++++++++++++++++++++++++++++++
算法CALL4:
0040101C/$55            PUSH EBP
0040101D|.8BEC          MOV EBP,ESP
0040101F|.83C4 FC       ADD ESP,-4
00401022|.53            PUSH EBX
00401023|.56            PUSH ESI
00401024|.57            PUSH EDI
00401025|.33D2          XOR EDX,EDX
00401027|.8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]
0040102A|.8B4D 0C       MOV ECX,DWORD PTR SS:[EBP+C]             ;ECX赋值4
0040102D|.F7F9          IDIV ECX                                 ;EAX中的值除4
0040102F|.5F            POP EDI
00401030|.5E            POP ESI
00401031|.5B            POP EBX
00401032|.C9            LEAVE
00401033\.C2 0800       RETN 8





--------------------------------------------------------------------------------
【经验总结】
这个crackme在下断的方法不常见,希望能给大家带来点用处~~~
算法是:
1. 用户名ASCII逐位相乘,取后八位,值记为A
2.A循环左移一位,记为B。
3.一个循环:
先取B的最后一位的值对应表(71362de9f8ab45c)的数值.
然后除4,再去循环去最后一位数对应的数值。
一直到EAX等于0
4.把上面循环取的的数值连接起来就是正确的注册玛:
一组可用的注册玛:
               goqq2008
               5ccce24adf5c3

注意,如果调试一次后请关闭crackme再调试~~输入注册码也一样,如果输入错误的注册码请重启crackme再输入正确的~

--------------------------------------------------------------------------------

yezishop 发表于 2006-8-27 01:20:25

难民,,偶像哇。。好厉害,连算法都分析出来了

黑夜彩虹 发表于 2006-8-30 11:31:33

难民,,偶像哇。。好厉害,连算法都分析出来了

lgjxj 发表于 2006-8-30 14:49:00

既然大家都 “难民,,偶像哇。。好厉害,连算法都分析出来了” 不差我一份
页: [1]
查看完整版本: HappyTown's crackme算法分析