关于fork和execve系统调用

Pwn*_*Pwn 10 unix linux

据说fork系统调用创建了调用进程的克隆,然后(通常)子进程发出execve系统调用以更改其映像并运行新进程.为什么这两步?

BTW,什么execve代表什么?

cam*_*amh 15

两步的原因是灵活性.在这两个步骤之间,您可以修改新执行程序将继承的子进程的上下文.

您可能想要改变的一些事情是:

  • 文件描述符
  • 用户/组ID
  • 处理组和会话ID
  • 当前目录
  • 资源限制
  • 调度优先级和亲和力
  • 文件创建掩码(umask)

如果你没有拆分fork和exec而是只有一个类似spawn的系统调用,那么如果你想在子进程中设置不同的那些,就需要为每个这些进程属性设置参数.例如,请参阅Windows API中的CreateProcess参数列表.

使用fork/exec,您可以在执行新程序之前更改子项中所需的任何可继承的进程属性.

设置文件描述符是在子进程上下文中更改的常见事项之一.如果要捕获程序的输出,通常会在父系统中使用pipe(2)系统调用创建管道,在fork(2)之后,您将关闭父进程中的写入结束并关闭在调用execve(2)之前,在子进程中读取结束.(您还将使用dup(2)将管道的子端设置为文件描述符1(stdout)).这在单个系统调用中可能是不可能的或限制性的.


0x6*_*015 11

  • exec:执行新进程
  • v:使用参数数组
  • e:同时指定环境

exec的其他变体比比皆是:

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
Run Code Online (Sandbox Code Playgroud)
  • l:列出arg on function
  • p:使用$ PATH查找可执行文件


S.L*_*ott 9

每一步都比较简单.

在Unix中,您的进程有两个部分 - 带有应用程序代码("text")的只读存储区和读写存储区("data").

fork克隆了读写区域,只留下文本页面.您现在有两个进程运行相同的代码.它们的区别在于寄存器值 - 来自fork的返回值 - 它将父项与子项分开.

exec替换文本页面,仅保留数据页面.有许多形式的exec,取决于你传递给它的环境信息量.有关其他变体列表,请参见http://linux.die.net/man/3/exec.

  • 嗯,exec替换整个mm,而不仅仅是"text"...请参阅/usr/src/linux/fs/exec.c和/usr/src/linux/fs/binfmt_elf.c (6认同)