为什么execve系统调用在没有任何argv参数的情况下运行“/ bin / sh”,而不是“/ bin / ls”?

时间:2016-04-17 07:23:15

标签: c linux system-calls glibc shellcode

我对__NR_execve的系统调用感到困惑。当我学习linux系统调用。我知道使用execve的正确方法是这样的:

char *sc[2]; 
sc[0]="/bin/sh"; 
sc[1]= NULL; 
execve(sc[0],sc,NULL); 

然后函数execve将调用syscall()进入系统内核,并将参数放在寄存器EAXEBXECX和{{1 }}。但是,如果我使用

,它仍然会成功
EDX

但如果我将execve("/bin/sh",NULL,NULL); 替换为"/bin/sh",则会失败并显示:

"/bin/ls"

我想知道为什么在A NULL argv[0] was passed through an exec system call. 失败时没有足够的参数可以成功执行"/bin/sh"

1 个答案:

答案 0 :(得分:10)

这不是内核问题,无论filenameargv是否envp,内核都会运行NULL arc of exec,它只是一个unix约定argv[0]指向程序名称。

你看到的是正常的,没有错。因为ls是GNU的coreutils的一部分,并且coreutils包中的所有程序都调用set_program_name来进行一些设置工作,你可以在源代码中看到它检查argv[0]是否为NULL,以及如果是,它会调用abort。 另一方面,/bin/sh显然是一个不属于coreutils的程序,并且不会检查argv[0],这就是它没有问题的原因。

参考源代码:

http://www.cmsws.com/examples/applications/phpexcel/Documentation/API/PHPExcel/PHPExcel_Cell.html#methodgetColumn

http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c#n1285