In general, the set of strings that are passed to main()
in the argv
array are set inside the program user space, mostly in a fixed place at the top of the program stack.
The reason for such a fixed place, is that some programs modify this area to allow for a privileged program (e.g. the ps
command) to gather and show you different command arguments, as the program evolves at runtime. This is used in programs like sendmail(8)
or in user program's threads, to show you which thread is doing what job in your program.
This is a feature that is not standard, it is used differently by the different operating systems (I have described you the BSD way) As far as I know, linux also exhibits this behaviour and Solaris.
In general, this makes the arguments to main something that, belonging to the user process space, has to be modified with care (using some operating system specific contract), as it is normally subject to rigid conventions. The ps(1)
command digs in the user space of the process it is going to show in order to show the long listing showing the command parameters. The different operating systems document (probably you can get this from the linker standard script used in your system the exact format or how the stack is intialized by the exec(2)
familiy of calls -- the exec(2)
manual page should be of help also)
I don't exactly know if this is what you expect, or if you just want to see if you can modify the arguments.... as something belonging to the user space of the proces, they are modifiable most probably, but I cannot guess any reasons to do that, apart of those described in this answer.
By the way, the FreeBSD manual page for the execlp(2)
system call shows the following excerpt:
The type of the argv
and envp
parameters to execle()
, exect()
, execv()
,
execvp()
, and execvP()
is a historical accident and no sane
implementation should modify the provided strings. The bogus parameter
types trigger false positives from const
correctness analyzers. On
FreeBSD, the __DECONST()
macro may be used to work around this
limitation.
This states clearly that you cannot modify them (in FreeBSD at least). I assume the ps(8)
command will handle the extra work of verifying those parameters in a proper way in order to never incurr in a security issue bug (well, this can be tested, but I leave it as an exercise for the interested people)
EDIT
If you look at /usr/include/sys/exec.h
(line 43) in FreeBSD, you will find that there's a struct ps_strings
located in the top of the user stack, that is used by ps(1)
command to find and locate the the process environment and argv
strings. While you can edit this to change the information a program gives to ps(1)
, you have a setproctitle(3)
library function (again, all of this is FreeBSDish, you'll have to dig to get the way linux, or other, solves this problem)
I've tried this approach, but it doesn't work. Today there's a library function call to get this approach, but the top of the stack is actually filled with the data mentioned above (I assume for compatibility reasons)
argv
can also change any other data in your process space; so DLL intection, debuggers etc. The question simplifies to: what can change arbitrary data in my programs process space? – Varienargv
parameter tomain()
. As it belongs to the process, it should be capable, depending if the argument strings are located in read-only or writable memoy. – Yeast