欢迎来到 嗅灵易学

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

SmartCheck 6.03的InstallShield序列号破解(下) (9千字)

SmartCheck 6.03的InstallShield序列号破解(下) (9千字)

(接上)
对话框中填的序列号的格式为0000-000000-00,当然数字也可以为字母。
前面的第一步判断,前三位必须是那一堆字符中的数字,因此我们前三个填510,后面仍然乱填一气(这里填5101-234567-FF),先跟进去再说。
下面比较零乱,是我以前分析Softice的utility.dll时留下的记录,SmartCheck的utility.dll结构几乎和它一模一样,许多东西玩起来也就轻松了。^_^
Exported fn(): DigitCheck - Ord:0001h
:10001110 56                      push esi
:10001111 57                      push edi
:10001112 8B7C240C                mov edi, dword ptr [esp+0C]    //序列号地址
:10001116 83C9FF                  or ecx, FFFFFFFF
:10001119 33C0                    xor eax, eax
:1000111B F2                      repnz
:1000111C AE                      scasb
:1000111D F7D1                    not ecx            //求长度。
:1000111F 2BF9                    sub edi, ecx
:10001121 8BC1                    mov eax, ecx
:10001123 8BF7                    mov esi, edi
:10001125 BF80CB0010              mov edi, 1000CB80
:1000112A C1E902                  shr ecx, 02
:1000112D F3                      repz
:1000112E A5                      movsd
:1000112F 8BC8                    mov ecx, eax
:10001131 83E103                  and ecx, 00000003
:10001134 F3                      repz
:10001135 A4                      movsb                //搬到一个地方去。
:10001136 E895000000              call 100011D0
:1000113B E840010000              call 10001280
:10001140 33C9                    xor ecx, ecx
:10001142 890DACCB0010            mov dword ptr [1000CBAC], ecx

//这两个CALL会根据序列号的前8位数字经过查表运算得来一系列值,也就内定了前八个字符必须是数字。详细内容见后面。
计算出来八个值:04 0C 09 04 06 0A 0A 0B,放在1000CBB0处。
:10001148 8A81B0CB0010            mov al, byte ptr [ecx+1000CBB0]    //取第一个
:1000114E 8A91B4CB0010            mov dl, byte ptr [ecx+1000CBB4]    //取第四个
:10001154 32C2                    xor al, dl                //先异或
//八个值中,第一个值和第四个值异或,再和最后一个值或,结果如不是数字或者字母则加7变成字母,比较后通过则继续计算第二个和第五个,并且仍和最后一个或,依此类推。
:10001156 8A15B7CB0010            mov dl, byte ptr [1000CBB7]        //一直都是取最后一个
:1000115C 0AC2                    or al, dl                //再或
:1000115E 0C30                    or al, 30
:10001160 3C39                    cmp al, 39
:10001162 8881B8CB0010            mov byte ptr [ecx+1000CBB8], al    //存结果
:10001168 7E08                    jle 10001172
:1000116A 0407                    add al, 07                //变字母
:1000116C 8881B8CB0010            mov byte ptr [ecx+1000CBB8], al    //也是存结果
//这里的AL是算出来的一个字符,算出一个后马上跟输入的序列号的最后四位比较。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001168(C)
|
:10001172 8A81B8CB0010            mov al, byte ptr [ecx+1000CBB8]
:10001178 8A9188CB0010            mov dl, byte ptr [ecx+1000CB88]
//这是输入序列号的后四位地址。前八位数字计算出来的四个字符必须和序列号末尾的四个字母一样才行。
:1000117E 3AC2                    cmp al, dl
:10001180 7406                    je 10001188            //比!
:10001182 0C20                    or al, 20
:10001184 3AC2                    cmp al, dl
:10001186 7514                    jne 1000119C            //不等就完蛋了
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001180(C)
|
:10001188 41                      inc ecx
:10001189 83F904                  cmp ecx, 00000004        //比完四对就……
:1000118C 7CBA                    jl 10001148
:1000118E 890DACCB0010            mov dword ptr [1000CBAC], ecx
:10001194 B801000000              mov eax, 00000001        //正确标志
:10001199 5F                      pop edi
:1000119A 5E                      pop esi
:1000119B C3                      ret
这里程序算出来的四个字符是“BFBF”
——————————————————————————————

