是什么导致了这种分段错误?书中的例子

1 c

我正在阅读一本书,我尝试运行这个例子,但是我收到了一个分段错误 - gdb说它是在设置argv [0] = filename时;

此代码直接从本书的可下载代码示例中复制/粘贴.

#include <unistd.h>

int main() {
  char filename[] = "/bin/sh\x00";
  char **argv, **envp; // arrays that contain char pointers

  argv[0] = filename; // only argument is filename - segmentation fault here
  argv[1] = 0;  // null terminate the argument array

  envp[0] = 0; // null terminate the environment array

  execve(filename, argv, envp);
}
Run Code Online (Sandbox Code Playgroud)

编辑:这本书是黑客:Jon Erickson的剥削艺术,它有很好的评论.此特定示例用作将shell转换为shellcode部分中的机器代码的第一个教程,特别是它是exec_shell.c,可以从http://nostarch.com/hacking2/htm下载.我想一些有关使用此代码的上下文是必要的,以避免下面的一些负面评论,抱歉留下详细信息,并感谢您的帮助.

Dan*_*idy 11

这显然不是一本很好的书.问题是既没有argv也没有envp初始化,所以当你写信时argv[0],你试图覆盖内存中的一些随机位置.

尝试这样的事情:

#include <unistd.h>

int main() {
  char *filename = "/bin/sh";
  char *argv[2], *envp[1];

  argv[0] = filename;
  argv[1] = 0;

  envp[0] = 0;

  execve(filename, argv, envp);
}
Run Code Online (Sandbox Code Playgroud)

这个替代方案初始化argvenvp在堆栈上,有足够的空间分别包含两个指针和一个指针.

在上面的代码中,我做了一个额外的修改来修复另一个常见的(但在这种情况下,无害)误解.的\x00,这是在端部"/bin/sh\x00"是多余的,因为用C静态字符串是隐式空终止."/bin/sh\x00"是由两个空值终止的字符串.

另外,正如caf所指出的,这是一个更紧凑的例子,具有完全相同的含义:

#include <unistd.h>

int main() {
  char *filename = "/bin/sh";
  char *argv[2] = { filename, 0 };
  char *envp[1] = { 0 };

  execve(filename, argv, envp);
}
Run Code Online (Sandbox Code Playgroud)