前言
python 里面有 dis 模块,可以查看 python 源代码编译成的字节码。
而 php 里面要查看 zend 虚拟机中执行的 opcode,则可以使用 vld 扩展。
安装
进入 pecl 上的扩展包界面,找到最新的 0.17.0 版本的扩展包并下载:
| 1
 | wget https://pecl.php.net/get/vld-0.17.0.tgz
 | 
解压后进入扩展目录进行安装:
| 12
 3
 
 | ../bin/phpize./configure --with-php-config=/home/aluvion/桌面/php7.4.7/bin/php-config --enable-vld
 make && make install
 
 | 
最后修改 php.ini 启用扩展:
查看 phpinfo:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | root@Aluvion:/home/aluvion/桌面/php7.4.7/bin# ./php -i | grep vldvld
 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(是否执行脚本),测试脚本:
| 12
 3
 4
 
 | <?php$y = 3;
 $fn1 = fn($x) => $x * $y;
 echo $fn1(2);
 
 | 
运行:
| 1
 | ./php -dvld.active=1 -dvld.execute=0 index.php
 | 
结果:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 
 | Finding entry pointsBranch 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
 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
 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