使用动态调试器分析WinRAR软件【x64dbg】
实验:使用动态调试器分析WinRAR软件 广告弹窗代码
一、实验目的:
了解常用动态调试器及其基本使用
掌握Windows PE程序逆向分析的一般过程
二、实验环境:
操作系统:Windows 10
实验对象:WinRAR 5.40 32位版本
三、实验内容:
1. 实验背景
WinRAR是Windows操作系统环境中经典的压缩和解压缩工具软件,曾经是Windows平台装机必装的软件,然而近几年的简体中文版中植入了广告弹窗代码,每次打开软件会弹出如图 1所示的广告窗口,特别是当电脑是网络离线状态的时候,这个弹窗由于无法加载广告地址上的内容,会造成电脑的卡顿,WinRAR软件的界面无法显示等问题。
简体中文版的WinRAR无论是否输入了注册码都无法取消这个弹窗,而其他语言版本中都不存在这个问题,因此屏蔽这段广告代码将能让这款经典的软件焕然一新,更好的为我们服务。
2. 实验内容
通过前面的恶意代码分析课程的学习,我们知道WinRAR是典型的Windows PE可执行文件。通过使用动态调试工具,对程序进行汇编语言级别的分析,可以查找并分析弹窗广告部分的程序代码。
实验通过使用动态分析工具,如x64dbg,对广告弹窗代码进行动态调试分析,定位并修改PE文件中引起广告弹窗的代码,就可以实现去除弹窗的干扰,达到在没有源代码的条件下对一款软件进行修改的目标。
四、实验步骤:
1. 观察分析目标的程序特征。
WinRAR软件广告弹窗行为特征分析,发现其弹出的广告框是一个非模态对话框,这个关键信息可以进行一个大胆的猜测,那就是广告弹窗的窗体是采用了CreateWindowsEx这类窗口新建API函数实现的。
模态窗口(modal window)是一种当弹出后,用户必须先与该窗口交互,直到关闭后才能返回到父窗口的窗口类型。在模态窗口打开的情况下,用户无法对同一应用程序的其他窗口进行操作。这种窗口通常用于执行必须完成的任务,如保存文件、确认删除等操作。
非模态窗口(modeless window),与模态窗口相反,当它弹出后,用户仍然可以自由地与应用程序的其他窗口进行交互。非模态窗口不会阻止用户访问应用程序的其他部分,常用于提供信息和功能,但不需要用户立即作出反应的场景,如工具箱、实时状态更新等。
大家可以先运行一下Winrar实验程序,亲自体验一下这个广告窗口非模态窗口特点。
2. 使用Spy++查看相关特征参数。
使用Spy++软件查找窗口功能,查看需要分析的广告弹出窗口如图 2所示。请大家注意窗口的一些属性,特别关注图中“类”和“样式”这两个属性值,后面调试分析会用到。
提示:Spy++软件启动后,可以使用Ctrl-F快捷键打开查找窗口。将瞄准器光标拖放到需要分析的Windows窗口上就可以得到所需参数信息。
3. 动态调试广告弹窗代码,定位启动代码调用点。
判断弹窗使用的API函数名称,然后使用动态调试器的断点功能,设置API断点进行调试分析是本实验基本思路。通常打开窗口使用的是CreateWindow和CreateWindowEx两种API,每个API函数分别有多字节和Unicode编码2个版本,例如CreateWindowEx函数在实际的程序发布编译后,可以分别使用CreateWindowExA和CreateWindowExW两个版本,所以调试时需要注意调试所用版本情况,如图3所示的实验截图显示当前的是Unicode版本。
实验可以使用x32dbg调试器的“符号”窗口功能,查看WinRAR主模块(图3界面中单击左侧模块列表中winrar.exe)中调用的API函数清单。本质是查看主模块的导入表,如图 3所示表明主模块中使用了CreateWindowExW函数。结合前面步骤中分析得到的结果,广告窗口是非模态窗口,而CreateWindowExW函数正是能够创建非模态窗口的函数,因此大胆推测广告窗口的构建代码和此函数关系密切。因此可以考虑使用API函数断点调试的方式查找广告窗口启动代码位置。
注意:x64dbg是开源的PE文件动态调试工具,能够动态分析Windows下32位和64位PE程序。这类实验样本是32位程序,所以使用x64dbg套件中对应的x32dbg程序分析。
4. 添加API断点调试,查找广告弹窗代码。
4.1 添加API断点
使用x32dbg添加API断点可以使用以下2种方式,可以选择其中任意一种方式:
(1)在符号窗口中右键单击查找到的API,如图 3界面中在CreateWindowExW单击右键,在菜单中选择“切换断点”或者使用F2快捷键添加API断点。
(2)在x32dbg界面底部的命令窗口输入命令添加断点。
添加断点可以使用SetBPX, bp和bpx三个命令,这里以bpx为例介绍基本用法。
1 |
|
参数:
Address/API:断点的地址或者API名称
bpName:可选参数,用于标记断点名称
bpType:可选参数,标记断点类型,可使用ss,long和ud2三种取值。
例如实验中可以使用命令bpx CreateWindowExW
添加断点。
提示:断点添加成功后可以在x32dbg的“断点视图”页面中查看是否正确设置了断点。
4.2 断点调试
添加断点后,使用F9执行代码,当遇到断点触发,调试器会停在断点代码位置。本实验中,加载的断点函数CreateWindowExW是比较常见的Windows API,除了目标代码调用外,还会有很多地方调用,这就需要不断使用F9执行调试,每次触发到断点的代码时候,需要检查是否是查找的广告窗口。
广告窗口具有的特征由Spy++软件获得,包括窗口类名称,窗口样式和窗口句柄等数值。当断点触发的时候,将以上窗口的参数数值和x32dbg寄存器中看到的数值进行对比,x32dbg工具提供了一个单独的窗口显示当前函数调用的参数,如图 4中红色线框区域,如果内部的值和Spy++截获的广告窗口参数一致,就可以确定广告代码了窗口调用。
此时蓝色线框区域显示的就是CreateWindowExW函数执行的汇编代码,在此函数中找到RET指令,双击就能显示调用此函数的代码,即这里需要查找的新建广告窗口的代码位置,如图 5所示中第3行代码。
这里请同学们思考,以上是通过多次执行F9,利用断点使程序停止后,人工检查断点是否是我们需要查找的位置,有没有办法让调试器自动查找这个位置?这个问题也是实验最后的思考题,请大家结合条件断点设置分析(提示:条件断点)。
5. 修改并制作补丁
通过前面的分析,可以找到广告窗口的启动代码。本实验的初衷是去除这个令人厌烦的广告窗口的出现,最彻底的方式就是将这部分的代码完全清除。但现实工作中,在汇编级别对代码进行修改是复杂的,也很难完全在编译好的二进制文件中进行这种操作,因此通常的做法是使用JMP
指令绕开不需要执行的代码,或者使用NOP
空指令替换不需要执行的指令。
查阅资料对CreateWindowExW函数进行了分析可知,其调用需要使用12个参数,从反汇编代码中反映就是在CreateWindowExW函数调用前的12个PUSH语句,用于传输并设置这12个参数。因此从传递参数的PUSH指令到Call CreateWindowExW指令,屏蔽这中间的13条语句就能禁止广告窗口代码的执行。(这就是说修改指令执行,不去Create广告窗口,自然就没有广告弹窗出现了。)
具体方法可以在第一条PUSH命令修改为JMP指令,使得代码运行到这类的时候会跳转到第13条指令后面的一条指令的地址,这样就能绕过广告窗口的执行。修改方法可以通过单击空格键,在弹出汇编窗口中输入修改后的汇编指令代码(JMP指令后面跟上的是Call CreateWindowExW函数后面一条指令的地址),如图 6所示。
注意:汇编代码必须选择正确的编码引擎后,右下脚显示绿色“指令编码成功”字样才有效。
6. 制作补丁,持久化保存PE可执行文件
通过以上的汇编指令修改只更改了PE文件加载到内存中的机器指令,并没有修改可执行PE文件。如果需要在修改PE文件,需要使用二进制文件编辑器修改,如HxD等软件编辑。HxD等文件编辑器打开PE文件后,采用的是文件偏移地址,和调试器中使用的虚拟地址不同,需要将以上调试的内存地址映射到文件偏移地址。
地址转换公式:文件偏移地址=RVA+PointerToRawData-VirtualAddress
以上公式中,RVA是相对虚拟地址,即指令在内存中的地址减去PE文件加载到内存中的起始地址(通常是PE头部中ImageBase字段值,但如果冲突可能会加载到其他位置!)。PointerToRawData和VirtualAddress分别是PE文件的节表(如图 7)中的两列数据,分别表示具体某一个“节”分别在文件和内存中的相对位置,因此在使用以上公式前,应确认需要计算的地址在哪个节中。另外需要注意的是以上节表中数据都是相对数据,即相对文件加载到内存或文件头的位置,其中VirtualAddress一列数据起始也是相对地址RVA,而不是通常内存分析中提到的虚拟地址。
x32dbg工具在汇编窗口中,对需要查看的指令单击右键,在弹出的右键菜单中,可以方便的获得虚拟地址,RVA,文件偏移地址等信息,给实际工作提高了效率,但本实验中,请同学们使用以上的信息和公式计算并验证文件偏移地址和内存虚拟地址之间的转换。
以上是在使用HxD这类底层二进制文件编辑工具的修改方法,不过由于其操作繁琐效率低下,本次实验使用x64dbg套件中的补丁功能一键完成。
x64dbg工具提供了补丁功能,单击工具栏中的补丁按钮就能弹出图 8所示的补丁保存窗口,单击“修补文件”按钮就能方便将修改过的内存中的文件镜像保存到PE文件中。实验中可以保存在Winrar.exe相同的文件夹中,并使用Winrar1.exe。
五、测试:
双击执行Winrar1.exe,可以发现程序正常启动已经不会出现广告窗口了,达到修改目标。如果出现程序报错等意外情况,说明前面的操作中有误,可以尝试重新做一次。
六、实验结果:
- 广告窗口新建指令地址,即CreateWindowEx指令地址:( )。
- .text节VirtualAddress地址:( )。
- 如果实验中使用HxD等二进制文件编辑器修改,需要打开文件后在文件偏移位置为( )的地方,修改数据为( )。
七、思考题:
- 是否可以使用条件断点,通过限制断点触发条件,更高效率的捕获到需要的代码位置?提示,请参考附处理器与函数参数调用关系。
- 如果不使用JMP指令,使用NOP空指令填充方式修改应该如何操作。
- 如果不是用x64dbg工具中的补丁功能,如何直接EXE修改文件,如使用HxD修改。
- 使用x64dbg,修改https://www.winrar.com.cn/ 上最新版本的Winrar软件(64位)。
附:CreateWindowExW函数参考
1
2
3
4
5
6
7
8
9
10
11
12
13
14
>HWND CreateWindowExW(
DWORD dwExStyle,
LPCWSTR lpClassName, //窗口类名称
LPCWSTR lpWindowName, //窗口名称
DWORD dwStyle, //窗口样式
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
>);完整参考:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw