2011-10-04 63 views
1

我們已經做了一個Zend擴展,我們想寫的zval的回聲應該寫出來的地址,但我們不知道如何接收它們,因爲我們已經注意到回聲「測試」之間存在差異;和$ a =「test」; echo $ a;Zend擴展,得到echo的參數?

.... Some stuff that overrides the echo opcode .... 

FILE *tmpfile; 
int echo_handler(ZEND_OPCODE_HANDLER_ARGS) 
{ 
    zend_op *opline = execute_data->opline; 
    tmpfile = fopen("/tmp/echo.test","a+"); 
    fprintf(tmpfile,"Echo was called\n"); 
    fclose(tmpfile); 

    return ZEND_USER_OPCODE_DISPATCH; 
} 

無論它是否是變量,我們如何獲取參數?

+0

查看我的回答。儘管它應該起作用,但我想知道你需要做什麼?也許你正在採取錯誤的做法,或對錯誤問題採取正確的做法。 – Flavius

+0

嗯,我們試圖在模塊中實現某種污點,我們的方法如下(對於非常簡單的污點) 1.在執行開始時,獲取$ _GET元素的zvals地址(完成) 2 。在echo上,獲取zval地址的地址以回顯並檢查它是否是_GET zvals之一。 (未完成 - 在迴音上掛鉤) 這看起來合法嗎? –

+0

是的,它非常簡單,正如你所說的 - 我的解決方案應該可行。在我的空閒時間裏,我正在研究一些相關的內容:一個擴展,它將賦予PHP腳本靜態代碼分析功能,這對您也同樣有趣。 – Flavius

回答

0

回聲處理程序是

static int ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) 
{ 
    zend_op *opline = EX(opline); 

    zval z_copy; 
    zval *z = &opline->op1.u.constant; 

    if (IS_CONST != IS_CONST && 
     Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && 
     zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { 
     zend_print_variable(&z_copy); 
     zval_dtor(&z_copy); 
    } else { 
     zend_print_variable(z); 
    } 

    ZEND_VM_NEXT_OPCODE(); 
} 
Zend/zend_vm_execute.h

,正如你可以看到它基本上是調用zend_print_variable()

鉤功能,你應該在正確的軌道上。

紅利:它也適用於print聲明。

+0

現在,我開始迷失在Zend代碼中,我一直在使用zend_set_user_opcode_handler(ZEND_ECHO,echo_handler);方法掛鉤回聲,這是每次按計劃觸發的,但opline-> op1.op_type是4(IS_VAR),這意味着op1.u.contant將不會保存具有該值的zval,但是我計算出如何從execute_data中檢索它...除了源代碼之外是否還有任何可用於execute_data結構的文檔? –

+0

編輯:我想不出如何從execute_data中檢索zval,當op1.op_type是IS_VAR –

+0

我仍然丟失:/您引用的處理程序僅用於當op1.optype是IS_CONST,但ZEND_ECHO_SPEC_VAR_HANDLER使用另一種訪問zval echo的方法,但是如果我使用與ZEND_ECHO_SPEC_VAR_HANDLER相同的方法,它會嘗試訪問一些「隨機」數據,因爲指針似乎是未設置/未設置的。是否可以直接掛鉤在ZEND_ECHO_SPEC_VAR_HANDLER而不是任何回顯操作碼上? –