欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

pediy03_00088.html

1.破解软件
   名字为pwindpro,版本号5.00,该软件是通过NDIS来直接
读取网卡数据报,可以用它来做网络监听软件,有源代码的,
我目前在做的一个项目可能用到它,所以我就破解他了。
2.破解工具
   icomp,w32dasm,trw2000,VC6.0
3.破解过程
   若光破这个程序是很简单的,它是自解压的,解压后的
目录在C:\Windows\Temp下,我等它解压完,把其拷入另一个
目录,接着我观察该目录,发现在Disk1下面有setup.ins,这
个文件是经过压缩的,还有个_setup.lib,先用Fi查看文件类
型,发现他们均是.z结尾的,这种文件可以用icomp来解压。
然后我把_setup.lib解压,发现里面有个很可疑的dll即Serial.dll
.于是我把该文件用W32dasm反汇编。呵呵,它就导出一个函数
SerialCheck,肯定就是它了,然后吗,用trw跟进该函数,怎么
跟呢,它不是会弹出出错对话框吗,OK,bpx messageboxa,然后
F12,呵呵,是不是到了Serial啊,赶快往前翻,在SerialCheck的
入口点下一个断点,以后就每次都会在这中断了。跟踪发现它仅用
返回值来标记是否合法,所以我简单的把它的返回值始终设为1,
这样,一切OK,不用再输入序列号了。
   接着呢,破是破掉了,但总觉得不爽,索性把它的注册机
也写出来了。下面是我写该注册机的过程,该程序的注册算法
比较简单,我只用了一天的时间把它写出来,最主要的时间
还浪费在写代码上,一开始我想用纯C语言来写,但碰到一个问
题,就是汇编指令imul调用之后会设置高位寄存器,如果两个
操作数均是DWORD,在C中如何取到结果的高位,C中调用乘法后
它自动帮你截断了,而我又必须要有该信息,所以,我就请教了
一个人,Craxy Z,从他那我获得了灵感,VC不是支持内嵌汇编语
句吗,我直接写汇编语句不就可以了,(顺带一句,那位能用C语
言来解决该问题的,能不能告诉我方法,那种将数字堪称数组,
然后自己写乘法的方法就不用说了),接下来的工作就很简单了。
4.注册机写作过程
* Referenced by a CALL at Address:
|:1000101A
|
:10001030 8B542408        mov edx, dword ptr [esp+08]
  ;[esp+08]指向输入的序列号
:10001034 83EC20         sub esp, 00000020
:10001037 83C9FF         or ecx, FFFFFFFF
:1000103A 33C0          xor eax, eax
:1000103C 56           push esi
:1000103D 57           push edi
:1000103E 8BFA          mov edi, edx
:10001040 F2           repnz
:10001041 AE           scasb
:10001042 F7D1          not ecx
:10001044 49           dec ecx
:10001045 83F913         cmp ecx, 00000013
  ;看其长度是否为19,
  ;格式为xxxx-xxxx-xxxx-xxxx
:10001048 741F          je 10001069
:1000104A 8B44242C        mov eax, dword ptr [esp+2C]
:1000104E 6A30          push 00000030
* Possible StringData Ref from Data Obj ->"Invalid Serial Number"
                 |
:10001050 68EC910010       push 100091EC
* Possible StringData Ref from Data Obj ->"Serial number has incorrect
lengt
h!"
                 |
:10001055 68C8910010       push 100091C8
:1000105A 50           push eax
* Reference To: USER32.MessageBoxA, Ord:01C3h
                 |
