system和execve的那些理解

在pwn过程中,system和execve这两个函数大家都是老朋友了,这几天趁着新生赛(对于初学者可能有些难,但是对于我刚刚好)好好深入学习了一下(博主老菜狗了)

execve

execve这个函数有三个参数

int execve(const char *file,char *const argv[],char *const envp[])

第一个参数,是要打开运行的二进制文件,这个是个文件路径,绝对路径和相对路径都可以
在说明第二个参数之前,我们要说明一下这个execve的功能,我们知道程序的执行是由进程执行的,那么如果使用的execve,这个函数非常霸道,直接改变进程的函数内容,这个函数后面的代码全部不执行,转头去执行我们第一个参数指向的二进制代码
然后我们要知道主函数是有参数的,这一点可能和平时认知不一样,我们可以通过这个参数传一些信息给主函数

 int main(int argc,char* argv[])

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

system

这个函数想必大家更为熟悉,system("/bin/sh")我们就可以拿到shell,其实system本质是调用了execve函数

这个是system的片段源码,我们可以看见,首先fork了一个子进程,然后再子进程中调用了execve函数,然后还有一段就是wait函数,等待子进程执行完,这也就是为什么system本质是调用execve,但是system却可以执行接下来的代码,原来是子进程挡刀了,我们着重看一下,system只有一个参数,就是cmd,但是我们可以看到execve有三个参数,先看第一个参数,我们发现是"/bin/sh"铁打不动,接下来还有就是new_argv不为空,之前说不为空的话sh就可以变成一个解析器,它也可以变成shell,你看这个new_argv第一个变量是"/sh"这个应该是这个内核的路径已经调整到了/bin下了,因为我试过用c语言编写的话,单独/sh是不行的,要/bin/sh,然后第二个参数是-c,这个在sh手册里也有说明,这个表示我后面要向这个shell输入指令了,然后第三个变量就是我们system的参数cmd(也就是指令),接下来第四个变量就是NULL,所以说system和execve还是有很大的关系的
同时还有个要说明,system里面的参数其实就是我们shell的指令,在指令中sh flag这个我们说过sh可以打开一个shell,也可以是shell程序解析器,这个指令就是去解析flag,我们在上面说过这样子会把flag的内容当做报错输出,这样子也是一种形式
其实execve还有很多参数和功能,感兴趣的可以在shell里输入man sh去查看手册

posted @ 2022-10-06 19:38  予柒  阅读(1019)  评论(0编辑  收藏  举报
返回顶端
Live2D /*修改地一:waifu.css*/
/*修改地二:waifu.css*/
/*修改地三:live2d.js*/ /*修改地四:waifu-tips.js*/