[英]Why can the execve system call run “/bin/sh” without any argv arguments, but not “/bin/ls”?
我对__NR_execve
的系统调用很困惑。 当我学习linux系统调用。 我知道使用execve
的正确方法是这样的:
char *sc[2];
sc[0]="/bin/sh";
sc[1]= NULL;
execve(sc[0],sc,NULL);
然后函数execve
将调用syscall()
进入系统内核,并将参数放在寄存器EAX
, EBX
, ECX
和EDX
。 但是,如果我使用它仍然会成功
execve("/bin/sh",NULL,NULL);
但是如果我用"/bin/ls"
替换"/bin/sh"
"/bin/ls"
,它会失败:
A NULL argv[0] was passed through an exec system call.
我想知道为什么在"/bin/ls"
失败的情况下,如果没有足够的参数可以成功执行"/bin/sh"
?
这不是内核问题,内核将运行filename
arg of execve而不管argv
和envp
是否为NULL
,它只是argv[0]
指向程序名称的unix约定。
而你所看到的只是正常,没有错。 因为ls
是GNU的coreutils的一部分,并且coreutils包中的所有程序都调用set_program_name
来进行一些设置工作,你可以在源代码中看到它检查argv[0]
是否为NULL,并且它会在调用时调用abort
。 另一方面, /bin/sh
显然是一个不属于coreutils的程序,并且不会检查argv[0]
,这就是为什么它运行没有问题。
参考源代码:
http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c#n1285
http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/progname.c#n51
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.