WinRAR x64 v5.5中文版去广告过程

时间:2022-09-02 00:39:10

之前用的别人破解的WinRAR,最近更新到5.5后,居然弹出了广告,并且是在有注册文件的情况下。这一点就说明其简体中文的代理很黑,即便对于注册用户也想弹出广告赚取流量费。最近都在苦逼的搞开发,好久没玩过了,就拿它开开刀。

一、获取广告窗口类名

Visual Studio自带了一个名为spy++的窗口信息查看工具,搜索spyxx即可找到。这里要注意使用x64版本的,其文件名为spyxx_amd64.exe。打开该软件并开启WinRAR,广告窗口即刻蹦了出来:
WinRAR x64 v5.5中文版去广告过程
按Ctrl+F后将查找工具的小图标拖到广告窗口上,可以看出,其注册的窗口类为”RarReminder”。

二、x64dbg追踪

由于这次调试的是x64版本的WinRAR,神器OllyDBG无法派上用场,好在有一个名为x64dbg的新晋调试器基本能够代替其功能。这次就用它来调试吧:
用x64dbg载入程序,默认断在了ntdll领空,F9跑起来后断在了程序OEP处:
WinRAR x64 v5.5中文版去广告过程
直接右键——在当前模块查找字符串,输入“RarReminder”,共两处命中:
WinRAR x64 v5.5中文版去广告过程
第一处是注册该广告窗口类:
WinRAR x64 v5.5中文版去广告过程
第二处是创建该广告窗口:
WinRAR x64 v5.5中文版去广告过程

2-1. 废掉广告窗口类注册动作

先在IDA中看看,第一处所在的函数应该是在集中注册窗口类,只要有一个注册失败整个程序就退出运行了。

.text:00000001400D8951                 lea     rax, sub_14009EE78
.text:00000001400D8958 mov [rsp+28h+WndClass.lpfnWndProc], rax
.text:00000001400D895D movdqa xmm0, cs:xmmword_1401197B0
.text:00000001400D8965 movdqa xmmword ptr [rsp+28h+WndClass.hbrBackground], xmm0
.text:00000001400D896E lea rax, aRarreminder ; "RarReminder"
.text:00000001400D8975 mov [rsp+28h+WndClass.lpszClassName], rax
.text:00000001400D897D lea rcx, [rsp+28h+WndClass] ; lpWndClass
.text:00000001400D8982 call cs:RegisterClassW
.text:00000001400D8988 test ax, ax
.text:00000001400D898B jz loc_1400D9107
.text:00000001400D8991 lea rax, sub_1400DC40C

针对此处,将对.text:00000001400D8982的call给nop掉,但要注意堆栈平衡,并且把判断返回值和跳向自杀的语句给nop掉,以防程序一言不合就退出。当然,这里还有一个trick,直接把call指令换成pop rax,既避免了注册广告窗口类,又避免了rax返回空而导致程序自杀。

异常退出

然而真这么做,马上就会发现问题——F9再次跑起来,很快抛出异常并终止进程了。由于我们改的指令只是动了堆栈,隐约感觉是堆栈平衡被破坏了。
仔细观察,调用RegisterClassW的call指令前并没有压栈动作,这一点和我们熟悉的Win32下的API调用有极大不同,取而代之的是对rcx寄存器进行了赋值,而其取得的恰恰就是WndClass的地址!
这里,已经有足够的理由猜测Win64下系统API调用的约定已经换成了__fastcall,不再是Win32时代下我们熟悉的那个__stdcall。下面实证一下:
WinRAR x64 v5.5中文版去广告过程
WinRAR x64 v5.5中文版去广告过程
可以看出,call执行前后RSP的值并没有发生任何变化。

解决方案

这里最终采用的操作是将call、test和je三条指令都nop掉,nop掉后,测试无误。

2-2. 干掉广告窗口显示动作

继续执行,程序断在了创建窗口的API处:
WinRAR x64 v5.5中文版去广告过程
向上翻一翻,直接就发现了广告地址。嗨呀,好气啊!

x64dbg和IDA的地址对不上?!

问题出在我对IDA中ImageBase的理解上:
我一直认为在IDA中拉到最上面就是基地址,这样算起来就是0x140001000,然而,仔细看IDA的描述:

.text:0000000140001000 ;
.text:0000000140001000 ; +-------------------------------------------------------------------------+
.text:0000000140001000 ; | This file has been generated by The Interactive Disassembler (IDA) |
.text:0000000140001000 ; | Copyright (c) 2015 Hex-Rays, <support@hex-rays.com> |
.text:0000000140001000 ; +-------------------------------------------------------------------------+
.text:0000000140001000 ;
.text:0000000140001000 ; Input MD5 : 23A325892A72F1830339E2AC4FD682B2
.text:0000000140001000 ; Input CRC32 : B1D47F33
.text:0000000140001000
.text:0000000140001000 ; File Name : C:\Users\xxx\Desktop\WinRAR\WinRAR.exe
.text:0000000140001000 ; Format : Portable executable for AMD64 (PE)
.text:0000000140001000 ; Imagebase : 140000000
.text:0000000140001000 ; Section 1. (virtual address 00001000)
.text:0000000140001000 ; Virtual size : 00107D71 (1080689.)
.text:0000000140001000 ; Section size in file : 00107E00 (1080832.)
.text:0000000140001000 ; Offset to raw data for section: 00000400
.text:0000000140001000 ; Flags 60000020: Text Executable Readable
.text:0000000140001000 ; Alignment : default
.text:0000000140001000 ; PDB File Name : D:\Projects\WinRAR\build\winrar64\Release\WinRAR.pdb
.text:0000000140001000
.text:0000000140001000 include uni.inc ; see unicode subdir of ida for info on unicode
.text:0000000140001000
.text:0000000140001000 .686p
.text:0000000140001000 .mmx
.text:0000000140001000 .model flat
.text:0000000140001000
.text:0000000140001000 ; ===========================================================================

真正的地址是Imagebase中的值,为0x140000000,这样就能对应上了。在x64dbg中,直接在指令上右击,选择复制,是能看到RVA的。IDA中的RVA地址我是通过当前地址-基地址手工计算得到的。这样换算显得十分不方便,之前在Win32时代倒是可以通过清除PE头部的两处标记让加载器不执行重定位操作,Win64下有没有类似操作呢?以后再探究吧。

干掉广告函数

既然发现整个函数都和广告有说不清道不明的关系,并且IDA中的交叉引用还不止一处,那就直接把整个函数干掉把,干脆在函数头用ret大法!
WinRAR x64 v5.5中文版去广告过程

三、保存修改后的镜像

在x64dbg中,没有找到之前OD的复制–所有更改选项,经过多方查找,终于知道是在右键菜单的“补丁”中。选择修补文件即可导出修改后的可执行文件。
WinRAR x64 v5.5中文版去广告过程

运行修改后的文件,再没有广告框弹出了。