最适合新手的病毒分析——彩虹猫病毒

article/2025/6/18 16:14:01

本文为看雪论坛精华文章

看雪论坛作者ID:谁的狗哥

‍‍

前言

彩虹猫是一款很有意思的病毒,结构也很简单,适合小白分析练手。这篇分析也是我的一个练习项目,不但展示了分析结果,也重点阐述了分析过程中遇到问题时的解决思路,尽量做到详细、多图、无死角,希望能对同样是新手的读者一点帮助。

样本名称: MEMZ.exe

MD5:19DBEC50735B5F2A72D4199C4E184960

SHA1:6FED7732F7CB6F59743795B2AB154A3676F4C822

实验平台:Windows 7 Ultimate With Service Pack 1

分析工具:PEiD v0.95、StudyPE x64 v1.11、IDA x32 v7.4、Bochs v2.6.9、VMWare WorkStation v15.56、Olly ICE v1.10

一、初步观察和信息收集

拿到样本不要一来就拖进IDA和OllyDbg,在没有任何参考信息的情况下很容易迷失方向,应该先做最基本的观察,为之后的分析提供思路。特别是这次的彩虹猫样本,有很明显的用户能直接观察的特征。让我们先把病毒在虚拟机中运行起来。

双击病毒样本后接连弹出两个警告弹窗,希望用户明白运行病毒的风险。点击确定后,桌面会慢慢出现一些诡异的现象,比如:

  • 自动弹出多个浏览器搜索窗口

  • 鼠标异常晃动

  • 窗口颜色怪异

  • 反复出现系统提示音

  • 出现6个MEMZ进程

自动弹出多个浏览器搜索窗口

鼠标异常晃动

窗口颜色怪异

反复出现系统提示音

出现6个MEMZ进程

这6个名为MEMZ的进程,用户尝试关闭任意一个,或者手动关闭计算机,都会遭至大量弹窗随后蓝屏,接着Windows无法正常启动,只会循环播放一只彩虹猫附带欢快的背景音乐,无论你重启多少次都是如此。运行观察结束后再用一些基本的可执行文件信息查看工具进行勘察。

首先上场的是PEiD,监测到该样本可能使用了ASProtect v1.32进行加壳或加密,可能会给本次分析带来一点小困难。

接着使用StudyPE+查看样本的导入表,发现了很多有意思的函数,这些导入函数能给我们提供大量的信息,我把这些函数大致分为三类:

第一类:很明显能和观察到的现象直接联系:

  • 自动弹出多个浏览器搜索窗口----ShellExecute

  • 鼠标异常晃动----SetCursorPos、GetCursorPos

  • 桌面出现奇怪图标----DrawIcon

  • 窗口颜色怪异----BitBlt、StretchBlt

  • 反复出现系统提示音----PlaySoundA

  • 出现6个MEMZ进程----ShellExecute

自动弹出多个浏览器搜索窗口----ShellExecute

鼠标异常晃动----SetCursorPos、GetCursorPos

桌面出现奇怪图标----DrawIcon

窗口颜色怪异----BitBlt、StretchBlt

反复出现系统提示音----PlaySoundA

出现6个MEMZ进程----ShellExecute

第二类:不能直接关联,但常成对出现完成某些功能:

  • OpenProcessToken、AdjustTokenPrivilege、LookUpPrivilegeValue 给进程提权

  • GetMessage、TranslateMessage、DispatchMessage 建立消息循环

  • CreateToolhelp32Snapshot、Process32First、Process32Next 遍历进程

  • SetWindowHookEx、UnhookWindowHookEx、CallNextHookEx 给窗口下钩子

  • LoadLibrary、GetProcAddress 加载库并导入函数

OpenProcessToken、AdjustTokenPrivilege、LookUpPrivilegeValue 给进程提权

GetMessage、TranslateMessage、DispatchMessage 建立消息循环

CreateToolhelp32Snapshot、Process32First、Process32Next 遍历进程

SetWindowHookEx、UnhookWindowHookEx、CallNextHookEx 给窗口下钩子

LoadLibrary、GetProcAddress 加载库并导入函数

第三类:不确定干了什么事或者我根本不熟悉

  • SendInput、GetSystemMetrics、DefWindowProc……

SendInput、GetSystemMetrics、DefWindowProc……

对于复杂的样本,还可以使用监控类工具看看样本对文件、进程、注册表、网络进行了哪些操作,不过这次样本比较简单,以上信息已经足够指导接下来的分析工作了。

二、入口部分

使用IDA载入样本,定位到入口函数Start并按下F5获得伪代码,该功能极大地提升了样本分析的效率,毕竟看高级语言比看汇编还是快得多。

但是这些伪代码只是IDA根据现有信息猜测出来的,并不能保证100%准确,有的时候甚至会对我们的分析工作产生误导,一会你就能看到。现在让我们继续回到IDA生成的伪代码。

暂时别着急深入细节,先从整体把握走向。在start函数的起始部分调用Get CommandLineW、CommandLineToArgvW获取进程参数,之后整个Start函数就根据进程参数分成了几大块,整理后其结构如下:

注意,这段体现start函数结构的伪代码并不是直接照搬自IDA,而是为了整体逻辑清晰而特意整理修改过的。接下来就要依次分析这三大部分,为了方便表述,这三个部分我称为“watchdog部分”、“/main部分”和“无参数部分” 。

我们第一次双击样本时自然是不带参数的,所以我们先来看start函数的无参数部分。

三、无参数部分

此处先是用MessagexBox依次弹出两个警告信息提示框,这也正是我们运行病毒时所看到的。若两个弹窗都被用户确认,使用GetModuleFileNameW获取当前进程的路径并保存,当然所保存的空间由LocalAlloc提前申请。

接着用do while执行5次循环,每次循环都调用一次ShellExecuteW,参数正是刚才得到的样本进程路径,以及字符串"/watchdog",即以“/watchdog”为参数,生成5个MEMZ.exe进程。

在最后调用了ShellExecuteExW以“/main”为参数生成了一个MEMZ.exe进程,一般带Ex后缀是加强版函数,表示在普通版函数基础上进行了功能的扩展,这里特意用了一个功能更强的函数一定有特别的目的。

该函数接收一个SHELLEXECUTEINFOA结构体,结构体中设定了进程路径和执行参数,跟前面普通版函数传递的参数其实没什么区别。

关键是紧接着调用了SetPriorityClass,当中对hProcess成员复制为0x80,查看MSDN得知该值意味着创建的进程将拥有最高的响应优先级,最后调用ExitProcess使当前进程结束。如果你不会使用MSDN我在文末备注有介绍。

现在我们知道在观察阶段看到的6个MEMZ.exe进程是怎么来的了:最开始双击生成了一个原始进程,原始进程生成了5个watchdog进程和1个/main进程,然后原始进程迅速结束了自己,等我们打开任务管理器查看时,还存在6个MEMZ.exe。

IDA全称是交互式反汇编器(Interactive Disassembler),重点在于“交互式”,我们可以把手动分析后的任何想法和有用的信息都记录在IDA里,比如给IDA自动生成的变量和函数起一个有意义的名字,这些名字会在所有用到该变量或函数的地方生效。完成后应该像下图这样。

在后面的分析中,请大家自行完成注释的添加,为了后面的文章不剧透,我贴出来的图大部分还是未注释的状态。至此无参数部分分析完毕。

四、"watchdog"部分

1. 主体

该部分的主体代码量很少,我一张图就全展示清楚了,但里面的坑可一点都不少。

首先是CreateThread创建一个线程,IDA给自动命名为sub_40114A。在这里给大家提一个醒,以watchdog为参数运行的MEMZ.exe进程是有5个的,也就是说这里看到的创建一个线程是“某个进程“的行为,5个进程一共应该创建了5个线程,在后面的分析中大家也要注意这一点。我们进入sub_40114A看看这个线程干了些什么事。

2. 子函数sub_40114A

同样代码很少一张图概括完。前三个函数用来获取当前进程路径,顺便说一下这种多个函数配合起来做事的情况有很多,常常是最后一个函数完成关键功能,前面几个都是为它提供必要的参数,比如LocalAlloc申请空间用来存路径字符串,GetCurrentProcess获取当前进程句柄,这都是第三个函数要用到的。

接着一个大的while循环把后面的代码都包了进去,注意该while循环的条件永远为真,说明是个死循环。在循环内部使用CreateToolhelp32Snapshot给进程拍快照,再用Process32FirstW和Process32NextW进行遍历,这都是非常常见的操作,我们在观察阶段查看导入表时也发现了这三个函数,这里就用上了。

当然光做进程遍历是没意义的,肯定要干点活。每当遍历到一个进程时都要获取它的路径,并和我们之前获取的路径对比,如果相同就让计数器加1,很明显这就是在看当前有多少个MEMZ.exe的进程。

当遍历完所有进程后,我们就统计出了MEMZ.exe的进程个数。然后最关键的地方来了,由于Sleep函数的存在,死循环每隔一段时间就能统计出当前MEMEZ.exe进程的个数并存放在v4变量中,然后先判断v4和v7的大小,再让v7保存v4的值。

如此就形成了一个监测机制,v7永远只保存v4最大的值,一旦v4的值小于了v7就会被if语句监测到,并进入sub_401021子函数。这不正好和我们观察阶段的发现一致吗?只要MEMZ.exe进程数量减少,系统就会蓝屏重启,这就是它的监测原理。反过来我们可以推测sub_401021就是完成系统蓝屏重启功能的。

3. 子函数sub_401021

前面进展得很顺利,到这里就碰到麻烦了。在这个子函数的开头是一个do while循环,循环次数为20次,用CreateThread创建线程,这没什么特别的,像往常一样我们双击StartAddress准备去看这个线程做了什么事,但是双击过后却没有任何反应,这其实是IDA的代码识别出现错误,相关问题我在第七节“IDA的一些问题”中做详细解释。

在这里为了不影响我们的分析主线,直接键盘按G输入地址4010FE就可以跳到StartAddress的代码。该处的MessageBoxA用于弹出消息,有26条消息保存在lpText所指向的地址中。使用sub_401A55获取随机数保存在v3,v3对0x1A取余以实现在26条消息中随机选取一条并显示。

