2011-12-01 3 views
15

test.php: द्विआधारी प्रतिनिधित्व के रूप मेंPHP ओपोड वास्तव में निष्पादित बाइनरी कोड से कैसे संबंधित है? सादे पाठ के रूप

debian:~ php -d vld.active=1 -d vld.execute=0 -f test.php 

Finding entry points 
Branch analysis from position: 0 
Return found 
filename:  /root/test.php 
function name: (null) 
number of ops: 5 
compiled vars: !0 = $x 
line  # * op       fetch   ext return operands 
--------------------------------------------------------------------------------- 
    2  0 > EXT_STMT 
     1  ASSIGN             !0, 'a' 
    3  2  EXT_STMT 
     3  ECHO              !0 
    4  4 > RETURN             1 

branch: # 0; line:  2- 4; sop:  0; eop:  4 
path #1: 0, 

test.php:

debian:~ php -d apc.stat=0 -r " 
    require '/root/test.php'; 
    echo PHP_EOL; 
    echo chunk_split(bin2hex(
    apc_bin_dump(array('/root/test.php')) 
),64); 
" 

(

<?php 
$x = "a"; 
echo $x; 

opcode के रूप में test.php test.php की गूंज-आउटपुट छोड़ना)

b110000001000000325dedaa64d801bca2f73027abf0d5ab67f3023901000000 
    2c0000000a000000871000000300000000000000000000004c0000005b000000 
    8a0200008a020000650000002f726f6f742f746573742e7068700002070f9c00 
    00000000000000000000000000000000000000000000000000000000000100fa 
    000000fe00000005000000050000007c02000001000000100000000100000000 
    00000000000000ffffffff0000000000000000000000000000000000000000ff 
    ffffffeb00000000000000000000000000000000000000ffffffff0000000000 
    00000001000000000000002f726f6f742f746573742e7068700001000000204a 
    3308080000000000000000000000000000000000000008000000000000000000 
    0000000000000000000008000000000000000000000000000000000000000000 
    00000200000065000000204a3308040000000000000001000000000000000000 
    00001000000000000000100000000100000006000000010000007a0200000100 
    00000100000006000000000000000200000026000000204a3308080000000000 
    0000000000000000000000000000080000000000000000000000000000000000 
    0000080000000000000000000000000000000000000000000000030000006500 
    0000900f34080800000000000000000000000000000000000000100000000000 
    0000100000000100000006000000080000000000000000000000000000000000 
    0000000000000300000028000000204a33080800000000000000000000000000 
    00000000000001000000010000002c70d7b6010000000100d7b6080000000000 
    000000000000000000000000000000000000040000003e000000610088020000 
    01000000bd795900780000000000000000000000000000000000000000000000 
[ ... a lot of lines just containing 0s ... ] 
    0000000000000038000000c30000007f0000007a010000830000007c0200008f 
    0000003c000000400000004400000008 

अब मैं इस बारे में और जानना चाहता हूं कि ओपोड बाइनरी प्रतिनिधित्व में कैसे अनुवाद करता है।

संपादित और स्पष्ट किया सवाल:

कैसे opcode द्विआधारी संस्करण में अनुवाद किया जाता है? क्या आप वहां 'ए' के ​​प्रवेश को देख सकते हैं! 0? कहीं कहीं ईसीएचओ कथन है और यह क्या आउटपुट करता है?

मुझे बाइनरी संस्करण में कुछ पैटर्न मिले जो ओपोड के लाइन प्रतिनिधित्व द्वारा लाइन पर संकेत देते हैं। जब लाइन-लेंथ 4 बाइट के लिए सेट है

हेक्साडेसिमल प्रतिनिधित्व पैटर्न का पता चलता है:

संपादित ("2f726f6f742f746573742e706870" "/root/test.php" का हेक्साडेसिमल प्रतिनिधित्व है) और विभिन्न कार्यक्रमों के बीच तुलना की।

... 
00000002 // 2 seems to be something like the "line number" 
00000065 // seems to increase by 1 for every subsequent statement. 
00000040 // 
06330808 // seems to mark the START of a statement 
00000000 
00000000 
00000000 
00000000 
00000001 // 
00000012 // In a program with three echo statements, 
03000007 // this block was present three times. With mild 
00000001 // changes that seem to represent the spot where 
00000006 // the output-string is located. 
00000008 // 
00000000 
00000000 
00000000 
00000000 
00000000 
00000002 // 2 seems to be something like the "line number" 
00000028 // 
00000020 // 
4a330808 // seems to mark the END of a statement 
00000000 
00000000 
00000000 
00000000 
00000008 // repeating between (echo-)statements 
00000000 
00000000 
00000000 
00000000 
00000008 // repeating between (echo-)statements 
... 

