execve
execve这个函数有三个参数
1 | int execve(const char *file,char *const argv[],char *const envp[]) |
第一个参数,是要打开运行的二进制文件,这个是个文件路径,绝对路径和相对路径都可以
1、文件路径为/bin/sh,这个sh其实是个shell程序,如果argv是空(0也可以),那么就会去打开一个shell,所以execve(“/bin/sh”,0,0)是我们最常用的,but如果argv不为空呢,sh就可以变成变成一个shell脚本解析器,这时候argv应该是这么组成char *argv[]={“/bin/sh”,”flag”,NULL}
2、文件路径为/bin/cat,这个cat故名思议就是打印文件内容的程序,函数形式为execve(“/bin/cat”,argv,0),argv[]={“/bin/cat”,”flag”,NULL}这样子这个数组的第一个内容是文件路径,这个和execve的第一个参数一样,但是吧由于argv的特性,所以数组的第一个一定得是这个,然后第二个就是我们要解析的脚本路径,我这边是相对路径,然后第三个是空,这个是argv的要求,要求最后一个一定得是NULL,这个有什么用呢,如果argv里面的要解析的文件不是shell程序,那么就会把文件内容以报错的形式输出出来,如果题目把0(标准输入)和1(标准输出)关了,还能这么拿到flag
1 | int main(int argc,char* argv[]) |
在说明第二个参数之前,我们要说明一下这个execve的功能,我们知道程序的执行是由进程执行的,那么如果使用的execve,这个函数后面的代码全部不执行,转头去执行我们第一个参数指向的二进制代码
主函数是有参数的,可以通过这个参数传一些信息给主函数
第二个参数,我们上面提到了主函数有两个参数,第二个参数叫做argv,这个刚好和我们第二个参数名字一样,其实我们第二个参数就是原封不动的传给要去执行的二进制代码的argv参数,这个参数的详细介绍后面再说
第三个参数是环境变量,这个我并没有细究,因为通常都是NULL