SetWindowsHookEx和UnhookWindowsHookEx用于给窗口下钩子,干了什么事要到回调函数fn里去看。code==3表明目标窗口即将被创建,此时lParam表示该窗口的基本信息(坐标、大小等),修改这些信息可以在窗口真正创建之前生效,下方正是在随机修改窗口的位置。这些信息都可以在MSDN中查到。

sub_401021的后半部分是两种关机的方式:先主动诱发蓝屏关机,如果不成功则主动退出Windows。

前一种方式使用LoadLibrary加载ntdll库,再连续两次调用GetProcAddress获取两个函数地址,这两个函数是未公开的Windows API,只能用这种方式来隐式调用。随后依次调用这两个函数,主动引发蓝屏。

顺便提一下,很多恶意程序在隐式调用时会对函数名字符串先加密,要用的时候再解密,或者干脆不使用函数名而用函数编号,显然我们分析的样本没有做这种“隐蔽处理”。

后一种方式先用一系列函数给当前进程提权,然后调用ExitWindowsEx主动关闭Windows。为什么要先提权?调用ExitWindowsEx关闭Windows需要相应的权限,详情见MSDN。

总结一下,我们确认了之前的猜想,sub_401021确实是一个强制关机的函数,先创建线程用于弹出大量位置和内容都随机的窗口,再使用蓝屏或退出Windows的方式强制关闭计算机。

4. 注册并创建窗口

我们依次分析了函数开头->sub_40114A->sub_401021,已经陷入了太多细节,是时候回到watchdog的主体部分。这张图之前出现过,为了大家方便看我再次贴出来。在创建sub_40114A后,调用RegisterClassExA注册了一个名为“hax”的用户自定义窗口类型,并用CreateWindowExA将其创建。

此处有个小问题,传递给RegisterClassExA函数的结构体变量pExecInfo定义为了SHELLEXECUTEINFOW类型,而不是该函数所需要的WNDCLASSEXA类型,这是IDA的识别出现了错误,为了不干扰主线分析,其讲解安排在了第七节”IDA的一些问题“。

5. 回调函数sub_401000

创建的窗口有一个回调函数sub_401000。经查询MSDN,常量值16和22分别对应窗口消息WM_CLOSE和WM_ENDSESSION,那么整体含义就很明了了:该窗口回调函数会对窗口消息进行过滤,若消息为WM_CLOSE或者WM_ENDSESSION,则调用sub_401021强制关机(这个函数前面刚分析过)。而WM_CLOSE或WM_ENDSESSION消息是在系统关机时,由操作系统发送给各个窗口。

若是其他消息,则并不做任何处理,丢给系统默认处理函数DefWindowProcW。

如此一来,sub_401021这个强制关机函数在两处被调用。第一个是监测watchdog进程数量,如有减少就调用。第二个是监测用户是否主动关机,如有也调用。这和我们观察阶段看到的完全一致。

6. 消息循环

紧接着的代码 GetMessage、TranslateMessage、DispatchMessage被包进一个大的while循环,这是常见的操作,叫做“消息循环”。

由于在前面创建了窗口,并且还对发送给窗口的消息进行了过滤,意味着我们必须自己写消息循环完成收取消息和派发消息的工作,否则创建的窗口是收不到消息的。Windows并不会自动帮我们完成消息循环,这在MSDN里有明确解释,给出两条参考链接:

一篇关于消息循环的博客:

https://www.cnblogs.com/zxjay/archive/2009/06/27/1512372.html

MSDN中关于创建消息循环的官方回答:

https://docs.microsoft.com/en-us/windows/win32/winmsg/using-messages-and-message-queues

五、"/main"部分

1. 主体

由于开头部分代码和MBR有极强的联系,我索性把它划到MBR章节了,到时候再一块说。让我们把窗口往下拉一拉,这里有一个do while 循环,/main部分的分析就从这儿开始。

此处的do while循环以v8为计数器,内部用CreateThread创建线程,循环跑10次(v8 < 0xA),一共创建10个线程。这不由地让人好奇,创建这么多线程是要做什么?先别慌跳进去看,它还附带一个参数v9,并被赋予初始值off_405130,每次循环自增2。以off开头表明是某个静态地址,我们双击过去看看。

off_405130地址所指向的是一块数据区,并且这里的数据还有非常强的规律性。每组都由1个dd类型的数据加4个db类型的数据组成,一共有10组,由于篇幅原因我只截取了部分组,为了方便大家观察,组与组之间我用了两种颜色隔开。

类似dd、db这样的符号在IDA里很常见,它们表示该地址所对应的数据大小,详细解释如下:

1字 = 2字节

再回过头来看看前面的do while,v9被赋值为off_405130并作为参数传入。Sleep函数里也用到了v9,它将v9看作了数组首地址,并每次取数组的第1项(数组项数从0开始)。

每次循环v9都会自增2,由于v9的数据类型是DWORD *,每次自增2就是自增两个DWORD*的大小,即8个字节。那么随着循环的进行,v9和v9[1]的值将会按如下所述变化:

v9的值指向的都是不同的静态地址,如果你挨个双击跳过去看,会发现它们其实都是函数地址。而v9[1]是Sleep函数的参数,所指向的肯定是时间量(毫秒)。

