吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4116|回复: 2
收起左侧

[会员申请] 申请会员ID:longs75【申请通过】

[复制链接]
吾爱游客  发表于 2020-1-13 16:25
1、申 请 I D:longs75
2、个人邮箱:longs75@126.com
3、原创技术文章:NOD32view 9.00版 破解过程

一、NOD32view 软件介绍
NOD32view 是一款俄国人编写的将ESET NOD32杀毒软件病毒库下载到本地电脑的辅助工具。利用下载的病毒库,可以在局域网建立一个病毒库升级服务器,网内所有安装ESET杀毒软件的电脑都可以连接到升级服务器免费升级病毒库。2020年以后,NOD32view 开始出现提示升级对话框,强制要求升级,无法进入升级画面。NOD32view 官网提示,NOD32view 更新到9.00版后停止更新,因此只能通过破解,恢复NOD32view 9.00正常使用。
运行软件,正常界面如下图:


2020年后,运行软件弹出窗口提示升级,然后退出,无法进入正常界面,如下图:


二、破解过程
首先用查壳工具PEiD检查一下,发现软件被加了壳:
UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo
用“UPX静态脱壳机 0.3”脱壳成功,开始进行破解。
根据一般思路,首先想到的就是找到弹出这个窗口的代码位置,这段代码前面应该有个获取系统时间并判断的代码段,修改代码跳过窗口,就应该能进入正常界面。于是用OD对软件进行跟踪,一路F8、F7下来,很快找到了弹出这个窗口的代码:
0041BEAA   > \B9 08000000       mov     ecx, 8
0041BEAA   > \B9 08000000                mov     ecx, 8
0041BEAF   .  8D7C24 1C                  lea     edi, dword ptr [esp+1C]
0041BEB3   .  8D7424 50                  lea     esi, dword ptr [esp+50]
0041BEB7   .  33C0                       xor     eax, eax
0041BEB9   .  F3:A6                      repe    cmps byte ptr es:[edi], byte ptr [esi]
0041BEBB   .  74 04                      je      short 0041BEC1
0041BEBD   .  1BC0                       sbb     eax, eax
0041BEBF   .  1BC5                       sbb     eax, ebp
0041BEC1   >  3BC3                       cmp     eax, ebx
0041BEC3   .  0F8E FF000000              jle     0041BFC8  /*跳转至正确界面
0041BEC9   .  53                         push    ebx   /*没有跳转就弹出升级窗口
0041BECA   .  8D4C24 64                  lea     ecx, dword ptr [esp+64]
0041BECE   .  E8 7DD1FEFF                call    00409050
0041BED3   .  8D4C24 60                  lea     ecx, dword ptr [esp+60]
0041BED7   .  C78424 28020000 01000000   mov     dword ptr [esp+228], 1
0041BEE2   .  899C24 D4000000            mov     dword ptr [esp+D4], ebx
0041BEE9   .  E8 69660400               call    00462557  /*这个CALL弹出提示升级窗口

再往前看一下,有一个GetLocalTime的API调用:
0041BDD5   . FF15 70D34>call    dword ptr [<&KERNEL32.GetLocalTime>]   ; \GetLocalTime
很明显,调用系统时间后,进行了比较,超过了时间(2020年),强制升级。
马上动手修改代码,在CMP指令前让EAX=EBX,让程序强行跳转到正确方向:
原代码:0041BEBF   .  1BC5          sbb     eax, ebp
修改为:0041BEBF   .  8BC3          mov     eax, ebx
本次修改命名为:Crack1。运行Crack1之后的软件,果然跳过了升级窗口,但是出现了意外情况,如下图:


经过OD跟踪,发现在后续代码中出现非法寻址方式,也就是出现了非法指令,导致软件崩溃。尝试修复了几处非法指令,但直到进入一个子程序,有多个入口调用它,再也无法修复,Crack1失败。
Crack1虽然失败了,但有一个奇怪现象:我印象中Crack1之后好象成功进入了界面,而且一切操作正常!但再运行时,无论如何也无法正常工作了。不管怎么说,破解出现不稳定情况也是失败。
Crack1虽然失败了,但这是个很好的基础,因为它已经跳过了升级窗口,下一步只要找到出现非法指令的原因就可以了。同时还发现,Crack1虽然失败了,但将系统时间调回2019年后,Crack1可以正常运行,也就是说,可以反复比较不同系统时间下Crack1的运行状态,找到发生问题的那段代码。为了快速切换系统时间,我用VB编写了一个自动切换系统时间的小程序,如下图:


反复调整系统时间运行Crack1,发现一个重要线索:时间调到2020年运行时,就会崩溃,然而在2019年运行Crack1时,第1次也是崩溃,退出后重新运行,再往后就正常了。后来进一步发现,在2020年运行Crack1崩溃后,马上改在2019年运行NOD32view原程序,第1次运行时居然也会崩溃!!!
NOD32view原程序怎么会出错呢?马上想到:一定是软件在电脑的某个地方设置了时间标记。每次运行软件都会设置这个标记,在2020年运行Crack1时,软件在电脑中标记了一个错误时间值(只有Crack1后才会运行到这段代码,设置错误时间值),回到2019年,因为检测到错误时间标记,即使原版程序也会崩溃。
由于2019年运行原版程序只在第1次崩溃,以后都正常,因此进一步分析:软件一定是先做时间标记,后进行检测,在软件崩溃前已经完成了标记。如果是这样的话,在2019年运行软件时,它一定做了一个正确标记!为了验证这一想法,将系统时间设到2019年正常运行了一次软件后退出,马上切换到2020年运行Crack1,果然,Crack1第1次运行正常,后面再运行就是一直崩溃了。
于是第二个思路就有了:找到做标记的代码段,让它永远做正确标记,问题就解决了。
这个标记一定跟日期有关!!!
这个做标记的代码段,一定是在Crack1修改的那个代码段之后!
我首先想到会不会是在注册表中做手脚,用注册表监控软件监视Crack1运行了几次,没有发现特别的线索。于是决定再用OD跟踪一下,查找这个做标记的代码段。
把系统时间调回2020年,用OD对Crack1进行跟踪,一路F8,只要遇到让软件崩溃的CALL,就用F7跟进去,直到来到这个调用:
00460393  .  FF50 64    call    dword ptr [eax+64]
在正确日期下,这个调用在整个软件运行过程中被调用了12次,每次根据EAX值不同,会转向不同入口,而在此之前的CALL都是只执行一次。Crack1就在它的第一次调用中。
在这个CALL下断点。
由于做标记的代码段一定在Crack1修改的那个代码段之后,在这个CALL之前的调用都不用管它。把日期调到2019年,运行一下Crack1,设置一下正确标记,退出,切换到2020年,在OD中打开Crack1,运行到断点,这个CALL运行0次时退出跟踪。假如做标记的代码段在这个CALL之前,再运行Crack1一定会崩溃的,经再次运行Crack1,没有崩溃,说明还没有执行到。
重复上个操作,运行到断点,让CALL运行1次(按F8)时立即退出跟踪。经再次运行Crack1,软件崩溃了,做标记的代码段就在这个CALL第1次调用中!!!
再次用OD加载Crack1,运行到断点时,按F7跟进去。
观察这段代码,里边有大量的API调用,我们关心的是与时间有关的API,另一个关注的重点是与注册表有关的API。
观察代码发现大量读注册表的API,但我们要找的是写注册表的API:RegSetValueExA
在这段调用中发现了两、三个RegSetValueExA,但观察这几处写注册表的API前后代码,都没有与时间相关的操作,按照上边寻找标记代码段的方法测试了一个,不起作用,排除了。
进一步观察代码,发现三处与时间相关的代码段:

第一段代码在:0041BDA2—0041BDD5之间,经分析,它用于获取系统时间,用于Crack1的判断,不必管它。
后两处代码段分别在:0041CBC8—0041CBt9,0041CE7A—0041CEB5,这两段代码非常相似,其中第三处如下:

这四个与时间相关的API太扎眼了:
第一个:GetFileTime  /* 读文件修改时间
第二个:GetLocalTime  /*读取系统当前时间
第三个:SystemTimeToFileTime /*系统时间格式转换成文件时间格式
第四个:SetFileTime  /* 当前时间写入文件时间。
这段代码把当前系统时间保存为文件时间,也就是说,当软件运行结束后,这个文件的时间被修改成了当前时间,这不是一个很好的时间标记吗?
在这两处代码起点处下断点。第二处代码拦不到,说明程序正常情况下执行不到,到第三处代码中断后,按F8调试,可以发现,执行完SetFileTime这条API函数时,标记就出现了!就是下面这条代码:
0041CEB5 . FF15  E8D24700  call dword ptr [<&KERNEL32.SetFileTime>]  ; \SetFileTime
这是哪个文件呢?在这个API调用前,要设置文件句柄:
0041CE7F . 56   push    esi        ; |hFile = 0000011C (window)
可以看到文件句柄hFile =11C,保存在ESI寄存器中,谁打开的这个文件?往前找,看看是哪条指令让ESI=11C:
0041CD33   .  A1 58764900      mov     eax, dword ptr [497658]
0041CD38   .  50               push    eax
0041CD39   .  C74424 34 010000  mov     dword ptr [esp+34], 1
0041CD41   .  E8 AA4A0200      call     004417F0
0041CD46   .  8BF0             mov     esi, eax
在这个子程序调用之后,EAX=11C,然后让ESI=11C。
很显然,这个子程序打开了一个文件,EAX得到文件句柄,又给了ESI,子程序只有一个参数EAX:
0041CD38   .  50               push    eax
查看EAX的值,它指向一个字符串:“NOD32view.psw”!!!
跟踪到此已经真相大白,NOD32view.psw保存的是ESET杀毒软件在线升级时用到的用户名和密码,如果目录下没有这个文件,软件会自动生成,然后每次运行软件时,都要更新该文件的修改时间,而这个文件的修改时间,正是判断软件是否超期的依据!!
原理搞清楚后,下面就是修改了,修改前要弄清楚两个问题,时间值保存在哪个变量(内存地址)中?合法的时间范围是多少?
第一个问题,保存文件时,时间变量的地址:
0041CEAB . 8D5424 38        lea     edx, dword ptr [esp+38]
0041CEAF . 52         push    edx                     ; /pLastWrite
0041CEB0 . 6A 00        push    0                     ; |pLastAccess = NULL
0041CEB2 . 6A 00        push    0                     ; |pCreationTime = NULL
0041CEB4 . 56       push    esi                        ; |hFile
0041CEB5 . FF15 E8D24700    call    dword ptr [<&KERNEL32.SetFileTime>]   ; \SetFileTime
通过上面代码可以看到,时间变量为EDX,EDX= dword ptr [esp+38] = [0018FB88]
从网上下载了一个更改文件时间的小软件,通过更改NOD32view.psw文件的修改时间为不同的合法值并运行软件,然后打开OD内存查看器,可以看到时间变量保存在: [0018FB88]和[0018FB8C],这是一个64位变量,经测算,文件时间每发生1秒的变化, 低位[0018FB88]的值变化量是989680,所以[0018FB88]能表示的最大时间是FFFFFFFF/989680=1AD,即429秒。这么小的值,我们完全可以忽略这个变量,只关心它的高32位[0018FB8C]的值。
第二个问题,合法时间的范围是多少?
其实我们不需要太精确的时间范围,比如:2018年1月1日—2019年12月1日之间都是合法时间值,通过上述那个改文件时间的小软件,把NOD32view.psw的文件修改时间设置两次并跟踪[0018FB8C]的值,就会得出一个合法的时间范围,在这个范围内任意取一个值就行了,当然我最近比较清闲,最终还是找出它最大的时间范围:
NOD32view.psw 文件的修改时间必须在2015/12/2 7:57:14—2020/1/1 15:20:52之间,程序才能正常运行。[0018FB8C]取值范围在01D12C94—01D5C073之间,即可满足时间要求(不要取两边极限值),这里取值为 01D40000。SystemTimeToFileTime 函数没什么用处了,全部NOP掉,腾出空间放改写的代码:
0041CE9B   .  8D4424 38         lea     eax, dword ptr [esp+38]
0041CE9F   .  C740 04 0000D401  mov    dword ptr [eax+4], 1D40000  /*强制为合法时间
0041CEA6   ?  90                nop  /*上面这个指令让时间永远是合法值,
0041CEA7   ?  90                nop  /*然后在下面API数中写入文件。
0041CEA8   ?  90                nop
0041CEA9   ?  90                nop
0041CEAA   ?  90                nop
0041CEAB . 8D5424 38        lea     edx, dword ptr [esp+38]
0041CEAF . 52         push    edx                     ; /pLastWrite
0041CEB0 . 6A 00        push    0                     ; |pLastAccess = NULL
0041CEB2 . 6A 00        push    0                     ; |pCreationTime = NULL
0041CEB4 . 56       push    esi                        ; |hFile
0041CEB5 . FF15 E8D24700    call    dword ptr [<&KERNEL32.SetFileTime>]   ; \SetFileTime
修改完成,本次修改命名为:Crack2。
为什么是Crack2呢?通过运行Crack2可以发现,当NOD32view.psw的修改时间为非法值时,Crack2还是会崩溃,但在崩溃之前,已经把NOD32view.psw的修改时间改为正确值了,所以只会崩溃1次,以后再运行就会正常。另外,软件中改写用户名密码并保存时(一般一个月或几个月设置一次),也会改写NOD32view.psw的修改时间为非法值,Crack2再运行时还得崩溃1次,然后全部正常。
所以说Crack2破解不完美,但已经能够使用了。
不完美多没面子,显然软件中某处代码,在我们修改dword ptr [esp+3C] = [0018FB8C]之前,把这个值用来干坏事了,这个其实很简单,这个值从读出来到写回去,就那么几行代码,它在这里:
0041CE80 . FF15 ECD24700     call    dword ptr [<&KERNEL32.GetFileTim>; \GetFileTime
0041CE86 . 8B4C24 3C         mov     ecx, dword ptr [esp+3C]  /*ECX=文件修改时间
0041CE8A . 8D5424 50         lea     edx, dword ptr [esp+50]
0041CE8E . 52                push    edx
0041CE8F . 890D 081A4A00     mov     dword ptr [4A1A08], ecx  /*干坏事!!!
0041CE95 . FF15 70D34700     call    dword ptr [<&KERNEL32.GetLocalTi>; \GetLocalTime
从上面可以看到,读取的文件修改时间后,时间变量的高32位值dword ptr [esp+3C]保存在dword ptr [4A1A08]变量中,这个变量的值必须是合法时间值,否则软件会崩溃!
分析到这里,我们不仅搞清楚软件电脑中怎么做时间标记,而且明白程序中如何识别利用这个标记,我们只要把变量dword ptr [4A1A08]赋一个合法值,比如:
C705 081A4A00 0000D401     MOV DWORD PTR [4A1A08],1D40000
NOD32view.psw的修改时间这个标记就完全失效了。到此,软件被完美破解。
总结:
破解NOD32view ,需要修改两处代码:
第一,修改软件判断时间的代码,跳过升级对话框,修改如下:
原代码:0041BEBF   .  1BC5          sbb     eax, ebp
修改为:0041BEBF   .  8BC3          mov     eax, ebx
或者修改0041BEC1>  3BC3   cmp   eax, ebx,改为:cmp  eax,eax 等等,效果相同。
或者直接暴力跳转至正确入口。
第二,修改软件中对DWORD PTR [4A1A08]变量的赋值,让它永远正确,修改如下:
原代码:
::0041CE80::FF15 ECD24700  CALL DWORD PTR [47D2EC]    >>>: KERNEL32.DLL:GetFileTime
::0041CE86::  8B4C24 3C                MOV     ECX, DWORD PTR [ESP+3C]         
::0041CE8A::  8D5424 50                LEA     EDX, DWORD PTR [ESP+50]         
::0041CE8E::  52                       PUSH    EDX                             
::0041CE8F::  890D 081A4A00            MOV     DWORD PTR [4A1A08], ECX         
:::0041CE95::  FF15 70D34700  CALL DWORD PTR [47D370] >>>: KERNEL32.DLL:GetLocalTime
修改为:
::0041CE80::FF15 ECD24700  CALL DWORD PTR [47D2EC]    >>>: KERNEL32.DLL:GetFileTime
::0041CE86::C705 081A4A00 0000D401   MOV DWORD PTR [4A1A08],1D40000
::0041CE90::8D5424 50                LEA EDX,DWORD PTR [ESP+50]
::0041CE94::52                       PUSH EDX
::0041CE95::  FF15 70D34700  CALL DWORD PTR [47D370] >>>: KERNEL32.DLL:GetLocalTime
破解完毕。

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2020-1-14 15:41
I D:longs75
邮箱:longs75@126.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。

ps:过程有些简单,但鉴于原创给予通过,登陆后把文章整理一下发到脱壳破解区吧,最好带上图,另外你修改这么多处倒是可以换个思路,直接把限制时间改成什么2099年啥的,也许可以改很少代码就实现过程,或者在检测代码的起始位置retn得了。
longs75 发表于 2020-1-14 23:07
新人longs75报到!
感谢版主支持,很高兴加入吾爱破解大家庭。对汇编编程和破解纯属业余爱好,能力有限,版主见笑了。

这个软件在两处检测时间,第一处检查系统时间,第二处是检查文件修改时间。这两处互相独立,所以都需要修改。
第一处比较简单,修改判断条件,让程序跳转到正确方向就可以了。
第二处复杂一些,取出时间值后并不判断,而是在后面代码中进行运算,然后导致非法指令。你说的对,如果再研究一下它的算法,直接在算法中修改,我也认为应该可以更简单的。

图片、附件都有,申请ID时一直传不上去,明天整理一下再发。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 13:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表