前言
python 里面有 dis 模块,可以查看 python 源代码编译成的字节码。
而 php 里面要查看 zend 虚拟机中执行的 opcode,则可以使用 vld 扩展。
安装
进入 pecl 上的扩展包界面,找到最新的 0.17.0 版本的扩展包并下载:
wget https://pecl.php.net/get/vld-0.17.0.tgz
解压后进入扩展目录进行安装:
../bin/phpize
./configure --with-php-config=/home/aluvion/桌面/php7.4.7/bin/php-config --enable-vld
make && make install
最后修改 php.ini 启用扩展:
extension=vld.so
查看 phpinfo:
root@Aluvion:/home/aluvion/桌面/php7.4.7/bin# ./php -i | grep vld
vld
vld support => enabled
vld.active => 0 => 0
vld.col_sep => =>
vld.dump_paths => 1 => 1
vld.execute => 1 => 1
vld.format => 0 => 0
vld.save_dir => /tmp => /tmp
vld.save_paths => 0 => 0
vld.skip_append => 0 => 0
vld.skip_prepend => 0 => 0
vld.verbosity => 1 => 1
确认 vld 已经开启。
使用
主要的两个参数,-dvld.active(是否使用扩展)和 -dvld.execute(是否执行脚本),测试脚本:
<?php
$y = 3;
$fn1 = fn($x) => $x * $y;
echo $fn1(2);
运行:
./php -dvld.active=1 -dvld.execute=0 index.php
结果:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename: /home/aluvion/桌面/php7.4.7/bin/index.php
function name: (null)
number of ops: 9
compiled vars: !0 = $y, !1 = $fn1
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 3
3 1 DECLARE_LAMBDA_FUNCTION '%00%7Bclosure%7D%2Fhome%2Faluvion%2F%E6%A1%8C%E9%9D%A2%2Fphp7.4.7%2Fbin%2Findex.php%3A3%240'
2 BIND_LEXICAL ~3, !0
3 ASSIGN !1, ~3
4 4 INIT_DYNAMIC_CALL !1
5 SEND_VAL_EX 2
6 DO_FCALL 0 $5
7 ECHO $5
5 8 > RETURN 1
branch: # 0; line: 2- 5; sop: 0; eop: 8; out0: -2
path #1: 0,
Function %00%7Bclosure%7D%2Fhome%2Faluvion%2F%E6%A1%8C%E9%9D%A2%2Fphp7.4.7%2Fbin%2Findex.php%3A3%240:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename: /home/aluvion/桌面/php7.4.7/bin/index.php
function name: {closure}
number of ops: 5
compiled vars: !0 = $x, !1 = $y
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
3 0 E > RECV !0
1 BIND_STATIC !1
2 MUL ~2 !0, !1
3 > RETURN ~2
4* > RETURN null
branch: # 0; line: 3- 3; sop: 0; eop: 4
path #1: 0,
End of function %00%7Bclosure%7D%2Fhome%2Faluvion%2F%E6%A1%8C%E9%9D%A2%2Fphp7.4.7%2Fbin%2Findex.php%3A3%240
上半是主脚本的 opcode,下半是匿名函数的 opcode,还挺好看懂的。
Orz