c++ 进程守护之打不死的小强

//进程守护之打不死的小强          云守护
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "PSAPI.H"
#pragma comment( lib, "PSAPI.LIB" )

HANDLE	CreateRemoteThreadProc(char* ProcessName);
DWORD	WINAPI WatchThread(LPVOID lparam);
DWORD	WINAPI remote(LPVOID pvparam);
DWORD	processtopid(char *processname);
BOOL	EnablePriv();
//先打开notepad,在运行本程序

typedef struct _remoteparameter
{
	DWORD		rpWaitForSingleObject;
	DWORD		rpOpenProcess;
	DWORD       rpWinExec;
	DWORD	    rpProcessPID;           
	HANDLE		rpProcessHandle;
	char	    path[MAX_PATH];
}REMOTEPARAM;

int main(int argc, char* argv[])
{
	HANDLE RemoteThreadHandle;
	HANDLE LocateThreadHandle;
	EnablePriv();
	RemoteThreadHandle=CreateRemoteThreadProc("notepad.exe");
	//本地线程循环注入notepad
	LocateThreadHandle=CreateThread(NULL,NULL,WatchThread,(LPVOID)RemoteThreadHandle,NULL,NULL);
	WaitForSingleObject(LocateThreadHandle,INFINITE);

	WaitForSingleObject(RemoteThreadHandle,INFINITE);//线程等待,循环等待notepad的远程线程执行完毕。即 notepad关闭本程序才关闭
	return 0;
}
//创建远程线程,线程注入
HANDLE CreateRemoteThreadProc(char* ProcessName)
{
		HANDLE	ThreadHandle;
		char	FilePath[MAX_PATH];

		GetModuleFileName(NULL,FilePath,MAX_PATH);//得到文件所在路径
		printf("%s\n",FilePath);
		//根据进程名获取进程ID
		int procID=processtopid(ProcessName);
		printf("The process pid is %d\n",procID);
		HINSTANCE         hkernel32;
		HANDLE            rphandle;
		char             *remotethr;
		char             *remotepar;
		int               cb;
		//根据ID打开notepad的进程空间
   		rphandle=OpenProcess(PROCESS_CREATE_THREAD |  PROCESS_VM_OPERATION  | 
			PROCESS_VM_WRITE, FALSE,procID);
		if(rphandle==NULL)
		{
	   		printf("Open Remote Process  is Error\n");
		}
		else
		{
			printf("open process is ok\n");
		}

		/*****************************************************************/
						/*将远程线程函数代码拷入目标进程*/
		/*****************************************************************/
		cb=sizeof(TCHAR)*4*1024;
		//在notepad进程中分配空间,存储函数remote
		remotethr=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_EXECUTE_READWRITE); 
		if(remotethr==NULL)
		{
			printf("VirtualAllocEx for Thread Error\n");
			CloseHandle(rphandle);       
		}
		else
			printf("VirtualAllocEx is ok\n");
		//往notepad空间中写入数据指针remote指向的数据,大小为cb
		if(WriteProcessMemory(rphandle,remotethr,(LPVOID)remote,cb,NULL)==FALSE)
		{
			printf("WriteProcessMemory for Thread Error\n");
			CloseHandle(rphandle);
		}
		else
			printf("WriteProcessMemory is ok\n");

		/*****************************************************************/
						/*将远程线程函数参数拷入目标进程*/
						/*这里需要重定位远程线程需要的API*/
		/*****************************************************************/
		REMOTEPARAM rp;
		memset((char*)&rp,0,sizeof(rp));

		hkernel32=GetModuleHandle("kernel32.dll");

		if(hkernel32==NULL)
		{
			printf("hKernel32 is Error\n");
		}
		//通过让目标进程执行OpenProcess,WinExec,WaitForSingleObject,函数重新打开本程序

		rp.rpProcessPID			=GetCurrentProcessId();
		rp.rpOpenProcess		=(DWORD)GetProcAddress(hkernel32,"OpenProcess");
		rp.rpWinExec			=(DWORD)GetProcAddress(hkernel32,"WinExec");
		rp.rpWaitForSingleObject=(DWORD)GetProcAddress(hkernel32,"WaitForSingleObject");
		_tcscpy(rp.path,FilePath);	
		cb=sizeof(char)*sizeof(rp);
		//rphandle指向notepad进程,分配空间,存储参数
		remotepar=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
		if(remotepar==NULL)
		{
			printf("VirtualAllocEx for Parameter Error\n");
			CloseHandle(rphandle);
		}
		//往notepad进程写入传给remote的参数
		if(WriteProcessMemory(rphandle,remotepar,(LPVOID)&rp,cb,NULL)==FALSE)
		{
			printf("WriteProcessMemory for Parameter Error\n");
			CloseHandle(rphandle);
		}

		/*****************************************************************/
						/*将远程线程注入目标进程*/
		/*****************************************************************/
		//在noetpad进程中创建新线程执行remote函数,参数为remotepar,返回线程句柄
		ThreadHandle=CreateRemoteThread(rphandle,NULL,0,(LPTHREAD_START_ROUTINE)remotethr,(LPVOID)remotepar,0,NULL);
		
		if(ThreadHandle==NULL)
		{
			printf("CreateRemotThreadHandle Error\n");
			CloseHandle(rphandle);
		}
		else
			printf("CreateRemotThreadHandle is ok\n");

		return ThreadHandle;
}
//获取进程ID
DWORD processtopid(char *processname)
{
	DWORD    lpidprocesses[1024],cbneeded,cprocesses;
	HANDLE   hprocess;
	HMODULE  hmodule;
	UINT     i;
	TCHAR    normalname[MAX_PATH]=("UnknownProcess");
    
	if(!EnumProcesses(lpidprocesses,sizeof(lpidprocesses),&cbneeded))
	{
		return -1;  
	}
	cprocesses=cbneeded/sizeof(DWORD);
	for(i=0;i<cprocesses;i++)
	{
		hprocess=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,lpidprocesses[i]);
		if(hprocess)
		{
			if(EnumProcessModules(hprocess,&hmodule,sizeof(hmodule),&cbneeded))
			{
				GetModuleBaseName(hprocess,hmodule,normalname,sizeof(normalname));
				if(!strcmp(normalname,processname))  
				{
					CloseHandle(hprocess);
					return (lpidprocesses[i]);
				}
			}
		}
	}
	CloseHandle(hprocess);
	return 0;
}
//提升进程权限
BOOL EnablePriv()
{
	HANDLE hToken;
	if ( OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken) )
	{
		TOKEN_PRIVILEGES tkp;
		
		LookupPrivilegeValue( NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid );	//修改进程权限
		tkp.PrivilegeCount=1;
		tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
		AdjustTokenPrivileges( hToken,FALSE,&tkp,sizeof tkp,NULL,NULL );	//通知系统修改进程权限
	}
		return 0;
}
//远程线程要执行的函数
DWORD WINAPI remote(LPVOID pvparam)
{
	REMOTEPARAM *rp=(REMOTEPARAM*)pvparam;
	
	typedef UINT			(WINAPI *EWinExec)				(LPCSTR, UINT);
	typedef HANDLE			(WINAPI *EOpenProcess)			(DWORD, BOOL, DWORD);
	typedef DWORD			(WINAPI *EWaitForSingleObject)	(HANDLE, DWORD);
	
	
	EWinExec				tWinExec;
	EOpenProcess			tOpenProcess;
	EWaitForSingleObject	tWaitForSingleObject;
	
	
	tOpenProcess			=(EOpenProcess)rp->rpOpenProcess;
	tWaitForSingleObject	=(EWaitForSingleObject)rp->rpWaitForSingleObject;
	tWinExec				=(EWinExec)rp->rpWinExec;
	
	//	重新打开本进程ID,使本进程可以访问
	rp->rpProcessHandle=tOpenProcess(PROCESS_ALL_ACCESS,FALSE,rp->rpProcessPID);
	
	tWaitForSingleObject(rp->rpProcessHandle,INFINITE);
	//打开本程序
	tWinExec(rp->path, SW_SHOW);
	return 0;
}
//守护进程
DWORD	WINAPI WatchThread(LPVOID lparam)
{
	HANDLE	RemoteThreadHandle=(HANDLE)lparam;
	DWORD	ExitCode;

	GetExitCodeThread(RemoteThreadHandle,&ExitCode);

	while(true)
	{
		if(ExitCode!=STILL_ACTIVE)//如果远程线程不激活,就重新激活
		{
			printf("RemoteThreadHandle is over\n");
			RemoteThreadHandle=CreateRemoteThreadProc("notepad.exe");
		}
		Sleep(3000);	
	}
	return 0;
}

你可能感兴趣的:(c++ 进程守护之打不死的小强)