• 标 题:SysSync Version 1.02简单算法分析+VB注册机源代码 (8千字)
  • 作 者:BurSH
  • 时 间:2003-07-10 19:27:37
  • 链 接:http://bbs.pediy.com

软件名称:SysSync Version 1.02
软件介绍:Browse to two separate locations and then synchronise in either direction. List files to be excluded from the synchronisation. Synchronise complete folder hierarchies. Save profiles of each synchronisation set up to quickly re run. 
下载地址:http://www.mike.franklin.btinternet.co.uk/downloads/syssync.zip

破解人:BurSH (于2003.7.10)
所属组织:FCG-CCG-BCG-OCN-DFCG
破解工具:Trw2000 1.23

/--------------------\
| 寻找正确的注册码:  |
\--------------------/

任意输入用户名和注册码,Ctrl+N呼出Trw2000,下断点Bpx GetWindowTextA,F5,回到软件注册界面点确定,Trw2000弹出后输入Pmodule回到软件领空,F12按33下(因为按34下的话软件就弹出注册失败的对话框),再按一下F10,看到如下代码:

016F:00417383 8B442428         MOV      EAX,[ESP+28]      //将用户名放入EAX
016F:00417387 3BC6             CMP      EAX,ESI           //此时ESI=0
016F:00417389 7505             JNZ      00417390          //是否输入用户名?
016F:0041738B B8B4474500       MOV      EAX,004547B4      //再次将用户名放入EAX-_-
016F:00417390 8D542454         LEA      EDX,[ESP+54]      //[ESP+54]指向正确注册码将要放的地方
☆这里说明一下,软件的注册算法有个缺陷--不能使用一个字母的用户名.因为如果只有一位用户名,[ESP+54]指向的地址的数值就会参加计算,而软件启动时对注册码的校验[ESP+54]指向的数值会与现在的不同,造成了在软件注册界面弹出注册成功的对话框,启动时却提示软件还未注册.☆
016F:00417394 52               PUSH     EDX
016F:00417395 50               PUSH     EAX
016F:00417396 E87548FFFF       CALL     0040BC10          //算法Call,F8跟进!
016F:0041739B 8D7C245C         LEA      EDI,[ESP+5C]
016F:0041739F 83C9FF           OR       ECX,BYTE -01
016F:004173A2 33C0             XOR      EAX,EAX
016F:004173A4 83C408           ADD      ESP,BYTE +08
016F:004173A7 F2AE             REPNE SCASB 
016F:004173A9 F7D1             NOT      ECX
016F:004173AB 49               DEC      ECX
016F:004173AC 8D442454         LEA      EAX,[ESP+54]     //将正确注册放入EAX
016F:004173B0 51               PUSH     ECX
016F:004173B1 8B4C2440         MOV      ECX,[ESP+40]     //将你输入的注册吗的位数放入ECX
016F:004173B5 50               PUSH     EAX
016F:004173B6 51               PUSH     ECX
016F:004173B7 56               PUSH     ESI
016F:004173B8 8D4C2444         LEA      ECX,[ESP+44]
016F:004173BC E86F41FFFF       CALL     0040B530         //里面比较注册码正确与否
016F:004173C1 3BC6             CMP      EAX,ESI          //正确的话EAX置零
016F:004173C3 7511             JNZ      004173D6         //比较成功就往下走弹出成功的对话框!       
016F:004173C5 56               PUSH     ESI
016F:004173C6 6A40             PUSH     BYTE +40
016F:004173C8 C6856C01000001   MOV      BYTE [EBP+016C],01
016F:004173CF 6840454600       PUSH     DWORD 00464540   //一些提示注册成功的话入栈^0^!
016F:004173D4 EB0E             JMP      SHORT 004173E4
016F:004173D6 56               PUSH     ESI
016F:004173D7 56               PUSH     ESI
016F:004173D8 C6856C01000000   MOV      BYTE [EBP+016C],00
016F:004173DF 68A8444600       PUSH     DWORD 004644A8   //一些提示注册失败的话入栈:(
016F:004173E4 E8163C0300       CALL     0044AFFF         //这里弹出对话框
016F:004173E9 6A01             PUSH     BYTE +01
016F:004173EB 8D4C2438         LEA      ECX,[ESP+38]

/----------------------------------------\
| 跟进40BC10的算法Call,我们看到如下代码:  |
\----------------------------------------/

