2011-12-01 30 views
15

test.php的爲純文本:PHP操作碼與實際執行的二進制代碼有什麼關係?

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

test.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); 
" 

(跳過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 

現在我想了解更多關於如何操作碼轉換爲二進制表示。

的編輯和澄清的問題:

如何操作碼轉換成二進制版本? 你可以在那裏看到「a」的分配爲!0嗎? 在那裏ECHO聲明和輸出什麼地方?

我在二進制版本中發現了幾行暗示操作碼的逐行表示的模式。

( 「2f726f6f742f746573742e706870」 是 「/root/test.php」 的十六進制表示)

EDIT:當線路長度被設置爲4個字節

十六進制表示顯示圖案並在不同的方案之間進

... 
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並將其鏈接到C代碼。

編輯

Does PHP have a virtual machine like Java?

Is the Zend engine embeddable outside of PHP?

回答

9

大問題...

UPDATE:操作碼由PHP虛擬機(Zend引擎)直接執行。看起來好像它們是由./Zend/zend_vm_execute.h中定義的不同處理函數執行的。

有關如何執行Zend操作碼的更多信息,請參見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擴展可以幫助作者: 德里克Rethans的,安德烈Zmievski或馬庫斯·博格

他們的電子郵件地址是在srm_oparray的頂部。 c在擴展源中。

UPDATE:發現了一些端倪

在PHP 5.3.8,我發現操作碼被執行,其中三根導線:

./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.h:2413查看「整數加法」操作碼的例子。

+0

已經檢查過這些資源;因爲我在上面使用VLD。它們似乎涵蓋了從PHP代碼到操作碼的轉換。 – Raffael

+0

已更新...添加電子郵件地址建議。 – Homer6

+0

所以你已經簽出了源代碼?這肯定會導致某個地方。但我不熟悉C,那是我的障礙。到目前爲止,我發現的所有內容都是T_ECHO分配給號碼316. – Raffael

相關問題