v9是4个字节的DWORD * 类型,那它指向的当然就是4字节的DWORD类型,所以这些时间量都是4字节的DWORD类型。我们在IDA中右键单击地址就可以选择其解析长度,我们用4字节来解析它。

把所有时间量都这样操作,并在最后用右键选择数据展示的进制,选择10进制,毕竟我们更习惯用10进制来表示时间量。

所有步骤完成后,IDA应该显示为下图这样:

看到这样的结构,很容易让人想到病毒作者写代码时应该用了结构体数组,结构体的构成如下:

10个这样的结构体在一个数组中:

现在我们明白了,创建了10个进程,并且每次创建都会有延迟时间,这个延迟时间和进程的函数地址是放在一起的,一共有10组,都在一个大数组off_405130里。

2.子函数sub_401A2B

这个子函数的代码很短:用大数组中的函数地址依次创建线程。由于是函数指针,要用它调用函数当然得声明其参数、返回值、调用方式之类的,这都是C语言里很常见的用法。

这10个函数做的事很简单,我以sub_40156D为例。它调用GetCursorPos获取鼠标指针坐标,然后用各种方式修改这个坐标的值,比如这里调用sub_401A55生成随机数并返回,用这些随机数与鼠标指针坐标做运算,最后调用SetCursorPos来设置鼠标指针坐标,用户就会发现鼠标指针随机晃动了。所有这10个函数都干的类似的事,这里不再依次分析。

不过提醒一句,一些含有大量计算的部分,如果不是很重要,没必要完全了解算法细节。比如这个函数sub_00401AA0,它的参数是窗口名的字符串,进行的操作是把这些字符串前后颠来倒去,最后把打乱的字符串返回。

你已经知道它就是为了打乱窗口名字符串,给这个函数起个合适的名字就可以先溜了,不用管它是怎么算的,如果后面有的分析必须要我们完全理解这个算法,再回过头来看也不迟。

当你把大数组里的函数分析完后,最好给他们一个统一的命名,我以MessUp为开头命名了这10个函数。

sub_401A2B大致做了什么我们清楚了,就是依次调用这10个函数。这里还有一个小细节,10个函数每个的返回值部分都有不同,有的是返回一个随机值,有的是返回一个固定值。

返回值被保存在v1,每次循环都会在if语句中判断!v1--是否为真,也即v1自减1后是否为0,控制v1的值就能决定循环的次数,再配合后面的Sleep函数就能决定这10个函数的激活时间。这10个函数中,有的需要一个固定的激活时间,有的需要一个随机的激活时间,只需要控制返回值即v1就可以了。

六、MBR部分

1. 主体

终于到了最后的重头戏了,MBR部分完成了该样本的核心功能。

在继续分析之前,得要清楚什么是MBR。MBR全称主引导记录(Master Boot Record),整个硬盘最开头的512字节就是它。

计算机启动后会先运行MBR里的代码进行各种状态的检查和初始化的工作,然后再把控制权转交给操作系统(简单地讲就是一个JMP指令跳到操作系统的起始代码),Windows就加载启动了。

MEMZ病毒干了一件很可恶的事,它直接把整个MBR覆盖掉了,变成了它自己的代码,那么它想干什么都行了,只要它不主动交出代码执行流程,Windows绝没有启动的机会。

MBR里既有代码也有数据,开头的0-446字节是代码,紧接着就是数据,数据部分记录着硬盘的分区信息,结尾以固定的0x55 0xAA作为结束符,如果你了解过PE文件结构,应该对这种做法不陌生。

对MBR有个初步了解后,我们回头来看代码。现在先回到/main未分析的部分,我们前面提到过,它和MBR有紧密关联。

首先使用CreateFileA以文件形式打开了主硬盘,也即PhysicalDrive0,这样方便后续的覆盖操作。紧接着用LocalAlloc分配一段以0为初始值的内存空间,并拷贝两段神秘数据到分配的内存空间。

这两段数据中第一段byte_402118大小304字节,第二段byte_402248大小1952字节,拷贝时中间跳过了206字节。最后将内存空间的数据覆盖到主硬盘(PhysicalDrive0)的开头部位,原始MBR遭到破坏。

第一段正好就覆盖了MBR的代码区域,所以几乎可以肯定这304字节是代码。第二段数据已经不属于MBR的范围,而且高达1952字节,很可能是用于显示动画的图像数据和音频数据。

一旦将MBR覆盖,侵入也即宣告成功,病毒作者赶紧写了一堆话想要好好炫耀一番,这段话被写入note.txt文件中,并用Windows自带的记事本打开。

2. 安装和配置Bochs

现在新的问题摆在面前,写入硬盘的这些神秘数据我们可以复制出来,然后导入IDA里,但分析起来太困难了,有大量的地址是在运行时确定的,要是能让代码跑起来,能下断点,能单步调试就太棒了。

可惜的是,MBR运行在16位环境直接和硬件打交道,此阶段Windows根本没加载,OllyDbg或者WinDebug这种常用的调试器当然用不了。这时该一个神器登场了--Bochs(发音同“box”)。

Bochs和VMware一样,也是虚拟机,不过它是专门为调试而生的,MBR代码会运行在它虚拟出的硬件中,并允许我们像使用OllyDbg一样下断点、单步调试。

