首页
社区
课程
招聘
[原创]happytown第17个crackme算法分析
2007-1-21 17:32 5284

[原创]happytown第17个crackme算法分析

2007-1-21 17:32
5284
【文章标题】: happytown第17个crackme算法分析
【文章作者】: dewar
【作者邮箱】: huazi0745@sina.com
【下载地址】: 看雪论坛搜索
【加壳方式】: 无
【保护方式】: 无
【编写语言】: VC
【使用工具】: OD
【操作平台】: WINXP
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  本人菜鸟一只,这是我的笔记,内容很菜,高手略过.
  1.PEID查无壳,VC编写.
  2.OD截入,停在OEP处,按Ctrl+N,在名称一栏中找到USER32.GetDlgItemTextA,选中后右击====>在每个参考上设置断点.打开断点窗口可看到已设置好两个断点.(一个用户名的,一个注册码的,正好^_^)
  3.F9运行,输入注册信息
  用户名:dewarj
  注册码:abcdefghijklmn
  为什么这么输往下看就知道了.
  4.点Check按钮,程序立即中断在如下的地方:
  ......
  004011B6  |.  68 C9000000   PUSH 0C9                           ; /Count = C9 (201.)
  004011BB  |.  52            PUSH EDX                           ; |Buffer
  004011BC  |.  68 E8030000   PUSH 3E8                           ; |ControlID = 3E8 (1000.)
  004011C1  |.  50            PUSH EAX                           ; |hWnd
  004011C2  |.  FF15 AC504000 CALL DWORD PTR DS:[<&USER32.GetDlg>; \<====中断在这里.获取用户名及长度,用户名放入EDX所指的缓存中,长度在EAX中
  004011C8  |.  8BF0          MOV ESI,EAX                        ;  长度=>ESI
  004011CA  |.  83FE 06       CMP ESI,6
  004011CD  |.  0F8C 3B020000 JL CrackMe_.0040140E               ;  长度不能小于6
  004011D3  |.  83FE 0F       CMP ESI,0F
  004011D6  |.  0F8F 32020000 JG CrackMe_.0040140E               ;  长度不能大于15
  004011DC  |.  8D4C24 4C     LEA ECX,DWORD PTR SS:[ESP+4C]      ;  取用户名到ECX
  004011E0  |.  56            PUSH ESI
  004011E1  |.  51            PUSH ECX
  004011E2  |.  E8 39020000   CALL CrackMe_.00401420             ;  用户名小写转化为大写
  004011E7  |.  83C4 08       ADD ESP,8
  004011EA  |.  85C0          TEST EAX,EAX                       ;  用户名中有无字母外的字符
  004011EC  |.  0F84 1C020000 JE CrackMe_.0040140E               ;  有就跳向失败
  004011F2  |.  33ED          XOR EBP,EBP
  004011F4  |.  33C9          XOR ECX,ECX
  004011F6  |.  3BF5          CMP ESI,EBP
  004011F8  |.  7E 2F         JLE SHORT CrackMe_.00401229
  004011FA  |>  33FF          /XOR EDI,EDI                       ;  EDI清零
  004011FC  |.  3BCD          |CMP ECX,EBP                       ;  循环变量ECX与EBP比较
  004011FE  |.  7E 24         |JLE SHORT CrackMe_.00401224       ;  小于等于就跳
  00401200  |>  8A543C 4C     |/MOV DL,BYTE PTR SS:[ESP+EDI+4C]  ;  取用户名的第EDI个字符
  00401204  |.  8A440C 4C     ||MOV AL,BYTE PTR SS:[ESP+ECX+4C]  ;  取用户名的第ECX个字符
  00401208  |.  3AD0          ||CMP DL,AL                        ;  两位进行比较
  0040120A  |.  75 13         ||JNZ SHORT CrackMe_.0040121F      ;  不等就跳
  0040120C  |.  3BCE          ||CMP ECX,ESI                      ;  相等就看是不是串尾
  0040120E  |.  8BC1          ||MOV EAX,ECX                      ;  循环变量EAX=ECX
  00401210  |.  7D 0D         ||JGE SHORT CrackMe_.0040121F      ;  是就跳
  00401212  |>  8A5404 4D     ||/MOV DL,BYTE PTR SS:[ESP+EAX+4D] ;  \不是就
  00401216  |.  885404 4C     |||MOV BYTE PTR SS:[ESP+EAX+4C],DL ;  |将用户名第EAX(ECX)位的后一字符前移一位
  0040121A  |.  40            |||INC EAX                         ;  |循环变量EAX+1(下一位)
  0040121B  |.  3BC6          |||CMP EAX,ESI                     ;  |是否到串尾
  0040121D  |.^ 7C F3         ||\JL SHORT CrackMe_.00401212      ;  /没有就循环
  0040121F  |>  47            ||INC EDI                          ;  循环变量EDI+1(下一位)
  00401220  |.  3BF9          ||CMP EDI,ECX                      ;  EDI与ECX比较
  00401222  |.^ 7C DC         |\JL SHORT CrackMe_.00401200       ;  小于就循环
  00401224  |>  41            |INC ECX                           ;  循环变量ECX+1(下一位)
  00401225  |.  3BCE          |CMP ECX,ESI                       ;  是否到串尾
  00401227  |.^ 7C D1         \JL SHORT CrackMe_.004011FA        ;  没有就循环
  00401229  |>  8D4424 4C     LEA EAX,DWORD PTR SS:[ESP+4C]      ;  以上是去重,但不完全:ECX位ECX+1位与前面有重复,则ECX+1位保留.
  0040122D  |.  50            PUSH EAX                           ; /String
  0040122E  |.  FF15 04504000 CALL DWORD PTR DS:[<&KERNEL32.lstr>; \取处理后的用户名长度
  00401234  |.  8BF0          MOV ESI,EAX
  00401236  |.  83FE 06       CMP ESI,6                          ;  不能小于6位
  00401239  |.  0F8C CF010000 JL CrackMe_.0040140E               ;  小于跳向失败
  5.到这里我们知道,我们输入的用户名只能是6~15位,且只能是英文字母.程序得到用户名后要对其进行处理,处理完后的用户名长度不能小于6位.处理过程是这样的:
  (1)取用户名的第i位字符(i的范围从1到用户名长度);
  (2)用户名第i位前的各位依次与第i位进行比较,如果相同就删除第i位并将其后的各字符前移一位,然后继续比较(这时用户名是变化的);
  (3)i加1,如果小于用户名长度(不是串尾)就回到(1)循环
  去重不完全的原因是在第(2)中,当第i+1位前移到第i位后它就躲过了比较.可见当相邻N(N≥2)位相同时,若其前相同字符数≤(N-1),就会保留下一个来.如EAEEBEEECEEED经过处理的变化经过是:
  EAEEBEEECEEED==>EAEBEEECEEED==>EAEBECEEED==>EAEBECD
  最后的'EEE'因前面会留下3个'E'所以全部去掉了.
  这样,我输的dewarj就变成了DEWARJ
  0040123F  |.  8D4C24 4C     LEA ECX,DWORD PTR SS:[ESP+4C]
  00401243  |.  8D5424 20     LEA EDX,DWORD PTR SS:[ESP+20]
  00401247  |.  51            PUSH ECX                           ; /String2
  00401248  |.  52            PUSH EDX                           ; |String1
  00401249  |.  FF15 00504000 CALL DWORD PTR DS:[<&KERNEL32.lstr>; \lstrcpyA
  0040124F  |.  B3 41         MOV BL,41                          ;  A
  00401251  |.  896C24 10     MOV DWORD PTR SS:[ESP+10],EBP
  00401255  |.  8D7434 20     LEA ESI,DWORD PTR SS:[ESP+ESI+20]
  00401259  |>  80FB 4A       /CMP BL,4A                         ;  J
  0040125C  |.  75 0A         |JNZ SHORT CrackMe_.00401268
  0040125E  |.  B3 49         |MOV BL,49                         ;  I
  00401260  |.  C74424 10 010>|MOV DWORD PTR SS:[ESP+10],1
  00401268  |>  0FBEC3        |MOVSX EAX,BL
  0040126B  |.  8D4C24 20     |LEA ECX,DWORD PTR SS:[ESP+20]
  0040126F  |.  50            |PUSH EAX
  00401270  |.  51            |PUSH ECX
  00401271  |.  E8 2A020000   |CALL CrackMe_.004014A0
  00401276  |.  83C4 08       |ADD ESP,8
  00401279  |.  85C0          |TEST EAX,EAX
  0040127B  |.  75 03         |JNZ SHORT CrackMe_.00401280
  0040127D  |.  881E          |MOV BYTE PTR DS:[ESI],BL
  0040127F  |.  46            |INC ESI
  00401280  |>  8A5424 10     |MOV DL,BYTE PTR SS:[ESP+10]
  00401284  |.  896C24 10     |MOV DWORD PTR SS:[ESP+10],EBP
  00401288  |.  FEC2          |INC DL
  0040128A  |.  02DA          |ADD BL,DL
  0040128C  |.  80FB 5B       |CMP BL,5B                         ;  ASCII(Z)=5A
  0040128F  |.^ 75 C8         \JNZ SHORT CrackMe_.00401259       ;  从A到Z按顺序补上用户名中没有的字符(J除外)
  6.接着对用户名进行处理:从A到Z按顺序补上用户名中没有的字符(J除外),这样就得到了真正参与运算的用户名.我输入的dewarj得到的是:DEWARJBCFGHIKLMNOPQSTUVXYZ
  00401291  |.  8B8C24 E00100>MOV ECX,DWORD PTR SS:[ESP+1E0]
  00401298  |.  8D8424 140100>LEA EAX,DWORD PTR SS:[ESP+114]
  0040129F  |.  68 C9000000   PUSH 0C9                           ; /Count = C9 (201.)
  004012A4  |.  50            PUSH EAX                           ; |Buffer
  004012A5  |.  68 E9030000   PUSH 3E9                           ; |ControlID = 3E9 (1001.)
  004012AA  |.  51            PUSH ECX                           ; |hWnd
  004012AB  |.  FF15 AC504000 CALL DWORD PTR DS:[<&USER32.GetDlg>; \取注册码
  004012B1  |.  83F8 0E       CMP EAX,0E                         ;  必须是14位
  004012B4  |.  0F85 54010000 JNZ CrackMe_.0040140E
  004012BA  |.  8D9424 140100>LEA EDX,DWORD PTR SS:[ESP+114]
  004012C1  |.  50            PUSH EAX
  004012C2  |.  52            PUSH EDX
  004012C3  |.  E8 58010000   CALL CrackMe_.00401420             ;  转为大写
  004012C8  |.  83C4 08       ADD ESP,8
  004012CB  |.  85C0          TEST EAX,EAX                       ;  不能是除字母以外的其它字符
  004012CD  |.  0F84 3B010000 JE CrackMe_.0040140E
  004012D3  |.  8B5C24 10     MOV EBX,DWORD PTR SS:[ESP+10]
  004012D7  |.  896C24 1C     MOV DWORD PTR SS:[ESP+1C],EBP
  004012DB  |.  8B6C24 1C     MOV EBP,DWORD PTR SS:[ESP+1C]
  004012DF  |.  8B7C24 1C     MOV EDI,DWORD PTR SS:[ESP+1C]
  004012E3  |>  8B4424 1C     /MOV EAX,DWORD PTR SS:[ESP+1C]     ;  取注册码的第EAX组(一组2位)
  004012E7  |.  8A9404 140100>|MOV DL,BYTE PTR SS:[ESP+EAX+114]  ;  第1位=>DL
  004012EE  |.  8A8C04 150100>|MOV CL,BYTE PTR SS:[ESP+EAX+115]  ;  第2位=>CL
  004012F5  |.  8DB404 150100>|LEA ESI,DWORD PTR SS:[ESP+EAX+115>;  ESI=注册码第EAX组第2位的地址
  004012FC  |.  80FA 4A       |CMP DL,4A                         ;  第1位与'J'比较
  004012FF  |.  884C24 17     |MOV BYTE PTR SS:[ESP+17],CL       ;  CL=>[ESP+17]
  00401303  |.  75 02         |JNZ SHORT CrackMe_.00401307       ;  不等就跳(不处理)
  00401305  |.  B2 49         |MOV DL,49                         ;  相等,J变I
  00401307  |>  33C9          |XOR ECX,ECX
  00401309  |.  8D7424 20     |LEA ESI,DWORD PTR SS:[ESP+20]     ;  ESI=处理后用户名的首址
  0040130D  |>  33C0          |/XOR EAX,EAX                      ;  循环变量清零EAX=0
  0040130F  |>  381406        ||/CMP BYTE PTR DS:[ESI+EAX],DL    ;  DL与用户名的第EAX位比较
  00401312  |.  75 0A         |||JNZ SHORT CrackMe_.0040131E     ;  不等就跳(下一位)
  00401314  |.  8B5C24 10     |||MOV EBX,DWORD PTR SS:[ESP+10]   ;  相等就
  00401318  |.  8BE9          |||MOV EBP,ECX                     ;  记下组数=>EBP
  0040131A  |.  894424 18     |||MOV DWORD PTR SS:[ESP+18],EAX   ;  记下位数=>[ESP+18]
  0040131E  |>  40            |||INC EAX                         ;  下一位
  0040131F  |.  83F8 05       |||CMP EAX,5                       ;  循环变量EAX与5比较
  00401322  |.^ 7C EB         ||\JL SHORT CrackMe_.0040130F      ;  少于5就循环
  00401324  |.  41            ||INC ECX                          ;  下一组
  00401325  |.  83C6 05       ||ADD ESI,5                        ;  指针ESI后移5位
  00401328  |.  83F9 05       ||CMP ECX,5                        ;  5组都完了没?
  0040132B  |.^ 7C E0         |\JL SHORT CrackMe_.0040130D       ;  没有就循环
  0040132D  |.  33F6          |XOR ESI,ESI
  0040132F  |.  8D4C24 20     |LEA ECX,DWORD PTR SS:[ESP+20]
  00401333  |>  33C0          |/XOR EAX,EAX                      ;  循环变量清零EAX=0
  00401335  |>  8A5424 17     ||/MOV DL,BYTE PTR SS:[ESP+17]     ;  [ESP+17]=CL(注册码第EAX组第2位)=>DL
  00401339  |.  3811          |||CMP BYTE PTR DS:[ECX],DL        ;  与用户名的第EAX位比较
  0040133B  |.  75 04         |||JNZ SHORT CrackMe_.00401341     ;  不等就跳(不处理)
  0040133D  |.  8BFE          |||MOV EDI,ESI                     ;  相等就:组数存EDI
  0040133F  |.  8BD8          |||MOV EBX,EAX                     ;  位数存EBX
  00401341  |>  40            |||INC EAX
  00401342  |.  41            |||INC ECX                         ;  下一位
  00401343  |.  83F8 05       |||CMP EAX,5                       ;  位数与5比较
  00401346  |.^ 7C ED         ||\JL SHORT CrackMe_.00401335      ;  小于就循环
  00401348  |.  46            ||INC ESI                          ;  下一组
  00401349  |.  83FE 05       ||CMP ESI,5                        ;  组数与5比较
  0040134C  |.^ 7C E5         |\JL SHORT CrackMe_.00401333       ;  小于就循环
  0040134E  |.  3BEF          |CMP EBP,EDI                       ;  注册码第EAX组中的两位在用户名中是否同组
  00401350  |.  895C24 10     |MOV DWORD PTR SS:[ESP+10],EBX     ;  注册码第2位在用户名某组中的位数=>[ESP+10]
  00401354  |.  75 3A         |JNZ SHORT CrackMe_.00401390       ;  不同组就跳
  00401356  |.  8B4424 18     |MOV EAX,DWORD PTR SS:[ESP+18]     ;  同组就:
  0040135A  |.  85C0          |TEST EAX,EAX                      ;  注册码第1位在用户名某组中的位数是不是第0位
  0040135C  |.  75 0A         |JNZ SHORT CrackMe_.00401368       ;  不是就跳(不处理)
  0040135E  |.  C74424 18 040>|MOV DWORD PTR SS:[ESP+18],4       ;  是就0变4
  00401366  |.  EB 04         |JMP SHORT CrackMe_.0040136C
  00401368  |>  FF4C24 18     |DEC DWORD PTR SS:[ESP+18]         ;  注册码第1位在用户名某组中的位数减1
  0040136C  |>  85DB          |TEST EBX,EBX                      ;  注册码第2位在用户名某组中的位数是不是第0位
  0040136E  |.  75 07         |JNZ SHORT CrackMe_.00401377       ;  不是就跳(不处理)
  00401370  |.  BB 04000000   |MOV EBX,4                         ;  是就0变4
  00401375  |.  EB 01         |JMP SHORT CrackMe_.00401378
  00401377  |>  4B            |DEC EBX                           ;  注册码第2位在用户名某组中的位数减1
  00401378  |>  8B4424 18     |MOV EAX,DWORD PTR SS:[ESP+18]
  0040137C  |.  8BD5          |MOV EDX,EBP
  0040137E  |.  895C24 10     |MOV DWORD PTR SS:[ESP+10],EBX
  00401382  |.  8D0CA8        |LEA ECX,DWORD PTR DS:[EAX+EBP*4]
  00401385  |.  03D1          |ADD EDX,ECX                       ;  EDX=第1位的组数*5+第1位的位数
  00401387  |.  8D0CBB        |LEA ECX,DWORD PTR DS:[EBX+EDI*4]  ;  CL=用户名(注册码第2位所在组数,注册码第2位所在位数)
  0040138A  |.  8A4414 20     |MOV AL,BYTE PTR SS:[ESP+EDX+20]   ;  AL=用户名(注册码第1位所在组数,注册码第1位所在位数)
  0040138E  |.  EB 46         |JMP SHORT CrackMe_.004013D6
  00401390  |>  8B4C24 18     |MOV ECX,DWORD PTR SS:[ESP+18]     ;  不同组就:
  00401394  |.  3BCB          |CMP ECX,EBX                       ;  注册码第EAX组中的两位在用户名中是否同位(组不同)
  00401396  |.  75 30         |JNZ SHORT CrackMe_.004013C8       ;  不同就跳
  00401398  |.  85ED          |TEST EBP,EBP                      ;  相同就:第1位所在的组数是否为0
  0040139A  |.  75 07         |JNZ SHORT CrackMe_.004013A3
  0040139C  |.  BD 04000000   |MOV EBP,4                         ;  为0就变4
  004013A1  |.  EB 01         |JMP SHORT CrackMe_.004013A4
  004013A3  |>  4D            |DEC EBP                           ;  第1位组数减1
  004013A4  |>  85FF          |TEST EDI,EDI                      ;  第2位所在组数是否为0
  004013A6  |.  75 07         |JNZ SHORT CrackMe_.004013AF
  004013A8  |.  BF 04000000   |MOV EDI,4                         ;  是0就变4
  004013AD  |.  EB 01         |JMP SHORT CrackMe_.004013B0
  004013AF  |>  4F            |DEC EDI                           ;  第2位组数减1
  004013B0  |>  8D04A9        |LEA EAX,DWORD PTR DS:[ECX+EBP*4]
  004013B3  |.  8BCD          |MOV ECX,EBP
  004013B5  |.  03C8          |ADD ECX,EAX
  004013B7  |.  8D14BB        |LEA EDX,DWORD PTR DS:[EBX+EDI*4]
  004013BA  |.  8A440C 20     |MOV AL,BYTE PTR SS:[ESP+ECX+20]   ;  AL=用户名(注册码第1位所在组数,注册码第1位所在位数)
  004013BE  |.  8BCF          |MOV ECX,EDI
  004013C0  |.  03CA          |ADD ECX,EDX
  004013C2  |.  8A4C0C 20     |MOV CL,BYTE PTR SS:[ESP+ECX+20]   ;  CL=用户名(注册码第2位所在组数,注册码第2位所在位数)
  004013C6  |.  EB 16         |JMP SHORT CrackMe_.004013DE
  004013C8  |>  8D14AB        |LEA EDX,DWORD PTR DS:[EBX+EBP*4]
  004013CB  |.  8BC5          |MOV EAX,EBP
  004013CD  |.  03C2          |ADD EAX,EDX                       ;  EAX=第1位组数*5+第2位的位数
  004013CF  |.  8D0CB9        |LEA ECX,DWORD PTR DS:[ECX+EDI*4]
  004013D2  |.  8A4404 20     |MOV AL,BYTE PTR SS:[ESP+EAX+20]   ;  AL=用户名(注册码第1位所在组数,注册码第2位所在位数)
  004013D6  |>  8BD7          |MOV EDX,EDI
  004013D8  |.  03D1          |ADD EDX,ECX
  004013DA  |.  8A4C14 20     |MOV CL,BYTE PTR SS:[ESP+EDX+20]   ;  CL=用户名(注册码第2位所在组数,注册码第1位所在位数)
  004013DE  |>  8B5424 1C     |MOV EDX,DWORD PTR SS:[ESP+1C]
  004013E2  |.  3A4414 3C     |CMP AL,BYTE PTR SS:[ESP+EDX+3C]   ;  AL与'CRACKINGFORFUN'中的相应位进行比较
  004013E6  |.  75 26         |JNZ SHORT CrackMe_.0040140E       ;  相等才行
  004013E8  |.  3A4C14 3D     |CMP CL,BYTE PTR SS:[ESP+EDX+3D]   ;  AL与'CRACKINGFORFUN'中的相应位进行比较
  004013EC  |.  75 20         |JNZ SHORT CrackMe_.0040140E       ;  相等才行
  004013EE  |.  83C2 02       |ADD EDX,2
  004013F1  |.  83FA 0E       |CMP EDX,0E
  004013F4  |.  895424 1C     |MOV DWORD PTR SS:[ESP+1C],EDX
  004013F8  |.^ 0F8C E5FEFFFF \JL CrackMe_.004012E3
  004013FE  |.  5F            POP EDI
  004013FF  |.  5E            POP ESI
  00401400  |.  5D            POP EBP
  00401401  |.  B8 01000000   MOV EAX,1                          ;  返回1,就成功
  00401406  |.  5B            POP EBX
  00401407  |.  81C4 CC010000 ADD ESP,1CC
  0040140D  |.  C3            RETN
  0040140E  |>  5F            POP EDI
  0040140F  |.  5E            POP ESI
  00401410  |.  5D            POP EBP
  00401411  |.  33C0          XOR EAX,EAX                        ;  返回0,就死
  00401413  |.  5B            POP EBX
  00401414  |.  81C4 CC010000 ADD ESP,1CC
  0040141A  \.  C3            RETN
  7.将上面的算法整理一下:
  首先,将一个14位的固定的字符串'CRACKINGFORFUN'2位一组,共分为7位,将我们输入的用户名处理后的字串5个一组,可分得5组
  第0组:DEWAR
  第1组:JBCFG
  第2组:HIKLM
  第3组:NOPQS
  第4组:TUVXY
  多出一个Z来,多出来的原因是程序本意是去除J的,但我们的用户名中有意加入了J,所以会多一位.加上程序去重不完全,所以如果你用户名输入的是'EAEEBEEECEEEEDJ'将会多出4位来.程序只取前25位来计算注册码,多出来的几位在正确的注册码中不会出现,并无太大的影响.
  (1)将输入的注册码(共14位),2位一组,分为7组.
  (2)检查每组第0位是不是J,是就用I代替,
  (3)得到每组第0位和第1位在用户名中对应的组数和位数.记为第0位=(组数0,位数0),第1位=(组数1,位数1)
  (4)如组数0=组数1,就得到两位新的注册码:第0位=(组数0,(位数0-1)),第1位=(组数1,(位数1-1))(如果位数0(或位数1)原来为0就变4)
  (5)如位数0=位数1,就得到两位新的注册码:第0位=((组数0-1),位数0),第1位=((组数1-1),位数1)(如果组数0(或组数1)原来为0就变4)
  (6)如果组数和位数都不相同,就得到两位新的注册码:第0位=(组数0,位数1),第1位=(组数1,位数0)
  (7)将得到的新的注册码与固定字符串'CRACKINGFORFUN'的相应组进行逐位比较,一旦不同就GAME OVER;
  (8)7组都算完了没有,没有就重复第(2)直到算完.全部符合就OK.
  8.正确的注册码可由字符串'CRACKINGFORFUN'倒推回去得到:
  (1)分组情况同7.
  (2)得到字符串'CRACKINGFORFUN'每组中第0位和第1位在用户名中对应的组数和位数.记为第0位=(组数0,位数0),第1位=(组数1,位数1);
  (3)如组数0=组数1,则两位注册码:第0位=(组数0,(位数0+1)),第1位=(组数1,(位数1+1))(如果位数0(或位数1)原来为4就变0)
  (4)如位数0=位数1,则两位注册码:第0位=((组数0+1),位数0),第1位=((组数1+1),位数1)(如果组数0(或组数1)原来为4就变0)
  (5)如果组数和位数都不相同,则两位注册码:第0位=(组数0,位数1),第1位=(组数1,位数0)
  (6)7组都算完了没有,没有就重复第(2)直到算完.
  (7)将计算得出的7组注册码按顺序连接起来就是正确的注册码了.
  本例中:
  固定字符串  C   R   A   C   K   I   N   G   F   O   R   F   U   N  
        组数  1   0   0   1   2   2   3   1   1   3   0   1   4   3     
        位数  2   4   3   2   2   1   0   4   3   1   4   3   1   0
  
  注册码组数  1   0   0   1   2   2   3   1   1   3   0   1   4   3
  注册码位数  4   2   2   3   3   2   4   0   1   3   3   4   0   1
  注  册  码  G   W   W   F   L   K   S   J   B   Q   A   G   T   O
  
--------------------------------------------------------------------------------
【经验总结】
  1.由于注册码的计算和输入的用户名有关系,所以当输入的用户名中无J时,计算出的注册码是没有问题的.
  2.当输入的注册名中有J出现时,如果所计算出的注册码中的J出现在奇数位,那么它一定处于某组的第0位,会用I来代替,所以
  最后比较时一定不会满足要求.此时就没有正确的注册码,必须更换注册名.
  3.当输入的注册名中有J出现时,如果所计算出的注册码中的J出现在偶数位,那么它一定处于某组的第1位,计算时当正常的字
  符处理,不会有任何的影响,此是所计算出的注册码就是有效的.
  
--------------------------------------------------------------------------------
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年01月20日 20:41:22

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 7
打赏
分享
最新回复 (6)
雪    币: 2256
活跃值: (941)
能力值: (RANK:2210 )
在线值:
发帖
回帖
粉丝
逍遥风 55 2007-1-21 18:13
2
0
很不错的文章
雪    币: 297
活跃值: (21)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
dewar 8 2007-1-21 19:28
3
0
谢谢鼓励~~~!
雪    币: 214
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
ljy3282393 1 2007-1-21 22:27
4
0
支持一下!
雪    币: 148
活跃值: (25)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
coolstar14 1 2007-1-22 12:15
5
0
鼓掌, 支持一下.
雪    币: 424
活跃值: (10)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
大菜一号 21 2007-1-22 15:04
6
0
棒呀``偶搞了N遍都不知道那个三重循环是用来干嘛的``楼主强呀``咸谢分享``向你学习了`
雪    币: 405
活跃值: (10)
能力值: ( LV9,RANK:1130 )
在线值:
发帖
回帖
粉丝
binbinbin 28 2007-1-25 10:31
7
0
看到这么多文字就得支持。~~~
他的CM我都要慢慢看的。太强拉
游客
登录 | 注册 方可回帖
返回