不愿看废话的请直接Goto body 否则:
作者按:
这是我差不多一年前的破解日记。这里稍作修改放在坛里供大家抛砖(希望也能引玉)。
在这里我代表个人感谢看雪论坛对我的影响。看雪陪伴了我做解密的几乎全部生涯。同时感谢
trw,od,softice,w32dasm...等优秀软件的作者无私的贡献...
这些天做了3个深思4软件锁的复制(老有人在mail和QQ里问深思4的问题,等有机会我再写一篇
把普遍问到的问题再作一次回答吧。),很累,没时间刮胡子,都快一厘米长了。眼看元旦来了,还
是留作新年来到钟声响起的那一刻落刀吧 ;)
值此新年之际,祝看雪所有的兄弟姐妹 ha...appy...niu yearrrrrrrr!!
好了,废话少说,正文开始
body:
破解对象:一套相当不错的jap服装相关软件(不好意思,还是支持正版的好,这里就不指出了)
(注:这个软件模块很多,这里只贴出这一个模块的破解日记,如大家支持,再把其他的模块日记也贴出。
)
破解工具:TRW2000(感谢刘前辈为我们做了这么好的工具-我一直都不认为trw比od差),W32DASM,UtrlEdit
,PEID092
作者:kingday
QQ: 6661860
WebSite: http://www.iping.cn
如需转载,请保留以上信息
------------------------------------------------------------------------
首先,我们分析一下软件的情况。
1)双击运行没有任何反映
2)PEID092查后没有任何壳。显示为VC写的
3)朋友告诉我,这是用狗加密的。问他什么狗,说不知道。因为他也没狗。
4)朋友还告诉我,插狗后就可以正确运行了。(等于没说)
先不管它什么狗,用W32DASM打开看看。来到字串参考处,发现sentinel字样,哦,应该就是
这个可爱的狗狗了,大家都叫它圣天诺(不错,很好听的名字,不过还是要打你没商量)。
似乎很多朋友谈到打狗,就认为知道什么狗,然后套公式就稳扎稳打了。其实我个人觉得,这是
大错特错的。当然每种狗是相对其他狗有其鲜明的特点(如,彩虹狗的花指令迷宫术等),但只要
加密人稍微变一下加密算法就足够你折腾了,套公式的一般解法一点用都没有。所以我们还是应该
从基础的方式开始。
再仔细看看字串参考,很可惜没有什么有价值的信息。看样子必须要请出我们伟大的TRW了(现在我
们请伟大的TRW隆重登场,大家鼓掌。呵呵)
首先LOAD程序,然后
我们下bpx createfilea断下后按F12和F10来到下面
:0045FF68 6880D16500 push 0065D180
:0045FF6D 8BCD mov ecx, ebp
* Reference To: MFC42.Ordinal:17E5, Ord:17E5h
|
:0045FF6F E83E1D1C00 Call 00621CB2
:0045FF74 8B85C4000000 mov eax, dword ptr [ebp+000000C4]
:0045FF7A BE01000000 mov esi, 00000001
:0045FF7F 3BC6 cmp eax, esi
:0045FF81 0F843B010000 je 004600C2
:0045FF87 8D4C2410 lea ecx, dword ptr [esp+10]
* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:0045FF8B E85A151C00 Call 006214EA
:0045FF90 8D4C2420 lea ecx, dword ptr [esp+20]
:0045FF94 C68424F801000005 mov byte ptr [esp+000001F8], 05
* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:0045FF9C E849151C00 Call 006214EA
:0045FFA1 8D44241C lea eax, dword ptr [esp+1C]
:0045FFA5 8DB5D0010000 lea esi, dword ptr [ebp+000001D0]
:0045FFAB 50 push eax
:0045FFAC B306 mov bl, 06
:0045FFAE 56 push esi
:0045FFAF 6A02 push 00000002
:0045FFB1 889C2404020000 mov byte ptr [esp+00000204], bl
:0045FFB8 E803421A00 call 006041C0
:0045FFBD 83C40C add esp, 0000000C
:0045FFC0 83F8F7 cmp eax, FFFFFFF7
:0045FFC3 0F849D000000 je 00460066 =>&1。
:0045FFC9 83F801 cmp eax, 00000001
:0045FFCC 7460 je 0046002E =>&2。
:0045FFCE 83F802 cmp eax, 00000002
:0045FFD1 7408 je 0045FFDB =>&3。
:0045FFD3 6A00 push 00000000
当我们到&1,&2,&3后,程序默认都不会跳(等会我们就知道了,因为我们没狗嘛),而是一路下来,直到下
面直接退出,没有任何提示。
重来一次,我们把&1强行跳转后,程序弹出一个黄色的对话框提示:期限已到(哦,原来这狗是带试用的)
,几秒钟后就自动消失了。
我继续跟进去,发现到了另外一个DLL文件的领空,调用的是一个检测时间限制的函数,可是无论我怎么跟
踪修改,依然还是那黄色的对话框,只是提示的的信息不一样而已,大意都是期限到了,然后退出。走了不
少弯路,浪费了我20多分的时间。
我们回到&2,强行跳一下来到&4处
* Reference To: MSVCRT.exit, Ord:0249h =>很明显,到这里就退出了。呵呵,exit太现眼了。
|
:0045FFD5 FF1578796300 Call dword ptr [00637978]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045FFD1(C)
|
:0045FFDB 8B85C4000000 mov eax, dword ptr [ebp+000000C4]
:0045FFE1 85C0 test eax, eax
:0045FFE3 7549 jne 0046002E
:0045FFE5 837C241C01 cmp dword ptr [esp+1C], 00000001
:0045FFEA 7542 jne 0046002E
:0045FFEC 8D4C2424 lea ecx, dword ptr [esp+24]
* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:0045FFF0 E8F5141C00 Call 006214EA
* Possible Reference to Menu: MenuID_0080
|
* Possible Reference to String Resource ID=00128: "AGMS S"
|
:0045FFF5 6880000000 push 00000080
:0045FFFA 8D4C2428 lea ecx, dword ptr [esp+28]
:0045FFFE C68424FC01000007 mov byte ptr [esp+000001FC], 07
* Reference To: MFC42.Ordinal:1040, Ord:1040h
|
:00460006 E819171C00 Call 00621724
:0046000B 8B4C2424 mov ecx, dword ptr [esp+24]
:0046000F 6888130000 push 00001388
:00460014 56 push esi
:00460015 51 push ecx
:00460016 E8F54E1A00 call 00604F10
:0046001B 83C40C add esp, 0000000C
:0046001E 8D4C2424 lea ecx, dword ptr [esp+24]
:00460022 889C24F8010000 mov byte ptr [esp+000001F8], bl
* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:00460029 E8AA141C00 Call 006214D8
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0045FFCC(C), :0045FFE3(C), :0045FFEA(C)
|
:0046002E 8D4C2420 lea ecx, dword ptr [esp+20] =>&4,来到这里,继续按F10往下
走
:00460032 C68424F801000005 mov byte ptr [esp+000001F8], 05
* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0046003A E899141C00 Call 006214D8 =>干么的?不知道,没进去看。懒得管它
:0046003F 8D4C2410 lea ecx, dword ptr [esp+10]
:00460043 C68424F801000002 mov byte ptr [esp+000001F8], 02
* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0046004B E888141C00 Call 006214D8
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004600CD(C), :004600EF(C)
|
:00460050 E8CB401A00 call 00604120 =>读狗关键CALL,如果EAX返回为1就正确
:00460055 83F801 cmp eax, 00000001 =>如果你看完这篇文章,通过最后的修改后
,就知道上面的CALL返回的EAX=0。
:00460058 6A00 push 00000000
:0046005A 0F849D000000 je 004600FD =>&5,这里很关键。强行跳就可以了
* Reference To: MSVCRT.exit, Ord:0249h
|
:00460060 FF1578796300 Call dword ptr [00637978]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045FFC3(C)
|
* Possible Reference to String Resource ID=11203: "P蚯"
|
:00460066 68C32B0000 push 00002BC3
:0046006B 8D4C2424 lea ecx, dword ptr [esp+24]
好了,到这里,程序就完全可以正确运行进入主界面了。其实再跟一下,发现下面的&6的CALL就是进入主界
面的关键。
我们不管它,继续测试一下程序,发现点‘菜单-文件-新建’后程序没有任何提示就自动退出了。
:006221B7 6A0A push 0000000A
:006221B9 58 pop eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:006221AA(U)
|
:006221BA 50 push eax
:006221BB 56 push esi
:006221BC 53 push ebx
:006221BD 53 push ebx
* Reference To: KERNEL32.GetModuleHandleA, Ord:0126h
|
:006221BE FF1598716300 Call dword ptr [00637198]
:006221C4 50 push eax
:006221C5 E8D6010000 call 006223A0 =>&6。到这里跳出主界面
:006221CA 894598 mov dword ptr [ebp-68], eax
:006221CD 50 push eax
* Reference To: MSVCRT.exit, Ord:0249h =>到这里程序就自动退出了
|
:006221CE FF1578796300 Call dword ptr [00637978]
:006221D4 8B45EC mov eax, dword ptr [ebp-14]
:006221D7 8B08 mov ecx, dword ptr [eax]
:006221D9 8B09 mov ecx, dword ptr [ecx]
:006221DB 894D88 mov dword ptr [ebp-78], ecx
:006221DE 50 push eax
:006221DF 51 push ecx
* Reference To: MSVCRT._XcptFilter, Ord:0048h
|
:006221E0 E82D000000 Call 00622212
:006221E5 59 pop ecx
:006221E6 59 pop ecx
:006221E7 C3 ret
-----------------------------------------------
----
破解新建功能
我们下bpx createfilea后,来到下面
从下面我们可以看到有三处 a,b,c都是je 0044B7D9. 我们随便到达一个,比如b处(这里偷了一下懒,因为
要
到A处,必须在@处强行跳一次)
来到b处后,我们用r fl z把标志z置为1,使得可以强行跳转。然后X退出,嘿嘿,我们的程序没有退出,说
明我们
这点改的正确。可是很遗憾,按照常理点‘新建’后一般都会弹出新建对话框的,可是我们这没有,难道这
个程序比
较特殊,本就不会弹出?我们接着往下看
:0044B750 81EC94000000 sub esp, 00000094
:0044B756 56 push esi
:0044B757 8BF1 mov esi, ecx
:0044B759 57 push edi
:0044B75A 83BEC400000001 cmp dword ptr [esi+000000C4], 00000001
:0044B761 740E je 0044B771 =>@
:0044B763 6A02 push 00000002
:0044B765 E836891B00 call 006040A0
:0044B76A 83C404 add esp, 00000004
:0044B76D 8BF8 mov edi, eax
:0044B76F EB2B jmp 0044B79C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044B761(C)
|
:0044B771 6A01 push 00000001
:0044B773 E828891B00 call 006040A0
:0044B778 8BF8 mov edi, eax
:0044B77A 83C404 add esp, 00000004
:0044B77D 83FF01 cmp edi, 00000001
:0044B780 7457 je 0044B7D9 =>a
:0044B782 8D442408 lea eax, dword ptr [esp+08]
* Possible Reference to Dialog: DialogID_0094
|
:0044B786 C744240894000000 mov [esp+08], 00000094
:0044B78E 50 push eax
* Reference To: KERNEL32.GetVersionExA, Ord:0175h
|
:0044B78F FF1554716300 Call dword ptr [00637154]
:0044B795 837C241801 cmp dword ptr [esp+18], 00000001
:0044B79A 743D je 0044B7D9 =>b
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044B76F(U)
|
:0044B79C 83FF01 cmp edi, 00000001
:0044B79F 7438 je 0044B7D9 =>b,这里改为EB38
:0044B7A1 6A00 push 00000000
:0044B7A3 8BCE mov ecx, esi
* Reference To: MFC42.Ordinal:1078, Ord:1078h
|
:0044B7A5 E8005E1D00 Call 006215AA
:0044B7AA 8B10 mov edx, dword ptr [eax]
:0044B7AC 8BC8 mov ecx, eax
:0044B7AE FF92C4000000 call dword ptr [edx+000000C4]
:0044B7B4 8B10 mov edx, dword ptr [eax]
:0044B7B6 6A00 push 00000000
:0044B7B8 8BC8 mov ecx, eax
:0044B7BA FF5264 call [edx+64]
:0044B7BD 8BCE mov ecx, esi
:0044B7BF C786E02B000001000000 mov dword ptr [esi+00002BE0], 00000001
:0044B7C9 E8E2CEFFFF call 004486B0
:0044B7CE 5F pop edi
:0044B7CF 33C0 xor eax, eax
:0044B7D1 5E pop esi
:0044B7D2 81C494000000 add esp, 00000094
:0044B7D8 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0044B780(C), :0044B79A(C), :0044B79F(C)
|
:0044B7D9 E842891B00 call 00604120 =>d,程序来到这里。我们进去看看
:0044B7DE 48 dec eax =>e,
:0044B7DF 5F pop edi
:0044B7E0 F7D8 neg eax
:0044B7E2 1BC0 sbb eax, eax
:0044B7E4 5E pop esi
:0044B7E5 40 inc eax
:0044B7E6 81C494000000 add esp, 00000094
:0044B7EC C3 ret
这里就是d处的call了。这个是干什么的,我们分析一下(其实,它就是一个关键CALL,用来读狗返回EAX值
的)
通过上面的破解后,点‘新建’不会退出了,但是不会弹出新建对话框,我们继续往下看
* Referenced by a CALL at Addresses:
|:0044B7D9 , :00460050
|
:00604120 83EC1C sub esp, 0000001C
* Reference To: KERNEL32.GetACP, Ord:00B9h
|
:00604123 FF1500716300 Call dword ptr [00637100] =>这是干什么的?不管它,因为它
的领空在kernel
:00604129 3DA4030000 cmp eax, 000003A4 =>f。到这里,EAX始终等于A408
:0060412E 0F8483000000 je 006041B7 =>g。哈,在这里,一跳就OK。先别高兴,
修改后,再运行,啊,程序根本没有任何反映,连主界面都进不去。
:00604134 8D442400 lea eax, dword ptr [esp]
:00604138 50 push eax
:00604139 E8A24B0000 call 00608CE0
:0060413E 83C404 add esp, 00000004
:00604141 85C0 test eax, eax
:00604143 7406 je 0060414B =>h
:00604145 33C0 xor eax, eax =>i
:00604147 83C41C add esp, 0000001C
:0060414A C3 ret =>j
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00604143(C)
|
:0060414B 8D4C2414 lea ecx, dword ptr [esp+14]
:0060414F 51 push ecx
:00604150 E8CB4C0000 call 00608E20
:00604155 83C404 add esp, 00000004
:00604158 85C0 test eax, eax
:0060415A 7514 jne 00604170
:0060415C 8B542414 mov edx, dword ptr [esp+14]
:00604160 668B4C2418 mov cx, word ptr [esp+18]
:00604165 8954240C mov dword ptr [esp+0C], edx
:00604169 66894C2410 mov word ptr [esp+10], cx
:0060416E EB0C jmp 0060417C
我们到g处后,同样用r fl
z后,可爱的新建对话框终于出来了(呵呵,还是有对话框的,我们的猜测正确),然后我们用UEDIT把0F8483
000000 改
为0F8583000000,重新运行一下程序,哦,我的天,双击后没有任何反映。初步判断,刚修改的是关键跳转
,我们把g修改回来,然后在g下断点,往
下走到h,呵呵,不跳,我们注意一下i,哦,把eax清0,然后到j返回,程序主界面出来了。哦,你明白了
吗?再不明白我就没话说了。
我们再到g强行跳转到je 006041B7去看看
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0060412E(C)
|
:006041B7 B801000000 mov eax, 00000001 =>k。看到了么?跳到这里后,EAX=1,返回
的是1
:006041BC 83C41C add esp, 0000001C
:006041BF C3 ret
k处把EAX置为1,然后返回。我们在回头看d处的那个CALL,发现下面e处有个dec eax。哦,在这里把返回的
EAX减去1了,结果还是0
我们分析一下。程序开始时如果EAX返回为0就正确,到新建的地方,要EAX返回为1,然后再减去1等于0后,
才正确。知道怎么改了吧。
呵呵,现在简单了。
我们把k 改为B800000000,然后再把e改为90。
再运行一下,呵呵,完全正确。
再全面测试一下程序,哈哈,没发现其他问题。看样子我们修改的那个读狗CALL是真的很管用
打完收工,庆祝一下。
(兄弟说:中华来一支吧!)
(不不不,老兄从不吸烟,还是给我杯咖啡吧。)
(转载请注名出处和作者信息)
kingday
2005-1-13
(2005-1-13日记,2005-12-31修改)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)