How to use PHPEmbedSAPI to implement Opcodes viewer

Source: Internet
Author: User
Tags sapi
This article mainly introduces how to use PHPEmbedSAPI to implement the Opcodes viewer. if you need it, you can refer to PHP to provide an Embed SAPI. that is to say, PHP allows you to call functions provided by PHP/ZE in C/C ++. This article uses the Embed SAPI to implement a PHP opcodes viewer.

First, download the PHP source code for Compilation. now I am using PHP5.3 alpha2

Go to the source code directory:

./Configure -- enable-embed -- with-config-file-scan-dir =/etc/php. d -- with-mysql -- with-config-file-path =/etc/
./Make
./Make install

Finally, remember to copy the generated libphp5.so to the Directory of the runtime library. I copied it directly to/lib/. Otherwise, an error will be reported when running your own embed program:

./Embed: error while loading shared libraries: libphp5.so: cannot open shared object file: No such file or directory

If you are not familiar with php sapi, I suggest you read my article: Understanding Zend SAPIs (Zend SAPI Internals)
At this time, you can embed the PHP script parser in your C code. my example:

#include "sapi/embed/php_embed.h"int main(int argc, char * argv[]){ PHP_EMBED_START_BLOCK(argc,argv); char * script = " print 'Hello World!';"; zend_eval_string(script, NULL,          "Simple Hello World App" TSRMLS_CC); PHP_EMBED_END_BLOCK(); return 0;}

Then you need to specify the include path, a simple Makefile.

CC = gccCFLAGS = -I/usr/local/include/php/ \   -I/usr/local/include/php/main \   -I/usr/local/include/php/Zend \   -I/usr/local/include/php/TSRM \   -Wall -gLDFLAGS = -lstdc++ -L/usr/local/lib -lphp5ALL: $(CC) -o embed embed.cpp $(CFLAGS) $(LDFLAGS)

After the compilation is successful, run. we can see that stdout outputs Hello World!

Based on this, we can easily implement a Opcodes dumper similar to vld:
First, we define the opcode conversion function (all opcodes can view Zend/zend_vm_opcodes.h );

Char * opname (zend_uchar opcode) {switch (opcode) {case ZEND_NOP: return "ZEND_NOP"; break; case ZEND_ADD: return "ZEND_ADD"; break; case ZEND_SUB: return "ZEND_SUB"; break; case ZEND_MUL: return "ZEND_MUL"; break; case ZEND_DIV: return "ZEND_DIV"; break; case ZEND_MOD: return "ZEND_MOD"; break; case ZEND_SL: return "ZEND_SL"; break; case ZEND_SR: return "ZEND_SR"; break; case ZEND_CONCAT: return "ZEND_CONCAT"; break; case when: return "then"; break; case ZEND_BW_AND: return "ZEND_BW_AND"; break; case ZEND_BW_XOR: return "ZEND_BW_XOR"; break; case ZEND_BW_NOT: return "ZEND_BW_NOT"; break ;/*... omitted .... */default: return "UNKNOW"; break;

Then define the zval and znode output functions:

 char *format_zval(zval *z){ static char buffer[BUFFER_LEN]; int len; switch(z->type) {  case IS_NULL:   return "NULL";  case IS_LONG:  case IS_BOOL:   snprintf(buffer, BUFFER_LEN, "%d", z->value.lval);   return buffer;  case IS_DOUBLE:   snprintf(buffer, BUFFER_LEN, "%f", z->value.dval);   return buffer;  case IS_STRING:   snprintf(buffer, BUFFER_LEN, "\"%s\"", z->value.str.val);   return buffer;  case IS_ARRAY:  case IS_OBJECT:  case IS_RESOURCE:  case IS_CONSTANT:  case IS_CONSTANT_ARRAY:   return "";  default:   return "unknown"; }}char * format_znode(znode *n){ static char buffer[BUFFER_LEN]; switch (n->op_type) {  case IS_CONST:   return format_zval(&n->u.constant);   break;  case IS_VAR:   snprintf(buffer, BUFFER_LEN, "$%d", n->u.var/sizeof(temp_variable));   return buffer;   break;  case IS_TMP_VAR:   snprintf(buffer, BUFFER_LEN, "~%d", n->u.var/sizeof(temp_variable));   return buffer;   break;  default:   return "";   break; }}

Then define the output function of op_array:

void dump_op(zend_op *op, int num){ printf("%5d %5d %30s %040s %040s %040s\n", num, op->lineno,   opname(op->opcode),   format_znode(&op->op1),   format_znode(&op->op2),   format_znode(&op->result)) ;}void dump_op_array(zend_op_array *op_array){ if(op_array) {  int i;  printf("%5s %5s %30s %040s %040s %040s\n", "opnum", "line", "opcode", "op1", "op2", "result");  for(i = 0; i < op_array->last; i++) {   dump_op(&op_array->opcodes[i], i);  } }}

Finally, it is the main function of the program:

int main(int argc, char **argv){ zend_op_array *op_array; zend_file_handle file_handle; if(argc != 2) {  printf("usage: op_dumper 《script》\n");  return 1; } PHP_EMBED_START_BLOCK(argc,argv); printf("Script: %s\n", argv[1]); file_handle.filename = argv[1]; file_handle.free_filename = 0; file_handle.type = ZEND_HANDLE_FILENAME; file_handle.opened_path = NULL; op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC); if(!op_array) {  printf("Error parsing script: %s\n", file_handle.filename);  return 1; } dump_op_array(op_array); PHP_EMBED_END_BLOCK(); return 0;}

Compile and run the test script (sample. php ):

The code is as follows:


Sample. php:
Echo "laruence ";

Command:

The code is as follows:


./Opcodes_dumper sample. php

Get the output result (if you are confused about the following results, I suggest you read this article again: an in-depth understanding of the principles of PHP Opcodes ):

Script: sample. php

Opnum line opcode op1 op2 result
0 2 ZEND_ECHO "laruence"
1 4 ZEND_RETURN 1

Haha, how is it fun?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.