• 标 题:H******** 4.01.11的不完全破解 (4千字)
  • 作 者:kingtall
  • 时 间:2001-4-14 13:07:31
  • 链 接:http://bbs.pediy.com

软件:H******** 4.01.11
保护方式:授权文件保护,未注册时每次启动会有一个提示注册的对话框
该版本的保护方式与以前版本的保护方式不同,由序列号方式改为授权文件方式,注册时要求输入授权文件的全部内容。这对小弟的破解工作倒没有什么影响,小弟偏爱暴力法破解(本人比较懒,懒得算注册号),且喜欢装入程序,从头单步运行,直到弹出注册对话框(当然加壳的程序除外)。

先把H*****.exe 拷到别的目录,作为备份。
启动trw2000,打开C:\Program Files\H******** 4\H*****.exe,装入,按F10。若按F10带过一个call时,弹出提示注册对话框,就关闭对话框,trw2000会自动弹出。实在不行的话,退出程序,trw2000也会自动弹出。用鼠标选中刚才的call,按F9设断点,g,程序会正常运行。关闭程序,重新装入,全速运行,在刚才的断点中断。按F8进入call内,按F10重复刚才的过程,用不了几次,就能找到关键部位。请看(本人用log2命令无法存盘,只好keyin了,哪位大哥知道log2的用法,不妨指点小弟一下):

42E279 8B837001000    mov eax,[ebx+170]; [ebx+170]=[4fdd30]=0
42e27f 85c0          test eax,eax
42e281 0f85d9000000  jnz near 42e360; (no jump)

这时如果敲入rfl z命令,g,哈哈,注册对话框没有出现。很明显4fdd30这个全局变量中放的就是注册标志,若为0,就是没有注册。现在,重新装入程序,bc,下bpm 167:4fdd30 w,g。来到下面这一段:

436fcd e85ec9feff    call 423930
436fd2 83c404          add esp,4
436fd5 a330dd4f00    mov [4fdd30],eax; eax=0    

是谁让我们的eax变成0的?一定是上面那个call了。bc,下bpx 42e279,g。退出hypersnap,从新装入,g。
trw在436fcd中断,按F8进入。废话少说,来到下面这一段:

423a6c 33c0          xor eax,eax ;原来在这里了。
423a6e 5b            pop ebx
423a6f 8b4df4
...
423a7c c3            ret

记下代码(建议大家多抄几行,我的是e870f606005f5e33c0),启动uedit,查找e870f606005f5e33c0,找到后将33c0改为9090。存盘,试一下。

居然弹出一个对话框,说程序被损坏了,怎么办呢?有了,ctrl+m呼出trw,下bpm lockmytask,g。按ok按钮,trw立即弹出。按几次F12,回到H*****的领空,看看上一行是什么?原来是call user32!messagebox。早知是这样,下bpx messagebox不久完了吗。现在怎么办呢?往上看看,有没有比较语句,能跳过messagebox,若找不到,就ret到上一层call中,找一找能不能跳过这个call。我ret了三四次,找到下面这一段:

42de41 e89a5cffff call 423ae0
42de46 85c0      test eax,eax
42de48 751d      jnz 42de67;

把751d改为eb1d就行了,不再出程序被损坏的messagebox了,程序可以运行了,抓下的图片中没有公司标记了,行了吗?不行,程序现在动不动就出现非法操作,然后只能退出。下面是win98的提示信息。

H***** 在 00de:f5fa0f3d 的模块
<未知> 中导致无效页错误。
Registers:
EAX=0073fad4 CS=0167 EIP=f5fa0f3d EFLGS=00010246
EBX=0073fad4 SS=016f ESP=00640004 EBP=00640024
ECX=006400a8 DS=016f ESI=8174cedc FS=229f
EDX=bff768d5 ES=016f EDI=006400d0 GS=0000
Bytes at CS:EIP:

Stack dump:
bff768c9 006400d0 0073fad4 006400ec 006400a8 006401dc bff768d5 0073fad4 006400b8 bff882eb 006400d0 0073fad4 006400ec 006400a8 f5fa0f3d 00640294

我比较了一下,每次退出时的ip,寄存器都是一样的,于是有了一个办法。装入程序,下bp if (eax==73fad4),因为每次出错时的eax都是73fad4。g。程序启动了,画面出来了,似乎一切正常。动一动鼠标,没动几下,出来一个蓝屏,trw说它不能中断。上帝啊,连trw都不能中断,我要绝望了。

