0x00 Preface
The last three white hat challenges are over, but people still do not care, discussing the writeup in the knowledge point, which is more interesting about the weak type of PHP:
Array (0) >999999999
This result is true.
In the group, Daniel gave various thoughts, and related articles:
php.net/manual/zh/language.operators.comparison.php
But the basic is the conclusion that others give, I do not like the conclusion sex very much, this only let me know the result, do not know why have such result.
0x01 PHP Dynamic Debugging (php5.6 for 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. Related articles recommended
In-depth understanding of the Zend Execution engine (PHP5)
Using VLD to view opcode
"Mode PHP source code"
0x02 opcode Analysis
You can see that the key operation is Is_smaller, and if you look closely at the recommended article, 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 contents of the red box, I believe you can read the above content (PS: Too much detail, please learn the recommended article)
The approximate logic is that two parameters come in through the Zendi_convert_scalar_to_number function, because one of our arrays is shaped, so two parameter types and values are 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; } }
And then again into the loop arrives
} else if (Z_type_p (OP1) ==is_array) {Zval_long (result, 1); return SUCCESS;} else if (Z_type_p (OP2) ==is_array) {Zval_lon G (result,-1); return SUCCESS;
From opcode you can see that OP2 is an array (0) so here it returns-1
Finally (z_lval_p (result) < 0) established, returns True
if (compare_function (result, OP1, op2 tsrmls_cc) = = FAILURE) {return FAILURE;} Zval_bool (Result, (z_lval_p (Result) < 0)); return SUCCESS;
Reprint please indicate from L.N's blog "[Popular Science Small article]php kernel dynamic debugging about weak type comparison"