Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么execve系统调用run“/bin/sh“;没有任何argv参数,但不是/垃圾箱/垃圾箱;?_C_Linux_System Calls_Glibc_Shellcode - Fatal编程技术网

为什么execve系统调用run“/bin/sh“;没有任何argv参数,但不是/垃圾箱/垃圾箱;?

为什么execve系统调用run“/bin/sh“;没有任何argv参数,但不是/垃圾箱/垃圾箱;?,c,linux,system-calls,glibc,shellcode,C,Linux,System Calls,Glibc,Shellcode,我对的系统调用感到困惑。当我学习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/sh”替换为“/bin/ls”,它将失败: A NU

我对
的系统调用感到困惑。当我学习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/sh”
替换为
“/bin/ls”
,它将失败:

A NULL argv[0] was passed through an exec system call.

我想知道为什么
“/bin/sh”
可以在没有足够参数的情况下成功执行,而
“/bin/ls”
失败?

这不是内核问题,内核将运行execve的
filename
arg,而不管
argv
envp
是否为
NULL
,这只是unix约定的
argv[0]
指向程序名

你所看到的一切都很正常,没有什么不对劲。由于
ls
是GNU的coreutils的一部分,coreutils包中的所有程序都调用
set\u program\u name
来执行一些设置工作,您可以在源代码中看到,如果为空,它将检查
argv[0]
,如果为空,它将调用
abort
。 另一方面,
/bin/sh
显然是一个不属于coreutils的程序,并且不检查
argv[0]
,这就是为什么它运行时没有问题

请参阅源代码:


我根本不指望
NULL
在那里工作;
execve
手册页说明
argv
是一个参数字符串数组;
NULL
指针不是指向数组的有效指针。(对
env
使用
NULL
也不好看;相反,使用
execv
execvp
,或传递指向
char*p=NULL
的指针)数组在作为函数参数传递时是指向其第一个元素的指针,因此NULL在这里肯定有效。@AnttiHaapala:,并将其视为指向空列表的指针。这是不鼓励的,而且不可移植,但在Linux上是未来的证明。我看到的主要用例是利用外壳代码,在系统调用(x86
int0x80
syscall
)之前将两个寄存器归零,而不是将
0
推到两个寄存器中。i、 e.它节省了几个字节的漏洞利用负载大小,并且如果负载中已经存在
“/bin/sh”
字符串,则不需要写入内存。@petercordes认为hellcodez保持兼容性很好,但是是的,手册页确实提到了这个例外,下面是一个没有任何argv的最小示例: