庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>安全技术>软件破解>算法研究>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

*出租销售系统 5.6--算法分析 上

 作者:本站收集   日期:2005-5-26
字号选择〖 〗/ 双击滚屏 单击停止   
下载地址 http://www.zzshow.com/bookVcd.exe
加密方式:注册码+ 反跟踪 +反汇编
功能限制:功能限制
PJ工具:W32Dasm8.93黄金版,FI2.5,OLLYDBG1.09中文修正版
PJ日期:2003-04-20
作者newlaos申明:只是学习,请不用于商业用途或是将本文方法制作的注册机任意传播,造成后果,本人一概不负。

1、先用FI2.5看一下主文件“bookVcd.exe”,没有加壳,程序是用DELPHI编写的
2、用W32Dasm8.93黄金版对bookVcd.exe进行静态反汇编,再用串式数据参考,找到"注册码错误,请与作者联系",双击来到下面代码段。
3、该软件对TRW20001.23进行反调试,也就是说不能用TRW调试,一调试就出错。只是能用OLLYDBG1.09进行动态调试,下断BPX 00575C56(通常在注册成功与否的前面一些下断,这样,才能找到关键部分),
输入假码: 78787878

.......
.......  
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00575BE6(C)
|
:00575C56 6A00                    push 00000000   <===你会发现在这里设才能断下来。作者为了防破解在上面的代码段动了些手脚,如果不知道,就很容易进行死胡同。
:00575C58 49                      dec ecx
:00575C59 75F9                    jne 00575C54
:00575C5B 53                      push ebx
:00575C5C 8BD8                    mov ebx, eax
:00575C5E 33C0                    xor eax, eax
:00575C60 55                      push ebp
:00575C61 68B35D5700              push 00575DB3
:00575C66 64FF30                  push dword ptr fs:[eax]
:00575C69 648920                  mov dword ptr fs:[eax], esp
:00575C6C 8D55F8                  lea edx, dword ptr [ebp-08]
:00575C6F 8B8300030000            mov eax, dword ptr [ebx+00000300]
:00575C75 E8363DEDFF              call 004499B0   <===算出注册码的长度
:00575C7A 8B45F8                  mov eax, dword ptr [ebp-08] <===EAX=78787878
:00575C7D 8D55FC                  lea edx, dword ptr [ebp-04]
:00575C80 E84F35E9FF              call 004091D4
:00575C85 8B45FC                  mov eax, dword ptr [ebp-04] <===EAX=78787878
:00575C88 8B15845E5900            mov edx, dword ptr [00595E84]
:00575C8E 8B12                    mov edx, dword ptr [edx]    <===EDX=3702619562
:00575C90 E847EFE8FF              call 00404BDC
:00575C95 7436                    je 00575CCD  <===关键跳转,了也就是说,上面的EAX和EDX必须相等了
:00575C97 6A00                    push 00000000

* Possible StringData Ref from Code Obj ->"error"
                                |
:00575C99 B9C05D5700              mov ecx, 00575DC0

* Possible StringData Ref from Code Obj ->"注册码错误,请与作者联系."
                                |
:00575C9E BAC85D5700              mov edx, 00575DC8
:00575CA3 A1185D5900              mov eax, dword ptr [00595D18]
:00575CA8 8B00                    mov eax, dword ptr [eax]
:00575CAA E83942EFFF              call 00469EE8
:00575CAF 8B8300030000            mov eax, dword ptr [ebx+00000300]
:00575CB5 E8E217ECFF              call 0043749C
:00575CBA 8B8300030000            mov eax, dword ptr [ebx+00000300]
:00575CC0 8B10                    mov edx, dword ptr [eax]
:00575CC2 FF92C0000000            call dword ptr [edx+000000C0]
:00575CC8 E9B5000000              jmp 00575D82

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00575C95(C)            <===跳到这里就说明注册成功了,向上看
|
:00575CCD 8B830C030000            mov eax, dword ptr [ebx+0000030C]
:00575CD3 E8F443F4FF              call 004BA0CC
:00575CD8 8B830C030000            mov eax, dword ptr [ebx+0000030C]
.......
.......(此处删除一段与算法无关的代码)
* Possible StringData Ref from Code Obj ->"information"
                                |
:00575D65 B9345E5700              mov ecx, 00575E34

* Possible StringData Ref from Code Obj ->"恭喜您已经注册成功,请重新运行本软件!"
                                |
:00575D6A BA405E5700              mov edx, 00575E40
:00575D6F A1185D5900              mov eax, dword ptr [00595D18]
:00575D74 8B00                    mov eax, dword ptr [eax]
:00575D76 E86D41EFFF              call 00469EE8
:00575D7B 8BC3                    mov eax, ebx
:00575D7D E89A08EFFF              call 0046661C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00575CC8(U)
|
:00575D82 33C0                    xor eax, eax
:00575D84 5A                      pop edx
:00575D85 59                      pop ecx
:00575D86 59                      pop ecx
.......
.......