:1000105B FF15EC800010      Call dword ptr [100080EC]
:10001061 5F           pop edi
:10001062 33C0          xor eax, eax
:10001064 5E           pop esi
:10001065 83C420         add esp, 00000020
:10001068 C3           ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001048(C)
|
:10001069 8BFA          mov edi, edx
:1000106B 83C9FF         or ecx, FFFFFFFF
:1000106E 33C0          xor eax, eax
:10001070 53           push ebx
:10001071 F2           repnz
:10001072 AE           scasb
:10001073 F7D1          not ecx
:10001075 2BF9          sub edi, ecx
:10001077 8D5C240C        lea ebx, dword ptr [esp+0C]
:1000107B 8BD1          mov edx, ecx
:1000107D 8BF7          mov esi, edi
:1000107F 8BFB          mov edi, ebx
:10001081 8D44240C        lea eax, dword ptr [esp+0C]
:10001085 C1E902         shr ecx, 02
:10001088 F3           repz
:10001089 A5           movsd
  ;拷贝字符串到另一个地方
:1000108A 8BCA          mov ecx, edx
* Possible StringData Ref from Data Obj ->"-"
                 |
:1000108C 6830900010       push 10009030
:10001091 83E103         and ecx, 00000003
:10001094 50           push eax
:10001095 F3           repz
:10001096 A4           movsb
:10001097 E863050000       call 100015FF
  ;该函数将原来串中的"-"用00来替代了
* Possible StringData Ref from Data Obj ->"-"
                 |
:1000109C 6830900010       push 10009030
:100010A1 6A00          push 00000000
:100010A3 A3A09E0010       mov dword ptr [10009EA0], eax
:100010A8 E852050000       call 100015FF
* Possible StringData Ref from Data Obj ->"-"
                 |
:100010AD 6830900010       push 10009030
:100010B2 6A00          push 00000000
:100010B4 A3A49E0010       mov dword ptr [10009EA4], eax
:100010B9 E841050000       call 100015FF
* Possible StringData Ref from Data Obj ->"-"
                 |
:100010BE 6830900010       push 10009030
:100010C3 6A00          push 00000000
:100010C5 A3A89E0010       mov dword ptr [10009EA8], eax
:100010CA E830050000       call 100015FF
  ;上面的四个call 100015ff分别处理序列号的四项
:100010CF 8B3DA09E0010      mov edi, dword ptr [10009EA0]
:100010D5 83C420         add esp, 00000020
:100010D8 8BF0          mov esi, eax
:100010DA 85FF          test edi, edi
:100010DC 8935AC9E0010      mov dword ptr [10009EAC], esi
:100010E2 5B           pop ebx
:100010E3 0F841C020000      je 10001305
:100010E9 83C9FF         or ecx, FFFFFFFF
:100010EC 33C0          xor eax, eax
:100010EE F2           repnz
:100010EF AE           scasb
:100010F0 F7D1          not ecx
:100010F2 49           dec ecx
:100010F3 83F904         cmp ecx, 00000004
  ;我上面提到的序列号格式是由这获知的
  ;以下一长段都是在检查格式对不对的
:100010F6 0F8509020000      jne 10001305
:100010FC 8B3DA49E0010      mov edi, dword ptr [10009EA4]
:10001102 85FF          test edi, edi
:10001104 0F84DC010000      je 100012E6
:1000110A 83C9FF         or ecx, FFFFFFFF
:1000110D F2           repnz
:1000110E AE           scasb
:1000110F F7D1          not ecx
:10001111 49           dec ecx
:10001112 83F904         cmp ecx, 00000004
:10001115 0F85CB010000      jne 100012E6
:1000111B 8B15A89E0010      mov edx, dword ptr [10009EA8]
:10001121 85D2          test edx, edx
:10001123 0F849E010000      je 100012C7
:10001129 8BFA          mov edi, edx
:1000112B 83C9FF         or ecx, FFFFFFFF
:1000112E F2           repnz
:1000112F AE           scasb
:10001130 F7D1          not ecx
:10001132 49           dec ecx
:10001133 83F904         cmp ecx, 00000004
:10001136 0F858B010000      jne 100012C7
:1000113C 85F6          test esi, esi
:1000113E 0F8464010000      je 100012A8
:10001144 8BFE          mov edi, esi
:10001146 83C9FF         or ecx, FFFFFFFF
:10001149 F2           repnz
:1000114A AE           scasb
:1000114B F7D1          not ecx
:1000114D 49           dec ecx
:1000114E 83F904         cmp ecx, 00000004
:10001151 0F8551010000      jne 100012A8
  ;到这为止,长度检查完毕
