recently I had to clean up a hacked server. The malicious process would appear as "who" or "ifconfig eth0" or something like that in "ps aux" output, even tough the executable was just a jumble of letters, which was shown in /proc/[pid]/status .

I'm curious as to how the process managed to mask itself like that.

  • What's type of the execuable?
    – cuonglm
    Nov 12, 2014 at 7:23
  • It was binary, not a shell script if that's what you ask.
    – Pentium100
    Nov 12, 2014 at 7:25

5 Answers 5


Manipulating the name in the process list is a common practice. E.g. I have in my process listing the following:

root      9847  0.0  0.0  42216  1560 ?        Ss   Aug13   8:27 /usr/sbin/dovecot -c /etc/dovecot/d
root     20186  0.0  0.0  78880  2672 ?        S    Aug13   2:44  \_ dovecot-auth
dovecot  13371  0.0  0.0  39440  2208 ?        S    Oct09   0:00  \_ pop3-login
dovecot   9698  0.0  0.0  39452  2640 ?        S    Nov07   0:00  \_ imap-login
ericb     9026  0.0  0.0  48196  7496 ?        S    Nov11   0:00  \_ imap [ericb]

Dovecot uses this mechanism to easily show what each process is doing.

It's basically as simple as manipulating the argv[0] parameter in C. argv is an array of pointers to the parameters with which the process has been started. So a command ls -l /some/directory will have:

argv[0] -> "ls"
argv[1] -> "-l"
argv[2] -> "/some/directory"
argv[3] -> null

By allocating some memory, putting some text in that memory, and then putting the address of that memory in argv[0] the process name shown will have been modified to the new text.

  • 4
    It does not work quite like that. Pointing argv[0] to a different location doesn't change how the process appears to ps. The kernel doesn't care about the pointers in argv. Rather the kernel remembers which range of memory the actual arguments is in and makes that visible to ps and other tools. Those tools will then have to identify the boundaries between the arguments by looking for the NUL termination between each argument.
    – kasperd
    Sep 17, 2018 at 23:53

Changing argv[] is not portable. On Linux you can't simply change argv[0] to point to a longer string either. You'd have to overwrite the existing arguments and take care not to overwrite the environment variables that follow in the address space.

libbsd provides an implementation of setproctitle(3) for Linux that makes this much easier.


There are two Linux-standard ways to do this, one of which comes from glibc and might be portable to other non-Linux systems:

It's possible that changing argv[0] used to work, but at least on my current Linux system it does nothing to the output in ps.

See this answer for more details and a code example: https://stackoverflow.com/a/55584492/737303


In language like C, a process can change its name by changing argv[0].


#include <stdio.h>

int main(int argc, char *argv[]) {
    argv[0][2] = 'A';
    return 0;

Then compile it:

$ gcc test.c
$ ls
$ ./a.out

In other terminal:

$ ps -ef | grep '[a].out'
$ ps -ef | grep '[A].out'
cuonglm  17979 17569  0 14:51 pts/0    00:00:00 ./A.out

Higher level language also allows you to do this, example in Perl, you can modify $0 variable to change process name.


It is common for a hacker/rootkit/exploit to immediately replace the various systems tools such as /bin/bash, /bin/ps, /bin/ls, etc., with hacked versions which modify the output to hide their hacked scripts/executables but otherwise behave the same.

For this reason, I recommend using a physical CD in any physical servers that you can reference a copy of known-good basic utilities. This way, if you suspect a compromise, you can reference a version of these tools which are read-only and are known to be safe.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.