4、很快就你就会发现,关键算法段不在这里。怎么办?再用串式数据参考找啊找,又发现"您已经注册成为了正版用户",这其实就是当你点击菜单里的注册项时,程序就会判断,如果你已经注册就会显示这个,如果你没有注册就会出现要注册的提示框。呵呵,注册算法部分找到了:-)
依然是用OLLYDBG1.09进行动态调试,设断点005761B5,当你点击菜单里的注册项时,立即断下来。

------------------------********************-----------------------------

:005761B4 56                      push esi

* Reference To: kernel32.GetComputerNameA, Ord:0000h
                                |
:005761B5 E8C60FE9FF              Call 00407180 <===获取计算名称函数
:005761BA 83F801                  cmp eax, 00000001
:005761BD 1BC0                    sbb eax, eax
:005761BF 40                      inc eax
:005761C0 84C0                    test al, al
:005761C2 750C                    jne 005761D0 <===如果获取到就从这里跳走了
:005761C4 8BC6                    mov eax, esi
:005761C6 E875C6E8FF              call 00402840
:005761CB E929010000              jmp 005762F9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005761C2(C)
|
:005761D0 8D45F8                  lea eax, dword ptr [ebp-08]
:005761D3 8BD6                    mov edx, esi <===EDX=POWERLAOS
:005761D5 E8F6E7E8FF              call 004049D0
:005761DA 8B55F8                  mov edx, dword ptr [ebp-08] <===EDX=POWERLAOS
:005761DD B888805900              mov eax, 00598088

* Possible StringData Ref from Code Obj ->"zjhloveling"
                                |
:005761E2 B93C635700              mov ecx, 0057633C  <===作者内定的字符
:005761E7 E8F8E8E8FF              call 00404AE4 <===将计算名和内定的字符串连起来
:005761EC 8D55F4                  lea edx, dword ptr [ebp-0C]
:005761EF A188805900              mov eax, dword ptr [00598088] <===EAX="POWERLAOSzjhloveling"
:005761F4 E8DBFEFFFF              call 005760D4  <===这就是算法软件机器码的CALL
:005761F9 8B55F4                  mov edx, dword ptr [ebp-0C] <===EDX="981727556"这就是我的机器码了
:005761FC B888805900              mov eax, 00598088
:00576201 E82EE6E8FF              call 00404834
:00576206 8BC6                    mov eax, esi
:00576208 E833C6E8FF              call 00402840
:0057620D 8D55F0                  lea edx, dword ptr [ebp-10]
:00576210 A188805900              mov eax, dword ptr [00598088]
:00576215 E8BAFEFFFF              call 005760D4  <===关键的算法CALL,F8跟进(晕,和生成机器码的CALL是一样的)
:0057621A 8B55F0                  mov edx, dword ptr [ebp-10] <===EDX="3702619562"就是注册码了
:0057621D B88C805900              mov eax, 0059808C
:00576222 E80DE6E8FF              call 00404834
:00576227 8B83F0020000            mov eax, dword ptr [ebx+000002F0]
.......
.......(省去一段与算法无关的代码)
:005762AA 8D45B0                  lea eax, dword ptr [ebp-50]

* Possible StringData Ref from Code Obj ->"zjhloveling"
                                |
:005762AD BA3C635700              mov edx, 0057633C
:005762B2 E8B1F5E8FF              call 00405868
:005762B7 8D55B0                  lea edx, dword ptr [ebp-50]
:005762BA 58                      pop eax
:005762BB E8F8F5E8FF              call 004058B8
:005762C0 7521                    jne 005762E3  <===这里是一个关键跳转,如果跳走就要出现注册对话框,如果不跳就显示已经注册
:005762C2 6A00                    push 00000000

* Possible StringData Ref from Code Obj ->"提示"
                                |
:005762C4 B984635700              mov ecx, 00576384

* Possible StringData Ref from Code Obj ->"您已经注册成为了正版用户"
                                |