但Bochs的调试器是纯命令行的,使用起来不太方便,而ida提供了Bochs插件,可以调用Bochs并给出图形化的界面,使调试过程更友好。不过该插件对Bochs的版本有要求,比如我用的IDA 7.4要求版本为v2.6.x,具体要求可在IDA帮助文件中搜索Bochs获得:

使用IDA的bochs插件调试MBR代码的具体的操作如下:

1. 用bochs的bximage.exe工具创建硬盘镜像文件,默认名c.img。

2. 用bximage.exe的查看镜像文件信息功能,查询c.img的CHS信息(柱面、磁头、扇区)

3. 用16进制编辑器把要分析的mbr代码和数据拷贝到c.img(推荐使用010editor)

4. 复制一份bochs自带的 bochsrc-sample.txt,搜索ata0-master,将该行的path改为c.img的路径(路径不能含有中文)并添加CHS信息,完成后整行类似于: ata0-master:type=disk, mode=flat, path="C:UsersGhostDesktopc.img",cylinders=20, heads=16, spt=6

5. bochsrc-sample.txt改名为.bxrc,并双击该配置文件,bochs会加载这个配置文件运行c.img,如果能成功说明bochs直接运行是可以的,下一步可以由ida来调用bochs

点击调试后IDA就会展现调试界面,这个界面和OllyDbg几乎是一样的,有数据窗口、代码窗口、栈窗口、寄存器窗口等等。调试默认情况下没有断点,病毒程序的MBR代码会直接运行,打开Bochs窗口可以看到运行时生成的猫咪动画。

当然我们希望病毒加载好后就在第一行代码处暂停,给我们操作的机会。点击IDA顶部菜单Debugger-Debugger Options,在弹出的窗口中勾选Suspend on Process entry point即可实现。

一切准备就绪就可以进行MBR代码的分析了。

3. 分析MBR代码

MBR代码是16位汇编,需要对中断、寄存器、内存分段机制有所了解。无奈这篇帖子已经写得太长了,写完MBR部分会超过字数限制且阅读体验也会很差。

我把代码的结构图和一些特殊地址的功能放在这里,有需要的小伙伴可以用作参考。如果你觉得这部分分析困难很大,推荐看一本《x86汇编语言 :从实模式到保护模式》,看完再回过头来分析就如鱼得水了。

如果已经完全透地分析完,还可以根据自己的需要对MEMZ进行“定制”:

  • 还原出加密算法后,修改画面数据和音频数据,达到显示全新动画的效果(Bad Apple 可以一战!)

  • 对病毒进行升级,使其不仅能感染老式的MBR格式,甚至可以感染新的GPT格式(比如Windows 10)

  • 写一个修复工具,完成对病毒感染后的修复

还原出加密算法后,修改画面数据和音频数据,达到显示全新动画的效果(Bad Apple 可以一战!)

对病毒进行升级,使其不仅能感染老式的MBR格式,甚至可以感染新的GPT格式(比如Windows 10)

写一个修复工具,完成对病毒感染后的修复

如果感兴趣的小伙伴多就再开一篇帖子讲讲一些有意思的玩法。

B800开始为显存地址

七、IDA的一些问题

1. 栈不平衡问题

在分析sub_401021时,StartAddress双击并不能成功跳转。如果你平时有看输出窗口的习惯(你确实应该有这个习惯)就会看到一条报错信息,在汇编窗口也能看到类似的红色报错信息。

它们所提供的信息并不太多,都是很简短的几个字,但是包含有ebp和sp这两个和栈有直接关系的寄存器,这暗示我们栈可能出了什么问题。

但问题到底是什么呢?猜是猜不出来,IDA自带了帮助文件,按F1打开帮助窗口,输入关键词后就能得到详细的解释。原谅我因为篇幅和时间不可能全部翻译,但大意为造成该问题的原因是“栈不平衡”。

我第一次分析到这儿时,总觉得很费解。如果代码有问题导致栈不平衡,那病毒在运行期间就会报错啊,难道是病毒作者故意手写了栈不平衡的汇编代码,用以达到某种特殊的目的?盯着IDA看了半天也没什么用,索性我决定用OllyDbg全程跟踪sub_401021,看看栈到底发生了什么事。

想要在OlldyDbg里定位到这个函数是很简单的,该函数用到了两个字符串“RtlAdjustPrivilege”和“NtRaiseHardError”,并且没做任何加密处理,在OllyDbg里右键-查找-所有参考字符串,找到我们的目标字符串,直接双击过去即可成功定位。随后往上滚动几行,就是sub_401021的入口,在这行按F2下断点。

别急着按F9开始调试,这时候按F9运行程序断点根本断不下来,程序的执行流程是有条件的,每次都要合适的条件,程序最终才能走向我们想要调试的sub_401021。一个更方便我们测试的方法是在OD中直接修改指令。

在参数的判断阶段,jnz指令控制了参数判断后程序的执行路径,按空格并在弹出的窗口输入nop,勾选“使用NOP填充”,点击汇编按钮后该行原本的6字节指令变为6个nop,nop的意思是CPU不执行任何动作,那么程序执行到此处,就永远不会发生跳转,一定会执行watchdog部分,我们的目的就达到了。

