2011-10-04 31 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而不是任何回显操作码上? –