• 标 题:彩票探索者之神投手 R2001.10.18破解~~~~~祝各位好运 (10千字)
  • 作 者:Sam.com
  • 时 间:2001-11-7 5:54:12
  • 链 接:http://bbs.pediy.com

彩票探索者之神投手 R2001.10.18

下载地址:http://www.probersoft.com/ 请先下载它的学习版和升级版然后安装即可
保护类型:用机器码来算注册码,每次进入都提示注册,未注册功能有限制。

最近下载了几个彩票软件来玩,可是好几个都找不到破解,只好自己动手啦。这个软件挺狡猾的,它用了ASPack v2.11加壳,这个好办用Caspr就能搞掂,只不过脱了壳后它一运行就把自己删除了,但还是能用W32Dasm来反汇编的。刚开始粗略跟了一下,它并不是整个注册码明码对比的,马上想到它用了什么复杂的算法,仔细看一下原来它并不复杂,看看我下面的过程吧。另外一个叫彩票王5.01标准版的是VB的,搞得我头都痛啦,我的系统是Windows ME的SmartCheck用不了,气死我啦,用Trw2000跟得晕头转向。


先把它反汇编找到下面的出错信息
--Step 1-----------------------------------------------------------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00564D3C(C)      <---从这里跳过来的,往上找
|
:005651D7 6A30                    push 00000030

* Possible StringData Ref from Data Obj ->"提示信息"
                                  |
:005651D9 6879158300              push 00831579

* Possible StringData Ref from Data Obj ->"注册失败!"
                                  |
:005651DE 6898158300              push 00831598
:005651E3 8B8574FFFFFF            mov eax, dword ptr [ebp+FFFFFF74]
:005651E9 E822282400              call 007A7A10
:005651EE 50                      push eax

* Reference To: USER32.MessageBoxA, Ord:0000h


--Step 2-----------------------------------------------------------------------------------------
:00564D35 E83AB9FBFF              call 00520674
:00564D3A 85C0                    test eax, eax
:00564D3C 0F8495040000            je 005651D7    <---不能跳,经典比较,进入上面的Call看看
~~~~~~~~

下面就是注册码的比较核心,它是一个一个注册码分开比较的
--Step 3-----------------------------------------------------------------------------------------
* Referenced by a CALL at Addresses:
|:005228D1  , :00522954  , :005233AD  , :00523430  , :00564B11 
|:00564D35  , :00564D47 
|
:00520674 55                      push ebp
:00520675 8BEC                    mov ebp, esp
:00520677 83C4D0                  add esp, FFFFFFD0
:0052067A 53                      push ebx
:0052067B 56                      push esi
:0052067C 57                      push edi
:0052067D 8955D4                  mov dword ptr [ebp-2C], edx <--d edx里面是什么?有可疑哦
:00520680 8945FC                  mov dword ptr [ebp-04], eax <--d eax里面是我输入的注册码
:00520683 B820DF8100              mov eax, 0081DF20
:00520688 E867932C00              call 007E99F4
:0052068D C745F401000000          mov [ebp-0C], 00000001
:00520694 8D55FC                  lea edx, dword ptr [ebp-04]
:00520697 8D45FC                  lea eax, dword ptr [ebp-04]
:0052069A E89D3F2D00              call 007F463C
:0052069F FF45F4                  inc [ebp-0C]
:005206A2 66C745E80800            mov [ebp-18], 0008
:005206A8 C745D001000000          mov [ebp-30], 00000001
:005206AF 66C745E81400            mov [ebp-18], 0014
:005206B5 66C745E81400            mov [ebp-18], 0014
:005206BB 8B45D4                  mov eax, dword ptr [ebp-2C]
:005206BE 33DB                    xor ebx, ebx
:005206C0 8BF8                    mov edi, eax
:005206C2 EB3E                    jmp 00520702              <---跳走啦,先往下看

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00520714(C)
|
:005206C4 8D7301                  lea esi, dword ptr [ebx+01]
:005206C7 56                      push esi
:005206C8 8D45FC                  lea eax, dword ptr [ebp-04]
:005206CB 50                      push eax
:005206CC E8AF3E2D00              call 007F4580
:005206D1 83C408                  add esp, 00000008
:005206D4 8D45FC                  lea eax, dword ptr [ebp-04]
:005206D7 E874432D00              call 007F4A50              <---这两个Call都不用跟进去
:005206DC 8B45D4                  mov eax, dword ptr [ebp-2C]
:005206DF 8B0F                    mov ecx, dword ptr [edi]  <---d edi看看又是刚才那可疑的数据 ecx=00000036

这里应该是用我的机器码算出来的数据表,经过运算得出真的注册码,但它是怎么算出来我就没去研究
0030:02BB668C 36 00 00 00 29 00 00 00-21 00 00 00 20 00 00 00 6...)...!... ...
0030:02BB669C 0D 00 00 00 09 00 00 00-06 00 00 00 FA FF FF FF ............?
0030:02BB66AC F1 FF FF FF E5 FF FF FF-E7 FF FF FF DA FF FF FF ????
0030:02BB66BC D7 FF FF FF CB FF FF FF-BD FF FF FF BB FF FF FF ????
0030:02BB66CC B9 FF FF FF AB FF FF FF-A9 FF FF FF 95 FF FF FF ????
0030:02BB66DC 97 FF FF FF 8B FF FF FF-80 FF FF FF 81 FF FF FF ???
0030:02BB66EC 0F 27 00 00 0F 27 00 00-0F 27 00 00 0F 27 00 00 .'...'...'...'..


:005206E1 0375FC                  add esi, dword ptr [ebp-04]
:005206E4 4E                      dec esi                    <---esi是假注册码的地址

:005206E5 8B80D0000000            mov eax, dword ptr [eax+000000D0] <--这个很很重要 eax=FFFFFFF8

:005206EB 0FAFC3                  imul eax, ebx              <---ebx是计数器

:005206EE 0FBE16                  movsx edx, byte ptr [esi]  <---假注册码的的第一位

:005206F1 2BC8                    sub ecx, eax  <---用ecx和eax相减就得出真注册码的的第一位,这里
                                                    当算到第5.10.15.20位的时候ecx都是2D即是'-'
                                                    所以注册码的形式是xxxx-xxxx-xxxx-xxxx-xxxx

:005206F3 3BD1                    cmp edx, ecx  <---有比较了,用我的假注册码的的第一位和刚才运
                                                    算的结果比较,我这里是算出的结果是36,即是
                                                    数字6。

:005206F5 7407                    je 005206FE    <---相等就往下跳,这里可以改为jne并在此设断点每
                                                    次运行到此时看ecx的值就能看到所有的注册码。
                                                    另外有个问题,我们怎么知道注册码的个数究竟
                                                    几个呢、请往下看。
                                                   
:005206F7 33D2                    xor edx, edx
:005206F9 8955D0                  mov dword ptr [ebp-30], edx
:005206FC EB18                    jmp 00520716

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005206F5(C)
|
:005206FE 43                      inc ebx            <---计数器加一
:005206FF 83C704                  add edi, 00000004  <---edi指向可疑数据的下四位29,用来运算下一位注册码

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005206C2(U)
|
:00520702 837DFC00                cmp dword ptr [ebp-04], 00000000
:00520706 7408                    je 00520710                <--这个只是检查地址,不会跳走的
:00520708 8B4DFC                  mov ecx, dword ptr [ebp-04] <--假注册码的地址
:0052070B 8B41FC                  mov eax, dword ptr [ecx-04] <--假注册码的个数
:0052070E EB02                    jmp 00520712

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00520706(C)
|
:00520710 33C0                    xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052070E(U)
|
:00520712 3BD8                    cmp ebx, eax  <---ebx是计数器,注册码是一个一个比较的
:00520714 7CAE                    jl 005206C4    <---往上跳啦

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005206FC(U)
|
:00520716 837DD001                cmp dword ptr [ebp-30], 00000001
:0052071A 7539                    jne 00520755
:0052071C 837DFC00                cmp dword ptr [ebp-04], 00000000
:00520720 7408                    je 0052072A  <---如果注册码正确的话这两个比较都不会跳的,记住这两个错误的出口地址
:00520722 8B55FC                  mov edx, dword ptr [ebp-04]
:00520725 8B42FC                  mov eax, dword ptr [edx-04]
:00520728 EB02                    jmp 0052072C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00520720(C)
|
:0052072A 33C0                    xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00520728(U)
|
:0052072C 66C745E81400            mov [ebp-18], 0014
:00520732 8B55D4                  mov edx, dword ptr [ebp-2C]
:00520735 83F834                  cmp eax, 00000034  <--eax是我输入的注册码的个数,不能大于52个
:00520738 8D1482                  lea edx, dword ptr [edx+4*eax] <--edx指向数据表的地址
:0052073B 7D18                    jge 00520755

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00520753(C)
|
:0052073D 813A0F270000            cmp dword ptr [edx], 0000270F
:00520743 7407                    je 0052074C  <--比较,这里一定要跳,还记得下面的错误地址吗?
                                                  看看数据表,看来0000270F是结束标志。算了算前面
                                                  的数据一共能算出24位注册码出来,所以得出了上面
                                                  注册码的形式。
:00520745 33C0                    xor eax, eax
:00520747 8945D0                  mov dword ptr [ebp-30], eax
:0052074A EB09                    jmp 00520755

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00520743(C)
|
:0052074C 40                      inc eax
:0052074D 83C204                  add edx, 00000004
:00520750 83F834                  cmp eax, 00000034
:00520753 7CE8                    jl 0052073D

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0052071A(C), :0052073B(C), :0052074A(U)
|
:00520755 66C745E80800            mov [ebp-18], 0008
:0052075B 8B45D0                  mov eax, dword ptr [ebp-30]
:0052075E BA02000000              mov edx, 00000002
:00520763 50                      push eax
:00520764 8D45FC                  lea eax, dword ptr [ebp-04]
:00520767 FF4DF4                  dec [ebp-0C]
:0052076A E8E9402D00              call 007F4858
:0052076F 58                      pop eax
:00520770 8B55D8                  mov edx, dword ptr [ebp-28]
:00520773 64891500000000          mov dword ptr fs:[00000000], edx
:0052077A 5F                      pop edi
:0052077B 5E                      pop esi
:0052077C 5B                      pop ebx
:0052077D 8BE5                    mov esp, ebp
:0052077F 5D                      pop ebp
:00520780 C3                      ret
--End--------------------------------------------------------------------------------------------