还有一招,内存补丁。希望你备份的H*****.exe还在,把它考回来。我用的补丁是ppatcher 3.93,这可是ppatcher的作者thewd亲自email给我的。thewd挺负责任的,有信必回,你要是能对ppatcher提出什么意见或建议,他还会发给你一个最新版的ppatcher。扯远了。ppatcher.ppc的内容如下:

#Process Patcher Configuration File
Version=3.93

PatchAuthor=thewd
PatchContactInformation=thewd@hotmail.com

DisplayName=h*****.exe v4.01.11
Filename=h*****.exe
Filesize=1056768
Address=0x42de48:0x75:0xeB
Address=0x4337e6:0x75:0xeB
Address=0x4387e5:0x75:0xeB
Address=0x42e281:0x0f:0xe9
Address=0x42e282:0x85:0xda
Address=0x42e283:0xd9:0x00
Address=0x42e284:0x00:0x00
Address=0x42e285:0x00:0x00
Address=0x42e286:0x00:0x90
#End of Configuration File

这回行了吧。ppatcher.ppc所修改的地址跟我刚才说的不太一样,因为光修改423a6c处的xor eax,eax,还有一点问题。按菜单中的关于和注册两项时,还会出现非法操作。修改也很简单,只要下bpm 4fdd30,就很容易找到比较点了。

罗里罗唆说了半天,总结一下。
1. 4fdd30 是一个全局变量,存放的是注册标志,跟注册有关的判断都以它为依据。
2. 程序有自校验功能,但在42de48处可以跳过。
3. 程序还有暗桩,修改之后动不动就非法操作。本人功力不够找不到,只好用内存补丁。比较遗憾。请高手们赐教。

注:H*** 3.53 和 3.63.01 的自校验方式与 4.01.11不同,修改文件后,再运行会提示有个文件找不到,而且用trw2000也无法装入。颇为奇怪。那位有兴趣共同研究一下。3.63.01避注册框的比较点是45ae8b。

  • 标 题:多谢bnbnf兄的提示,已经破解了H*** 3.63.01,过程请看 (721字)
  • 作 者:kingtall
  • 时 间:2001-4-14 16:22:46

多谢bnbnf兄的提示,终于破解了H*** 3.63.01。方法如下:
先打开资源管理器,找到C:\Program Files\H*****目录,再运行trw2000,按ctrl+M 呼出trw2000,下bpx createfilea,然后g回到资源管理器,在管理器中运行hsdx.exe,trw会弹出两次。第一次不用管,g 。trw第二次弹出时按F12会回到hshelper!.text的天空。关键代码就在这里。请看
6308105b 50          push eax ;eax指向hsdx.exe
6308105c ff1538600863 call kernel32!createfilea
63081062 83f8ff      cmp eax,-1
63081065 8945f8      mov [ebp-8],eax     
63081068 0f84a1000000 jz 63081110 ;若已修改过hsdx.exe,这里就是no jump 。

单步执行到这里时,下rfl z,然后g 。程序界面终于出来了。具体修改过程就不说了。另外更正一下,上次提到3.63.01的关键点是错的,正确地址是416006 。

  • 标 题:注册H******** ver. 3.63.01算法 (10千字)
  • 作 者:zombieys
  • 时 间:2001-4-16 16:22:48

注册H******** ver. 3.63.01算法

软件名称:H******** ver. 3.63.01
主要目的:寻找自己的注册码
破解难度:中等难度(算码部分稍微复杂了一点)

    不说废话了,直接进入正题。输入大名zombieys和注册码1212-1212-1212-1212-1212-1212(为什么不填78?我的内存里到处都是78,找不到啦,所以换换),下s 30:0 l ffffffff '1212',bpm搜到的地址。点注册,按几次f12和f10来到这里:


算NAME的CALL

