将空程序参数向量传递给execve()是否合法?
问题描述:
考虑下面的C码(x86_64的)将空程序参数向量传递给execve()是否合法?
#include <unistd.h>
int main()
{
execve("/bin/ls", 0, 0);
}
予编译为gcc a.c
和执行;我得到了SIGABRT
错误
A NULL argv[0] was passed through an exec system call. Aborted
下一页上gdb下运行,起初我也得到了SIGABRT
,但是我做了第二次运行和它的工作!
Starting program: /bin/ls [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
为什么?
我测试了/bin/sh
,发现它总是以* argv的[] = NULL工作...
我又写了一些可执行文件(不包括所需要的任何参数)来测试,发现所有这些工作。
所以我猜只有/bin/sh
或其他shell可以将* argv []设置为NULL,其他文件(如/bin/ls
)会失败或意外行为。
答
为execve()
系统调用的手册页说
的
argv
和envp
阵列必须各自包括在所述阵列的端部的空指针。
如果您的程序不符合这些要求,那么从这一点开始事情将不会如何。如果它对某些程序“起作用”,那只是运气不好。
手册页还表示
按照惯例,第一这些字符串(即
argv[0]
)应包含与正在执行的文件关联的文件名。
该约定相当强大(由POSIX授权),所以不能这样做的程序可以被认为是越野车。如果你要依靠argv[0]
,你的main()
测试它被正确调用是个好主意,所以你可以通过一个很好的错误消息而不是错误来失败,但并不是所有的程序都会这样做。
阅读[未定义行为](https://en.wikipedia.org/wiki/Undefined_behavior)。 –
阅读https://linux.die.net/man/2/execve并查看它期望的参数。 –
是的,我知道这是UB,execve()期望的是什么参数,但有什么方法可以找出它为什么工作,或者只是运气。 我正在解决一些安全挑战,如果我能找出它的工作原理,这对我的shellcode可能是一个很大的改进。 – poming