管家婆的软件做的很好,虽然大企业看不上眼,小公司倒是普遍使用这个个软件。这次用管家婆财贸双全+V6.0(build6.0.0.6001)来做个例子。本文纯属技术交流,转摘请保持完整。
软件采用精灵狗加密。大家都知道精灵狗是没有用来写入代码的存储空间的,加密强度相对较低,用它主要是是经济(RMB30-35)。这个版本比起同类的普及版或辉煌版在加密上稍稍用心了点,打印功能关联到了外壳,照常规脱壳,打印功能就随之一同被脱掉了。对付这种加密,可以参考王景泉的导出EXE文件中的函数的方法,但我这里不采用。软件用的是压缩壳,最经典的,谁都会脱,但我这里不脱。废话到此,我们来看一下具体的方法(算是PEDIY吧):
按照常规,我们OD载入目标程序,按部就班来到原始入口,停住然后分析代码,然后寻找找狗限制软件的地方,由于是商用软件,我这里仅举两个例子。
限制一. 没有狗的情况下结束程序。由于有提示,带壳调试,拦个MessageBoxA立马见效。要修改返回值为零还是强制跳过,大家自己选择,我这里就用强制跳过。
代码:0062cc48h JNZ SHORT 0062CC9E (我们需要跳过,直接jmp吧)
限制二.试用版狗时间限制。同样,快到期限会有提示,MessageBoxA拦下。这里为了区别前面,我就不改跳转了,先看段代码:
...
006302E6 MOV EAX,GraspStd.00630DAC ; ASCII "2006-04-30"
006302EB CALL GraspStd.0040D9A0
006302F0 FSTP QWORD PTR SS:[EBP-E0]
006302F6 WAIT
006302F7 CALL GraspStd.0040C3C0
006302FC FCOMP QWORD PTR SS:[EBP-E0]
00630302 FSTSW AX
00630304 SAHF
00630305 JBE SHORT GraspStd.00630330
00630307 PUSH 10
00630309 MOV ECX,GraspStd.00630DB8
0063030E MOV EDX,GraspStd.00630DC4
00630313 MOV EAX,DWORD PTR DS:[A38A10]
00630318 MOV EAX,DWORD PTR DS:[EAX]
0063031A CALL GraspStd.00459C34
0063031F MOV EAX,DWORD PTR DS:[A38A10]
00630324 MOV EAX,DWORD PTR DS:[EAX]
00630326 CALL GraspStd.00459B90
0063032B JMP GraspStd.006305FC
00630330 MOV EAX,GraspStd.00630DAC ; ASCII "2006-04-30"
...
注释中的ASCII "2006-04-30"是使用版狗的生命上限,超过这个时间试用版狗就不起作用了。那么假如我把这个时间往后改,那试用版狗就可以无期限使用。
好了,目标明确,我们要做的修改是:
(1) 0062cc48 处 JNZ SHORT 0062CC9 改成0062cc48 jmp SHORT 0062CC9
(2) 00630DAC 处 2006-04-30 修改成不过期的年限,比如2010-04-30
最后剩下的就是怎么修改,由于软件部分功能在外壳中,脱壳不是最有效的解法(后续工作一堆),我最早解这个软件是写了个loarder,用调试API,可惜速度令人不满。现在用个简单的方法,把补丁代码从loarder转移到dll中,就是DIY it。写个动态链接库,把补丁代码写进去,比如上面两个地方的补丁可以这样写:
patch proc
mov eax,62cc48h
mov byte ptr[eax],0EBh ;启动时检测狗部分,75改成EB
mov eax,630dach
mov dword ptr [eax],36313932h ;年份,36313932就是2916年
;...
;其他补丁代码
;...
ret
patch endp
用loardPE给目标文件增加引入函数patch,然后在程序将要跳转到原始入口之前我们调用这个函数patch,给个实例大家看看:
原始文件代码:
016C4395 E9 EBFEFFFF JMP GraspStd.016C4285
016C439A B8 10B36000 MOV EAX,GraspStd.0060B310
016C439F 50 PUSH EAX
016C43A0 0385 22040000 ADD EAX,DWORD PTR SS:[EBP+422]
016C43A6 59 POP ECX
016C43A7 0BC9 OR ECX,ECX
016C43A9 8985 A8030000 MOV DWORD PTR SS:[EBP+3A8],EAX
016C43AF 61 POPAD ;再熟悉不过了
016C43B0 75 08 JNZ SHORT GraspStd.016C43BA
016C43B2 B8 01000000 MOV EAX,1
016C43B7 C2 0C00 RETN 0C ;用ret跳到程序原始入口
修改后的代码:
016C4395 ^\E9 EBFEFFFF JMP GraspStd.016C4285
016C439A B8 10B36000 MOV EAX,GraspStd.0060B310
016C439F 50 PUSH EAX
016C43A0 0385 22040000 ADD EAX,DWORD PTR SS:[EBP+422]
016C43A6 59 POP ECX
016C43A7 0BC9 OR ECX,ECX
016C43A9 8985 A8030000 MOV DWORD PTR SS:[EBP+3A8],EAX
016C43AF FF15 16006D01 CALL DWORD PTR DS:[<&graspstd4.patch>] ; patch是新加的函数,<&graspstd4.patch>是地址
016C43B5 61 POPAD
016C43B6 75 02 JNZ SHORT GraspStd.016C43BA
016C43B8 90 NOP
016C43B9 90 NOP
016C43BA 68 00000000 PUSH 0
016C43BF C3 RETN
OD选择修改部分保存到文件,运行,正版了吧?
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)