:005762C9 BA8C635700              mov edx, 0057638C
:005762CE A1185D5900              mov eax, dword ptr [00595D18]
:005762D3 8B00                    mov eax, dword ptr [eax]
:005762D5 E80E3CEFFF              call 00469EE8
:005762DA 8BC3                    mov eax, ebx
:005762DC E83B03EFFF              call 0046661C
:005762E1 EB16                    jmp 005762F9

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00576291(C), :005762C0(C)
|
:005762E3 A1745E5900              mov eax, dword ptr [00595E74]
.......
.......
----------:00576215 call 005760D4  算法CALL,F8跟进)------------------------
.......
.......(省去一段与算法无关的代码)
:0057610A 8B45F4                  mov eax, dword ptr [ebp-0C] <===EAX="981727556"
:0057610D E886E9E8FF              call 00404A98  <===算出机器码的长度
:00576112 8BC8                    mov ecx, eax  

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005760A5(C)
|
:00576114 85C9                    test ecx, ecx
:00576116 762A                    jbe 00576142 <===如果机器码的长度为0,就跳走。这里不跳
:00576118 BE01000000              mov esi, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00576140(C)     ************最关键的循环结构************
|
:0057611D 8B45FC                  mov eax, dword ptr [ebp-04] <===EAX="981727556"
:00576120 0FB64430FF              movzx eax, byte ptr [eax+esi-01] <===依次取"981727556"字符的ASC值
:00576125 03D8                    add ebx, eax
:00576127 69C3D8600B00            imul eax, ebx, 000B60D8
:0057612D BB7B000000              mov ebx, 0000007B
:00576132 33D2                    xor edx, edx <===EDX清0
:00576134 F7F3                    div ebx  <===除以7B
:00576136 69C039300000            imul eax, 00003039 <===得到的商再乘以0x3039
:0057613C 8BD8                    mov ebx, eax  <===最后的EBX就是我们要的结果
:0057613E 46                      inc esi
:0057613F 49                      dec ecx
:00576140 75DB                    jne 0057611D     <===向上跳构成一个循环结构

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00576116(C)
|
:00576142 8BC3                    mov eax, ebx  <===最后EBX就是我们要的注册码了,但还只是16进制的形式DCB17DAA  
:00576144 33D2                    xor edx, edx
:00576146 52                      push edx
:00576147 50                      push eax
:00576148 8B45F8                  mov eax, dword ptr [ebp-08]
:0057614B E8D033E9FF              call 00409520
:00576150 33C0                    xor eax, eax
:00576152 5A                      pop edx
:00576153 59                      pop ecx
:00576154 59                      pop ecx
:00576155 648910                  mov dword ptr fs:[eax], edx
:00576158 6875615700              push 00576175

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00576173(U)
|
:0057615D 8D45F4                  lea eax, dword ptr [ebp-0C]
:00576160 E87BE6E8FF              call 004047E0
:00576165 8D45FC                  lea eax, dword ptr [ebp-04]
:00576168 E873E6E8FF              call 004047E0
:0057616D C3                      ret
......
......

----------------------------------------------------------------------------


5、注册机源程序
=====================VB6.0源程序,在WIN98下测试通过=================

Private Sub Text1_Change()
  
astr1 = Text1.Text
charlen = Len(astr1)
e = 1
For i = 1 To charlen
     sumtmp = Asc(Mid(astr1, i, 1))
     If sumtmp < 48 Or sumtmp > 57 Then
         e = 2
     End If
Next
If charlen = 0 Then e = 3
  
If e = 1 Then
  ebx = "0"
  For i = 1 To charlen
     sumtmp = bigadd(ebx, CStr(Asc(Mid(astr1, i, 1))))
     strtmp = oct2hex(bigmul(sumtmp, "745688"))
     strtmp = hex2oct(Right(strtmp, 8))
     strtmp = bigdiv(strtmp, "123")
     ebx = hex2oct(Right(oct2hex(bigmul(strtmp, "12345")), 8))
  Next
  laststr = CStr(ebx)
Else
  laststr = "你输入的机器码有误"
End If
Text2.Text = laststr
End Sub

'*************上面部分就是真正的实现部分******下面只是大数运算的函数而已********


Function hex2oct(sum16)
'专门将大的16进制转为10进制的函数(目前只支持56位转换)
'函数定义是sum16为56位以下的16进制数的字符串表示形式

astr1 = UCase(sum16)
nlen = Len(astr1)
For i = 1 To nlen   '检查16进制的合法性
  SUMSUM = Asc(Mid(astr1, i, 1))
  If (SUMSUM >= 48 And SUMSUM <= 57) Or (SUMSUM >= 65 And SUMSUM <= 70) Then
    e = 1
    Else
    e = 2
  End If
Next i
If nlen = 0 Then
e = 3
End If

Select Case e
Case 1
'在这里填入16进制转为10进制的代码段
bigsum = "0"
For i = 1 To nlen
    sesum = CStr(CInt("&h" + Mid(astr1, nlen - i + 1, 1)))
    For J = 1 To i - 1
       sesum = bigmul(sesum, "16")
    Next J
    bigsum = bigadd(bigsum, sesum)
Next i
laststr = bigsum
hex2oct = laststr
Case 2
hex2oct = "你的输入非法!"
Case 3
If Option1.value = True Then
  hex2oct = "16 进制实时显示"
  Else
  hex2oct = "10 进制实时显示"
End If
End Select


End Function
Function oct2hex(sum10)
'专门将大的10进制转为16进制的函数(目前只支持56位转换)
'函数定义是sum10为56位以下的10进制数的字符串表示形式
astr1 = sum10
e = 1 '输入操作数正确标志
For i = 1 To Len(astr1)   '检查10进制的合法性
SUMSUM = Asc(Mid(astr1, i, 1))
If SUMSUM < 48 Or SUMSUM > 57 Then
e = 2
End If
Next i
If Len(astr1) = 0 Then
e = 3
End If

Select Case e
Case 1
x = Array("", "", "", "", "", "", "", "", "", "", "", "", "", "")  '对数组进行定义,每个单元代表4位数,这个数组可以代表56位长度的10进制数
上一篇:*出租销售系统 5.6--算法分析 下    下一篇:**登录专家2.10版注册算法  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-5-26
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