总结一下:软件注册时产生一个唯一的机器码,然后用机器码算出一个数据表,再用一个固定的数FFFFFFF8依次和数据表中的数相减得出正确的注册码,就这么简单。正确的注册码是保存在软件安装目录的supercp.ini里的。

                                                                       
                                                                            3:58 2001-11-7

  • 标 题:来到论坛,看到贴子数最多的是这个! (3千字)
  • 作 者:5,555
  • 时 间:2001-11-9 15:52:06

首先看这里,这是注册成功的提示:

:0056504D 6A30                    push 00000030

* Possible StringData Ref from Data Obj ->"提示信息"
                                  |
:0056504F 6879158300              push 00831579

* Possible StringData Ref from Data Obj ->"恭喜,注册成功!"
                                  |
:00565054 686A158300              push 0083156A
:00565059 8B8574FFFFFF            mov eax, dword ptr [ebp+FFFFFF74]
:0056505F E8AC292400              call 007A7A10
:00565064 50                      push eax

* Reference To: USER32.MessageBoxA, Ord:0000h
                                  |
:00565065 E8B80B2900              Call 007F5C22

再看上位仁兄提到的:

:005206E5 8B80D0000000            mov eax, dword ptr [eax+000000D0] <--这个很很重要 eax=FFFFFFF8

:005206EB 0FAFC3                  imul eax, ebx              <---ebx是计数器

:005206EE 0FBE16                  movsx edx, byte ptr [esi]  <---假注册码的的第一位

:005206F1 2BC8                    sub ecx, eax  <---用ecx和eax相减就得出真注册码的的第一位,这里
                                                    当算到第5.10.15.20位的时候ecx都是2D即是'-'
                                                    所以注册码的形式是xxxx-xxxx-xxxx-xxxx-xxxx

:005206F3 3BD1                    cmp edx, ecx  <---有比较了,用我的假注册码的的第一位和刚才运
                                                    算的结果比较,我这里是算出的结果是36,即是
                                                    数字6。

:005206F5 7407                    je 005206FE    <---相等就往下跳,这里可以改为jne并在此设断点每
                                                    次运行到此时看ecx的值就能看到所有的注册码。
                                                    另外有个问题,我们怎么知道注册码的个数究竟
                                                    几个呢、请往下看。
                                                   
:005206F7 33D2                    xor edx, edx
:005206F9 8955D0                  mov dword ptr [ebp-30], edx
:005206FC EB18                    jmp 00520716

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005206F5(C)
|
:005206FE 43                      inc ebx            <---计数器加一

我们知道,如果将5206F5处的JE改为JNE并用ASPACK压缩后,程序就能破解,弹出刚刚开始的“恭喜注册成功”的对话框。但是没有注册码我们的心里始终觉得别扭。我们不需要它假心假意地恭喜我们注册成功,而是想为什么不在这里改一下让它自己为我们弹出真正的注册码呢?用楼上的方法BPX并一BYTE一BYTE地抄太麻烦了。
上面的5206F3--5206FD处的代码是无用的(对我们)。干掉它,让它为我们服务。将5206F3处开始的代码改为:
005206F3: B500    mov ch,0        ;每次都打上结尾标记,避免弹出后面带乱字符的串
005206F5:66898B6A158300  mov [ebx+83156A],cx      ;将正确的注册码储存起来。为什么是[ebx+83156A]呢?上位仁兄提到:“:005206FE 43                      inc ebx            <---计数器加一 ”;而刚刚开始我们查到的“* Possible StringData Ref from Data Obj ->"恭喜,注册成功!"
:00565054 686A158300              push 0083156A
”说明83156A处指向的正是注册成功的提示信息。明确了:我们现在做的就是将它的正确的注册码存储到注册成功的信息处将弹出来,告诉我们。然后我们可以名正言顺地注册了:)
    修改完毕,用ASPACK压缩一下(这个工具版主主页上有http://www.pediy.com/tools.htm)。
    经过实验,我们可以运行改良后的程序,输入形如“xxxx-xxxx-xxxx-xxxx-xxxx”格式的注册码,然后确定,抄下注册码(如果你够懒,也可以用Alt+PrintScreen粘贴到画图里面去)。运行备份的原程序,输入这个注册码,OK!

  • 标 题:呵呵,忘了一点事情。这样做肯定会非法操作的:) (173字)
  • 作 者:5,555
  • 时 间:2001-11-9 18:17:54


005206F3: B500    mov ch,0
005206F5:66898B6A158300  mov [ebx+83156A],cx     
后面加上
005206FC: 90      NOP
005206FD: 90      NOP
这样才不会破坏原来的程序结构。