现在的位置: 首页 > 综合 > 正文

基于visual c++之windows核心编程代码分析(43)剿灭病毒编程

2012年08月22日 ⁄ 综合 ⁄ 共 9436字 ⁄ 字号 评论关闭

编制或者在计算机程序中插入的破坏计算机功能或者破坏数据,影响计算机使用并且能够自我复制的一组计算机指令或者程序代码被称为计算机病毒(Computer Virus)。具有破坏性,复制性和传染性。

 

我们如何编程干掉病毒呢,有的病毒很拽很得瑟。

看我们来实践干掉病毒

提升权限

//                   函数功能:提升权限                            //
//      参数: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;
}

 

删除病毒让病毒不能自己启动

 

///                    函数功能:删除自启动项                            ///
////////////////////////////////////////////////////////////////////////////
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);
		}
	}
}

批处理调用

////              使用说明:将批处理放在程序同一个文件夹中,然后调用下面的代码    ////
////                        将kill.bat改成相应的文件名                            ////
//////////////////////////////////////////////////////////////////////////////////////                      
GetModuleFileName(NULL,szPath,MAX_PATH); //获取程序的路径
lstrcpy( _tcsrchr(szPath, _T('\\') ) + 1, _T("kill.bat") );//然后去掉程序名加上kill.bat
strcpy(szCmdLine,"cmd.exe /c start ");//WinExec的命令行
strcat(szCmdLine,szPath);
WinExec(szCmdLine,SW_SHOWNORMAL);

 

对抗病毒镜像劫持

///                     函数功能:对抗映像劫持                           ///
////////////////////////////////////////////////////////////////////////////
VOID DeleteRunouceRegistry()//这里以任务管理器为例
{   
	HKEY hTestKey;
	CHAR szBuf[128];
	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\taskmgr",0,KEY_READ|KEY_WRITE,&hTestKey)==ERROR_SUCCESS)
	{
		if(RegDeleteValue(hTestKey,"Debugger")!=ERROR_SUCCESS)
		{
			sprintf(szBuf,"%d",GetLastError());
			MessageBox(NULL,szBuf,NULL,MB_OK);
		}
	}
}

 

删除顽固文件

///                 函数功能:强删顽固文件                ///
///   使用说明:将\\??\\E:\\autorun.inf改成相应的文件名   ///
/////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
 
typedef unsigned long NTSTATUS;
typedef unsigned short USHORT;
typedef unsigned long ULONG;
typedef unsigned long DWORD;
typedef long LONG;
typedef __int64 LONGLONG;
 
typedef struct UNICODE_STRING{
    USHORT Length;
    USHORT MaxLen;
    USHORT *Buffer;
} UNICODE_STRING,*PUNICODE_STRING;
 
#define OBJ_INHERIT             0x00000002L
#define OBJ_PERMANENT           0x00000010L
#define OBJ_EXCLUSIVE           0x00000020L
#define OBJ_CASE_INSENSITIVE    0x00000040L
#define OBJ_OPENIF              0x00000080L
#define OBJ_OPENLINK            0x00000100L
#define OBJ_KERNEL_HANDLE       0x00000200L
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
#define OBJ_VALID_ATTRIBUTES    0x000007F2L
 
#define FILE_ATTRIBUTE_NORMAL               0x00000080
#define FILE_SHARE_DELETE                   0x00000004
#define FILE_OPEN_IF                        0x00000003
#define FILE_SYNCHRONOUS_IO_NONALERT        0x00000020
#define GENERIC_WRITE                       (0x40000000L)
#define SYNCHRONIZE                         (0x00100000L)
#define GENERIC_READ                        (0x80000000L)
 
