We have made a Zend extension which we want to write the addresses of the zval's echo is supposed to write out, but we cannot figure how to receive them because we have noticed that there is difference between echo "test"; and $a = "test"; echo $a;
.... Some stuff that overrides the 开发者_StackOverflowecho 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;
}
How do we get the arguments no matter if it is a variable or not?
The handler for echo is
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();
}
from Zend/zend_vm_execute.h
, and as you can see all it basically does is to call zend_print_variable()
.
Hook that function and you should be on the right track.
Bonus: it works for print
statements too.
精彩评论