016F:0040BC10 53               PUSH     EBX
016F:0040BC11 55               PUSH     EBP
016F:0040BC12 8B6C240C         MOV      EBP,[ESP+0C]    //将用户名放入EBP
016F:0040BC16 56               PUSH     ESI
016F:0040BC17 8B742414         MOV      ESI,[ESP+14]    
016F:0040BC1B 57               PUSH     EDI             
016F:0040BC1C 8BD6             MOV      EDX,ESI
016F:0040BC1E 33C0             XOR      EAX,EAX
016F:0040BC20 8BFD             MOV      EDI,EBP
016F:0040BC22 2BD5             SUB      EDX,EBP
016F:0040BC24 8A0F             MOV      CL,[EDI]        //取一位用户名
016F:0040BC26 84C9             TEST     CL,CL           //把所有用户名都取完了?
016F:0040BC28 7410             JZ       0040BC3A        //是则跳走
016F:0040BC2A 8A5C2801         MOV      BL,[EAX+EBP+01] //取下一位位用户名 
016F:0040BC2E 02D9             ADD      BL,CL           //将第两位用户名相加
016F:0040BC30 40               INC      EAX             //计数器EAX加一
016F:0040BC31 881C3A           MOV      [EDX+EDI],BL    //依次将结果放入[EDX+EDI] (其实就是放在ESI,看上面40BC1C-40BC22就知道了,注意EDI是计数器)
016F:0040BC34 47               INC      EDI             //计数器EDI加一 
016F:0040BC35 83F80A           CMP      EAX,BYTE +0A    
016F:0040BC38 7CEA             JL       0040BC24        //只计算十位用户名
016F:0040BC3A 83F80A           CMP      EAX,BYTE +0A    //如果这里是从40BC28跳来的,则会跳去40BC52进行后面几位的计算
016F:0040BC3D 7D13             JNL      0040BC52        //若EAX>=A,则跳
016F:0040BC3F 8BCE             MOV      ECX,ESI         //ECX=ESI(上面计算的结果的地址放在这里)
016F:0040BC41 8A5101           MOV      DL,[ECX+01]     //上面计算的一位结果依次放入DL
016F:0040BC44 8A19             MOV      BL,[ECX]        //后一位放入BL
016F:0040BC46 02D3             ADD      DL,BL           //DL=DL+BL
016F:0040BC48 881430           MOV      [EAX+ESI],DL    //逐个把计算结果放到前次计算结果的后面
016F:0040BC4B 40               INC      EAX             //计数器EAX加一
016F:0040BC4C 41               INC      ECX             //指针ECX加一
016F:0040BC4D 83F80A           CMP      EAX,BYTE +0A    //计算完十位了没有?
016F:0040BC50 7CEF             JL       0040BC41        //是就继续往下走
016F:0040BC52 33C9             XOR      ECX,ECX         //ECX清零
016F:0040BC54 BF05000000       MOV      EDI,05          //EDI=5
016F:0040BC59 33C0             XOR      EAX,EAX         //EAX清零
016F:0040BC5B 33D2             XOR      EDX,EDX         //EDX清零
016F:0040BC5D 8A0437           MOV      AL,[EDI+ESI]    //依次取出后五位的计算结果
016F:0040BC60 8A1431           MOV      DL,[ECX+ESI]    //依次取出前五位的计算结果
016F:0040BC63 03C2             ADD      EAX,EDX         //相加
016F:0040BC65 BB1A000000       MOV      EBX,1A          //EBX=1A
016F:0040BC6A 99               CDQ     
016F:0040BC6B F7FB             IDIV     EBX             //EAX=EAX\EDI,EDX=EAX/EDI的余数
016F:0040BC6D 8D4701           LEA      EAX,[EDI+01]    //EAX=EDI+1
016F:0040BC70 BF0A000000       MOV      EDI,0A          //EDI=A
016F:0040BC75 80C261           ADD      DL,61           //EAX/1A的余数加61(结果就是26个小写字母的ASCII码)
016F:0040BC78 881431           MOV      [ECX+ESI],DL    //依次将结果放回去
016F:0040BC7B 41               INC      ECX             //计数器ECX+1
016F:0040BC7C 99               CDQ     
016F:0040BC7D F7FF             IDIV     EDI             //EAX=EAX\EDI,EDX=EAX/EDI的余数
016F:0040BC7F 83F90A           CMP      ECX,BYTE +0A    //计算完了吗?
016F:0040BC82 8BFA             MOV      EDI,EDX         //EDI=EDX
016F:0040BC84 7CD3             JL       0040BC59        //十位注册码还没计算完就再跳回去
016F:0040BC86 C6043100         MOV      BYTE [ECX+ESI],00  
016F:0040BC8A 5F               POP      EDI             //最终计算得的十位注册码就放在ESI!
016F:0040BC8B 5E               POP      ESI
016F:0040BC8C 5D               POP      EBP
016F:0040BC8D 5B               POP      EBX
016F:0040BC8E C3               RET     

/==================================\
| 附上支持中文用户名的VB注册机源码 |
\==================================/

'我VB菜,代码写得罗嗦,随便大家笑去吧^_^!
Private Sub cmdCalc_Click()
On Error Resume Next

Dim i As Long, j As Long
Dim sn(9) As Long
Dim AscArray() As Byte

txtSerial.Text = ""

   If txtUserName.Text = "" Then
      txtSerial.Text = "请输入用户名"
      Exit Sub
   End If

AscArray = StrConv(txtUserName.Text, vbFromUnicode)
   
   If UBound(AscArray) = 0 Then
      txtSerial.Text = "用户名必须大于一位"
      Exit Sub
   End If
   
For i = 0 To UBound(AscArray)
    sn(i) = AscArray(i)
Next i

If UBound(AscArray) < 9 Then
    
    For i = 0 To UBound(AscArray)
    sn(i) = (sn(i) + sn(i + 1)) Mod 256
    Next i
   
    For j = 0 To 9 - i
    sn(i) = (sn(j) + sn(j + 1)) Mod 256
    i = i + 1
    Next j

Else
    
    For i = 0 To UBound(AscArray)
    sn(i) = sn(i) + sn(i + 1)
    Next i

End If

j = 5
For i = 0 To 9
    sn(i) = ((((sn(i) + sn(j)) Mod 26) Mod 256) + 97) Mod 256
    j = (j + 1) Mod 10
Next i

For i = 0 To 9
txtSerial.Text = txtSerial.Text & Trim(Chr(sn(i)))
Next i
    
End Sub