Click here to Skip to main content
15,886,137 members
Articles / Programming Languages / C++

How to Create an "unkillable" Windows Process

Rate me:
Please Sign up or sign in to vote.
3.25/5 (15 votes)
12 Oct 2010CPOL2 min read 61.7K   1.4K   58   20
This article explains how to implement a relatively eternal process.
screen.jpg

The topic of killing Windows processes has been investigated by developers and users probably from the first day this operating system appeared. Besides the task manager where it is possible to kill (practically) any process, there are a lot of freeware and shareware programs that will do all the dirty job of ending any process you select. But what to do if you need to write an "unkillable" program?

Once I came across this problem, I analyzed how several adware programs were running, such as Gator Adware, using methods making it possible to avoid being ended by the user. As a result, I worked out a fairly simple solution that is described in this article. This example implements a relatively eternal process. It is assumed that the user does not use any special technical tools in order to kill the process, but uses only the task manager or similar software.

How It Works

Since we cannot forbid the user to select our process in the task manager with the mouse and select the "End Process" command, let's create two processes that are the same - one of them will directly execute the code of the program, while the other one will only monitor whether the main program is running or not. The first process will also monitor whether the second auxiliary process is running. With this kind of implementation, no matter which of the two processes the user kills, the remaining process will start a working copy and our program will continue to work. schema.jpg

Implementation - Main Code

This is the main code of the program. If nothing is passed in the command line, we run the second process that will keep monitoring and then start performing the main function. If the ID of the main process is passed in the command line, we just monitor it. If it is closed, it gets started again.
C++
    CHAR theAppPath[MAX_PATH];
    HANDLE theParentProcess = NULL;

    BOOL CClient001App::InitInstance()
    {
        ....

	CString cmdLine = CString(::GetCommandLine());
	cmdLine = cmdLine.Right
	( cmdLine.GetLength()-cmdLine.ReverseFind(' ')-1);
	GetModuleFileName( AfxGetInstanceHandle(), theAppPath, MAX_PATH );
	DWORD procID = atoi(cmdLine);


	if( procID == 0 )
	{
	    _beginthread( AntikillThreadWaiter1, 0, NULL ); // starting the thread 
					// that will run and monitor the second copy
	}
	else
	{
		   HANDLE parentProc = OpenProcess
			   ( PROCESS_ALL_ACCESS, FALSE, procID );
		   if( parentProc )
		   {
			    theParentProcess = parentProc;
			   _beginthread( AntikillThreadWaiter2, 0, NULL );// starting 
					// the thread that will monitor whether 
					// the main program is running

			   while(1)
			   {
		                   Sleep( 500 );
			   }
		   }
	}

       /// the main code of the program goes here
        ....
}

Code of the AntikillThreadWaiter1 Thread

This thread only starts the second copy of the program to which it passes the current ID of the process in the command line. The second copy will wait till the main program is closed. If the user closes the second copy, this thread starts it again.

C++
void AntikillThreadWaiter1(LPVOID param )
{
  while(1)
  {
	  STARTUPINFO si;
	  PROCESS_INFORMATION pi;
	  CHAR theNewPath[MAX_PATH];
	  DWORD pid = GetCurrentProcessId();
	  wsprintf( theNewPath,"%s %d\0", theAppPath, pid );

	  memset(&si, 0, sizeof(STARTUPINFO));
	  si.cb = sizeof(STARTUPINFO);
	  CreateProcess(NULL, theNewPath , NULL, NULL,
		  FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, p);

	  WaitForSingleObject( pi.hProcess, INFINITE );
  }
}

Code of the AntikillThreadWaiter2 Thread

In its turn, the second thread waits till the main program the ID of whose process was passed in the command line is closed. If the user closes this process, this thread starts it again.

C++
void AntikillThreadWaiter2(LPVOID param )
{
	  WaitForSingleObject( theParentProcess, INFINITE );

	  STARTUPINFO si;
	  PROCESS_INFORMATION pi;
	  CHAR theNewPath[MAX_PATH];
	  wsprintf( theNewPath,"%s\0", theAppPath );

	  memset(&si, 0, sizeof(STARTUPINFO));
	  si.cb = sizeof(STARTUPINFO);
	  CreateProcess(NULL, theNewPath , NULL, NULL,
		  FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, p);
	  ExitProcess(0);

	  return; // :))
}

Instead of the Conclusion

The given mechanism can be used as a variant for realization of "permanent" programs, for example for client applications of monitoring systems or parental control. In this article, I used C++ and MFC, but it isn't a restriction of the idea as it can be realized in any other languages.

The Russian version of this article can be found at http://plaincodesource.blogspot.com/2010/10/windows.html.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Russian Federation Russian Federation
Professional Windows/Java Mobile/Web-applications developer since 2000.

Comments and Discussions

 
Questionsucks Pin
Member 1198601619-Dec-15 8:30
Member 1198601619-Dec-15 8:30 
GeneralMy vote of 1 Pin
Ivan Leonenko14-Oct-13 21:43
Ivan Leonenko14-Oct-13 21:43 
BugWeak code/solution Pin
Brandon-X1200028-Mar-12 2:59
Brandon-X1200028-Mar-12 2:59 
GeneralMy vote of 1 Pin
LegnylsEtros10-May-11 4:27
LegnylsEtros10-May-11 4:27 
Generali like it Pin
kazemtnt10-May-11 2:16
kazemtnt10-May-11 2:16 
GeneralAnother OLD method But ..........!! Pin
AhmedOsamaMoh5-Nov-10 9:43
AhmedOsamaMoh5-Nov-10 9:43 
GeneralMy vote of 5 Pin
Jaded Hobo2-Nov-10 9:52
Jaded Hobo2-Nov-10 9:52 
GeneralMy vote of 2 Pin
ArchElf22-Oct-10 8:48
ArchElf22-Oct-10 8:48 
GeneralMy vote of 2 Pin
Sandeep Datta18-Oct-10 8:37
Sandeep Datta18-Oct-10 8:37 
GeneralMy vote of 2 Pin
PatLeCat16-Oct-10 4:58
PatLeCat16-Oct-10 4:58 
AnswerWell, Pin
va_dev16-Oct-10 1:51
va_dev16-Oct-10 1:51 
AnswerRe: Well, Pin
PatLeCat16-Oct-10 4:51
PatLeCat16-Oct-10 4:51 
GeneralPoor Idea Pin
saikat_ov13-Oct-10 22:23
saikat_ov13-Oct-10 22:23 
GeneralVery naughty Pin
Jim Crafton13-Oct-10 10:52
Jim Crafton13-Oct-10 10:52 
Generalnot very nice Pin
haisan13-Oct-10 6:11
haisan13-Oct-10 6:11 
GeneralMy vote of 3 Pin
haisan13-Oct-10 6:10
haisan13-Oct-10 6:10 
GeneralVirus Pin
Ahmed Charfeddine13-Oct-10 1:30
Ahmed Charfeddine13-Oct-10 1:30 
Generalnice try, but .... Pin
Gunnar Bolle12-Oct-10 21:10
Gunnar Bolle12-Oct-10 21:10 
QuestionC# Source Code Pin
knoami12-Oct-10 6:25
knoami12-Oct-10 6:25 
AnswerRe: C# Source Code Pin
Brandon-X1200029-Jan-12 8:15
Brandon-X1200029-Jan-12 8:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.