首页
社区
课程
招聘
[原创]rOYALaCCEZZCRACKME算法分析
发表于: 2006-3-8 16:44 7075

[原创]rOYALaCCEZZCRACKME算法分析

2006-3-8 16:44
7075

【文章标题】: rOYALaCCEZZCRACKME算法分析
【软件名称】: rOYALaCCEZZCRACKME
【软件大小】: 35.5K
【下载地址】: http://ocn.e5v.com/bbs1/attachment.php?aid=920&checkid=f8a85&download=1
【编写语言】: ASM
【使用工具】: OLLYDBG
【操作平台】: WIN2000
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  1、peid查看为MASM32 / TASM32,无壳,ASM程序,省了不少事。
  2、OD载入,查看字符串,“you got the serial (puuh, that was hard”,嘿嘿,很好的切入点,双击,向上查找,在关键的地方00401096下断,运行,随便输入用户名和注册码,点确定,被断下:
  00401087  |.  6A 40         PUSH 40                                  ; /Count = 40 (64.)
  00401089  |.  68 84304000   PUSH rOYALaCC.00403084                   ; |Buffer = rOYALaCC.00403084
  0040108E  |.  68 EA030000   PUSH 3EA                                 ; |ControlID = 3EA (1002.)
  00401093  |.  FF75 08       PUSH [ARG.1]                             ; |hWnd
  00401096  |.  E8 A1020000   CALL <JMP.&USER32.GetDlgItemTextA>       ; \取注册码长度
  0040109B  |.  8BD8          MOV EBX,EAX
  0040109D  |.  6A 40         PUSH 40                                  ; /Count = 40 (64.)
  0040109F  |.  68 44304000   PUSH rOYALaCC.00403044                   ; |Buffer = rOYALaCC.00403044
  004010A4  |.  68 E8030000   PUSH 3E8                                 ; |ControlID = 3E8 (1000.)
  004010A9  |.  FF75 08       PUSH [ARG.1]                             ; |hWnd
  004010AC  |.  E8 8B020000   CALL <JMP.&USER32.GetDlgItemTextA>       ; \取用户名长度
  004010B1  |.  83F8 05       CMP EAX,5                                ;  是否大于5
  004010B4  |.  72 28         JB SHORT rOYALaCC.004010DE               ;  小于则跳到提示用户名不够的地方
  004010B6  |.  83F8 20       CMP EAX,20                               ;  是否大于20
  004010B9  |.  77 23         JA SHORT rOYALaCC.004010DE               ;  大于则跳到提示用户名太多
  004010BB  |.  0BDB          OR EBX,EBX                               ;  注册码长度与用户名长度对比
  004010BD  |.  74 1F         JE SHORT rOYALaCC.004010DE               ;  相同就跳死
  004010BF  |.  53            PUSH EBX
  004010C0  |.  50            PUSH EAX
  004010C1  |.  E8 7B000000   CALL rOYALaCC.00401141                   ;  算法,跟入
  004010C6  |.  83F8 01       CMP EAX,1                                ;  返回的EAX是否为1
  004010C9  |.  75 13         JNZ SHORT rOYALaCC.004010DE              ;  不是就跳错
  004010CB  |.  6A 00         PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
  004010CD  |.  68 34304000   PUSH rOYALaCC.00403034                   ; |Title = "You打e 1337 ;)"
  004010D2  |.  68 0B304000   PUSH rOYALaCC.0040300B                   ; |you got the serial (puuh, that was hard)
  004010D7  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
  004010D9  |.  E8 64020000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
  
  =============================================================================================
  跟进算法CALL 00401141
  
  00401141  /$  55            PUSH EBP
  00401142  |.  8BEC          MOV EBP,ESP
  00401144  |.  8B45 08       MOV EAX,[ARG.1]                          ;  用户名长度
  00401147  |.  C705 C4304000>MOV DWORD PTR DS:[4030C4],0              ;  段寄存器4030C4赋值0
  00401151  |.  BB 01000000   MOV EBX,1                                ;  EBX赋值1
  00401156  |.  EB 1D         JMP SHORT rOYALaCC.00401175
  00401158  |>  48            /DEC EAX                                 ;  用户名位数减1
  00401159  |.  0FB690 443040>|MOVZX EDX,BYTE PTR DS:[EAX+403044]      ;  逐个倒取用户名ASCII的十六进制码
  00401160  |.  33D3          |XOR EDX,EBX                             ;  异或HEX码和EBX的值(初始为1),放到EDX中
  00401162  |.  0FAFD3        |IMUL EDX,EBX                            ;  结果和EBX值相乘
  00401165  |.  83C3 05       |ADD EBX,5                               ;  EBX+5
  00401168  |.  3115 C4304000 |XOR DWORD PTR DS:[4030C4],EDX           ;  EDX的值异或段寄存器4030C4的值(初始为0)
  0040116E  |.  C105 C4304000>|ROL DWORD PTR DS:[4030C4],5             ;  结果循环左移5位
  00401175  |>  0BC0           OR EAX,EAX                              ;  用户名位数是否取完
  00401177  |.^ 75 DF         \JNZ SHORT rOYALaCC.00401158             ;  没有则继续循环
  00401179  |.  F715 C4304000 NOT DWORD PTR DS:[4030C4]                ;  计算结果取反,用户名最终结果在地址4030C4里
  
  0040117F  |.  33C9          XOR ECX,ECX                              ;  ECX清空
  00401181  |.  8B4D 08       MOV ECX,[ARG.1]                          ;  赋值用户名长度
  00401184  |.  D30D C4304000 ROR DWORD PTR DS:[4030C4],CL             ;  赋值用户名长度循环左移5位
  0040118A  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  0040118C  |.  C605 C8304000>MOV BYTE PTR DS:[4030C8],0               ;  4030C8地址赋值0
  00401193  |.  EB 17         JMP SHORT rOYALaCC.004011AC
  00401195  |>  0FB690 843040>/MOVZX EDX,BYTE PTR DS:[EAX+403084]      ;  逐个取注册码HEX码
  0040119C  |.  40            |INC EAX                                 ;  EAX=EAX+1(EAX初始为0)
  0040119D  |.  83FA 2D       |CMP EDX,2D                              ;  注册码是否为“-”
  004011A0  |.  75 0A         |JNZ SHORT rOYALaCC.004011AC             ;  不是就跳
  004011A2  |.  FEC8          |DEC AL                                  ;  EAX=EAX-1
  004011A4  |.  A2 C8304000   |MOV BYTE PTR DS:[4030C8],AL             ;  EAX的值放入4030C8地址
  004011A9  |.  8B45 0C       |MOV EAX,[ARG.2]                         ;  注册码长度放入EAX
  004011AC  |>  3B45 0C        CMP EAX,[ARG.2]                         ;  EAX的值(初始为0)与注册码长度对比
  004011AF  |.^ 75 E4         \JNZ SHORT rOYALaCC.00401195             ;  不等就循环
  004011B1  |.  803D C8304000>CMP BYTE PTR DS:[4030C8],0               ;  结果是否为0
  004011B8  |.  75 06         JNZ SHORT rOYALaCC.004011C0              ;  一定要跳
  004011BA  |.  33C0          XOR EAX,EAX
  004011BC  |.  C9            LEAVE
  004011BD  |.  C2 0800       RETN 8
  
  -------注册码中必须含有“-”号,并判断“-”号是第几位
  
  004011C0  |> \33C9          XOR ECX,ECX                              ;  ECX清空
  004011C2  |.  8A0D C8304000 MOV CL,BYTE PTR DS:[4030C8]              ;  上面的计算结果放入CL(-号的位置)
  004011C8  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  004011CA  |.  33DB          XOR EBX,EBX                              ;  EBX清空
  004011CC  |.  EB 14         JMP SHORT rOYALaCC.004011E2
  004011CE  |>  FEC9          /DEC CL                                  ;  “-”号前的注册码长度减1
  004011D0  |.  0FB691 843040>|MOVZX EDX,BYTE PTR DS:[ECX+403084]      ;  倒取“-”号前的注册码的十六进制码
  004011D7  |.  83FA 3F       |CMP EDX,3F                              ;  是否大于3F,就是判断是否大于A(41)
  004011DA  |.  76 0E         |JBE SHORT rOYALaCC.004011EA
  004011DC  |.  83FA 5B       |CMP EDX,5B                              ;  是否小于5B,判断是否小于Z(5A)
  004011DF  |.  73 09         |JNB SHORT rOYALaCC.004011EA
  004011E1  |.  90            |NOP
  004011E2  |>  0AC9           OR CL,CL                                ;  “-”号前的注册码长度是否取完
  004011E4  |.^ 75 E8         \JNZ SHORT rOYALaCC.004011CE             ;  不等就循环
  004011E6  |.  90            NOP
  004011E7  |.  90            NOP
  004011E8  |.  EB 06         JMP SHORT rOYALaCC.004011F0
  004011EA  |>  33C0          XOR EAX,EAX
  004011EC  |.  C9            LEAVE
  004011ED  |.  C2 0800       RETN 8
  
  ------------“-”号前的注册码必须为大写字母
  
  004011F0  |> \33C9          XOR ECX,ECX                              ;  ECX清空
  004011F2  |.  8A0D C8304000 MOV CL,BYTE PTR DS:[4030C8]              ;  “-”号前的注册码长度
  004011F8  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  004011FA  |.  33DB          XOR EBX,EBX                              ;  EBX清空
  004011FC  |.  EB 11         JMP SHORT rOYALaCC.0040120F
  004011FE  |>  FEC9          /DEC CL                                  ;  “-”号前的注册码长度减1
  00401200  |.  6BDB 1A       |IMUL EBX,EBX,1A                         ;  EBX=EBX*1A,EBX,初始为0
  00401203  |.  0FB691 843040>|MOVZX EDX,BYTE PTR DS:[ECX+403084]      ;  倒取“-”号前的注册码的十六进制码
  0040120A  |.  83EA 41       |SUB EDX,41                              ;  减41H
  0040120D  |.  03DA          |ADD EBX,EDX                             ;  加EBX的值
  0040120F  |>  0AC9           OR CL,CL                                ;  “-”号前的注册码长度是否取完
  00401211  |.^ 75 EB         \JNZ SHORT rOYALaCC.004011FE             ;  没有就继续循环
  00401213  |.  3B1D C4304000 CMP EBX,DWORD PTR DS:[4030C4]            ;  计算结果与401179处的用户名计算结果的值对比,4030C4放的是上面的用户名计算结果
  00401219      74 06         JE SHORT rOYALaCC.00401221               ;  必须要相等,要跳
  0040121B  |.  33C0          XOR EAX,EAX
  0040121D  |.  C9            LEAVE
  0040121E  |.  C2 0800       RETN 8
  
  ------------倒取“-”号前的注册码的HEX码减41,加1A结果要与用户名的最终计算结果相等
  
  
  00401221  |>  8B45 0C       MOV EAX,[ARG.2]                          ;  注册码长度放入EAX
  00401224  |.  2A05 C8304000 SUB AL,BYTE PTR DS:[4030C8]              ;  减“-”号前的注册码长度
  0040122A  |.  83F8 04       CMP EAX,4                                ;  是否为4
  0040122D      74 06         JE SHORT rOYALaCC.00401235               ;  不是就跳错,必须跳,要等于-号前要为4位
  0040122F  |.  33C0          XOR EAX,EAX
  00401231  |.  C9            LEAVE
  00401232  |.  C2 0800       RETN 8
  
  -------------注册码“-”号必须为4位注册码
  
  00401235  |> \33DB          XOR EBX,EBX                              ;  EBX清空
  00401237  |.  8A1D C8304000 MOV BL,BYTE PTR DS:[4030C8]              ;  “-”号前的注册码长度放入BL
  0040123D  |.  FEC3          INC BL                                   ;  BL=BL+1,BL为“-”号的位置
  0040123F  |.  0FB693 843040>MOVZX EDX,BYTE PTR DS:[EBX+403084]       ;  取“-”号后第一位注册码的十六进制码
  00401246  |.  8815 C9304000 MOV BYTE PTR DS:[4030C9],DL              ;  放入段寄存器地址4030C9
  0040124C  |.  FEC3          INC BL                                   ;  取下一位
  0040124E  |.  0FB693 843040>MOVZX EDX,BYTE PTR DS:[EBX+403084]       ;  取“-”号后第二位注册码的十六进制码
  00401255  |.  8815 CA304000 MOV BYTE PTR DS:[4030CA],DL              ;  放入段寄存器地址4030CA
  0040125B  |.  FEC3          INC BL                                   ;  取下一位
  0040125D  |.  0FB693 843040>MOVZX EDX,BYTE PTR DS:[EBX+403084]       ;  取“-”号后第三位注册码的十六进制码
  00401264  |.  8815 CB304000 MOV BYTE PTR DS:[4030CB],DL              ;  放入段寄存器地址4030CB
  0040126A  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  0040126C  |.  A0 C9304000   MOV AL,BYTE PTR DS:[4030C9]              ;  “-”号后第一位注册码的十六进制码放入AL
  00401271  |.  6BC0 03       IMUL EAX,EAX,3                           ;  乘3
  00401274  |.  A3 CC304000   MOV DWORD PTR DS:[4030CC],EAX            ;  放入段寄存器地址4030CC
  00401279  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  0040127B  |.  8A1D C9304000 MOV BL,BYTE PTR DS:[4030C9]              ;  “-”号后第一位注册码的十六进制码放入AL
  00401281  |.  6BDB 07       IMUL EBX,EBX,7                           ;  乘7
  00401284  |.  2BC3          SUB EAX,EBX                              ;  减EAX(0)的值
  00401286  |.  A3 D0304000   MOV DWORD PTR DS:[4030D0],EAX            ;  结果放入段寄存器地址4030D0
  0040128B  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  0040128D  |.  A0 C9304000   MOV AL,BYTE PTR DS:[4030C9]              ;  “-”号后第一位注册码的十六进制码放入AL
  00401292  |.  A3 D4304000   MOV DWORD PTR DS:[4030D4],EAX            ;  结果放入段寄存器地址4030D4
  00401297  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  00401299  |.  A0 CA304000   MOV AL,BYTE PTR DS:[4030CA]              ;  “-”号后第二位注册码的十六进制码放入AL
  0040129E  |.  2905 CC304000 SUB DWORD PTR DS:[4030CC],EAX            ;  减4030CC的值(“-”号后第一位注册码的十六进制码乘3)
  004012A4  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  004012A6  |.  A0 CA304000   MOV AL,BYTE PTR DS:[4030CA]              ;  “-”号后第二位注册码的十六进制码放入AL
  004012AB  |.  6BC0 02       IMUL EAX,EAX,2                           ;  乘2
  004012AE  |.  0105 D0304000 ADD DWORD PTR DS:[4030D0],EAX            ;  加4030D0地址的值(“-”号后第一位注册码的十六进制码乘7)
  004012B4  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  004012B6  |.  A0 CA304000   MOV AL,BYTE PTR DS:[4030CA]              ;  “-”号后第二位注册码的十六进制码放入AL
  004012BB  |.  0105 D4304000 ADD DWORD PTR DS:[4030D4],EAX            ;  加“-”号后第一位注册码的十六进制码
  004012C1  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  004012C3  |.  A0 CB304000   MOV AL,BYTE PTR DS:[4030CB]              ;  “-”号后第三位注册码的十六进制码放入AL
  004012C8  |.  6BC0 05       IMUL EAX,EAX,5                           ;  乘5
  004012CB  |.  0105 CC304000 ADD DWORD PTR DS:[4030CC],EAX            ;  加4030CC的值(“-”号后第一位注册码的十六进制码乘3)
  004012D1  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  004012D3  |.  A0 CB304000   MOV AL,BYTE PTR DS:[4030CB]              ;  “-”号后第三位注册码的十六进制码放入AL
  004012D8  |.  6BC0 07       IMUL EAX,EAX,7                           ;  乘7
  004012DB  |.  0105 D0304000 ADD DWORD PTR DS:[4030D0],EAX            ;  加4030D0地址的值(“-”号后第一位注册码的十六进制码乘7)
  004012E1  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  004012E3  |.  A0 CB304000   MOV AL,BYTE PTR DS:[4030CB]              ;  “-”号后第三位注册码的十六进制码放入AL
  004012E8  |.  6BC0 02       IMUL EAX,EAX,2                           ;  乘2
  004012EB  |.  2905 D4304000 SUB DWORD PTR DS:[4030D4],EAX            ;  计算结果减地址4030D4的值(“-”号后第一位注册码的十六进制码)
  004012F1  |.  813D CC304000>CMP DWORD PTR DS:[4030CC],204            ;  是否为204H
  004012FB      74 06         JE SHORT rOYALaCC.00401303               ;  不等就死,必须跳
  004012FD  |.  33C0          XOR EAX,EAX
  004012FF  |.  C9            LEAVE
  00401300  |.  C2 0800       RETN 8
  00401303  |>  833D D0304000>CMP DWORD PTR DS:[4030D0],19             ;  4030D0地址的值(“-”号后第一位注册码的十六进制码乘7)是否为19H,从这里可以推出“-”号后第一位注册码
  0040130A      74 06         JE SHORT rOYALaCC.00401312               ;  不等就死,必须跳
  0040130C  |.  33C0          XOR EAX,EAX
  0040130E  |.  C9            LEAVE
  0040130F  |.  C2 0800       RETN 8
  00401312  |>  833D D4304000>CMP DWORD PTR DS:[4030D4],0D             ;  地址4030D4的值(“-”号后第一位注册码的十六进制码)是否为0D,
  00401319  |.  74 06         JE SHORT rOYALaCC.00401321               ;  不等会死,一定要跳
  0040131B  |.  33C0          XOR EAX,EAX                              ;  EAX清空
  0040131D  |.  C9            LEAVE
  0040131E  |.  C2 0800       RETN 8
  00401321  |>  B8 01000000   MOV EAX,1                                ;  成功则赋标志位1
  00401326  |.  C9            LEAVE
  00401327  \.  C2 0800       RETN 8                                   ;  成功返回
  
  ================================================================================================
  
  
  算法总结:倒取用户名ASCII的十六进制码异或用户名位数,并乘用户名位数,再加5,结果左移5位,然后取反,结果假设为A。
  注册码中必须含有“-”号,“-”号前为4位,并且都为大写字母,倒取“-”号前的注册码的HEX码减41,加1A结果要与用户名的最终计算A结果相等。
  注册码“-”号后有三位参与计算,可以用逆推法计算出三位注册码。
  
  
  贴个C语言注册机源码:
  #include <stdio.h>
  #include <string.h>
  main()
  {
      char name[100];
      char SN[100];
      unsigned long mem,edx,sum;
      int c,count,ebx,regcode;
      ebx=1;
      mem=0;
      printf("\t\t KeyGen   For      rOYALaCCEZZCRACKME\n");
      printf("\t\t =========================\n");
      printf("Please Input Your Name:\n");
      gets(name);
      count=strlen(name);
      c=count-1;
      for(c;c>=0;c--)
      {
          edx=name[c];
          edx=edx ^ ebx;
          edx=edx * ebx;
          ebx=ebx + 5;
          mem=mem ^ edx;
          mem=mem << 5 | mem >> 27;
      }
      mem=~mem;
      mem=mem>>strlen(name) | mem << (32-strlen(name));
      sum=mem;
      while(mem>0)
      {
          regcode=mem%0x1a+0x41;
          printf("%c",regcode);
          mem=mem/0x1a;
      }
      printf("-RAC");
      getchar();
      
  }
  
  
  并感谢lnn1123[OCN]的帮助。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年03月08日 下午 04:40:47


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 615
活跃值: (1212)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
支持,写的很详细!
2006-3-8 18:01
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢,学习,慢慢看
2006-3-8 19:52
0
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
4
支持,写的非常详细
2006-3-8 22:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
前?:您真下面的呃句?意思是注?瘁和用?名樘度比蒉,但是我只知道其中一?是用?名樘度,而密瘁樘度是怎?到了另一?ebx彦面啊?
入樵期殓真的是疑惑重重啊
?好有您?呃些先人指路,有?方向

004010BB  |.  0BDB  OR EBX,EBX       ;  注册码长度与用户名长度对比
2006-3-10 09:25
0
雪    币: 560
活跃值: (359)
能力值: ( LV13,RANK:1370 )
在线值:
发帖
回帖
粉丝
6
谢谢peterwang细心的看这篇文章,请看上面:
00401096  |.  E8 A1020000   CALL <JMP.&USER32.GetDlgItemTextA>       ; 通过GetDlgItemTextA取输入的注册码长度
0040109B  |.  8BD8          MOV EBX,EAX                              ;  注册码长度放入EBX,此时EBX的长度为注册码个数

...

004010AC  |.  E8 8B020000   CALL <JMP.&USER32.GetDlgItemTextA>       ; \取用户名长度

...

004010BB  |.  0BDB          OR EBX,EBX                               ;  注册码长度与用户名长度对比
004010BD  |.  74 1F         JE SHORT rOYALaCC.004010DE               ;  相同就跳死

Or:或运算, X Or Y 指是否能满足条件X或者Y中的一个,而OR X,X的结果就是X,这里就是用GetDlgItemTextA函数取用户名个数存入EAX,与上面取得的注册码个数(就是现在的EBX)进行对比,能否满足,有时候代码往往需要上下连真看。
2006-3-10 11:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
laomms:
全部文章打印了。慢慢的??。第一次看到呃???的真明。
可能我比蒉愚忡,呃???的?铨也看不懂。
著著您。
如果有?铨搞不明白,再向您?教。

昨天特地到破解酵?注?,但是就是下蒌不到那??件。真不能?外部?接,
咄去了也?有找到哪?是。能否真明白一??或者乾脆帖上??
呃?好的?西是,少了例子,太可惜了

我要先自己研究一番,不懂的先查一查。

向您表示崇高的著意!!

2006-3-10 12:27
0
雪    币: 560
活跃值: (359)
能力值: ( LV13,RANK:1370 )
在线值:
发帖
回帖
粉丝
8
已经放到我的网络硬盘里了,你可以去那里下载,大家彼此学习才对!
2006-3-10 14:23
0
雪    币: 242
活跃值: (163)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
9
学了
2006-3-10 16:42
0
雪    币: 107
活跃值: (13)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
谢谢,学习中,写的挺详细。
2006-3-11 20:41
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
谢谢,学习,慢慢看
2006-4-6 09:16
0
游客
登录 | 注册 方可回帖
返回
//