• 标 题:VoxPhone Pro V3.0 Build 36所用的Rsagnt32.dll
  • 作 者:iloveeagle
  • 时 间: 2000.6.11
  • 链 接:http://bbs.pediy.com

(by iloveeagle 2000.6.11)
<tr> tr>

【作者】iloveeagle
破解文库 http://mypage.zhongo.com/~iloveeagle

软件的功能概述:
~~~~~~~~~~~~~~
    通过Internet打电话的软件,据说效果很不错。我没用过。

保护方法:
~~~~~~~~
    时间限制。用Rsagnt32.dll来保护。
    
破解过程:
~~~~~~~~
用bpx hmemcpy中断。被SoftIce拦截后,(BD *)清除所有断点,连续
按F12一直来到Rsagnt32.dll的代码区,代码窗和命令窗之间的分隔线
变为:

--------RSAGNT32!.TEXT+nnnnn----------

再F10一路按下。

* Reference To: USER32.GetDlgItemTextA, Ord:00EDh
                                  |
:10001E8C FF1578050310            Call dword ptr [10030578]
     ^^^^
(:00691E8C<-----在Debug时,看到的地址形式,其余类推。)
       ^^^^

:10001E92 B9FFFFFFFF              mov ecx, FFFFFFFF<--------|连续按F12后到这里。
:10001E97 2BC0                    sub eax, eax              |这是计算字符个数的典型语句段。
:10001E99 F2                      repnz                     |ECX的值就是字符个数。
:10001E9A AE                      scasb                     |
:10001E9B F7D1                    not ecx                   |
:10001E9D 49                      dec ecx<------------------|
:10001E9E 83F90A                  cmp ecx, 0000000A<---------Unlock Code的字符数应为10(D)
:10001EA1 7440                    je 10001EE3
:10001EA3 8D442474                lea eax, dword ptr [esp+74]

* Possible StringData Ref from Data Obj ->"Sorry, that unlocking code is "
                                        ->"not valid for this program."
                                  |
(略)
* Possible StringData Ref from Data Obj ->"Invalid Unlocking Code"
                                  |
(略)
* Reference To: USER32.MessageBoxA, Ord:0188h
                                  |
(略)
:10001EE2 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001EA1(C)
|
:10001EE3 BFD03A0210              mov edi, 10023AD0<-------------|;personal code的地址
:10001EE8 B9FFFFFFFF              mov ecx, FFFFFFFF              |
:10001EED 2BC0                    sub eax, eax                   |
:10001EEF F2                      repnz                          |
:10001EF0 AE                      scasb                          |
:10001EF1 F7D1                    not ecx                        |
:10001EF3 2BF9                    sub edi, ecx                   |
:10001EF5 8BC1                    mov eax, ecx                   |
:10001EF7 C1E902                  shr ecx, 02                    |
:10001EFA 8BF7                    mov esi, edi                   |
:10001EFC 8D7C240C                lea edi, dword ptr [esp+0C]    |拷贝personal code
:10001F00 F3                      repz                           |
:10001F01 A5                      movsd                          |
:10001F02 8BC8                    mov ecx, eax                   |
:10001F04 83E103                  and ecx, 00000003              |
:10001F07 F3                      repz                           |
:10001F08 A4                      movsb<-------------------------|
:10001F09 8D4C2440                lea ecx, dword ptr [esp+40]
:10001F0D A1B4780210              mov eax, dword ptr [100278B4]
:10001F12 51                      push ecx
:10001F13 05B6000000              add eax, 000000B6
:10001F18 8D4C2410                lea ecx, dword ptr [esp+10]
:10001F1C 50                      push eax
:10001F1D 51                      push ecx
:10001F1E E8BD170000              call 100036E0<----------------计算Unlock code的过程
:10001F23 8D4C244C                lea ecx, dword ptr [esp+4C]<--real Ucode的地址(1)
:10001F27 83C40C                  add esp, 0000000C
:10001F2A 68B0840210              push 100284B0<----------------fake Ucode的地址(2)
:10001F2F 51                      push ecx
:10001F30 E84B8A0100              call 1001A980<----------------真假注册码的比较过程
:10001F35 83C408                  add esp, 00000008
:10001F38 85C0                    test eax, eax
:10001F3A A1B4780210              mov eax, dword ptr [100278B4]
:10001F3F 7512                    jne 10001F53<---------------------------------(3)
:10001F41 66C740040100            mov [eax+04], 0001
:10001F47 33C0                    xor eax, eax
:10001F49 5F                      pop edi
:10001F4A 5E                      pop esi
:10001F4B 5B                      pop ebx
:10001F4C 81C430010000            add esp, 00000130
:10001F52 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001F3F(C)
|
:10001F53 8D4C2474                lea ecx, dword ptr [esp+74]

