execve 函数是所有执行程序函数最底层的实现了,其参数为
int execve (const char *__path, char *const __argv[], char *const __envp[]);
可以设置要执行程序的路径(完整路径,函数不会给你在PATH目录中找)
程序运行时参数信息
程序运行时环境变量信息(函数不会给你自动继承父进程的环境变量,需要手动设置)
一个例子:
#include
#include
extern char **__environ;
int main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "Usage:%s \n", argv[0]);
return -1;
}
char *cmdline[] = {"sh", NULL};
execve(argv[1], cmdline, __environ);
perror("execve:");
return 0;
}
其中程序参数信息的数组,第一个是程序的名称,其实可以是任意非空字符串,在使用ps查看进程的时候,可以起到伪装进程名的作用。
这个程序被加载起来后会使用当前进程,也就是父进程的进程空间来执行,所以这个函数不会返回(如果返回了 那么说明出错了)。
编译上述代码,运行下
./a.out /usr/bin/gedit
使用pstree 查看下进程树
├─konsole─┬─bash───pstree
│ ├─bash───gedit───4*[{gedit}]
│ └─2*[{konsole}]
会发现没有a.out这个进程,看起来像是bash直接启动了 gedit ,这就是所谓的替换了。