I am confused with the syscall of __NR_execve
. When I learn linux system call. The correct way that I know to use execve
is like this:
char *sc[2];
sc[0]="/bin/sh";
sc[1]= NULL;
execve(sc[0],sc,NULL);
Then the function execve
will call syscall()
to get into system kernel with putting the arguments on Registers EAX
, EBX
, ECX
and EDX
. However, It still succeed if I use
execve("/bin/sh",NULL,NULL);
But if I replace "/bin/sh"
with "/bin/ls"
,it fail with:
A NULL argv[0] was passed through an exec system call.
I wonder why "/bin/sh"
can be executed successfully without enough parameters while "/bin/ls"
fail?
RETURN VALUES As the execve() function overlays the current process image with a new process image the successful call has no process to return to. If execve() does return to the calling process an error has occurred; the return value will be -1 and the global variable errno is set to indicate the error.
Execve () The execve function is mainly used to smear(overlay) a process running because of the call to fork(). This makes the program that is currently running by the process called it to get replaced with another new program, involving a newly initialized heap, stack, and other data segments.
This is not a kernel issue. The kernel will run with the filename
arg of execve
regardless of whether argv
and envp
are NULL
or not. It is just a Unix convention that argv[0]
points to the program name.
And what you saw is just normal, i.e. nothing is wrong. Because ls
is part of GNU's coreutils, and all programs in the coreutils package call set_program_name
to do some setup work. You can see this in the source: it checks whether argv[0]
is NULL, and it will call abort
when it is.
On the other hand, /bin/sh
is apparently a program that does not belong to coreutils, and does not check against argv[0]
. That's why it runs without the problem.
Refer to the source code:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With