[Science tips] php kernel Dynamic Debugging 0x00 for weak types
The three white hat challenges in the last issue have been completed, but we are still trying to discuss the knowledge points in writeup. What is interesting about the weak php type is:
array(0)>999999999
The result is true.
Various experts in the group gave various ideas and related articles:
Php.net/manual/zh/language.operators.comparison.php
However, it is basically the conclusion given by others. I do not like the final result. this only gives me an idea of the result, and I do not know why such a result exists.
0x01 php Dynamic Debugging (php5.6 as an example)
1. download, unzip, and install
# wget http://cn2.php.net/distributions/php-5.6.0.tar.xz # xz -d php-5.6.0.tar.xz # tar vxf php-5.6.0.tar # cd php-5.6.0 # ./configure --enable-debug # make # sudo make install
2. recommended articles
In-depth understanding of Zend execution engine (PHP5)
View OPCode using vld
Debugging PHP source code
0x02 OPCode analysis
We can see that the key operation is IS_SMALLER. if you have carefully read the recommended article above, you can find the key function.
ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
0x03 gdb Dynamic Debugging
Pay attention to the content in the red box. I believe you can understand the content above. (ps: There are too many details. Please study the recommendation article first)
The general logic is that the two parameters are processed by the zendi_convert_scalar_to_number function. because one of us is an array and the other is an integer, the types and values of the two parameters remain unchanged.
#define zendi_convert_scalar_to_number(op, holder, result) if (op==result) { if (Z_TYPE_P(op) != IS_LONG) { convert_scalar_to_number(op TSRMLS_CC); } } else { switch (Z_TYPE_P(op)) { case IS_STRING: { if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) { ZVAL_LONG(&(holder), 0); } (op) = &(holder); break; } case IS_BOOL: case IS_RESOURCE: ZVAL_LONG(&(holder), Z_LVAL_P(op)); (op) = &(holder); break; case IS_NULL: ZVAL_LONG(&(holder), 0); (op) = &(holder); break; case IS_OBJECT: (holder) = (*(op)); zval_copy_ctor(&(holder)); convert_to_long_base(&(holder), 10); if (Z_TYPE(holder) == IS_LONG) { (op) = &(holder); } break; } }
Then enter the loop again
} else if (Z_TYPE_P(op1)==IS_ARRAY) { ZVAL_LONG(result, 1); return SUCCESS; } else if (Z_TYPE_P(op2)==IS_ARRAY) { ZVAL_LONG(result, -1); return SUCCESS;
Opcode shows that op2 is array (0), so here-1 is returned.
Returns true if (Z_LVAL_P (result) <0) is true.
if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) { return FAILURE; } ZVAL_BOOL(result, (Z_LVAL_P(result) < 0)); return SUCCESS;
Reprinted please indicate fromL. N.'s blog[Popular science articles] Dynamic Debugging of php kernel about weak types