这里是第一个CALL的内容,它的功能也就是先根据输入的前8个字符查一张表,如果查出来的东西符合要求(也就是前8个字符都是数字)则把前8个字符的ASCII码都转换成实际的数字存放在1000CBB8处:
* Referenced by a CALL at Address:
|:10001136 
|
:100011D0 53                      push ebx
:100011D1 33D2                    xor edx, edx
:100011D3 33DB                    xor ebx, ebx
:100011D5 56                      push esi
:100011D6 8915A8CB0010            mov dword ptr [1000CBA8], edx
:100011DC 33C9                    xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001240(U)
|
:100011DE A18C930010              mov eax, dword ptr [1000938C]
:100011E3 890DACCB0010            mov dword ptr [1000CBAC], ecx
:100011E9 83F801                  cmp eax, 00000001
:100011EC 7E20                    jle 1000120E
//也不知是什么判断,反正总是跳。
:100011EE 0FBE8180CB0010          movsx eax, byte ptr [ecx+1000CB80]
:100011F5 6A04                    push 00000004
:100011F7 50                      push eax
:100011F8 E883080000              call 10001A80
:100011FD 8B15A8CB0010            mov edx, dword ptr [1000CBA8]
:10001203 8B0DACCB0010            mov ecx, dword ptr [1000CBAC]
:10001209 83C408                  add esp, 00000008
:1000120C EB13                    jmp 10001221

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100011EC(C)
|
:1000120E 0FBE8180CB0010          movsx eax, byte ptr [ecx+1000CB80]    //表首地址
* Possible StringData Ref from Data Obj ->"          (((((              "
                                        ->"  H剟剟剟剟剟亖亖亖"
//第一张表的内容                        ->"倐倐倐"
                                        ->" "
                                  |
:10001215 8B3580910010            mov esi, dword ptr [10009180]
:1000121B 8A0446                  mov al, byte ptr [esi+2*eax]
:1000121E 83E004                  and eax, 00000004
//下面说明前八个字符必须都是数字。后四个字符根据这些数字来计算。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000120C(U)
|
:10001221 3BC3                    cmp eax, ebx
:10001223 741D                    je 10001242        //如果输入的不是数字,则这里会跳。
:10001225 83F908                  cmp ecx, 00000008    //满了8个则跳。
:10001228 7D18                    jge 10001242
:1000122A 8A8180CB0010            mov al, byte ptr [ecx+1000CB80]
:10001230 240F                    and al, 0F
:10001232 8882B0CB0010            mov byte ptr [edx+1000CBB0], al
:10001238 42                      inc edx
:10001239 8915A8CB0010            mov dword ptr [1000CBA8], edx
:1000123F 41                      inc ecx
:10001240 EB9C                    jmp 100011DE
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10001223(C), :10001228(C)
|
:10001242 83FA08                  cmp edx, 00000008
:10001245 7D33                    jge 1000127A
:10001247 4A                      dec edx
:10001248 B807000000              mov eax, 00000007
:1000124D 8915A8CB0010            mov dword ptr [1000CBA8], edx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000126D(C)
|
:10001253 3BD3                    cmp edx, ebx
:10001255 7D08                    jge 1000125F
:10001257 8898B0CB0010            mov byte ptr [eax+1000CBB0], bl
:1000125D EB0D                    jmp 1000126C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001255(C)
|
:1000125F 8A8AB0CB0010            mov cl, byte ptr [edx+1000CBB0]
:10001265 4A                      dec edx
:10001266 8888B0CB0010            mov byte ptr [eax+1000CBB0], cl
//这里1000cbb0处执行完后就存放了前8位数字的实际值,也就是
05 01 00 01 02 03 04 05
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000125D(U)
|
:1000126C 48                      dec eax
:1000126D 79E4                    jns 10001253
:1000126F A3ACCB0010              mov dword ptr [1000CBAC], eax
:10001274 8915A8CB0010            mov dword ptr [1000CBA8], edx
//这里存放俩处理过的字节数,都是8。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001245(C)
|
:1000127A 5E                      pop esi
:1000127B 5B                      pop ebx
:1000127C C3                      ret

下面是第二个CALL的内容,这个CALL把第一个CALL计算出来的数字再查一次表,结果覆盖了1000cbb0处的8个字节:
* Referenced by a CALL at Address:
|:1000113B 
|
:10001280 33C0                    xor eax, eax
:10001282 A3AC910010              mov dword ptr [100091AC], eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100012A7(C)
|
:10001287 0FBE88B0910010          movsx ecx, byte ptr [eax+100091B0]
:1000128E 8B148590800010          mov edx, dword ptr [4*eax+10008090]    //又查一次表
:10001295 40                      inc eax
:10001296 83F808                  cmp eax, 00000008            //处理8个字符
:10001299 8A0C0A                  mov cl, byte ptr [edx+ecx]
:1000129C A3AC910010              mov dword ptr [100091AC], eax
:100012A1 8888AF910010            mov byte ptr [eax+100091AF], cl    //存查表结果
:100012A7 7CDE                    jl 10001287
:100012A9 C3                      ret                    //返回
查出来的结果仍然放在1000cbb0,这里变成了04 0C 09 04 06 0A 0A 0B
最后得可以用的序列号: 5101-2345BF-BF
说明:此段和SoftICE的序列号破解过程除了指令定位地址不一样外,其他几乎一模一样,所以连说明文字都类似,*^_^*
至于注册机,应该也能写出来,但时间仓促,……。倘若没皮兄的“鞭策”,唉,……

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

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

0 0 0 举报
复制成功