लेकिन यह कैसे आभासी मशीनों इस तरह के एक स्तर पर काम की मेरी जानकारी भी वास्तव में propperly कि विश्लेषण और सी कोड से लिंक करने में सक्षम होना कमजोर है।

संपादित:

Does PHP have a virtual machine like Java?

Is the Zend engine embeddable outside of PHP?

उत्तर

9

ग्रेट सवाल ...

अद्यतन: opcodes सीधे पीएचपी वर्चुअल मशीन (जेंड इंजन) द्वारा क्रियान्वित कर रहे। ऐसा लगता है कि जैसे कि वे ./Zend/zend_vm_execute.h

में परिभाषित भिन्न हैंडलर कार्यों द्वारा क्रियान्वित कर रहे हैं कि कैसे Zend opcodes क्रियान्वित कर रहे हैं के बारे में अधिक जानकारी के लिए the architecture of the Zend Engine देखें।

इन संसाधनों थोड़ा मदद कर सकता है:

http://php.net/manual/en/internals2.opcodes.list.php

http://www.php.net/manual/en/internals2.opcodes.ops.php

इसके अलावा, मैं और अधिक सुराग के लिए PECL VLD स्रोत चेकआउट करने के लिए जा रहा हूँ ...

http://pecl.php.net/package/vld

http://derickrethans.nl/projects.html#vld

इसके अलावा, VLD PECL विस्तार में मदद मिल सकती के लेखकों लेखन: Derick Rethans, आंद्रेई Zmievski या मार्कस Borger

अपने ईमेल पते srm_oparray के शीर्ष पर हैं। विस्तार स्रोत में सी।

अद्यतन: कुछ और सुराग

पीएचपी 5.3.8 में पाया जाता है, मैं कहाँ opcodes क्रियान्वित कर रहे हैं के लिए तीन सुराग नहीं मिला:

./Zend/zend_execute.c:1270 
ZEND_API void execute_internal 

./Zend/zend.c:1214:ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) 
./Zend/zend.c:1236:     zend_execute(EG(active_op_array) TSRMLS_CC); 

./Zend/zend_vm_gen.php 

मैं zend_execute के लिए परिभाषा (नहीं पा सके), लेकिन मेरा अनुमान है कि यह ./zend_vm_gen.php

साथ उत्पन्न किया जा सकता है मुझे लगता है कि मुझे मिल गया ...

./Zend/zend_vm_execute.h:42 
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) 

मैं गलत हो सकता था, लेकिन ऐसा लगता है कि सभी ऑपोड हैंडलर को ./Zend/zend_vm_execute.h में भी परिभाषित किया गया है।

देखें "पूर्णांक अतिरिक्त" ऑपोड के उदाहरण के लिए ./Zend/zend_vm_execute.h39413 देखें।

+0

पहले से ही उन संसाधनों की जांच की गई है; क्योंकि मैं उपरोक्त वीएलडी का उपयोग कर रहा हूं। वे सिर्फ PHP कोड से ऑपोड में संक्रमण को कवर करने लगते हैं। – Raffael

+0

अपडेट किया गया ... ईमेल पता सुझाव जोड़ा गया। – Homer6

+0

तो क्या आपने पहले से ही स्रोत कोड की जांच की है? यह निश्चित रूप से कहीं नेतृत्व करेंगे। लेकिन मैं सी के साथ बातचीत नहीं कर रहा हूं, यह मेरी बाधा है। मुझे अब तक यह सब मिला है कि T_ECHO को संख्या 316 को सौंपा गया है। – Raffael

3

apc_bin_dump() एक इन-मेमोरी कैश प्रविष्टि का कच्चा प्रतिनिधित्व देता है।

यह apc_bd_t struct की सामग्री देता है।

यह संरचना त्रुटि पहचान के लिए कुछ चेकसम के साथ apc_bd_entry_t की एक सरणी है।

apc_bd_entry_t में apc_cache_entry_value_t शामिल है।

आप apc_bin_dump और apc_bin_load आंतरिक कार्यों को देखने के लिए देख सकते हैं कि डंप और लोड कैसे किए जाते हैं।

+0

यह एक मूल्यवान संकेत है – Raffael

संबंधित मुद्दे