青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
數(shù)據(jù)加載中……

使用PHP Embed SAPI實(shí)現(xiàn)Opcodes查看器

http://www.laruence.com/2008/09/23/539.html

 

PHP提供了一個(gè)Embed SAPI,也就是說,PHP容許你在C/C++語言中調(diào)用PHP/ZE提供的函數(shù)。本文就通過基于Embed SAPI實(shí)現(xiàn)一個(gè)PHP的opcodes查看器。
首先,下載PHP源碼以供編譯, 我現(xiàn)在使用的是PHP5.3 alpha2
進(jìn)入源碼目錄:

  1. ./configure --enable-embed --with-config-file-scan-dir=/etc/php.d --with-mysql --with-config-file-path=/etc/
  2. ./make
  3. ./make instal

最后,記得要將生成的libphp5.so復(fù)制到運(yùn)行時(shí)庫的目錄,我直接拷貝到了/lib/, 否則會(huì)在運(yùn)行你自己的embed程序的時(shí)候報(bào)錯(cuò):

  1. ./embed: error while loading shared libraries: libphp5.so: cannot open shared object file: No such file or director

如果你對(duì)PHP的SAPI還不熟悉的話,我建議你看看我的這篇文章:深入理解Zend SAPIs(Zend SAPI Internals)
這個(gè)時(shí)候,你就可以在你的C代碼中,嵌入PHP腳本解析器了, 我的例子:

  1. #include "sapi/embed/php_embed.h"
  2.  
  3. int main(int argc, char * argv[]){
  4.     PHP_EMBED_START_BLOCK(argc,argv);
  5.     char * script = " print 'Hello World!';";
  6.     zend_eval_string(script, NULL,
  7.                                       "Simple Hello World App" TSRMLS_CC);
  8.     PHP_EMBED_END_BLOCK();
  9.     return 0;
  10. }
  11.  

