飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3958|回复: 7

[原创] [原创]破解Boonz’s CreakMe

[复制链接]

该用户从未签到

发表于 2009-8-27 19:46:40 | 显示全部楼层 |阅读模式
【标题】:破解Boonz’s CreakMe
【作者】:riusksk(泉哥)
【主页】:[url]http://riusksk.blogbus.com[/url]
【软件】:[url]http://www.ccgcn.com/bbs/attachment.php?aid=431[/url]
【时间】:2009年8月27日星期四
【声明】:纯属技术学习,如有错误之处,烦请指出!


首先用OD载入,F9运行之,在用户名一框中(作者真懒,连用户名,密码之类的字样都懒得写上,只有两个文本框,上框用户名,下框密码)先填上1,看看是否是用户名长度限制,这只是个人习惯而已,至少总比在逆向分析的时候才知道好吧,呵呵……测试结果如下图1:
[img]http://bbs.pediy.com/attachment.php?attachmentid=30373&d=1251370951[/img]
                  图1
由此可见,用户名长度必须在4—50之间。接着我用”riusksk”作为用户名,密码为”78787878”来分析一下。输入之后,点击check按钮,提示 "Hello, Mr. Badboy!"。我们“查找“->“所有参考文件字串”后,发现这个CM居然是用明码比较的,如下图2所示:
[img]http://bbs.pediy.com/attachment.php?attachmentid=30374&d=1251370951[/img]
                                          图2
