现在病毒泛滥,采用的技术也越来越邪恶,要么是全盘感染,要么是进程注入,一不小心中了,清除都要清除好久,稍不留意,又会死灰复燃。因此学会写病毒专杀,对付起来就会轻松多了!这篇文章将会从ring3层阐述病毒专杀攻略。
主要从三部分来阐述,分别是进程相关部分、注册表相关部分、文件相关部分。
进程相关部分
一、对抗多进程保护
为了使病毒程序能够在电脑中存活更久,现在的病毒都会采用相关的技术来保护自己,一旦病毒进程被结束掉,就会重新创建病毒进程。最常用的就是多进程保护,如双进程保护,三进程保护。一旦病毒进程被结束掉,另外的进程就会检测到并重新创建病毒进程,已达到生生不息的目的。
攻略:将进程挂起,然后逐个结束掉
代码:
typedef DWORD (WINAPI *PFSuspendProcess)(HANDLE hProcess);
PFSuspendProcess SuspendProcess; //挂起进程的API,在ntdlll.dll中
//函数功能:挂起进程 参数:进程ID
VOID SuspendProc(DWORD dwPID)
{
HMODULE hNtDllLib=LoadLibrary("ntdll.dll"); //加载ntdll.dll,获得dll句柄
SuspendProcess=(PFSuspendProcess)GetProcAddress(hNtDllLib,"ZwSuspendProcess");
//获取ZwSuspendProcess的地址
if (SuspendProcess)
{
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID);
//获取指定进程ID的句柄
SuspendProcess(hProcess); //挂起进程
}
FreeLibrary(hNtDllLib);//释放dll
}
VOID TerminateProc(DWORD dwPID) //函数功能:结束进程 参数:进程ID
{
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID);
TerminateProcess(hProcess,0);
}
//函数功能:枚举进程并挂起进程
VOID WINAPI EnumProcessAndSuspendProcess()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
// Snapshot
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
printf( "CreateToolhelp32Snapshot (of processes) error!\n");
return ;
}
// 设置输入参数,结构的大小
pe32.dwSize = sizeof( PROCESSENTRY32 );
// 开始列举进程
if( !Process32First( hProcessSnap, &pe32 ) )
{
printf( "Process32First error!\n" ); // 出错信息
CloseHandle( hProcessSnap );
return ;
}
do
{
//枚举进程然后将病毒进程挂起
if (stricmp(pe32.szExeFile,"Global.exe")==0)
{
SuspendProc(pe32.th32ProcessID);
}
...
//在这里添加要结束的进程名
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap ); //关闭句柄
return ;
}
//函数功能:枚举进程并结束进程
VOID WINAPI EnumProcessAndTerminateProcess()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
// Snapshot
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
printf( "CreateToolhelp32Snapshot (of processes) error!\n");
return ;
}
// 设置输入参数,结构的大小
pe32.dwSize = sizeof( PROCESSENTRY32 );
// 开始列举进程
if( !Process32First( hProcessSnap, &pe32 ) )
{
printf( "Process32First error!\n" ); // 出错信息
CloseHandle( hProcessSnap );
return ;
}
do
{ //枚举进程然后将病毒进程结束
if (stricmp(pe32.szExeFile,"Global.exe")==0)
{
TerminateProc(pe32.th32ProcessID);
}
...
//在这里添加要结束的进程名
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap ); //关闭句柄
return ;
}
然后在主程序里调用EnumProcessAndSuspendProcess()和EnumProcessAndTerminateProcess()就能将病毒程序结束掉。管它几个进程相互保护,都能轻松干掉!
说明:为了能够卸载掉注入的dll,首先要打开进程获取进程句柄,但是系统进程是不能访问的,因此要通过提升进程的权限至SE_DEBUG权限才能访问系统进程
//函数功能:提升权限
//参数:lpszPrivilege:权限名 bEnablePrivilege:是否允许
BOOL SetPrivilege(LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
LUID luid;
HANDLE hProcessToken=NULL;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken))
return -1;
if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid=luid;
if(bEnablePrivilege)
tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes =0;
//Enable the privilege or disable all privilege
AdjustTokenPrivileges(hProcessToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL);
if(GetLastError()!=ERROR_SUCCESS)
return FALSE;
if(hProcessToken!=NULL)
CloseHandle(hProcessToken);
return TRUE;
}
//函数功能:卸载掉注入的dll 参数;dll名
int KillDLL(char *DllName)
{
// 解除所有进程中某DLL模块的加载
HANDLE hProcess=NULL;
if(!SetPrivilege(SE_DEBUG_NAME,TRUE))
{
return -2;
}
DWORD aProcesses[1024],cbNeeded,cProcesses;
unsigned int i;
//计算目前有多少进程,aerocesses[]用来存放有效的进程PIDs
if(!EnumProcesses(aProcesses,sizeof(aProcesses),&cbNeeded))
return -11;
cProcesses=cbNeeded/sizeof(DWORD);
//按有效的PID遍历所有的进程
for(i= 0;i<cProcesses;i++)
{
if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,aProcesses[i]))==NULL)
{
continue;
}
// 由目标进程地址空间写入DLL名称
DWORD dwSize,dwWritten;
dwSize=strlen(DllName)+1;
LPVOID lpBuf=VirtualAllocEx(hProcess,NULL,dwSize,MEM_COMMIT,PAGE_READWRITE);
if(lpBuf=NULL)
{
CloseHandle(hProcess);
continue;
}
//向其中写入dll的名称
if(WriteProcessMemory(hProcess,lpBuf,(LPVOID)DllName,dwSize,&dwWritten))
{
// 若写入字节数与实际写入字节数不相等,仍属失败
if(dwWritten!=dwSize)
{
VirtualFreeEx(hProcess,lpBuf,dwSize,MEM_DECOMMIT);
CloseHandle(hProcess);
continue;
}
}
else
{
CloseHandle(hProcess);
continue;
}
//使目标进程调用GetModuleHandIe,获得DLL在进程中的句柄
DWORD dwHandle,dwID;
LPVOID pFunc= GetModuleHandleA;
HANDLE hThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pFunc,lpBuf,0,&dwID);
//等待GetModuleHandle运行完毕
WaitForSingleObject(hThread,INFINITE);
//获得GetModuleHandle的返回值
GetExitCodeThread(hThread,&dwHandle);
// 释放目标进程中申请的空间
VirtualFreeEx( hProcess,lpBuf,dwSize,MEM_DECOMMIT);
CloseHandle(hThread);
//使目标进程调用FreeLibrary,卸载DLL
pFunc=FreeLibrary;
hThread= CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pFunc,(LPVOID)dwHandle,0,&dwID);
//等待FreeLibrary卸载完毕
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
}
if(hProcess!=NULL)
CloseHandle(hProcess);
return 0;
}
VOID DeleteRunouceRegistry()
{
HKEY hTestKey;
CHAR szBuf[128];
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",0,KEY_READ|KEY_WRITE,&hTestKey)==ERROR_SUCCESS)
{
if(RegDeleteValue(hTestKey,"Runouce")!=ERROR_SUCCESS)
{
sprintf(szBuf,"%d",GetLastError());
MessageBox(NULL,szBuf,NULL,MB_OK);
}
}
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!