:004096DB 55                      push ebp
:004096DC 8BEC                    mov ebp, esp
:004096DE 81EC04010000            sub esp, 00000104
:004096E4 8B4D08                  mov ecx, dword ptr [ebp+08]
:004096E7 33D2                    xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409705(U)
|
:004096E9 8A01                    mov al, byte ptr [ecx]                //读取输入的注册码
:004096EB 84C0                    test al, al                            //在A-Z之间才要
:004096ED 7418                    je 00409707
:004096EF 3C41                    cmp al, 41                            //过滤掉-(2dhex)
:004096F1 7C0F                    jl 00409702
:004096F3 8A01                    mov al, byte ptr [ecx]
:004096F5 3C5A                    cmp al, 5A
:004096F7 7F09                    jg 00409702
:004096F9 888415FCFEFFFF          mov byte ptr [ebp+edx-00000104], al    //将过滤后掉-后的24个注册码->[ebp+edx-00000104]
:00409700 EB01                    jmp 00409703

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004096F1(C), :004096F7(C)
|
:00409702 4A                      dec edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409700(U)
|
:00409703 41                      inc ecx
:00409704 42                      inc edx
:00409705 EBE2                    jmp 004096E9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004096ED(C)
|
:00409707 80A415FCFEFFFF00        and byte ptr [ebp+edx-00000104], 00
:0040970F 53                      push ebx
:00409710 56                      push esi
:00409711 8D85FCFEFFFF            lea eax, dword ptr [ebp+FFFFFEFC]
:00409717 57                      push edi
:00409718 50                      push eax
:00409719 E812A20200              call 00433930
:0040971E 8BD0                    mov edx, eax
:00409720 59                      pop ecx
:00409721 81FA80000000            cmp edx, 00000080
:00409727 8955FC                  mov dword ptr [ebp-04], edx
:0040972A 0F8DC5000000            jnl 004097F5
:00409730 A170504800              mov eax, dword ptr [00485070]
:00409735 3BD0                    cmp edx, eax
:00409737 0F8EB8000000            jle 004097F5
:0040973D 0FBEB405FBFEFFFF        movsx esi, byte ptr [ebp+eax-00000105]  //取注册码第5位
:00409745 83EE41                  sub esi, 00000041                      //让后-A(41HEX)->ESI
:00409748 33FF                    xor edi, edi
:0040974A 33C9                    xor ecx, ecx
:0040974C 893578304900            mov dword ptr [00493078], esi
:00409752 85D2                    test edx, edx
:00409754 894D08                  mov dword ptr [ebp+08], ecx
:00409757 7E5D                    jle 004097B6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004097B4(C)
|
:00409759 80BC0DFCFEFFFF41        cmp byte ptr [ebp+ecx-00000104], 41    //注册码要在A-Z之间
:00409761 8D9C0DFCFEFFFF          lea ebx, dword ptr [ebp+ecx-00000104]
:00409768 0F8C87000000            jl 004097F5
:0040976E 80BC3DFCFEFFFF5A        cmp byte ptr [ebp+edi-00000104], 5A
:00409776 7F7D                    jg 004097F5
:00409778 8D50FF                  lea edx, dword ptr [eax-01]
:0040977B 3BCA                    cmp ecx, edx                            //是第5位的话不计算
:0040977D 7503                    jne 00409782
:0040977F 4F                      dec edi
:00409780 EB2A                    jmp 004097AC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040977D(C)
|
:00409782 0FBE03                  movsx eax, byte ptr [ebx]              //取注册码
:00409785 50                      push eax
:00409786 E8C5000000              call 00409850                          //根据密码表算位数
:0040978B 2BC6                    sub eax, esi                            //减去上个字母ASCII值与41的差->EAX
:0040978D 59                      pop ecx
:0040978E 0FBE33                  movsx esi, byte ptr [ebx]              //当前字母ASCII值->ESI
:00409791 48                      dec eax
:00409792 83EE41                  sub esi, 00000041
:00409795 85C0                    test eax, eax                          //小于0的话+1A
:00409797 7D03                    jge 0040979C
:00409799 83C01A                  add eax, 0000001A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409797(C)
|
:0040979C 8B4D08                  mov ecx, dword ptr [ebp+08]
:0040979F 0441                    add al, 41                              //AL+41->AL
:004097A1 88877C304900            mov byte ptr [edi+0049307C], al        //把结果->[EDI+49307C]
:004097A7 A170504800              mov eax, dword ptr [00485070]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409780(U)
|
:004097AC 47                      inc edi
:004097AD 41                      inc ecx
:004097AE 3B4DFC                  cmp ecx, dword ptr [ebp-04]
:004097B1 894D08                  mov dword ptr [ebp+08], ecx
:004097B4 7CA3                    jl 00409759                            //接着计算

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409757(C)
|
:004097B6 0FBEB77B304900          movsx esi, byte ptr [edi+0049307B]
:004097BD 83057830490041          add dword ptr [00493078], 00000041
:004097C4 80A77B30490000          and byte ptr [edi+0049307B], 00
:004097CB 8D877B304900            lea eax, dword ptr [edi+0049307B]      //算得结果的最后一位->EAX
:004097D1 BF7C304900              mov edi, 0049307C
:004097D6 57                      push edi
:004097D7 83EE41                  sub esi, 00000041                      //算得结果的最后一位ASCII值-41->ESI
:004097DA E81D000000              call 004097FC
:004097DF 3BF0                    cmp esi, eax                            //算完后要和EAX值相同
:004097E1 59                      pop ecx
:004097E2 7511                    jne 004097F5                            //不同就死了
:004097E4 0FBE057C304900          movsx eax, byte ptr [0049307C]
:004097EB 310578304900            xor dword ptr [00493078], eax
:004097F1 8BC7                    mov eax, edi
:004097F3 EB02                    jmp 004097F7

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040972A(C), :00409737(C), :00409768(C), :00409776(C), :004097E2(C)
|
:004097F5 33C0                    xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004097F3(U)
|
:004097F7 5F                      pop edi
:004097F8 5E                      pop esi
:004097F9 5B                      pop ebx
:004097FA C9                      leave
:004097FB C3                      ret
.
.
.
:004348F0 8B542404                mov edx, dword ptr [esp+04]          //用你的名字算的数的地址->EDX
:004348F4 8B4C2408                mov ecx, dword ptr [esp+08]          //用注册码算的名字的地址->ECX
:004348F8 F7C203000000            test edx, 00000003
:004348FE 753C                    jne 0043493C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0043492C(C), :00434956(C), :00434972(U)
|
:00434900 8B02                    mov eax, dword ptr [edx]              //以下是计算相不相同
:00434902 3A01                    cmp al, byte ptr [ecx]
:00434904 752E                    jne 00434934
:00434906 0AC0                    or al, al
:00434908 7426                    je 00434930
:0043490A 3A6101                  cmp ah, byte ptr [ecx+01]
:0043490D 7525                    jne 00434934
:0043490F 0AE4                    or ah, ah
:00434911 741D                    je 00434930
:00434913 C1E810                  shr eax, 10
:00434916 3A4102                  cmp al, byte ptr [ecx+02]
:00434919 7519                    jne 00434934
:0043491B 0AC0                    or al, al
:0043491D 7411                    je 00434930
:0043491F 3A6103                  cmp ah, byte ptr [ecx+03]
:00434922 7510                    jne 00434934
:00434924 83C104                  add ecx, 00000004
:00434927 83C204                  add edx, 00000004
:0043492A 0AE4                    or ah, ah
:0043492C 75D2                    jne 00434900
:0043492E 8BFF                    mov edi, edi                        //要都相同才行

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00434908(C), :00434911(C), :0043491D(C), :0043494E(C), :00434964(C)
|:0043496D(C)
|
:00434930 33C0                    xor eax, eax
:00434932 C3                      ret