类似的修改不止一处,请大家自己动手修改所有必要的地方,保证程序运行后执行流程可以顺利到达sub_401021,并在我们的断点处断下来。

当然为了避免每次重新调试都要做这些修改,可以将我们的修改另存到一个新的可执行文件,以后直接调试修改后的文件就方便多了。

后面我干的事,就是用OllyDbg加载修改后的文件,不停用F8单步调试sub_401021,眼睛一直盯着栈窗口,想要看看栈到底哪里不平衡了。

让我失望的是,栈始终处于平衡状态,不过我确实发现了一些不同寻常的代码。为了方便展示,我回到IDA里给代码截图。

sub_401021的开头并没有和大多数函数一样开辟栈空间,而是把这个动作留到loc_401050才执行,中间用一个类似nop的指令jmp $ + 5来连接,我把jmp视作桥梁连接了上下两个部分。

【下半部分】使用了标准的函数入口的代码,创建了自己的栈并申请了1ch字节的栈空间。

(显示指令码的方式:IDA顶部菜单- Options-General-Disassembly-Number of opcode bytes,输入你想显示指令的最大长度,比如8)

用OllyDbg的实践证明栈不存在平衡问题,不由得使我怀疑,会不会是代码比较特殊,IDA的分析出错了?既然下半部分是个标准的函数开头,上半部分栈也是平衡的,干脆就把上下两个部分定义为两个函数吧。

在sub_401021中右键 -Edit Function-End address填入希望的函数结束地址,我们填入401050即jmp指令的下一行。IDA就将jmp及其上半部分定义为一个函数,并自动将jmp的下半部分定义为另一个函数。

完成后如下图所示,我用两个颜色区分了这两个函数,此时IDA的栈不平衡红色提示消失了。折腾了这么久原来是IDA的识别出错,看来IDA也并不总是可靠的。

至于编译器为什么生成这样奇怪的指令暂时还不清楚,可能是编译器的代码优化,也有可能这段代码是作者纯手工写的。

2. 结构体识别问题

这里IDA的识别出现了问题。pExecInfo变量的类型是 SHELLEXECUTEINFOW,此处强制转换为WNDCLASSEXA再赋值使用,意义为何?在变量pExecInfo上单击快捷键x弹出交叉引用窗口,这里展示了所有引用了该变量的地方。

两个红框之外的引用是结构体赋值,这个我们并不关心,红框是两个函数调用时对pExecInfo的引用,上方红框是我们此刻看到的 RegisterClassExA,下方红框 SetPriorityClass可以双击过去看看。

双击跳过来一看,似曾相识,甚至有我们自己命名的变量。定睛一看,这不就是我们前面分析“无参数部分”的末尾吗?

这就奇怪了,按MSDN的解释这两个函数使用的结构体类型完全不一样嘛,前一个是WNDCLASSEXA,后一个是SHELLEXECUTEINFOW,那么为什么IDA中两个函数使用了同一个结构体变量?

如果我们查一下MSDN,把这两个结构体的定义并排比较,就能得到答案。这应该是编译器优化的结果,编译器发现二者的结构体定义非常相似,SHELLEXECUTEINFOW是15个4字节类型,WNDCLASSEXA是12个4字节类型。

于是编译器就想,反正你们两个结构体的使用也不冲突,那我就预留一个15*4字节的空间,对于大的那个结构体刚好满足,对于小的那个结构体会多出来3*12字节,但它可以忽略不用啊,把开头的12*4字节看作是WNDCLASSEXA不就行了?

编译器一堆骚操作省了栈内存空间,但IDA看着编译后的结果并不知情。同一片内存空间怎么能给两个结构体用,这让我怎么给这段空间命名?但也不能放着不管啊,于是选了体积更大的结构体 SHELLEXECUTEINFOW来命名,而另一个只能委屈一下了,在函数调用的时候用(WNDCLASSEXA *)作指针的强制转换。

明白了这层道理,我们可以尝试给栈里的这片内存空间换个名字。切换到栈窗口后一定要想想再动手,千万别看到SHELLEXECUTEINFOW就直接右键修改成WNDCLASSEXA,此时你修改的其实是栈中偏移0x64处内存空间的定义,要知道WNDCLASSEXA是比 SHELLEXECUTEINFOW小3*4字节的。

正确的做法是选中偏移0x64的这行,用快捷键U清除当前的结构体定义,在比0x64小3*4字节的地方,即偏移0x58的位置定义结构体WNDCLASSEXA。

修改完定义后顺便把变量重命名为wndclass,这时候再看代码已经可以用WNDCLASSEXA结构体解析了。

八、备注

1. 如何查询Windows API

可能会有初学者对查找Windows API不熟练,甚至使用百度百科。一个更高效准确的方式是使用微软的MSDN,这里有微软对Windows API最权威的解读,但大部分都是英文。如果你有翻译需求可以使用微软自家浏览器Edge,用它翻译微软的技术文档会有非常不错的效果。

下面是一个查询SetPriorityClass函数的例子,在MSDN右上角的搜索框输入后就能得到结果,在函数的介绍页面详细描述了参数、返回值、一些注意事项,甚至还有带高亮的代码示例,相信我没有别的地方比这儿信息更全了。

2. 如何查询中断调用