:10001157 52           push edx
  ;edx为序列号的第三项
:10001158 E817040000       call 10001574
  ;该函数将字符串xyzw转化为数字(十进制)
  ;返回值在eax中,例如串"0101"就变为数字101
:1000115D 8BC8          mov ecx, eax
:1000115F B867666666       mov eax, 66666667
:10001164 8BD1          mov edx, ecx
:10001166 81E2FFFF0000      and edx, 0000FFFF
:1000116C F7EA          imul edx
:1000116E C1FA02         sar edx, 02
:10001171 8BC2          mov eax, edx
:10001173 C1E81F         shr eax, 1F
:10001176 03D0          add edx, eax
:10001178 66891554A20010     mov word ptr [1000A254], dx
  ;以上计算得到一个值,其后要用到
  ;它共设置两个字节,根据其地址,
  ;我把它记做var4,var5,并把该段
  ;计算过程定义成func3.1
:1000117F 8AC2          mov al, dl
:10001181 B20A          mov dl, 0A
:10001183 F6EA          imul dl
:10001185 2AC8          sub cl, al
:10001187 A1AC9E0010       mov eax, dword ptr [10009EAC]
:1000118C 50           push eax
  ;eax为序列号的第四项
:1000118D 880D58A20010      mov byte ptr [1000A258], cl
  ;cl的就算过程定义为func3.2
  ;并把代表它的地址记做var8
:10001193 E8DC030000       call 10001574
:10001198 8B0DA49E0010      mov ecx, dword ptr [10009EA4]
:1000119E 66A356A20010      mov word ptr [1000A256], ax
  ;不作任何处理直接将结果存入,
  ;记为func4,变量记做var6,var7
:100011A4 51           push ecx
  ;ecx为序列号的第二项
:100011A5 E8CA030000       call 10001574
:100011AA 8BC8          mov ecx, eax
:100011AC B81F85EB51       mov eax, 51EB851F
:100011B1 8BD1          mov edx, ecx
:100011B3 81E2FFFF0000      and edx, 0000FFFF
:100011B9 F7EA          imul edx
:100011BB C1FA05         sar edx, 05
:100011BE 8BF2          mov esi, edx
:100011C0 8BC2          mov eax, edx
:100011C2 C1EE1F         shr esi, 1F
:100011C5 03C6          add eax, esi
:100011C7 B264          mov dl, 64
:100011C9 A252A20010       mov byte ptr [1000A252], al
  ;al的计算过程定义为func2.1
  ;变量记做var2
:100011CE F6EA          imul dl
:100011D0 2AC8          sub cl, al
:100011D2 8D44243C        lea eax, dword ptr [esp+3C]
:100011D6 880D53A20010      mov byte ptr [1000A253], cl
  ;cl的计算过程定义为func2.2
  ;变量记做var3
:100011DC 8B0DA09E0010      mov ecx, dword ptr [10009EA0]
:100011E2 50           push eax
  ;eax为序列号的第一项
* Possible StringData Ref from Data Obj ->"%x"
                 |
:100011E3 68C4910010       push 100091C4
:100011E8 51           push ecx
:100011E9 E852030000       call 10001540
  ;该函数将字符串xyzw转换为0Xxyzw(十六进制)
  ;例如将串"1234"转换为0x1234
:100011EE 668B542448       mov dx, word ptr [esp+48]
:100011F3 6850A20010       push 1000A250
:100011F8 66891550A20010     mov word ptr [1000A250], dx
  ;dx即为上面得到的十六进制数
  ;其计算过程我定义为func1
:100011FF E88C010000       call 10001390
  ;★★★注意,该函数就是关键的比较函数了,后面有分析
:10001204 83C41C         add esp, 0000001C
:10001207 84C0          test al, al
:10001209 751F          jne 1000122A
  ;此处必须跳转才是正确的
:1000120B 8B44242C        mov eax, dword ptr [esp+2C]
:1000120F 6A30          push 00000030
* Possible StringData Ref from Data Obj ->"Invalid Serial Number"
                 |
:10001211 68EC910010       push 100091EC
* Possible StringData Ref from Data Obj ->"The serial number is invalid!"
                 |
:10001216 68A4910010       push 100091A4
:1000121B 50           push eax
* Reference To: USER32.MessageBoxA, Ord:01C3h
                 |
:1000121C FF15EC800010      Call dword ptr [100080EC]
:10001222 5F           pop edi
:10001223 33C0          xor eax, eax
:10001225 5E           pop esi
:10001226 83C420         add esp, 00000020
:10001229 C3           ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001209(C)
|
:1000122A 66A154A20010      mov ax, word ptr [1000A254]
  ;应该跳到1000126D处
  ;其后的比较告诉我们func3.1
  ;算出来的值var4,var5必须满足特定条件,
  ;即在【A--E】之间。
:10001230 663D0A00        cmp ax, 000A
:10001234 7437          je 1000126D
:10001236 663D0B00        cmp ax, 000B
:1000123A 7431          je 1000126D
:1000123C 663D0C00        cmp ax, 000C
:10001240 742B          je 1000126D
:10001242 663D0D00        cmp ax, 000D
:10001246 7425          je 1000126D
:10001248 663D0E00        cmp ax, 000E
:1000124C 741F          je 1000126D
:1000124E 8B4C242C        mov ecx, dword ptr [esp+2C]
:10001252 6A30          push 00000030
* Possible StringData Ref from Data Obj ->"Invalid Serial Number"
                 |
:10001254 68EC910010       push 100091EC
* Possible StringData Ref from Data Obj ->"The serial number is not for
this
"
                    ->"product!"
                 |
:10001259 6878910010       push 10009178
:1000125E 51           push ecx
* Reference To: USER32.MessageBoxA, Ord:01C3h
                 |
:1000125F FF15EC800010      Call dword ptr [100080EC]
:10001265 5F           pop edi
:10001266 33C0          xor eax, eax
:10001268 5E           pop esi
:10001269 83C420         add esp, 00000020
:1000126C C3           ret
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10001234(C), :1000123A(C), :10001240(C), :10001246(C), :1000124C(C)
|
:1000126D 6850A20010       push 1000A250
:10001272 E8D9010000       call 10001450
  ;这个call有点奇怪,但看了后面就知道了
  ;它可能是把一些特殊的序列号过滤掉
:10001277 83C404         add esp, 00000004
:1000127A 84C0          test al, al
:1000127C 741F          je 1000129D
:1000127E 8B54242C        mov edx, dword ptr [esp+2C]
:10001282 6A30          push 00000030
* Possible StringData Ref from Data Obj ->"Expired Serial Number"
                 |
:10001284 6860910010       push 10009160
* Possible StringData Ref from Data Obj ->"The period for free updates to
"
                    ->"this product has expired."
                 |
:10001289 6824910010       push 10009124
:1000128E 52           push edx
* Reference To: USER32.MessageBoxA, Ord:01C3h
                 |
:1000128F FF15EC800010      Call dword ptr [100080EC]
:10001295 5F           pop edi
:10001296 33C0          xor eax, eax
:10001298 5E           pop esi
:10001299 83C420         add esp, 00000020
:1000129C C3           ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000127C(C)
|
:1000129D 5F           pop edi
  ;正常的应该到达这
:1000129E B801000000       mov eax, 00000001
  ;eax为1表示通过检查
  ;简单的crack可以设置eax恒为1即可,
  ;当然,我们不满足于仅仅crack,
  ;下面我们来分析其注册过程,
:100012A3 5E           pop esi
:100012A4 83C420         add esp, 00000020
:100012A7 C3           ret
××××××××××××××××××××××××××××××××××××××

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功