计算方法:

第几位:1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A
密码表:X C F N A K S H I P Z U J L D O  R  G  V  Q  T  E  W  Y  B  M

ASCII :514B4650574C444E465659484A494346 54 53 54 46 5A 42 54 45
与41差:10A 5 F 16B 3 D 5 15187 9 8 2 F  13 12 13 5  19 1  13
注册码:Q K F P W L D N F V Y H J I C F  T  S  T  F  Z  B  T  E

生成码:W O R D  X C Z O M B I E Y S Z  O  M  B  I  E  Y  S  B
        |___________|
              |
    无限制的世界范围授权    //前6位跟授权方式有关,也可能只有第5位有关是W才行

你的名字的生成码:    Z O M B I E Y S Z  O  M  B  I  E  Y  S  B



计算公式:(注册码在密码表中的位置-1)-(上一位注册码ASCII值-41)-1+41=生成码
注:当生成码小于41时要+1A

当你输入NAME后你可以得到生成码的第7-22位,因为是无限制的世界范围授权所以前6位固定,而最后一位可以由从4097B6的计算确定所以很容易等到生成码,然后反推注册码。

这个玩艺确实不太好表达,自己跟踪一下就知道了。我的表达能力差,还可能有笔误,原谅我 哈哈.......

完活:)


这是我算的注册码:

名称:zombieys
授权类型:无限制的世界范围授权
代码:QKFP-WLDN-FVYH-JICF-TSTF-ZBTE




———————————————————————————————>
                .-"      "-.      Cracked by zombieys      >
                /      \      My oicq is 1789655        >
              |              |    My hp is zombieys.yeah.net>
              |,  .-.  .-.  ,|    My hp is zombieys.126.com >
                |)(__/  \__)(|                                >
                |/    /\    \|      Thanks for your supports  >
      (@_@)    (_    ^^    _)                                >
    _  )\_______\__|IIIIII|__/_____                          >
_)@8@8{}<________|-\IIIIII/-|____zombieys_____________________>