Click here to Skip to main content
Licence CPOL
First Posted 12 Oct 2010
Views 14,623
Downloads 281
Bookmarked 49 times

How to Create an "unkillable" Windows Process

By | 12 Oct 2010 | Article
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.
    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.

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.

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)

About the Author

Slava Archibasov

Software Developer

Russian Federation Russian Federation

Member

Follow on Twitter Follow on Twitter
Professional Windows/Java Mobile/Web-applications developer since 2000.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
BugWeak code/solution PinmemberBrandon T. H.2:59 28 Mar '12  
GeneralMy vote of 1 PinmemberLegnylsEtros4:27 10 May '11  
Generali like it Pinmemberkazemtnt2:16 10 May '11  
GeneralAnother OLD method But ..........!! PinmemberAdore C++9:43 5 Nov '10  
GeneralMy vote of 5 PinmemberJaded Hobo9:52 2 Nov '10  
GeneralMy vote of 2 PinmemberArchElf8:48 22 Oct '10  
GeneralMy vote of 2 PinmemberSandeep Datta8:37 18 Oct '10  
GeneralMy vote of 2 PinmemberPatLeCat4:58 16 Oct '10  
AnswerWell, PinmemberSlava Archibasov1:51 16 Oct '10  
AnswerRe: Well, PinmemberPatLeCat4:51 16 Oct '10  
GeneralPoor Idea Pinmembersaikat_ov22:23 13 Oct '10  
GeneralVery naughty PinassociateJim Crafton10:52 13 Oct '10  
Generalnot very nice Pinmemberhaisan6:11 13 Oct '10  
GeneralMy vote of 3 Pinmemberhaisan6:10 13 Oct '10  
GeneralVirus PinmemberAhmed Charfeddine1:30 13 Oct '10  
Generalnice try, but .... PinmemberGunnar Bolle21:10 12 Oct '10  
QuestionC# Source Code Pinmemberknoami6:25 12 Oct '10  
AnswerRe: C# Source Code PinmemberBrandon T. H.8:15 29 Jan '12  

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

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 12 Oct 2010
Article Copyright 2010 by Slava Archibasov
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid