几天没事就破这个软件了,顺便温习了一下8086汇编。简单的说一下破解要点,有兴趣的朋友练练吧。
<关键点1>:注册标志
:0001.051A E80300 call 0520 ;看,子程序入口就在下边
:0001.051D E9D210 jmp 15F2 ;注册过程结束,跳出。
* Referenced by a CALL at Addresses:
|:0001.051A, :0001.94BC, :0001.E4F5
|
:0001.0520 2E803E7F0801 cmp byte ptr cs:[087F], 01 子程序入口,判断是否为1
:0001.0526 7501 jne 0529 ;等于0则进入注册过程
:0001.0528 C3 ret 等于1就直接返回,跳过注册过程。
说明:cs:[087F]的内容就是判断注册是否成功的标志,等于0表明未注册,等于1表示已经注册。
<关键点2>:防修改子程序
有些人看完关键点1就急着爆破,你会发现你死的很难看~~~软件中有防修改子程序,你只要一改代码,就会死机!!!防修改子程序在这里:
* Referenced by a CALL at Addresses:
|:0001.2491, :0001.2658, :0001.288E, :0001.6C27, :0001.D332
|
:0001.138F 1E push ds
:0001.1390 56 push si
:0001.1391 50 push ax
:0001.1392 51 push cx
:0001.1393 0E push cs
:0001.1394 1F pop ds
:0001.1395 8D369A15 lea si, [159A]
:0001.1399 8D0E3A16 lea cx, [163A]
:0001.139D E88111 call 2521
:0001.13A0 8D36B5B8 lea si, [B8B5]
:0001.13A4 8D0E05B9 lea cx, [B905]
:0001.13A8 E89611 call 2541
:0001.13AB 8D361A47 lea si, [471A]
:0001.13AF 8D0E4947 lea cx, [4749]
:0001.13B3 E87B11 call 2531
:0001.13B6 8D369513 lea si, [1395]
:0001.13BA 8D0EBF14 lea cx, [14BF]
:0001.13BE E86011 call 2521
:0001.13C1 8D364E04 lea si, [044E]
:0001.13C5 8D0E2905 lea cx, [0529] 看,[044E]-[0529]之间的代码有防修改措施。
:0001.13C9 E87511 call 2541
:0001.13CC 8D36620D lea si, [0D62]
:0001.13D0 8D0EEB0D lea cx, [0DEB]
:0001.13D4 E85A11 call 2531
:0001.13D7 8D367403 lea si, [0374]
:0001.13DB 8D0EEE03 lea cx, [03EE]
:0001.13DF E85F11 call 2541
:0001.13E2 8D367607 lea si, [0776]
:0001.13E6 8D0EEF07 lea cx, [07EF]
:0001.13EA E84411 call 2531
:0001.13ED 8D365C0C lea si, [0C5C]
:0001.13F1 8D0EE40C lea cx, [0CE4]
:0001.13F5 E82911 call 2521
:0001.13F8 8D366DB8 lea si, [B86D]
:0001.13FC 8D0E7BB8 lea cx, [B87B]
:0001.1400 E82E11 call 2531
:0001.1403 8D364C60 lea si, [604C]
:0001.1407 8D0E6A60 lea cx, [606A]
:0001.140B E83311 call 2541
:0001.140E 8D3656D3 lea si, [D356]
:0001.1412 8D0E60D3 lea cx, [D360]
:0001.1416 E80811 call 2521
:0001.1419 8D36C60B lea si, [0BC6]
:0001.141D 8D0EE30B lea cx, [0BE3]
:0001.1421 E81D11 call 2541
:0001.1424 8D36A467 lea si, [67A4]
:0001.1428 8D0E0C68 lea cx, [680C]
:0001.142C E8F210 call 2521
:0001.142F 8D36EAB6 lea si, [B6EA]
:0001.1433 8D0EFAB6 lea cx, [B6FA]
:0001.1437 E8F710 call 2531
:0001.143A 8D362C03 lea si, [032C]
:0001.143E 8D0E4403 lea cx, [0344]
:0001.1442 E8FC10 call 2541
:0001.1445 8D362D46 lea si, [462D]
:0001.1449 8D0E4046 lea cx, [4640]
:0001.144D E8D110 call 2521
:0001.1450 59 pop cx
:0001.1451 58 pop ax
:0001.1452 5E pop si
:0001.1453 1F pop ds
:0001.1454 C3 ret
看到了吧,程序的关键之处都被做了防修改处理。这段子程序入口参数和返回是BX和DX,有5处地方调用这一子程序。解决办法:在每个调用的代码处计算出BX和DX的正确值,在调用前直接赋给BX和DX,然后NOP掉调用这段子程序的代码,就能避开防修改措施了。
<关键点3>:多处注册码判断。
以上两个关键点已经基本解决问题了,但还有一个小问题:软件在运行过程中还有几次判断注册码正确与否的过程,发现计算结果有误,就立即让cs:[087F]为0,代码在这里:
:0001.6058 8D367F08 lea si, [087F]
:0001.605C C7040000 mov word ptr [si], 0000
:0001.6060 C744020000 mov word ptr [si+02], 0000
:0001.6065 C744040000 mov word ptr [si+04], 0000
:0001.606A E91BC8 jmp 2888
还有几个把[087F]置0的代码段,有些可能执行不到。为了保险起见,把所有让[087F]为0的代码统统NOP掉,免得爆破不干净。注意:必须先完成关键点2的工作,因为这几处都做了防修改处理。
<关键点 4>:最后要提醒一下,软件中有几处功能都必须注册才能使用,判断注册成功的依据是:
[087F]=01,[0880]=0A,[0881]=14,[0882]=1E,[0883]=28,[0884]=32,[0885]=3C
是这段代码计算出来的:
:0001.15F2 2EA07F08 mov al, cs:[087F]
:0001.15F6 B40A mov ah, 0A
:0001.15F8 F6E4 mul ah
:0001.15FA 2EA28008 mov byte ptr cs:[0880], al
:0001.15FE 2EA07F08 mov al, cs:[087F]
:0001.1602 B414 mov ah, 14
:0001.1604 F6E4 mul ah
:0001.1606 2EA28108 mov byte ptr cs:[0881], al
:0001.160A 2EA07F08 mov al, cs:[087F]
:0001.160E B41E mov ah, 1E
:0001.1610 F6E4 mul ah
:0001.1612 2EA28208 mov byte ptr cs:[0882], al
:0001.1616 2EA07F08 mov al, cs:[087F]
:0001.161A B428 mov ah, 28
:0001.161C F6E4 mul ah
:0001.161E 2EA28308 mov byte ptr cs:[0883], al
:0001.1622 2EA07F08 mov al, cs:[087F]
:0001.1626 B432 mov ah, 32
:0001.1628 F6E4 mul ah
:0001.162A 2EA28408 mov byte ptr cs:[0884], al
:0001.162E 2EA07F08 mov al, cs:[087F]
:0001.1632 B43C mov ah, 3C
:0001.1634 F6E4 mul ah
:0001.1636 2EA28508 mov byte ptr cs:[0885], al
这个软件保护措施的特点是:
1 代码几乎全是明码,虽然有几处花指令,有几处代码变换,但对静态反汇编的结果影响不大.
2 有一处大循环、多出口的反跟踪代码段。由于入口、出口处的代码都没有加密,所以通过对静态反汇编的代码简单研究一下,不难找到出口。
3 有代码防修改机制。如何找到这个防修改的代码段?方法还是有一些的,留给大家研究吧,呵呵。因为我找到这个代码段比较偶然,事后想想有捷径可走,但没有走过,所以不能乱讲,要实事求是嘛。
最后说明一下,本人破解功力一般,本来想请CCDEBUGER版主帮忙破解一下,但出于各种不可抗拒的原因,只好硬着头皮自已上了,现在爆破成功,但发现写注册机有点儿困难,现在我还在研究。我从来没有写过注册机,都就爆破了事,不思进取,希望拿这个软件做个练习,成不成无所谓,就当是学习汇编了,呵呵。
双色球霸主V3.21破解完毕.还有什么不明白的地方请留言讨论.
5月27日,解决了一个暗桩,去掉暗桩后,经测试运行正常。
这个暗桩已经自己解决!!!
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.6779(C)
|
:0001.6791 3C3C cmp al, 3C ;出现暗桩的地方,al=3C
:0001.6793 7403 je 6798 ;“保存选号结果”子功能入口
:0001.6795 E99A00 jmp 6832
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.6793(C)
|
:0001.6798 8D36C5B4 lea si, [B4C5]
:0001.679C 2E89368931 mov cs:[3189], si
:0001.67A1 E8824D call B526
:0001.67A4 3D0000 cmp ax, 0000
:0001.67A7 7508 jne 67B1
:0001.67A9 83FA00 cmp dx, 0000
:0001.67AC 7503 jne 67B1
:0001.67AE E9D7C0 jmp 2888
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.67A7(C), :0001.67AC(C)
|
:0001.67B1 2E803E85083C cmp byte ptr cs:[0885], 3C ;注册成功?
:0001.67B7 740D je 67C6 ;注册成功跳转
:0001.67B9 2EC706A6DA2100 mov word ptr cs:[DAA6], 0021
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.67D5(U)
|
:0001.67C0 E87272 call DA35
:0001.67C3 E9C2C0 jmp 2888
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.67B7(C)
|
:0001.67C6 2E803EA93100 cmp byte ptr cs:[31A9], 00
:0001.67CC 7409 je 67D7
:0001.67CE 2EC706A6DA2300 mov word ptr cs:[DAA6], 0023
:0001.67D5 EBE9 jmp 67C0
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.67CC(C)
|
:0001.67D7 2E803EC50B50 cmp byte ptr cs:[0BC5], 50 ;暗桩!!
:0001.67DD 7418 je 67F7 ;相等则跳转到正确处
:0001.67DF E8929B call 0374 ;否则死翘翘~~~
:0001.67E2 2EA1EEFA mov ax, word ptr cs:[FAEE]
:0001.67E6 8ED8 mov ds, ax
:0001.67E8 A10600 mov ax, word ptr [0006]
:0001.67EB 0E push cs
:0001.67EC 1F pop ds
:0001.67ED 2E3B06F503 cmp ax, cs:[03F5]
:0001.67F2 7403 je 67F7
:0001.67F4 E9F4A5 jmp 0DEB
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.67DD(C), :0001.67F2(C)
|
:0001.67F7 2EA1A6DA mov ax, word ptr cs:[DAA6]
:0001.67FB 2EA2BACB mov byte ptr cs:[CBBA], al
:0001.67FF 2EC60652CC47 mov byte ptr cs:[CC52], 47
:0001.6805 90 nop
:0001.6806 E8D763 call CBE0
:0001.6809 E85464 call CC60
:0001.680C 2EC706A6DA0100 mov word ptr cs:[DAA6], 0001
:0001.6813 E81F72 call DA35
:0001.6816 2E8B368B31 mov si, cs:[318B]
:0001.681B 56 push si
:0001.681C 8D36D000 lea si, [00D0]
:0001.6820 E8D87C call E4FB
:0001.6823 5E pop si
:0001.6824 2E89368B31 mov cs:[318B], si
:0001.6829 2EC6068E3101 mov byte ptr cs:[318E], 01
:0001.682F E956C0 jmp 2888
就是这个暗桩搞的鬼!!在运行到保存选号结果这一子功能程序段时,软件再次判断注册是否成功,即cmp byte ptr cs:[0BC5], 50,等于50则表示注册成功。查看原来的破解,此处值是0,难怪会死翘翘~~~~别忙着改代码,再看防修改子程序,这段程序也被保护,不能修改,所以只能在其它未做保护的地方写上mov byte ptr cs:[0BC5], 50 。
---------------------以下给出完整爆破方案,供参考------------------
*****修改1*****
原代码:
* Referenced by a CALL at Addresses:
|:0001.051A, :0001.94BC, :0001.E4F5
|
:0001.0520 2E803E7F0801 cmp byte ptr cs:[087F], 01
:0001.0526 7501 jne 0529
:0001.0528 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.0526(C)
|
:0001.0529 1E push ds
:0001.052A 06 push es
:0001.052B 2EA17908 mov ax, word ptr cs:[0879]
:0001.052F 2E8B1E7B08 mov bx, cs:[087B]
:0001.0534 BAE001 mov dx, 01E0
:0001.0537 2E2B167D08 sub dx, cs:[087D]
:0001.053C 2E2B167B08 sub dx, cs:[087B]
...
...
修改为:
* Referenced by a CALL at Addresses:
|:0001.051A, :0001.94BC, :0001.E4F5
|
:0001.0520 2E803E7F0801 cmp byte ptr cs:[087F], 01
:0001.0526 7501 jne 0529
:0001.0528 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.0526(C)
|
:0001.0529 2EC6067F0801 mov byte ptr cs:[087F], 01 ; 置成功标志
:0001.052F 2EC606C50B50 mov byte ptr cs:[0BC5], 50 ; 置暗桩标志
:0001.0535 C3 ret ;直接返回,跳过注册过程
:0001.0536 012E2B16 add [162B], bp
:0001.053A 7D08 jge 0544
:0001.053C 2E2B167B08 sub dx, cs:[087B]
...
...
*****修改2*****
原代码:
:0001.600F 3C4D cmp al, 4D
:0001.6011 7577 jne 608A
:0001.6013 0E push cs
:0001.6014 1F pop ds
:0001.6015 8D367F08 lea si, [087F]
:0001.6019 BB0000 mov bx, 0000
:0001.601C B90300 mov cx, 0003
:0001.601F AD lodsw
:0001.6020 03D8 add bx, ax
:0001.6022 E2FB loop 601F
:0001.6024 83FB00 cmp bx, 0000
:0001.6027 7444 je 606D
:0001.6029 2EA1F703 mov ax, word ptr cs:[03F7]
:0001.602D 8AF4 mov dh, ah
:0001.602F 2EC606540C01 mov byte ptr cs:[0C54], 01
:0001.6035 E8ABAB call 0BE3
:0001.6038 8AE2 mov ah, dl
:0001.603A 8AF0 mov dh, al
:0001.603C 2EC606540C01 mov byte ptr cs:[0C54], 01
:0001.6042 E89EAB call 0BE3
:0001.6045 8AC2 mov al , dl
:0001.6047 2E03067A12 add ax, cs:[127A]
:0001.604C 2E3306EF03 xor ax, cs:[03EF]
:0001.6051 2E3B06550C cmp ax, cs:[0C55]
:0001.6056 7415 je 606D
:0001.6058 8D367F08 lea si, [087F]
:0001.605C C7040000 mov word ptr [si], 0000
:0001.6060 C744020000 mov word ptr [si+02], 0000
:0001.6065 C744040000 mov word ptr [si+04], 0000
:0001.606A E91BC8 jmp 2888
修改为:
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.5FED(C), :0001.6223(U)
|
:0001.600F 3C4D cmp al, 4D
:0001.6011 7577 jne 608A
:0001.6013 0E push cs
:0001.6014 1F pop ds
:0001.6015 8D367F08 lea si, [087F]
:0001.6019 BB0000 mov bx, 0000
:0001.601C B90300 mov cx, 0003
:0001.601F AD lodsw
:0001.6020 03D8 add bx, ax
:0001.6022 E2FB loop 601F
:0001.6024 83FB00 cmp bx, 0000
:0001.6027 EB44 jmp 606D ;此处直接跳过暗桩!!
:0001.6029 2EA1F703 mov ax, word ptr cs:[03F7]
:0001.602D 8AF4 mov dh, ah
:0001.602F 2EC606540C01 mov byte ptr cs:[0C54], 01
:0001.6035 E8ABAB call 0BE3
:0001.6038 8AE2 mov ah, dl
:0001.603A 8AF0 mov dh, al
:0001.603C 2EC606540C01 mov byte ptr cs:[0C54], 01
:0001.6042 E89EAB call 0BE3
:0001.6045 8AC2 mov al , dl
:0001.6047 2E03067A12 add ax, cs:[127A]
:0001.604C 2E3306EF03 xor ax, cs:[03EF]
:0001.6051 2E3B06550C cmp ax, cs:[0C55]
:0001.6056 7415 je 606D
:0001.6058 8D367F08 lea si, [087F]
:0001.605C C7040000 mov word ptr [si], 0000
:0001.6060 C744020000 mov word ptr [si+02], 0000
:0001.6065 C744040000 mov word ptr [si+04], 0000
:0001.606A E91BC8 jmp 2888
以上就是爆破的全过程。请大家自行修改吧,我已经换了M种N台电脑进行了测试,一切正常,感觉破解的比较完美,至今还未发现暗桩,如果哪位朋友发现暗桩了,请在此留言,不胜感谢
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)