* Possible StringData Ref from Data Obj ->"Sorry, that unlocking code is "
                                        ->"not valid for this program."

(略)
* Possible StringData Ref from Data Obj ->"Invalid Unlocking Code"
(略)
* Reference To: USER32.MessageBoxA, Ord:0188h
(略)
:10001F8C C3                      ret

按F10,经过上面(1)处时,(d ecx)在数据窗会看到真正的Unlock code;到(2)处时,(d 6984B0)会看到我输入的假注册码。
再看(3)处的跳转语句,可以看到call 1001A980的返回值eax应为0,否则注册失败。而call 1001A980实际上就是真假注册码的
比较过程。值得一提的是Patch程序时,应在call 1001A980内进行(只PATCH一处即可);而不宜在call 1001A980外,因为程序
在别的地方也调用了call 1001A980。看下面:

********************************************************************
在该DLL中还发现另一处取得fake code,计算real code和两者比较的代码:

* Reference To: USER32.GetDlgItemTextA, Ord:00EDh
                                  |
:100030DA FF1578050310            Call dword ptr [10030578]
:100030E0 B9FFFFFFFF              mov ecx, FFFFFFFF
:100030E5 2BC0                    sub eax, eax
:100030E7 F2                      repnz
:100030E8 AE                      scasb
:100030E9 F7D1                    not ecx
:100030EB 49                      dec ecx
:100030EC 83F90A                  cmp ecx, 0000000A
:100030EF 743E                    je 1000312F
:100030F1 A1B4780210              mov eax, dword ptr [100278B4]

* Possible StringData Ref from Data Obj ->"Sorry, that unlocking code is "
                                        ->"not valid for this program."
                                  |
(略)
* Possible StringData Ref from Data Obj ->"Invalid Unlocking Code"
                                  |
(略)
* Reference To: USER32.MessageBoxA, Ord:0188h
                                  |
(略)
:1000312E C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100030EF(C)
|
:1000312F 6860C60110              push 1001C660
:10003134 A1B4780210              mov eax, dword ptr [100278B4]
:10003139 05B6000000              add eax, 000000B6
:1000313E 50                      push eax
:1000313F 68E83A0210              push 10023AE8
:10003144 E897050000              call 100036E0<----------------计算Unlock code的过程
:10003149 83C40C                  add esp, 0000000C
:1000314C 6850C60110              push 1001C650<----------------fake Ucode的地址
:10003151 6860C60110              push 1001C660<----------------real Ucode的地址
:10003156 E825780100              call 1001A980<----------------真假注册码的比较过程
:1000315B 83C408                  add esp, 00000008
:1000315E 85C0                    test eax, eax
:10003160 A1B4780210              mov eax, dword ptr [100278B4]
:10003165 7511                    jne 10003178
:10003167 66C740040100            mov [eax+04], 0001
:1000316D 33C0                    xor eax, eax
:1000316F 5F                      pop edi
:10003170 5E                      pop esi
:10003171 81C400010000            add esp, 00000100
:10003177 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10003165(C)
|
:10003178 8D4C2408                lea ecx, dword ptr [esp+08]

* Possible StringData Ref from Data Obj ->"Sorry, that unlocking code is "
                                        ->"not valid for this program."
                                  |
(略)
* Possible StringData Ref from Data Obj ->"Invalid Unlocking Code"
(略)
* Reference To: USER32.MessageBoxA, Ord:0188h
(略)
:100031B0 C3                      ret

最后要和网友共享成果:(1)PATCH这个DLL并把它发布到网上,使网友们可以以任意Unlock Code注册,而不用管Personal Code
是什么。(2)作出注册机,使不会破解的网友可以由自己的Personal Code计算出Unlock Code。下面就是Unlock Code的计算过程。

* Referenced by a CALL at Addresses:****************************注册码计算过程
|:10001F1E   , :10003144   
|
:100036E0 83EC18                  sub esp, 00000018

* Possible StringData Ref from Data Obj ->"PQYZMERUOA"
                                  |
:100036E3 B948C90110              mov ecx, 1001C948
:100036E8 8D542400                lea edx, dword ptr [esp]
:100036EC 53                      push ebx
:100036ED 56                      push esi
:100036EE 8B01                    mov eax, dword ptr [ecx]
:100036F0 57                      push edi
:100036F1 8B5904                  mov ebx, dword ptr [ecx+04]
:100036F4 55                      push ebp
:100036F5 8902                    mov dword ptr [edx], eax
:100036F7 668B6908                mov bp, word ptr [ecx+08]
:100036FB 8A410A                  mov al, byte ptr [ecx+0A]