typedef struct _OBJECT_ATTRIBUTES{
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;
    PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
 
typedef NTSTATUS (__stdcall *ZWDELETEFILE)(
        IN POBJECT_ATTRIBUTES ObjectAttributes);
 
typedef VOID (__stdcall *RTLINITUNICODESTRING)(
        IN OUT PUNICODE_STRING DestinationString,
        IN PCWSTR SourceString);
 
typedef struct _IO_STATUS_BLOCK{
        DWORD Status;
        ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
 
typedef NTSTATUS (__stdcall *ZWCREATEFILE)(
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PLARGE_INTEGER AllocationSize OPTIONAL,
    IN ULONG FileAttributes,
    IN ULONG ShareAccess,
    IN ULONG CreateDisposition,
    IN ULONG CreateOptions,
    IN PVOID EaBuffer OPTIONAL,
    IN ULONG EaLength);
 
typedef VOID (NTAPI *PIO_APC_ROUTINE) (
   IN PVOID ApcContext,
   IN PIO_STATUS_BLOCK IoStatusBlock,
   IN ULONG Reserved);
 
typedef NTSTATUS (__stdcall *ZWWRITEFILE)(
    IN HANDLE FileHandle,
    IN HANDLE Event OPTIONAL,
    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
    IN PVOID ApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PVOID Buffer,
    IN ULONG Length,
    IN PLARGE_INTEGER ByteOffset OPTIONAL,
    IN PULONG Key OPTIONAL);
 
typedef NTSTATUS (__stdcall *ZWCLOSE)(
    IN HANDLE Handle);
 
int main()
{
    HINSTANCE hNtDll;
    ZWDELETEFILE ZwDeleteFile;
    RTLINITUNICODESTRING RtlInitUnicodeString;
    ZWCREATEFILE ZwCreateFile;
    ZWWRITEFILE ZwWriteFile;
    ZWCLOSE ZwClose;
 
    hNtDll = LoadLibrary ("NTDLL");
    if (!hNtDll)
       return 0;
 
    ZwDeleteFile = (ZWDELETEFILE)GetProcAddress (hNtDll,"ZwDeleteFile");
    RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress (hNtDll,"RtlInitUnicodeString");
    ZwCreateFile = (ZWCREATEFILE)GetProcAddress (hNtDll,"ZwCreateFile");
    ZwWriteFile = (ZWWRITEFILE)GetProcAddress (hNtDll,"ZwWriteFile");
    ZwClose = (ZWCLOSE)GetProcAddress (hNtDll,"ZwClose");
 
    UNICODE_STRING ObjectName;
    RtlInitUnicodeString(&ObjectName,L"\\??\\E:\\autorun.inf");//记得这里是要有\\??\\在前面的,WDK说的.
 
    OBJECT_ATTRIBUTES ObjectAttributes = {
        sizeof(OBJECT_ATTRIBUTES),          // Length
        NULL,                               // RootDirectory
        &ObjectName,                        // ObjectName
        OBJ_CASE_INSENSITIVE,               // Attributes
        0,                                  // SecurityDescriptor
        NULL,                               // SecurityQualityOfService
    };
 
    HANDLE hFile;
    PVOID content = "ForZwFileTest";
    IO_STATUS_BLOCK IoStatusBlock;
 
    ZwCreateFile(&hFile,
        GENERIC_WRITE|SYNCHRONIZE|GENERIC_READ,
        &ObjectAttributes,
        &IoStatusBlock,
        0,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_DELETE,
        FILE_OPEN_IF,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    ZwWriteFile(hFile, 0, 0, 0, &IoStatusBlock, content, 12, NULL, NULL);
    ZwClose(hFile);
 
    ZwDeleteFile(&ObjectAttributes);
 
    FreeLibrary (hNtDll);
    return 0;
}

 

多进程保护终结者

////                     功能:对抗多进程保护                              //////
////       主程序里调用EnumProcessAndSuspendProcess()和                    //////
////    EnumProcessAndTerminateProcess()就能将病毒程序结束掉               //////
/////////////////////////////////////////////////////////////////////////////////

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 ;
}

卸载被远程注射的dll

/////                     函数功能:卸载掉注入的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; 
}

 

 

 

 

 

 

 

 

 

 

抱歉!评论已关闭.