文章目录
- 写在前面
- 命令执行底层分析
写在前面
新法颁布,很多也不敢发了,就偶尔写一篇有意思的东西吧
命令执行底层分析
注意本篇是基于windows平台进行的分析
环境这方面就不多说了VisualStudio、Vscode、php-src源码编译
插件用了c\c++、CodeRunner,环境很简单不想多说,直接干活
故事从一个system('whoami');
说起,你明天都输入这些函数真的就不好奇干了些什么吗
分析前先给大家看看函数调用栈,很清晰
回到正题
通过全局搜索,我们定位到了ext\standard\exec.c
第263行
这时候顺便还发现exec
、system
、passthru
调用的是同一个函数php_exec_ex
静态调试有限,直接打上断点动态调试,首先是对cmd参数进行初始化处理
这是一个宏定义函数,实际上调用zend_parse_arg_string
实际上是对执行的命令检查是否为空并且赋值
接下来,看到这句话我似乎明白了当初的低版本命令执行等骚姿势为什么高版本不行了
接下来调用php_exec
发现函数内部会首先调用VCWD_POPEN()
函数去处理cmd指令,可以看到VCWD_POPEN()
函数调用会通过相应的平台去执行,不赘述
可以看到通过宏定义,实际上调用了virtual_popen
而virtual_popen
的核心是popen_ex
,对于不同平台实现也不同
继续看看它干了些什么
这里面有个比较关键的分配空间的操作,为什么加一个/c
你细品
实际上最终cmd的调用是cmd.exe /c "whoami"
是不是和bash -c
很像呢,从这里可以看出
进行类型转换
到这里也就会发现system命令执行函数底层都会调用系统终端cmd.exe来执行传入的指令参数,既然要调用cmd,肯定就要启动相应的进程
这里通过Windows系统API来启动cmd.exe进程,通过搜索引擎了解发现
在 Windows 平台上,创建进程有 WinExec,system,_spawn/_wspawn,CreateProcess,ShellExecute 等多种途径,但基本上还是由 CreateProcess 家族封装的。
本文章著作权归作者所有,任何形式的转载都请注明出处。
看看这个函数的函数声明,对照上面参数看一看就ok
因此它最终将进程运行的结果信息以流的形式返回,也就完成了PHP命令执行函数的整个调用过程
后面就是对这个返回的文件流的操作就不分析了