* Possible StringData Ref from Data Obj ->"JIKLICBXZC"
                                  |
:100036FE B93CC90110              mov ecx, 1001C93C
:10003703 895A04                  mov dword ptr [edx+04], ebx
:10003706 66896A08                mov word ptr [edx+08], bp
:1000370A 8B5904                  mov ebx, dword ptr [ecx+04]
:1000370D 668B6908                mov bp, word ptr [ecx+08]
:10003711 88420A                  mov byte ptr [edx+0A], al
:10003714 8D54241C                lea edx, dword ptr [esp+1C]
:10003718 8B01                    mov eax, dword ptr [ecx]
:1000371A 6633FF                  xor di, di
:1000371D 8902                    mov dword ptr [edx], eax
:1000371F 8A410A                  mov al, byte ptr [ecx+0A]
:10003722 8B742434                mov esi, dword ptr [esp+34]
:10003726 8B4C2430                mov ecx, dword ptr [esp+30]
:1000372A 895A04                  mov dword ptr [edx+04], ebx
:1000372D 66896A08                mov word ptr [edx+08], bp
:10003731 88420A                  mov byte ptr [edx+0A], al

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000377B(C)
|
:10003734 8B44242C                mov eax, dword ptr [esp+2C]
:10003738 B219                    mov dl, 19
:1000373A 0FBFEF                  movsx ebp, di
:1000373D B319                    mov bl, 19
:1000373F 8A440500                mov al, byte ptr [ebp+eax]
:10003743 32442C10                xor al, byte ptr [esp+ebp+10]
:10003747 32440D00                xor al, byte ptr [ebp+ecx]
:1000374B 2AE4                    sub ah, ah
:1000374D F6F2                    div dl
:1000374F 8AC4                    mov al, ah
:10003751 8A542C1C                mov dl, byte ptr [esp+ebp+1C]
:10003755 0441                    add al, 41
:10003757 88443500                mov byte ptr [ebp+esi], al
:1000375B 32540D00                xor dl, byte ptr [ebp+ecx]
:1000375F 32D0                    xor dl, al
:10003761 8AC2                    mov al, dl
:10003763 2AE4                    sub ah, ah
:10003765 F6F3                    div bl
:10003767 8AC4                    mov al, ah
:10003769 0441                    add al, 41
:1000376B 3C4F                    cmp al, 4F
:1000376D 7502                    jne 10003771
:1000376F B058                    mov al, 58

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000376D(C)
|
:10003771 6647                    inc di
:10003773 88443500                mov byte ptr [ebp+esi], al
:10003777 6683FF0A                cmp di, 000A
:1000377B 7CB7                    jl 10003734
:1000377D C6460A00                mov [esi+0A], 00
:10003781 5D                      pop ebp
:10003782 5F                      pop edi
:10003783 5E                      pop esi
:10003784 5B                      pop ebx
:10003785 83C418                  add esp, 00000018
:10003788 C3                      ret

把上面的汇编语句翻译成VB6,是下面的样子:

注册机源程序:
______________________________________________________
Private Sub Command1_Click()
  
  Dim n(1 To 10) As Integer
  Dim c(1 To 10) As Integer
  Dim d(1 To 10) As Integer
  Dim e(1 To 10) As Integer
  Dim i As Integer
  Dim t As Integer
  Dim ucode As String
  
  For i = 1 To 10
    c(i) = Asc(Mid$("PQYZMERUOA", i, 1))
  Next i
  For i = 1 To 10
    d(i) = Asc(Mid$("NVEW2973hb", i, 1))
  Next i
  For i = 1 To 10
    e(i) = Asc(Mid$("JIKLICBXZC", i, 1))
  Next i
  For i = 1 To Len(Trim$(Text1.Text))
   Text1.SelStart = i - 1
   Text1.SelLength = 1
   n(i) = Asc(Text1.SelText)
  Next i
  
  ucode = ""
  For i = 1 To 10
    t = (((n(i) Xor c(i) Xor d(i)) Mod &H19 + &H41) Xor e(i) Xor d(i)) Mod &H19 + &H41
    If (t = &H4F) Then
      t = &H58
    End If
    ucode = ucode & Chr(t)
  Next i
  
  Text2.Text = ucode
  
End Sub
-----------------------------------------------------------
Private Sub Command2_Click()
 Unload Me
End Sub
-----------------------------------------------------------
Private Sub Form_Load()
  Me.Move 3500, 2500
  
End Sub
-----------------------------------------------------------

Private Sub Text1_Change()
 If Len(Trim$(Text1.Text)) >= 10 Then
  Command1.Enabled = True
 Else
  Command1.Enabled = False
  Text2.Text = ""
 End If
End Sub
____________________________________________________________