PHP内核之opcode的处理函数查找

来源:互联网 发布:淘宝美工需要注意什么 编辑:程序博客网 时间:2024/05/21 20:31

首先我们需要知道有个存放 所有opcode 的 opcode_handler_t 的函数指针字段 的集合 的文件 php-5.5.12\Zend\zend_vm_execute.h

void zend_init_opcodes_handlers(void){/* opcode执行函数的指针字段集合 */  static const opcode_handler_t labels[] = {  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,  ZEND_NOP_SPEC_HANDLER,        ........        ZEND_FAST_RET_SPEC_HANDLER,  ZEND_FAST_RET_SPEC_HANDLER,  ZEND_FAST_RET_SPEC_HANDLER,  ZEND_FAST_RET_SPEC_HANDLER,  ZEND_FAST_RET_SPEC_HANDLER,  ZEND_FAST_RET_SPEC_HANDLER,  ZEND_FAST_RET_SPEC_HANDLER,  ZEND_NULL_HANDLER  };  zend_opcode_handlers = (opcode_handler_t*)labels;}

接下来进入正题:

这里我们使用 日志记录的方式 查找 opcode 对应的处理函数

在 zend_vm_get_opcode_handler 方法中添加以下代码:

static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op){static const int zend_vm_decode[] = {_UNUSED_CODE, /* 0              */_CONST_CODE,  /* 1 = IS_CONST   */_TMP_CODE,    /* 2 = IS_TMP_VAR */_UNUSED_CODE, /* 3              */_VAR_CODE,    /* 4 = IS_VAR     */_UNUSED_CODE, /* 5              */_UNUSED_CODE, /* 6              */_UNUSED_CODE, /* 7              */_UNUSED_CODE, /* 8 = IS_UNUSED  */_UNUSED_CODE, /* 9              */_UNUSED_CODE, /* 10             */_UNUSED_CODE, /* 11             */_UNUSED_CODE, /* 12             */_UNUSED_CODE, /* 13             */_UNUSED_CODE, /* 14             */_UNUSED_CODE, /* 15             */_CV_CODE      /* 16 = IS_CV     */};/* 日志记录法记录opcode的处理函数 */int   op_index;FILE          *stream;op_index = opcode * 25 + zend_vm_decode[op->op1_type] * 5 + zend_vm_decode[op->op2_type];if((stream = fopen("./tmp/php-opcode.log", "a+")) != NULL){fprintf(stream, "opcode: %d, zend_opcode_handlers_index: %d\n", opcode, op_index );}fclose(stream);return zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1_type] * 5 + zend_vm_decode[op->op2_type]];}


然后编译php源码包,为了方便看代码中的opcode,编译时候记得开启动态链接库 vld

configure --disable-all --enable-snapshot-build --enable-cli --enable-cgi --enable-object-out-dir=..\obj --enable-session  --enable-vld=shared


编译完成后 

1、在生成的 obj\Release_TS\php-5.5.12 下 手动新建 tmp 文件夹

2、在生成的 obj\Release_TS\php-5.5.12 下 做php.ini文件 并制定ext为扩展目录

3、添加php_vld.dll扩展

至此准备工作完成,接下来 我们看步入真正的查找工作

php代码:


opcode信息:



生成的opcode.log日志

其中的

opcode 数值 可从 http://php.net/manual/zh/internals2.opcodes.list.php 中查找到

 zend_opcode_handlers_index 就是 stati cconst opcode_handler_t labels[] 的索引,里面对应了处理函数的名称

0 0