仅用于信息防御学习,请勿用于非法用途!!!
目录
一、实验环境
二、函数分析
1、函数sub_403C98分析
2、函数sub_405360分析
3、函数sub_404018分析
三、小结
实验环境:windows xp sp2
病毒样本:87551e33d517442424e586d25a9f8522(MD5值)
软 件:PEiD、OllyDBG、IDA pro
(1)用IDA pro载入病毒样本
下图选中的代码是Delphi自动生成的反汇编代码,并不是我们所关心的病毒程序的功能代码,故不作讨论。
定位到0X0040CBSC位置,该函数通过调用GetModuleHandleA()函数,获取程序基地址和程序实例的句柄。
定位到0x0040CB7E和0x40CB8D位置,发现调用了同一个函数sub_403C98。
注意:如下图,有些IDA会自动分析出字符串“感谢艾玛...”,并且在函数sub_403C98之前,可以推测出前一个函数sub_403C98也传递了一个字符串。 因为我的IDA并没有自动解析出字符串的值,因此只能用OllyDbg进行动态调试。 (2)用OllyDbg载入病毒样本
跳转到0x40CB74处,可以在数据窗口看到偏移地址为0x40E7D4的数据;
执行到0x40CB79处,可以在数据窗口看到偏移地址为0x40CC40的数据;
(3)利用OllyDbg查看函数403C98的功能
按F7进去函数403C98,进入下图所示界面:
按F8单步步过,F7进去函数403D08,进入界面如下:
同理,按F7进入函数402520,进入界面如下:
call dword ptr [40D030]:
call 401860:
进入函数401860之后,可以看到两个API函数:InitializeCriticalSection和EnterCriticalSection,它们是对互斥的空间进行初始化,就是防止执行过程中被其他线程干扰。
继续F8单步步过,会发现程序调用了LocalAlloc函数,该函数用于内存分配。会分配0xFF8大小的空间,LMEM_FIXED代表固定内存。该函数执行完会返回一个指向新分配的内存对象的句柄。
至此,基本上确定了函数403D08的功能:分配一定大小的内存空间。
IDA进入函数403C98:
在IDA中将函数sub_403D08重命名为“AllocateRoom”,可以看到下一个待分析函数是sub_402650。
(4)分析函数sub_402650
OD进入call 402650:
需要注意“rep movs”语句,该rep是将ESI指向地址的值以4字节方式拷贝到EDI指向的地址中,重复执行ECX次,每次执行后ESI+4、EDI+4、ECX-1。另外,std代表地址递减,cld代表地址递增。
单步步过之后,可以发现只执行后两个rep语句。
在IDA中将函数sub_402650重命名为“CopyString”.
(5)至于IDA流程图中的402540函数
在OD中可以看到函数并没有被执行,直接被跳过了,故,不用花时间分析该函数。
(6)小结
至此,sub_403C98函数分析完毕,主要有两个用途:
总结:sub_403C98函数有两个参数,第一个参数保存在eax中,第二个参数保存在edx中。这个函数首先完成堆空间的申请,然后将edx中保存的字符串复制到新申请的空间中。执行后,eax的起始值下保存的是新申请的堆空间中,所复制的字符串的首地址。
在IDA中将函数sub_403C98重命名为:“AllocRoomAndCopyStr”
开始进行sub_405360函数的分析,首先根据IDA的提示,在OD中跳转到0x0040CB92位置。
数据窗口分别转到0x40CC94和0x40ccA4位置,可以看到相应的数据为:
进入函数00405360,可以看到下图中有些代码前面有粗线条(循环),直接跳到循环出。
按F8步过,发现0x62(=‘b’)赋值给了eax,且遇到了将一个常量赋值给ecx。
部分代码分析:
mov ecx,0A
将常量赋值给ecx,有两种可能性:ecx作为循环的次数;ecx作为接下来运算的除数。
xor edx,edx
清空edx
div ecx
除数为ecx,被除数为eax,商eax为9,余数edx为8。
做除法运算,有两种可能性:取商,也就是EAX存的内容;取余数,也就是EDX存的内容。
mov eax,dword ptr [ebp-4]
eax被重新赋值,因此,程序是要EDX中存的内容。
设置三个断点,并观察数据窗口:
显然,sub_405360是一段解密代码,利用“xboy”将乱码还原为“武汉男生...”。那么可以将sub_405360重命名为:DecodeString。
CODE:004053E5 mov eax, [ebp+var_14]
CODE:004053E8 movzx eax, byte ptr [eax+edi-1]
; 每次循环逐字节取出“xboy”中的字符进行运算,首先取出的是“b”。
CODE:004053ED mov ecx, 0Ah
; 将ecx赋值为0x0A,作为除法运算的除数。
CODE:004053F2 xor edx, edx
; 清空edx。
CODE:004053F4 div ecx
; 做除法运算,商保存在eax中,余数保存在edx中。
CODE:004053F6 mov eax, [ebp+var_4]
; 这里由于给eax重新赋值,说明程序实际想使用的是edx中的余数。
CODE:004053F9 movzx eax, byte ptr [eax+ebx-1]
; 每次循环逐字节取出乱码中的字符,赋值给eax进行接下来的运算。
CODE:004053FE xor edx, eax
; 异或运算,结果保存在edx中,也就是通过运算最终得出的字符。
CODE:00405400 lea eax, [ebp+var_18]
跳转到0x0040CBA4位置,会看到两条赋值语句,分别赋值给EDX和EAX,由于这个程序是使用Delphi编写,所以在call之前会将参数放到寄存器中,分别查看保存到EDX和EAX的内容。
两处保存的内容都是“武汉男生...”的字符串,唯一不同的是前一个是我们解密出来的字符串。
进入函数sub_404018。
同样发现存在粗线条(循环),直接跳转到循环处,分析循环。
在窗口跟随中,发现赋给ecx、eax的数据就是与“武汉男生...”有关的值,只是前者是原始的数据,后者是解密出来的数据。
CMP ECX, EBX ,实际上就是比对两个“武汉男生...”。
回到IDA,将sub_404018重命名为“CmpString”。
在IDA中,对接下来的执行流程进行分析:
从IDA中可以看到,一旦0x0040CBAC处的字符串比较成功,将会跳转到loc_40CBBC处,同样,0x0040CBD6处的字符串比较成功,程序将会跳转到loc_40CBE6处。
本文只对病毒的起始部分做了分析,下文将对病毒的三个模块——call sub_408024进行分析。