ed2k解析源码php,PHP源码调试分析

前言

在看代码的时候遇到了PHP的一些函数,有些函数的特性很魔性,并不好理解。

于是尝试搭建环境对PHP源码进行调试,希望更加深入的一些理解PHP的特性。

必备安装

目标:在Windows环境下,构建PHP7.2的源代码编译和调试环境

安装VisualStudio

首先需要安装最强IDEVisual Studio,这个软件的版本有很多,我选择的是Visual Studio Professional 2017 (version 15.7)。 下载链接:

ed2k://|file|mu_visual_studio_professional_2017_version_15.3_x86_x64_11100064.exe|1069960|900673A59F0798822207F72FAA0DA6A9|/

需要其他版本(VS2015等),可以到MSDN上的开发人员工具栏目自行选择下载即可。

安装过程非常简单,注意两个调试必备勾选,其他的选项根据自己需求选择

xmorient

php-sdk

PHP SDK是用于Windows PHP构建的工具包,也是必不可少的工具。 下载地址:

https://github.com/Microsoft/php-sdk-binary-tools

我选择的版本为最新版php-sdk-2.1.7。

PHP

本文主角,我选择的版本为PHP 7.2.1。 下载地址:

https://github.com/php/php-src

下载完成后使用Git Bash切换分支

cd php-src

git checkout PHP-7.2.1

编译PHP

进入php-sdk的目录,可以看到目录下面有4个Windows批处理文件

xmorient

前面安装的是Visual Studio 2017,操作系统也是64位的,因此这里选择phpsdk-vc15-x64.bat,打算编译64位的。

xmorient

在php-sdk目录打开CMD窗口,运行phpsdk-vc15-x64.bat。 可以发现有了新的Shell提示符$。

继续在新的shell下运行命令

phpsdk_buildtree phpdev

这时候我们会发现php-sdk这个目录下面会多一个名为phpdev的文件夹。

xmorient

注意Shell的运行路径也发生了变化php-sdk\phpdev\vc15\x64\。

xmorient

再将php-src整个文件夹移动至php-sdk\phpdev\vc15\x64\下面。

xmorient

然后shell中进入php-src目录,执行命令,下载依赖关系组件。

phpsdk_deps --update --branch maste

成功信息如下:

xmorient

运行buildconf.bat生成的configure文件,配置好参数,执行命令如下

configure --disable-all --enable-cli --enable-debug

成功信息如下:

xmorient

执行编译命令nmake

xmorient

编译成功信息为:

SAPI sapi\cli build complete

可执行的二进制文件路径为

php-sdk\phpdev\vc15\x64\php-src\x64\Debug_TS\php.exe

观察是否输出php信息,编译成功则输出

php.exe -v

调试配置

断点调试的需要一个趁手的工具,可以使用之前安装的Visual Studio 2017,但我个人选择的是轻量级的Vs code。

安装Vs code,然后这里需要安装C/C++的拓展,调试的方式为启动调试。

xmorient

点击调试 --> 打开配置,设置配置文件launch.json的参数如下

xmorient

program,二进制可执行文件路径。

args,同目录下运行的PHP文件,也就是我们要调试的文件

cwd,二进制可执行文件目录

点击调试按钮,即可开始调试。

xmorient

调试getimagesize函数

这里选择getimagesize这个函数进行断点调试。 探究为何这个函数如何加载网络图片资源;为何这个函数在Windows下

修改调试的1.php内容如下

getimagesize("http://www.rai4over.cn/images/avatar.jpg");

#getimagesize("./avatar.jpg");

?>

在php-sdk\phpdev\vc15\x64\php-src\ext\standard\image.c中设置getimagesize的断点

xmorient

点击调试后程序会停在这里则表示断点成功。 通常会使用F10,F11进行调试。 - F10,单步跳过,调试时不进入函数内部。 - F11,单步调试,调试时进入函数内部。

比较麻烦的,单纯的F11调试耗费时间,而F10又可能跳过函数关键函数,难以定位。

于是我便采F10为主,提升调试效率,一边F10,一边打开Wireshark观察HTTP请求流量。

当过某个函数产生流量后,再F11进入函数内部进行调试。

最终得到函数调用栈(由下至上):

send

php_sockop_write

_php_stream_write_buffer

_php_stream_write

php_stream_url_wrap_http_ex

php_stream_url_wrap_http

_php_stream_open_wrapper_ex

php_getimagesize_from_any

PHP_FUNCTION

send()是Windows Api,能够通过已经建立的连接发送数据。

在phpdev\vc15\x64\php-src\main\streams\xp_socket.c第77行被调用。

didwrite = send(sock->socket, buf, XP_SOCK_BUF_SIZE(count), (sock->is_blocked && ptimeout) ? MSG_DONTWAIT : 0);

这也是这个函数加载网络图片资源的原因,之前印象中一直以为只能获取本地资源,踩过大坑。

修改为获取本地图片资源

#getimagesize("http://www.rai4over.cn/images/avatar.jpg");

getimagesize("./avatar.jpg");

?>

函数栈调用

xmorient

在php-sdk\phpdev\vc15\x64\php-src\Zend\zend_virtual_cwd.c第841行,发现调用了FindFirstFileExW()函数。

hFind = FindFirstFileExW(pathw, FindExInfoBasic, &dataw, FindExSearchNameMatch, NULL, 0);

这个函数就是

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值