Pages

Sunday, 19 April 2020

What's argv[0]?


Command-line arguments are transferred to C programs' main function as argv.

int main(int argc, char** argv)

The first argument, argv[0], has special meaning regarding processes' information.

1 argv[0] is taken as process name by "ps" command

$ ps -ef
smstong  22944 22847  0 17:09 pts/16   00:00:01 vim test.c
smstong  23069  8866  0 17:10 pts/22   00:00:00 -bash
smstong  24605  1721  0 Apr17 pts/11   00:00:00 bash

2 argv[0] is not necessarily the program's filename

Usually, the argv[0] is set to the program's filename by its parent process via

execl("/usr/bin/yes", "yes", NULL);

This is also the way most shells invoking commands.

But it's OK to set it to any string.

execl("/usr/bin/yes", "any string", NULL);

This trick is sometimes used by malware to cheat normal users. e.g. The following statement disguises malware as "bash".

execl("/usr/bin/malware", "bash", NULL);
 

3 argv[0] can be changed by its process at anytime

argv[0] is not only able to be set before running a program by "execl()" but also be changed after the program starts.

int main(int argc, char** argv)
{
   strcpy(argv[0], "any string");
   ...    
}

 Be careful when doing so as it may override argv[1] if the new string is too long.
You can even do it more ridiculously by changing it randomly every second. 

So, judging a process only by its name is far less than enough.

4 argv[0] has more interesting usages

Some programs customize their function based on argv[0], which means that the same program acts differently if run with different names.

int main(int argc, char** argv)
{
    if(strcmp(argv[0], "app1")==0){
        // do something
    }
    else if(strcmp(argv[0], "app2") == 0){
        // do other thing
    }else {
        // do default thing
    }
    return 0;
}

This trick is not always a good idea as it makes the program's usage not clear. 

No comments:

Post a Comment