单纯找出注册码这不是我们的目的,我们关注的应该是算法。双击提示字符串"Hello, Mr. Badboy!"来到下列地址:
00401000 >/$  6A 00         PUSH 0                                   ; /pModule = NULL
00401002  |.  E8 6D030000   CALL <JMP.&kernel32.GetModuleHandleA>    ; \GetModuleHandleA
00401007  |.  A3 F0DC4000   MOV DWORD PTR DS:[40DCF0],EAX
0040100C  |.  6A 00         PUSH 0                                   ; /lParam = NULL
0040100E  |.  68 2B104000   PUSH KeyGenme.0040102B                   ; |DlgProc = keygenme.0040102B
00401013  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
00401015  |.  68 E9030000   PUSH 3E9                                 ; |pTemplate = 3E9
0040101A  |.  FF35 F0DC4000 PUSH DWORD PTR DS:[40DCF0]               ; |hInst = 00400000
00401020  |.  E8 79030000   CALL <JMP.&user32.DialogBoxParamA>       ; \DialogBoxParamA
00401025  |.  50            PUSH EAX                                 ; /ExitCode
00401026  \.  E8 43030000   CALL <JMP.&kernel32.ExitProcess>         ; \ExitProcess
0040102B  /.  55            PUSH EBP
0040102C  |.  8BEC          MOV EBP,ESP
0040102E  |.  817D 0C 10010>CMP DWORD PTR SS:[EBP+C],110
00401035  |.  75 7F         JNZ SHORT keygenme.004010B6
00401037  |.  6A EC         PUSH -14                                 ; /Index = GWL_EXSTYLE
00401039  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
0040103C  |.  E8 75030000   CALL <JMP.&user32.GetWindowLongA>        ; \GetWindowLongA
00401041  |.  0D 00000800   OR EAX,80000
00401046  |.  50            PUSH EAX                                 ; /NewValue
00401047  |.  6A EC         PUSH -14                                 ; |Index = GWL_EXSTYLE
00401049  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
0040104C  |.  E8 8F030000   CALL <JMP.&user32.SetWindowLongA>        ; \SetWindowLongA
00401051  |.  6A 03         PUSH 3                                   ; /Flags = SWP_NOSIZE|SWP_NOMOVE
00401053  |.  6A 00         PUSH 0                                   ; |Height = 0
00401055  |.  6A 00         PUSH 0                                   ; |Width = 0
00401057  |.  6A 00         PUSH 0                                   ; |Y = 0
00401059  |.  6A 00         PUSH 0                                   ; |X = 0
0040105B  |.  6A FF         PUSH -1                                  ; |InsertAfter = HWND_TOPMOST
0040105D  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
00401060  |.  E8 81030000   CALL <JMP.&user32.SetWindowPos>          ; \SetWindowPos
00401065  |.  68 D1070000   PUSH 7D1                                 ; /RsrcName = 2001.
0040106A  |.  FF35 F0DC4000 PUSH DWORD PTR DS:[40DCF0]               ; |hInst = 00400000
00401070  |.  E8 47030000   CALL <JMP.&user32.LoadIconA>             ; \LoadIconA
00401075  |.  50            PUSH EAX                                 ; /lParam
00401076  |.  6A 01         PUSH 1                                   ; |wParam = 1
00401078  |.  68 80000000   PUSH 80                                  ; |Message = WM_SETICON
0040107D  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
00401080  |.  E8 43030000   CALL <JMP.&user32.SendMessageA>          ; \SendMessageA
00401085  |.  68 EE030000   PUSH 3EE                                 ; /ControlID = 3EE (1006.)
0040108A  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
0040108D  |.  E8 18030000   CALL <JMP.&user32.GetDlgItem>            ; \GetDlgItem
00401092  |.  50            PUSH EAX                                 ; /hWnd
00401093  |.  E8 3C030000   CALL <JMP.&user32.SetFocus>              ; \SetFocus
00401098  |.  6A 01         PUSH 1                                   ; /Arg3 = 00000001
0040109A  |.  68 F88B0000   PUSH 8BF8                                ; |Arg2 = 00008BF8
0040109F  |.  68 00504000   PUSH keygenme.00405000                   ; |Arg1 = 00405000
004010A4  |.  E8 6D030000   CALL keygenme.00401416                   ; \keygenme.00401416
004010A9  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]
004010AC  |.  E8 D6000000   CALL keygenme.00401187
004010B1  |.  E9 CB000000   JMP keygenme.00401181
004010B6  |>  817D 0C 01020>CMP DWORD PTR SS:[EBP+C],201
004010BD  |.  75 17         JNZ SHORT keygenme.004010D6
004010BF  |.  FF75 14       PUSH DWORD PTR SS:[EBP+14]               ; /lParam
004010C2  |.  6A 02         PUSH 2                                   ; |wParam = 2
004010C4  |.  68 A1000000   PUSH 0A1                                 ; |Message = WM_NCLBUTTONDOWN
004010C9  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004010CC  |.  E8 F7020000   CALL <JMP.&user32.SendMessageA>          ; \SendMessageA
004010D1  |.  E9 AB000000   JMP keygenme.00401181
004010D6  |>  817D 0C 11010>CMP DWORD PTR SS:[EBP+C],111
004010DD  |.  75 7F         JNZ SHORT keygenme.0040115E
004010DF  |.  8B45 10       MOV EAX,DWORD PTR SS:[EBP+10]
004010E2  |.  3D F3030000   CMP EAX,3F3
004010E7  |.  75 41         JNZ SHORT keygenme.0040112A
004010E9  |.  6A 28         PUSH 28                                  ; /Count = 28 (40.)             《=我们在这边下断点
004010EB  |.  68 F8DC4000   PUSH keygenme.0040DCF8                   ; |Buffer = keygenme.0040DCF8
004010F0  |.  68 EE030000   PUSH 3EE                                 ; |ControlID = 3EE (1006.)
004010F5  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004010F8  |.  E8 B3020000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
004010FD  |.  6A 28         PUSH 28                                  ; /Count = 28 (40.)
004010FF  |.  68 F8DE4000   PUSH keygenme.0040DEF8                   ; |Buffer = keygenme.0040DEF8
00401104  |.  68 EF030000   PUSH 3EF                                 ; |ControlID = 3EF (1007.)
00401109  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
0040110C  |.  E8 9F020000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
00401111  |.  E8 F2000000   CALL keygenme.00401208                                                 《=加密算法在这里,我们跟进去
00401116  |.  68 F8DF4000   PUSH keygenme.0040DFF8                   ; /Text = "Hello, Mr. Badboy!"    《=停在这边
0040111B  |.  68 EF030000   PUSH 3EF                                 ; |ControlID = 3EF (1007.)
00401120  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
00401123  |.  E8 A6020000   CALL <JMP.&user32.SetDlgItemTextA>       ; \SetDlgItemTextA
00401128  |.  EB 57         JMP SHORT keygenme.00401181
0040112A  |>  3D F0030000   CMP EAX,3F0
0040112F  |.  75 16         JNZ SHORT keygenme.00401147
00401131  |.  6A 00         PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
00401133  |.  68 61DC4000   PUSH keygenme.0040DC61                   ; |Title = "NFO"
00401138  |.  68 2ADC4000   PUSH keygenme.0040DC2A                   ; |Text = "KeygenMe #1
重新载入运行,断下后,一直单步到00401111,然后跟进CALL keygenme.00401208,我们来到这里:

00401208  /$  68 F8DC4000   PUSH keygenme.0040DCF8                   ; /String = "riusksk"
0040120D  |.  E8 80010000   CALL <JMP.&kernel32.lstrlenA>            ; \lstrlenA
00401212  |.  A3 86DC4000   MOV DWORD PTR DS:[40DC86],EAX            ;  保存用户名长度
00401217  |.  833D 86DC4000>CMP DWORD PTR DS:[40DC86],4              ;  用户名长度必须大于4
0040121E  |.  0F8C 29010000 JL keygenme.0040134D
00401224  |.  833D 86DC4000>CMP DWORD PTR DS:[40DC86],32             ;  用户名长度必须小于0x32
0040122B  |.  0F8F 1C010000 JG keygenme.0040134D
00401231  |.  33C0          XOR EAX,EAX                              ;  清零
00401233  |.  33DB          XOR EBX,EBX
00401235  |.  33C9          XOR ECX,ECX
00401237  |.  BF F8DC4000   MOV EDI,keygenme.0040DCF8                ;  ASCII "riusksk"
0040123C  |.  8B15 86DC4000 MOV EDX,DWORD PTR DS:[40DC86]            ;  将用户名长度转存到EDX
00401242  |>  0FB60439      /MOVZX EAX,BYTE PTR DS:[ECX+EDI]         ;  提取用户名各字符u[i]
00401246  |.  83E8 19       |SUB EAX,19                              ;  u[i]-0x19
00401249  |.  2BD8          |SUB EBX,EAX                             ;  将上一循环算出的值EBX减去(u[i]-0x19),EBX初始为0
0040124B  |.  41            |INC ECX                                 ;  ECX为计数器
0040124C  |.  3BCA          |CMP ECX,EDX                             ;  依次循环处理各用户名字符
0040124E  |.^ 75 F2         \JNZ SHORT keygenme.00401242
00401250  |.  53            PUSH EBX                                 ; //<%lX> = FFFFFDA3,循环处理后的结果S1,注意这里的格式为大写字母
00401251  |.  68 F8DB4000   PUSH keygenme.0040DBF8                   ; |Format = "%lX"
00401256  |.  68 F8E04000   PUSH keygenme.0040E0F8                   ; |s = keygenme.0040E0F8
0040125B  |.  E8 38010000   CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
00401260  |.  83C4 0C       ADD ESP,0C
00401263  |.  33C0          XOR EAX,EAX
00401265  |.  33D2          XOR EDX,EDX
00401267  |.  33C9          XOR ECX,ECX
00401269  |.  03C3          ADD EAX,EBX                              ;  将结果S1保存到EAX
0040126B  |.  0FAFC3        IMUL EAX,EBX                             ;  S1平方
0040126E  |.  03C8          ADD ECX,EAX                              ;  ECX=S1^2
00401270  |.  2BD3          SUB EDX,EBX                              ; S1取反
00401272  |.  33D0          XOR EDX,EAX                              ;  S1取反后的值与S1异或运算
00401274  |.  0FAFD8        IMUL EBX,EAX                             ;  S1^3
00401277  |.  53            PUSH EBX                                 ; //<%lX> = F2CD03FB,结果S2
00401278  |.  68 F8DB4000   PUSH keygenme.0040DBF8                   ; |Format = "%lX"
0040127D  |.  68 F8E14000   PUSH keygenme.0040E1F8                   ; |s = keygenme.0040E1F8
00401282  |.  E8 11010000   CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
00401287  |.  83C4 0C       ADD ESP,0C
0040128A  |.  33C0          XOR EAX,EAX
0040128C  |.  33DB          XOR EBX,EBX
0040128E  |.  33D2          XOR EDX,EDX
00401290  |.  33C9          XOR ECX,ECX
00401292  |.  B8 F8E04000   MOV EAX,keygenme.0040E0F8                ;  ASCII "FFFFFDA3"
00401297  |.  03D8          ADD EBX,EAX                              ;  
00401299  |.  33CB          XOR ECX,EBX                              ;  
0040129B  |.  0FAFCB        IMUL ECX,EBX                             ;  40E0F8平方
0040129E  |.  2BC8          SUB ECX,EAX                              ;  40E0F8-S1
004012A0  |.  51            PUSH ECX                                 ; //<%lX> = 41720F48,结果S3
004012A1  |.  68 F8DB4000   PUSH keygenme.0040DBF8                   ; |Format = "%lX"
004012A6  |.  68 F8E24000   PUSH keygenme.0040E2F8                   ; |s = keygenme.0040E2F8
004012AB  |.  E8 E8000000   CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
004012B0  |.  83C4 0C       ADD ESP,0C
004012B3  |.  68 FCDB4000   PUSH keygenme.0040DBFC                   ; /Format = "Bon-"
004012B8  |.  68 F8DD4000   PUSH keygenme.0040DDF8                   ; |s = keygenme.0040DDF8
004012BD  |.  E8 D6000000   CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
004012C2  |.  83C4 08       ADD ESP,8
004012C5  |.  68 F8E04000   PUSH keygenme.0040E0F8                   ; /StringToAdd = "FFFFFDA3"
004012CA  |.  68 F8DD4000   PUSH keygenme.0040DDF8                   ; |ConcatString = "Bon-FFFFFDA3-F2CD03FB-41720F48"
004012CF  |.  E8 B2000000   CALL <JMP.&kernel32.lstrcatA>            ; \lstrcatA
004012D4  |.  68 01DC4000   PUSH keygenme.0040DC01                   ; /StringToAdd = "-"
004012D9  |.  68 F8DD4000   PUSH keygenme.0040DDF8                   ; |ConcatString = "Bon-FFFFFDA3-F2CD03FB-41720F48"
004012DE  |.  E8 A3000000   CALL <JMP.&kernel32.lstrcatA>            ; \lstrcatA
004012E3  |.  68 F8E14000   PUSH keygenme.0040E1F8                   ; /StringToAdd = "F2CD03FB"
004012E8  |.  68 F8DD4000   PUSH keygenme.0040DDF8                   ; |ConcatString = "Bon-FFFFFDA3-F2CD03FB-41720F48"
004012ED  |.  E8 94000000   CALL <JMP.&kernel32.lstrcatA>            ; \lstrcatA
004012F2  |.  68 01DC4000   PUSH keygenme.0040DC01                   ; /StringToAdd = "-"
004012F7  |.  68 F8DD4000   PUSH keygenme.0040DDF8                   ; |ConcatString = "Bon-FFFFFDA3-F2CD03FB-41720F48"
004012FC  |.  E8 85000000   CALL <JMP.&kernel32.lstrcatA>            ; \lstrcatA
00401301  |.  68 F8E24000   PUSH keygenme.0040E2F8                   ; /StringToAdd = "41720F48"
00401306  |.  68 F8DD4000   PUSH keygenme.0040DDF8                   ; |ConcatString = "Bon-FFFFFDA3-F2CD03FB-41720F48"
0040130B  |.  E8 76000000   CALL <JMP.&kernel32.lstrcatA>            ; \lstrcatA
00401310  |.  B8 F8DD4000   MOV EAX,keygenme.0040DDF8                ;  将S1,S2,S3和Bon连接成Bon-S1-S2-S3,作为最后的密码
00401315  |.  BB F8DE4000   MOV EBX,keygenme.0040DEF8                ;  ASCII "78787878"
0040131A  |.  53            PUSH EBX                                 ; /String2 => "78787878"
0040131B  |.  50            PUSH EAX                                 ; |String1 => "Bon-FFFFFDA3-F2CD03FB-41720F48"
0040131C  |.  E8 6B000000   CALL <JMP.&kernel32.lstrcmpA>            ; \lstrcmpA
00401321  |.  74 15         JE SHORT keygenme.00401338               ;  这里直接NOP掉,即可暴破
00401323  |.  68 17DC4000   PUSH keygenme.0040DC17                   ; /Format = "Hello, Mr. Badboy!"
00401328  |.  68 F8DF4000   PUSH keygenme.0040DFF8                   ; |s = keygenme.0040DFF8
0040132D  |.  E8 66000000   CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
00401332  |.  83C4 08       ADD ESP,8
00401335  |.  33C0          XOR EAX,EAX
00401337  |.  C3            RETN
00401338  |>  68 03DC4000   PUSH keygenme.0040DC03                   ; /Format = "Hello, Mr. Goodboy!"
0040133D  |.  68 F8DF4000   PUSH keygenme.0040DFF8                   ; |s = keygenme.0040DFF8
00401342  |.  E8 51000000   CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
00401347  |.  83C4 08       ADD ESP,8
0040134A  |.  33C0          XOR EAX,EAX
0040134C  |.  C3            RETN
0040134D  |>  6A 28         PUSH 28                                  ; /Length = 28 (40.)
0040134F  |.  68 F8DD4000   PUSH keygenme.0040DDF8                   ; |Destination = keygenme.0040DDF8
00401354  |.  E8 21000000   CALL <JMP.&kernel32.RtlZeroMemory>       ; \RtlZeroMemory
00401359  |.  68 65DC4000   PUSH keygenme.0040DC65                   ; /Format = "Name must be 4 - 50 chars long!"
0040135E  |.  68 F8DF4000   PUSH keygenme.0040DFF8                   ; |s = keygenme.0040DFF8
00401363  |.  E8 30000000   CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
00401368  |.  83C4 08       ADD ESP,8
0040136B  |.  33C0          XOR EAX,EAX
0040136D  \.  C3            RETN

