• 标 题:优软精灵画笔之大天使3.0注册算法分析及KeyGen (3千字)
  • 作 者:Maomao[CCG]
  • 时 间:2001-11-10 14:22:42
  • 链 接:http://bbs.pediy.com

精灵画笔之大天使3.0注册算法分析


作者:Maomao[CCG]
软件:Nupaint3.exe
      金山画王的下一代版本,效果非常不错,适合教学使用。
下载:http://www.eusoftware.com/download/wizc30.zip
工具:Trw2000 v1.23
日期:2001-11-10

    用TRW载入Nupaint3.exe,下断点bpx getwindowtexta后按F5返回程序。选择程序菜单“帮助->注册”,在对话框中输入注册码:ABCD-1234-5678-abcd,用户名Maomao[CCG],按“确定”后程序中断,下pmodule,bd *后,回到Nupaint3领空,来到了这里:
0167:00441E1A  CALL    ESI
0167:00441E1C  LEA      ECX,[ESP+10] <=====光标在这里
0167:00441E20  PUSH    BYTE +05
0167:00441E22  PUSH    ECX
按住F10,经过四次读对话框信息后,来到这里:
0167:00441F1F  REP MOVSB
0167:00441F21  CALL    `SERIAL!Uncode_a_SerialNo`  <=====计算注册码
0167:00441F26  ADD      ESP,BYTE +04
0167:00441F29  TEST    EAX,EAX
0167:00441F2B  POP      EBP
0167:00441F2C  JNL      00441F7F            <=====不跳说明注册失败
0167:00441F2E  MOV      EDX,[00490C90]
0167:00441F34  MOV      ESI,[0047D480]
在算注册码的一行上设断,按F5回到程序。再按“确定”,被中断在这一行上。用F8跟进去,按住F10,一会儿来到这里:
0167:1000132F  CMP      BYTE [ESP+04],57  <=====这里D ESP+4可看到输入的注册码
                                            取第一个字符与0x57('W')比较
0167:10001334  JNZ      1000135D
0167:10001336  CMP      BYTE [ESP+05],49  <===== 取第二个字符与0x49('I')比较
0167:1000133B  JNZ      1000135D
0167:1000133D  CMP      BYTE [ESP+06],5A  <===== 取第二个字符与0x5A('Z')比较
0167:10001342  JNZ      1000135D
0167:10001344  CMP      BYTE [ESP+07],42  <===== 取第二个字符与0x42('B')比较
0167:10001349  JNZ      1000135D         
0167:1000134B  LEA      EDX,[ESP+04]
0167:1000134F  PUSH    EDX
0167:10001350  CALL    10001270        <=====计算其它段注册码的call
0167:10001355  ADD      ESP,BYTE +04
0167:10001358  POP      EDI
0167:10001359  ADD      ESP,BYTE +14
0167:1000135C  RET   
    可以看出,如果输入的注册码前四位不是WIZB,程序将不进行下一次判断。在0167:10001350的call上设断,F5回到程序。将注册码改为"WIZB-1234-5678-abcd",按“确定”后,TRW中断在计算其它注册码的call上。用F8跟进去,来到这里:
0167:10001270  MOV      ECX,[ESP+04] <=====导入被重新排列的注册码
0167:10001274  PUSH    ESI
0167:10001275  PUSH    EDI
0167:10001276  XOR      EAX,EAX
0167:10001278  MOV      ESI,0C
0167:1000127D  LEA      EDX,[ECX+0F]  <=====取排列后的注册码最后一位
0167:10001280  MOVSX    EDI,BYTE [ESI+10005033] <=====取密码表中最后一位
                                                这里D ESI+10005033-F可以看到用于对照的密码表:
                                            WIZBIK01ADE1G1AL
0167:10001287  MOVSX    ECX,BYTE [EDX]  <=====取输入后被重列的注册码最后一位
                                              这里D EDX-F可以看到被重新列后的输入注册码
                                              我的被变成了:WIZBab123456cd78
0167:1000128A  SUB      ECX,EDI      <=====相减
0167:1000128C  JS      1000129C      <=====小于密码表字符则跳到结束
0167:1000128E  CMP      ECX,BYTE +08
0167:10001291  JNL      1000129C      <=====大于等于密码表字符+8也跳到结束
0167:10001293  ADD      EAX,ECX
0167:10001295  DEC      EDX
0167:10001296  DEC      ESI
0167:10001297  JNZ      10001280      <=====取下一位
0167:10001299  POP      EDI
0167:1000129A  POP      ESI
0167:1000129B  RET
  我输入的注册码是"WIZB-1234-5678-abcd",被重新排列成了"WIZBab123456cd78",哈哈,只要对照一下,把它的密码表顺序重新排列一下,就可以得到最小的注册码了:"WIZB-01AD-E1AL-IKG1",注册中没有用到用户名,看来与用户名无关,还是比较友好的。好了,收工~~~

做了一个KeyGen,已上传到白菜乐园,另外也上传到了BCG的FTP中。