前言

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


Web PHP

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

逆向花指令入门
Python从编译到执行