算法总结:
1.  用户名长度必须在4-50之间
2. S1=0
for (i=0;i< lstrlen(u);i++)
{S1=S1-(u[i]-0x19) }
3. S2=S1^3
4. S3=40E0F8*40E0F8-40E0F8=41720F48
5. password=Bon-S1-S2-S3
这里提供一组有效注册码:
用户名:riusksk
序列号:Bon-FFFFFDA3-F2CD03FB-41720F48

注册机源码:

#include "stdio.h"

void main()
{
  char username[60];
  int ulen;
  int i=0;
  unsigned long S1=0;
  unsigned long S2;
  unsigned long S3=0x41720F48

  printf("please input your name:");
  gets(username);
  ulen=strlen(username);
  if (ulen<4 || ulen>50)
    printf("Name must be 4 - 50 chars long!\n");
  else
  {

   for(i=0;i<ulen;i++)
    {
       S1=S1-(username[i]-0x19);
    }
   S2=S1*S1*S1;

   printf("\nYour serial is Bon-%lX-%lX-%lX",S1,S2,S3);
   printf("\nMade By riusksk\n\n\n");
   return;
  }
}
测试结果如图3:
[img]http://bbs.pediy.com/attachment.php?attachmentid=30375&d=1251370951[/img]
PYG19周年生日快乐!
  • TA的每日心情
    慵懒
    2015-10-9 11:25
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2009-8-27 20:52:13 | 显示全部楼层
    分析的真详细,学习了。
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-9-11 15:10:56 | 显示全部楼层
    来看看,学习下,支持你
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-5-6 16:27
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2009-10-11 17:51:56 | 显示全部楼层
    图片看不到了。。。支持的说!

    算法注册机我这边总是编译不成功,不知何解。

    [ 本帖最后由 野猫III 于 2009-10-11 18:16 编辑 ]
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-10-11 18:36:51 | 显示全部楼层

    回复 4# 野猫III 的帖子

    /:11 1.缺少;
    2.未定义变量
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-12-18 12:34
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2009-10-11 18:39:00 | 显示全部楼层
    原帖由 野猫III 于 2009-10-11 17:51 发表
    图片看不到了。。。支持的说!

    算法注册机我这边总是编译不成功,不知何解。

    1、unsigned long S3=0x41720F48
    少个分号
    2、头文件缺少
    #include "string.h"
    3、for(i=0;i<ulen;i++)
        {
           S1=S1-(username-0x19);
        }
    应该为
    1. for(i=0;i<ulen;i++)
    2.     {
    3.        S1=S1-(username[i]-0x19);
    4.     }
    复制代码
    代码被处理了,论坛原因。
    楼主把源码设置为插入代码即可。

    [ 本帖最后由 qifeon 于 2009-10-11 18:42 编辑 ]
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-5-6 16:27
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2009-10-11 19:30:55 | 显示全部楼层
    原帖由 qifeon 于 2009-10-11 18:39 发表

    1、unsigned long S3=0x41720F48
    少个分号
    2、头文件缺少
    #include "string.h"
    3、for(i=0;i


    谢谢青牛,我这改了也一样,用的是Dev C++,你带个源码上来给我下载试试。。。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-12-18 12:34
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2009-10-11 19:57:42 | 显示全部楼层
    有事才看到猫哥的帖子。/:013
    附件里注册机加源代码。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?加入我们

    x
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表