2011-12-01 8 views
15

test.php come testo normale:in che modo l'opcode PHP si riferisce al codice binario effettivamente eseguito?

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

test.php come codice operativo:

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 come rappresentazione binaria:

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

(saltando l'eco-output di 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 

Ora voglio saperne di più su come l'opcode si traduce nella rappresentazione binaria.

La domanda modificato e chiarito:

Come è il codice operativo tradotto nella versione binaria? Riesci a vedere l'ASSIGN di 'a' a! 0? C'è da qualche parte l'istruzione ECHO e cosa emette?

Ho trovato alcuni modelli nella versione binaria che suggeriscono una rappresentazione riga per riga dell'opcode.

("2f726f6f742f746573742e706870" è la rappresentazione esadecimale di "/root/test.php")

EDIT:

rappresentazione esadecimale rivela modelli quando la linea lunghezza è impostata su 4 byte e confrontato tra diversi programmi.

... 
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 
... 

Ma la mia conoscenza di come funzionano le macchine virtuali su un tale livello è troppo debole per essere in grado di analizzare davvero così propperly e collegarlo al codice C.

EDIT:

Does PHP have a virtual machine like Java?

Is the Zend engine embeddable outside of PHP?

risposta

9

Grande domanda ...

UPDATE: codici operativi sono eseguiti direttamente dalla macchina virtuale PHP (Zend Engine). Sembra che siano eseguiti da diverse funzioni di gestione definite in ./Zend/zend_vm_execute.h

Vedere the architecture of the Zend Engine per ulteriori informazioni su come vengono eseguiti gli opcode Zend.

Queste risorse potrebbero aiutare un po ':

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

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

Inoltre, ho intenzione di checkout la PECL VLD sorgente per altri indizi ...

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

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

Inoltre, la scrittura del VLD estensione PECL può aiutare gli autori: Derick Rethans, Andrei Zmievski o Marcus Börger

I loro indirizzi e-mail sono in cima alla srm_oparray. c nella fonte di estensione.

UPDATE: trovato alcuni indizi più

In PHP 5.3.8, ho trovato tre cavi per il quale vengono eseguiti i codici operativi:

./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 

non riuscivo a trovare la definizione per zend_execute(), ma credo che potrebbe essere generato con ./zend_vm_gen.php

credo di aver trovato ...

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

Potrei sbagliarmi, ma sembra che tutti i gestori di opcode siano definiti anche in ./Zend/zend_vm_execute.h.

Vedere ./Zend/zend_vm_execute.h:2413 per un esempio di ciò che sembra essere l'opcode "integer addition".

+0

già controllato quelle risorse; come sto usando VLD sopra. Sembrano solo coprire la transizione dal codice PHP all'opcode. – Raffael

+0

Aggiornato ... suggerimento di indirizzo email aggiunto. – Homer6

+0

Quindi hai già controllato il codice sorgente? Questo porterebbe sicuramente da qualche parte. Ma non ho dimestichezza con C, questo è il mio handicap. Tutto quello che ho trovato finora è che T_ECHO è assegnato al numero 316. – Raffael

3

apc_bin_dump() restituisce la rappresentazione non elaborata di una voce della cache in memoria.

Restituisce il contenuto di apc_bd_t struct.

Questa struttura è una matrice di apc_bd_entry_t con alcuni checksum per il rilevamento degli errori.

apc_bd_entry_t contiene uno apc_cache_entry_value_t.

È possibile controllare le funzioni interne apc_bin_dump e apc_bin_load per vedere come vengono creati il ​​dump e il carico.

+0

questo è un suggerimento prezioso – Raffael

Problemi correlati