execve() 有一个奇怪的行为取决于未使用变量的状态
execve() has a weird behavior depending on the state of an unused variable
我最近一直在研究 execve() 系统函数。这段代码可能没有多大意义,但这不是这个问题的主要焦点。 (自从使用 this 线程后,我设法使其正常工作)。
我遇到了一个非常奇怪的行为,想要解释或确认这样的事情不应该发生。
“窃听”代码是这样的:
#include <unistd.h>
int main(int argc, char **argv, char **env)
{
if (argc != 2)
return (ERROR_CODE);
char *test[] = { argv[1] };
char *a[] = { NULL };
execve(argv[1], test, env);
return (SUCCESS_CODE);
}
使用参数编译和执行它会正确执行该函数,在我的例子中:
$> gcc main.c
$> ./a.out "/bin/ls"
这将像 ls 函数一样工作。
现在 remove/comment 这一行:
char *a[] = { NULL };
这个变量显然没有用到,完全没用。
再次执行相同的步骤,由于某种原因,它没有输出任何内容,这个随机变量为我破解了代码。 (我是 运行 Ubuntu 20.04,Gnome 3.36.8 和 gcc 9.3.0)。
如果您需要有关我的 OS 或任何其他信息,请随时询问。
PS:我想我理解代码试图解决这个问题的方式,但这对我来说毫无意义。
$> man execve
main(int argc, char *argv[])
char *newargv[] = { NULL, "hello", "world", NULL };
...
execve(argv[1], newargv, newenviron);
手动示例以 null 终止“newargv”,我的想法是编译器以某种方式在某处决定将我的变量“test”和“a”融合在一起,以以 null 终止“test”?
是的,你 不小心 看到了那个“融合”,因为你没有用 NULL
正确地终止 argv
并且内存布局发生了对你有利。如果你不那么幸运,你会在那里得到垃圾,或者一个段错误。
The argument argv
is a pointer to a null-terminated array of character pointers to null-terminated character strings.
#include <unistd.h>
int main(int argc, char **argv, char **env)
{
if (argc != 2)
return (ERROR_CODE);
char *test[] = { argv[1], NULL };
execve(argv[1], test, env);
return (SUCCESS_CODE);
}
将是正确的调用。
我最近一直在研究 execve() 系统函数。这段代码可能没有多大意义,但这不是这个问题的主要焦点。 (自从使用 this 线程后,我设法使其正常工作)。
我遇到了一个非常奇怪的行为,想要解释或确认这样的事情不应该发生。
“窃听”代码是这样的:
#include <unistd.h>
int main(int argc, char **argv, char **env)
{
if (argc != 2)
return (ERROR_CODE);
char *test[] = { argv[1] };
char *a[] = { NULL };
execve(argv[1], test, env);
return (SUCCESS_CODE);
}
使用参数编译和执行它会正确执行该函数,在我的例子中:
$> gcc main.c
$> ./a.out "/bin/ls"
这将像 ls 函数一样工作。 现在 remove/comment 这一行:
char *a[] = { NULL };
这个变量显然没有用到,完全没用。 再次执行相同的步骤,由于某种原因,它没有输出任何内容,这个随机变量为我破解了代码。 (我是 运行 Ubuntu 20.04,Gnome 3.36.8 和 gcc 9.3.0)。
如果您需要有关我的 OS 或任何其他信息,请随时询问。
PS:我想我理解代码试图解决这个问题的方式,但这对我来说毫无意义。
$> man execve
main(int argc, char *argv[])
char *newargv[] = { NULL, "hello", "world", NULL };
...
execve(argv[1], newargv, newenviron);
手动示例以 null 终止“newargv”,我的想法是编译器以某种方式在某处决定将我的变量“test”和“a”融合在一起,以以 null 终止“test”?
是的,你 不小心 看到了那个“融合”,因为你没有用 NULL
正确地终止 argv
并且内存布局发生了对你有利。如果你不那么幸运,你会在那里得到垃圾,或者一个段错误。
The argument
argv
is a pointer to a null-terminated array of character pointers to null-terminated character strings.
#include <unistd.h>
int main(int argc, char **argv, char **env)
{
if (argc != 2)
return (ERROR_CODE);
char *test[] = { argv[1], NULL };
execve(argv[1], test, env);
return (SUCCESS_CODE);
}
将是正确的调用。