mbr分析过程中,最让我头疼的是中断和端口号没有一个权威的查询渠道,我只找到了一个可以查询中断的网站ctyme,如果有更好的查询方式记得留言告诉我。

3. 关于附件的说明(ReadMe.txt)

以下说明同样也包含在附件的.txt文件中:

“MEMZ.exe.virus”是病毒本体,加上.virus后缀是为了防止不小心双击运行了文件,若需在虚拟机中运行请删去这个后缀。

“MBR_code.hex”是从样本中提取的MBR部分数据,可用任何16进制编辑器打开。

“MEMZ.idb”是IDA 7.4导出的数据库文件(请注意不同版本可能有兼容问题),里面有贴主分析时写的注释及各种函数变量重命名,数据库文件可以脱离其原始文件单独使用。

病毒感染的目标必须使用MBR格式,更新的GPT格式将不能显示彩虹猫动画,所以测试环境请使用Windows 7 或更旧的操作系统。

样本只作为学习交流使用,请勿用于恶意用途。

解压密码:infected

解压密码:infected

解压密码:infected

看雪ID:谁的狗哥

*本文由看雪论坛 谁的狗哥 原创,转载请注明来自看雪社区。


http://www.hkcw.cn/article/SJmQcKQiVU.shtml

相关文章

19.9元可享逸品天王星ktv全年五折贵宾待遇!到店消费赠贵宾果盘~名额有限,速抢!

时代变迁,KTV也得跟上潮流与时俱进, 这不,逸品天王星的新面貌让你眼前一亮!文中有福利▼ 天王星共50间包房分别为主题:总统包房、VIP包房、和豪华包房 量贩式:大包 中包小包。每间房门打开后都能听见小编的一声“哇”!展开全文超豪华的点歌系统,曲目超多,欢唱随心!总…

高清戏曲下载:京剧高清资源合集目录

资源介绍 光头老蔡自2024年收集的各种戏曲资源,全部都是高清的版本,2024年之前的那种带(清泉)水印的RMVB格式的版本全部被抛弃。 新的超高清戏曲资源除少量用于珍藏的TS格式和MKV格式以外,全部收集的都是MP4格式的视频,便于在各种老年唱戏机上很方便的播放。 大部分视频都…

今日影评|他64岁下潜10000米“搞科研”只为拍电影,68岁的张艺谋也开始突破。

2018年3月9日•周五 电影制作人 文隽 22:27 你知道离地心最近的地方在哪里吗? 太平洋西部的“马里亚纳海沟”深10911米,是人类已知的海洋最深处和地表最浅点,也就是说,站在这里离地心最近。展开全文而迄今为止,世界上只有3个人来到过这里,其中一位,也是世界上单独下潜第…

黎姿和朱茵同框旧照曝光 颜值巅峰时谁更美(组图)

朱茵 黎姿 26日,有网友晒出朱茵黎姿早年一同参加节目时的动图;动图里黎姿和朱茵都披着长发,黎姿身穿一字领针织衫,而朱茵则穿着粉白色毛衣,两个圆形大耳环十分抢眼。朱茵 黎姿 看到两位女神的旧照,网友们纷纷感慨“当年的黎姿和朱茵,真的美得不像话啊!””狠狠打脸如今的网红!…

历经7次升级的珍宝馆,能有多好看?

珍宝,《现代汉语词典》解释为:“珠玉宝石的总称,泛指有价值的东西。” 若将这两个字置于故宫博物院之中,几经历史浸染的它们包裹迭代风貌,延伸出更为广义的内涵:一切稀缺的,有价值的东西,皆可纳入珍宝之列。图片来源 | 故宫博物院官网 早在1月28日,故宫博物院官网就发…

角川宣布旗下两家游戏资讯杂志将调整到同一部门

日本知名媒体集团角川集团今天宣布,他们将会在今年十月对旗下部分业务进行调整。调整过后,原本属于角川总社的《电击Playstation》将会划归进子公司Gzbrain,Gzbrain正是知名杂志《周刊Fami通》的出版公司。 《电击Playstation》是日本ASCII Media Works(原MediaWorks )发…

房子居然被霸占,女子:胜诉居然拿不回房

“胜诉”拿不回房子,房子被邻居霸占了3年,还在诉讼期间被拍卖了。这样的悲剧发生在山东临沂,而类似的事情在其他地方也有发生。 “我花了好几年的时间打官司,还花了不少钱找律师,就是为了能要回自己的房子。” 12月11日,家住临沂兰山区的杨娜向《法制日报》记者讲述了她和…

张建铭 | 孤独的风景

孤独的风景 文、图 | 张建铭 这些年走过不少旅游风景区,多是红火的、热闹的,那些熙熙攘攘车水马龙的热门大景区自不必说,就连处地偏僻、藏身深山的幽秘小景点,也被驴友和摄客们挂网热搜,成为追寻探访的深巷佳酿,不再幽草涧生,孤芳静香。 这是一种可喜的现象,至少说明我…

「气色堂企业文化」做一个有爱的人,为爱付出

【气色堂信条完整版】 2004-2008年,创始人王博因社会上的不良产品深受其害: ——母亲吃保健品住院一周下13次病危通知 ——父亲喝到假酒差点双目失明 ——夫人桂慧琳使用光子嫩肤和化妆品几乎毁容 ——儿子8岁长胡子…… 王博桂慧琳夫妇极其愤慨当时不负责任的产品!对…

s6最新6.8版本小炮攻略 s6小炮羊刀流玩法攻略

韩服的数据统计显示羊刀飓风小炮已成为主流选择 小炮为什么可以出羊刀? 让我们先列出羊刀的属性再做分析。鬼索的狂暴之刃 • +30攻击力,+40法术强度 • 唯一被动:每次普通攻击提供+8%攻击速度,+3攻击力和+4法术强度,持续5秒(最多可叠加8层,近战攻击提供2层效果)。在你拥…

揭秘!马云的家庭生活与子女

在中国,提及企业家,马云无疑是其中最具有影响力的一个。从一个默默无闻的小商贩到成为中国首富的历程,马云的故事激励了无数人为之奋斗。然而,除了他的商业成就之外,人们对马云的家庭生活和背后故事的了解却非常有限。在这篇文章中,我们将揭开马云家庭的神秘面纱,让你了…

研究:超八成失独家庭渴望再生养,经济压力是首要制约

界面新闻记者 | 赵孟界面新闻编辑 | 刘海川界面新闻记者 | 赵孟 界面新闻编辑 | 刘海川 在人口负增长与低生育率的时代背景下,失独家庭作为计划生育政策下的特殊群体,其生存现状与再生养问题日益受到社会关注。近日,北京枫彩心理咨询服务中心发布《失独家庭再生养状况调查报…

德国汽车“豪门内讧” 奔驰大众坑完宝马坑自己

文|刘璐 聂舒翼 继上周突击搜查宝马集团慕尼黑总部后,昨天,欧盟和德国反垄断官员继续搜查了戴姆勒和大众办公室,扩大了对其涉嫌垄断的调查。 由此,这起德国车企“豪门内讧”又有了新的剧情。戴姆勒(奔驰母公司)本想把锅甩给宝马,把自己“摘干净”,可最终还是坑了进去。…

资源分享|《丁香妈妈科学养育电子版》PDF版:高清电子书下载

《丁香妈妈科学养育》是由知名医疗健康平台丁香园推出的一部育儿指南,旨在为家长们提供科学且切实可行的育儿方法。该书汇集了专业医生和育儿专家的智慧,涵盖了从出生到学龄前各个阶段的详细指南。 本书基于最新的育儿研究和科学证据,内容丰富且实用,从婴儿护理、疾病预防、…

原创小S与舞蹈老师激情热舞,亢奋到身体发红,曾说很久与老公那个了

大小S姐妹果然不愧是热搜体质,别人费尽心思也上不去的热搜,对姐妹二人来讲,就像是吃饭和喝水这样简单。 刚进入7月份,姐妹两就频繁登上热搜,这边大S松口了,允许张兰、汪小菲和孩子见面,但是要在日本才能见,而另一边小S与男舞蹈老师激情热舞,则又登上了热搜。 这名男舞…

重磅!自贡再添文旅新地标,时空·龙门镇试营业中!

@所有自贡人 自贡又多了一个文旅新地标 经过大半年紧锣密鼓的规划建设 自贡文旅投投资打造的 全省重点文旅项目时空龙门镇 目前正在试营业 预计今年4月正式开街!展开全文实拍图 01 实地探访 时空龙门镇试营业开启 途经自贡恐龙博物馆时,就能看到一个风格别致的文旅小镇,一桥…

不得了,Lululemon【拯救婚姻】bra遭疯抢,断货!

本文不是广告,请放心阅读 2024开年大抢,“瑜伽服中的爱马仕”、都市丽人人手一件的Lululemon,有一款运动bra突然爆火了!(图源网络,版权属于原作者) 广大网友给它赐名为:【拯救婚姻的bra】。 内衣全面断货,二手网站开卖?一款bra竟然这么神奇?01 lululemon新款内衣抢断…

红邦小镇盛大揭幕,大家居品牌计划创行业盛举

三百多名嘉宾共赴红邦小镇 大家居计划创行业盛举 2018年12月29日,红邦小镇展示中心启动仪式暨大家居品牌战略合作启动仪式在南充嘉陵大道红邦小镇园区内隆重召开。本次启动仪式由四川红邦实业发展有限公司主办。广东省家具商会、四川家具制造业协会、西华师范大学艺术学院、明…

内地食用河豚正式解禁 首批市场流通资格月底便有

内地自1990年起不得流入市场的河豚,即将可以有条件地“合法”食用。 内地食用河豚正式“解禁”!当局宣布有条件开放两种养殖河豚的加工经营,正在考核首批16个河豚养殖基地,预计首批河豚本月底便拥有加工后在市场上流通的资格,届时便可进入市场。这意味着自1990年起不得流…

女人该不该藏私房钱:不藏私房钱都是傻白甜

小她居委会大姐技能上身,好好劝了她一番,可是女人到底该不该藏私房钱呢? 小她请三位持对立观点的财蜜来现身说法: 1、不藏私房钱就傻白甜了 私房钱就是安全感的代名词 单身的@小猫咪喵喵 这样说: 有句话说的好:钱不是万能的,但没有钱是万万不能的。 这说明了钱的重要性以…