然后就是要指明include path了,一個(gè)簡(jiǎn)單的Makefile

  1. CC = gcc
  2. CFLAGS = -I/usr/local/include/php/ \
  3.             -I/usr/local/include/php/main \
  4.             -I/usr/local/include/php/Zend \
  5.             -I/usr/local/include/php/TSRM \
  6.             -Wall -g
  7. LDFLAGS = -lstdc++ -L/usr/local/lib -lphp5
  8. ALL:
  9.     $(CC) -o embed embed.cpp $(CFLAGS) $(LDFLAGS

編譯成功以后, 運(yùn)行,我們可以看到, stdout輸出 Hello World!

基于這個(gè),我們就可以很容易的實(shí)現(xiàn)一個(gè)類似于vld的Opcodes dumper:
首先我們定義opcode的轉(zhuǎn)換函數(shù)(全部的opcodes可以查看Zend/zend_vm_opcodes.h);

  1. char *opname(zend_uchar opcode){
  2.     switch(opcode) {
  3.         case ZEND_NOP: return "ZEND_NOP"; break;
  4.         case ZEND_ADD: return "ZEND_ADD"; break;
  5.         case ZEND_SUB: return "ZEND_SUB"; break;
  6.         case ZEND_MUL: return "ZEND_MUL"; break;
  7.         case ZEND_DIV: return "ZEND_DIV"; break;
  8.         case ZEND_MOD: return "ZEND_MOD"; break;
  9.         case ZEND_SL: return "ZEND_SL"; break;
  10.         case ZEND_SR: return "ZEND_SR"; break;
  11.         case ZEND_CONCAT: return "ZEND_CONCAT"; break;
  12.         case ZEND_BW_OR: return "ZEND_BW_OR"; break;
  13.         case ZEND_BW_AND: return "ZEND_BW_AND"; break;
  14.         case ZEND_BW_XOR: return "ZEND_BW_XOR"; break;
  15.         case ZEND_BW_NOT: return "ZEND_BW_NOT"; break;
  16.         /*...省略 ....*/
  17.         default : return "UNKNOW"; break;

然后定義zval和znode的輸出函數(shù):

  1.  char *format_zval(zval *z)
  2. {
  3.     static char buffer[BUFFER_LEN];
  4.     int len;
  5.  
  6.     switch(z->type) {
  7.         case IS_NULL:
  8.             return "NULL";
  9.         case IS_LONG:
  10.         case IS_BOOL:
  11.             snprintf(buffer, BUFFER_LEN, "%d", z->value.lval);
  12.             return buffer;
  13.         case IS_DOUBLE:
  14.             snprintf(buffer, BUFFER_LEN, "%f", z->value.dval);
  15.             return buffer;
  16.         case IS_STRING:
  17.             snprintf(buffer, BUFFER_LEN, "\"%s\"", z->value.str.val);
  18.             return buffer;
  19.         case IS_ARRAY:
  20.         case IS_OBJECT:
  21.         case IS_RESOURCE:
  22.         case IS_CONSTANT:
  23.         case IS_CONSTANT_ARRAY:
  24.             return "";
  25.         default:
  26.             return "unknown";
  27.     }
  28. }
  29.  
  30. char * format_znode(znode *n){
  31.     static char buffer[BUFFER_LEN];
  32.  
  33.     switch (n->op_type) {
  34.         case IS_CONST:
  35.             return format_zval(&n->u.constant);
  36.             break;
  37.         case IS_VAR:
  38.             snprintf(buffer, BUFFER_LEN, "$%d", n->u.var/sizeof(temp_variable));
  39.             return buffer;
  40.             break;
  41.         case IS_TMP_VAR:
  42.             snprintf(buffer, BUFFER_LEN, "~%d", n->u.var/sizeof(temp_variable));
  43.             return buffer;
  44.             break;
  45.         default:
  46.             return "";
  47.             break;
  48.     }
  49. }
  50.  

然后定義op_array的輸出函數(shù):

  1. void dump_op(zend_op *op, int num){
  2.     printf("%5d %5d %30s %040s %040s %040s\n", num, op->lineno,
  3.             opname(op->opcode),
  4.             format_znode(&op->op1),
  5.             format_znode(&op->op2),
  6.             format_znode(&op->result)) ;
  7. }
  8.  
  9. void dump_op_array(zend_op_array *op_array){
  10.     if(op_array) {
  11.         int i;
  12.         printf("%5s %5s %30s %040s %040s %040s\n", "opnum", "line", "opcode", "op1", "op2", "result");
  13.         for(i = 0; i < op_array->last; i++) {
  14.             dump_op(&op_array->opcodes[i], i);
  15.         }
  16.     }
  17. }

最后,就是程序的主函數(shù)了:

  1. int main(int argc, char **argv){
  2.     zend_op_array *op_array;
  3.     zend_file_handle file_handle;
  4.  
  5.     if(argc != 2) {
  6.         printf("usage: op_dumper <script>\n");
  7.         return 1;
  8.     }
  9.     PHP_EMBED_START_BLOCK(argc,argv);
  10.     printf("Script: %s\n", argv[1]);
  11.     file_handle.filename = argv[1];
  12.     file_handle.free_filename = 0;
  13.     file_handle.type = ZEND_HANDLE_FILENAME;
  14.     file_handle.opened_path = NULL;
  15.     op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC);
  16.     if(!op_array) {
  17.         printf("Error parsing script: %s\n", file_handle.filename);
  18.         return 1;
  19.     }
  20.     dump_op_array(op_array);
  21.     PHP_EMBED_END_BLOCK();
  22.     return 0;
  23. }

編譯,運(yùn)行測(cè)試腳本(sample.php):
sample.php:

  1.    echo "laruence";

命令:

  1. ./opcodes_dumper sample.ph

得到輸出結(jié)果(如果你對(duì)下面的結(jié)果很迷惑,那么建議你再看看我的這篇文章:深入理解PHP原理之Opcodes):

  1. Script: sample.php
  2. opnum line opcode op1 op2 result
  3.     0 2 ZEND_ECHO "laruence"
  4.     1 4 ZEND_RETURN

呵呵,怎么樣,是不是很好玩呢?
源碼地址:http://code.google.com/p/opcodesdumper/

posted on 2011-06-19 20:53 肥仔 閱讀(524) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Web-后臺(tái)

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美成年网站| 亚洲欧美日韩在线高清直播| 久久久久久9999| 久久久久国产精品一区| 亚洲激情一区| 亚洲视频在线视频| 黄色精品一区二区| 亚洲精品久久嫩草网站秘色| 欧美无砖砖区免费| 美女脱光内衣内裤视频久久影院 | 久久天堂成人| 亚洲欧美日韩国产中文在线| 日韩亚洲在线| 亚洲一区自拍| 最新国产の精品合集bt伙计| 亚洲一区亚洲| 一本色道久久综合| 美女网站久久| 久久九九全国免费精品观看| 欧美另类亚洲| 快播亚洲色图| 国产精品一区一区| 亚洲精品国精品久久99热| 合欧美一区二区三区| 一区二区三区欧美日韩| 亚洲人午夜精品免费| 久久国产精品久久久久久| 亚洲综合成人在线| 欧美精品福利在线| 欧美激情偷拍| 一区二区三区中文在线观看| 亚洲性av在线| 在线一区免费观看| 久久亚洲国产成人| 久久蜜桃精品| 国产日韩欧美高清| 亚洲无线视频| 亚洲一区不卡| 欧美精品不卡| 亚洲国产精品激情在线观看| 狠狠色丁香婷婷综合| 亚洲欧美精品一区| 亚洲欧美另类国产| 国产精品二区三区四区| 亚洲精品一区在线| 久久久.com| 久久久久久久999精品视频| 国产精品少妇自拍| 亚洲一区二区精品在线| 国产精品99久久久久久www| 欧美国产日韩视频| 亚洲黄色免费网站| 最新中文字幕一区二区三区| 美女视频黄免费的久久| 欧美激情第1页| 91久久精品国产91久久性色| 欧美va天堂va视频va在线| 欧美成人情趣视频| 91久久精品日日躁夜夜躁欧美 | 狠狠入ady亚洲精品| 羞羞答答国产精品www一本 | 国产精品xxxav免费视频| 99精品视频免费全部在线| 亚洲一区二区黄| 国产精品欧美风情| 欧美一区二区三区日韩视频| 久久午夜国产精品| 亚洲国产老妈| 欧美男人的天堂| 亚洲免费观看高清完整版在线观看熊 | 国产精品视频不卡| 欧美一区二区三区免费视频| 久久亚洲不卡| 亚洲国产视频一区| 欧美日韩第一区| 亚洲一区三区视频在线观看 | 欧美三级电影网| 亚洲一区区二区| 麻豆精品国产91久久久久久| 亚洲人成毛片在线播放| 欧美网站在线| 久久av在线看| 亚洲精品国产日韩| 久久国产欧美日韩精品| 亚洲精品国产精品乱码不99| 欧美色综合网| 香蕉亚洲视频| 亚洲久久在线| 国产精品视频大全| 免费在线看成人av| 亚洲午夜久久久久久尤物| 久久精品99| 亚洲国产日韩美| 国产精品美女一区二区在线观看| 久久成人亚洲| 国产亚洲欧美日韩在线一区| 久久精品亚洲一区| 亚洲精品欧美极品| 国产婷婷精品| 欧美久久在线| 久久国产精品久久久久久| 日韩一区二区福利| 欧美视频网址| 亚洲精品一区二区三区婷婷月| 欧美在线一二三区| 一本色道88久久加勒比精品 | 欧美本精品男人aⅴ天堂| 亚洲天堂成人在线观看| 亚洲国产精品va在线看黑人| 国产精品麻豆va在线播放| 免费高清在线一区| 亚洲综合精品| 999亚洲国产精| 欧美国产三级| 久久精品99无色码中文字幕| 一区二区三区高清不卡| 亚洲国产日韩一级| 国模 一区 二区 三区| 国产精品第13页| 欧美日韩一区精品| 欧美风情在线| 欧美成人a∨高清免费观看| 亚洲一区综合| 亚洲一区在线观看免费观看电影高清| 亚洲国产精品一区二区www| 久久久久久久久久码影片| 欧美一区二区三区在| 亚洲午夜电影| 正在播放亚洲一区| 一本色道久久综合亚洲精品按摩| 亚洲日本中文字幕| 亚洲国产精品久久久久婷婷老年| 激情久久影院| 极品裸体白嫩激情啪啪国产精品| 国产欧美日韩91| 亚洲电影免费在线| 午夜国产一区| 亚洲欧美日韩精品| 亚洲免费在线看| 亚洲一区二区黄色| 亚洲视频在线看| 亚洲视频在线视频| 亚洲欧美日韩区 | 免费成年人欧美视频| 久久久人成影片一区二区三区观看| 午夜视频在线观看一区二区| 亚洲欧美日韩另类精品一区二区三区 | 欧美日韩亚洲国产精品| 欧美国产一区视频在线观看 | 欧美国产日韩视频| 亚洲国产高清aⅴ视频| 欧美aaaaaaaa牛牛影院| 欧美a级一区| 亚洲高清在线观看| 日韩午夜在线视频| 亚洲自拍啪啪| 久久久91精品国产一区二区精品| 久久综合九色综合久99| 欧美华人在线视频| 国产精品久久九九| 国产日韩欧美日韩大片| 在线观看亚洲a| 亚洲伦理在线| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲永久精品国产| 久久久久久久久久久成人| 欧美成人精品一区二区三区| 亚洲国内精品在线| 亚洲在线视频观看| 久久九九国产精品怡红院| 欧美精品福利在线| 国产区日韩欧美| 亚洲国产日韩一区| 亚洲午夜激情在线| 久久综合狠狠综合久久综合88| 亚洲国产婷婷香蕉久久久久久99| 在线亚洲欧美专区二区| 欧美一区二区三区免费观看视频| 免费成人av在线| 国产精品亚洲综合色区韩国| 在线观看欧美日本| 亚洲一区制服诱惑| 麻豆精品视频在线观看| 夜夜嗨一区二区三区| 老司机久久99久久精品播放免费| 欧美视频在线免费看| 在线精品国产成人综合| 亚洲婷婷综合久久一本伊一区| 久久精品国产99国产精品澳门| 欧美国产欧美亚洲国产日韩mv天天看完整 | 久久一区二区三区四区| 欧美日韩系列| 在线欧美亚洲| 午夜国产精品视频免费体验区| 欧美超级免费视 在线| 亚洲一区二区免费视频| 久久综合九九| 国产综合18久久久久久| 亚洲一区欧美一区| 欧美激情导航|