请选择 进入手机版 | 继续访问电脑版
查看: 1444|回复: 2

php内核动态调试关于弱类型比较

[复制链接]
  • TA的每日心情

    2016-5-24 16:08
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2016-5-24 16:11:49 | 显示全部楼层 |阅读模式
    0x00 前言
    上期的三个白帽挑战题已经结束,但是大家依旧意犹未尽,讨论着writeup中的知识点,其中比较有意思的是关于php弱类型的:
    [PHP] 纯文本查看 复制代码
    array(0)>999999999

    这个结果是true的。
    群里各位大牛给了各种思考,和相关文章:
    php.net/manual/zh/language.operators.comparison.php
    但是基本都是别人给出的结论,我不太喜欢结论性的东西,这只让我知道了结果,并不知道为什么有这样的结果。

    0x01 php动态调试(php5.6为例)
    1.下载解压并安装
    [PHP] 纯文本查看 复制代码
    # wget [url]http://cn2.php.net/distributions/php-5.6.0.tar.xz[/url] 
    # 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.相关文章推荐
    《深入理解Zend执行引擎(PHP5)》
    《使用vld查看OPCode》
    《调式PHP源码》

    0x02 OPCode分析
    2016052323395389938.png
    2016052323400835991.png
    可以看出关键操作是IS_SMALLER,如果你仔细看过上面推荐文章就可以找到关键函数
    [PHP] 纯文本查看 复制代码
    ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */


    0x03 gdb动态调试
    注意红框内容,相信看过上边内容的都能看懂(ps:详细内容太多,请先学习推荐文章)
    2016052323524785149.png
    大致逻辑是两个参数进来经过zendi_convert_scalar_to_number函数处理,由于我们一个是数组一个是整形,所以两个参数类型和值都不变
    [PHP] 纯文本查看 复制代码
    #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;                             
        }                                   
      }

    然后再次进入循环到达
    [PHP] 纯文本查看 复制代码
    } 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可以看到op2为array(0)所以这儿返回-1

    最后(Z_LVAL_P(result) < 0)成立,返回true
    [PHP] 纯文本查看 复制代码
    if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) { 
        return FAILURE; 
    } 
    ZVAL_BOOL(result, (Z_LVAL_P(result) < 0)); 
    return SUCCESS;

    评分

    参与人数 1i币 +8 收起 理由
    90_ + 8 支持原创

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2017-9-11 15:40
  • 签到天数: 425 天

    [LV.9]以坛为家II

    发表于 2016-5-24 19:50:33 | 显示全部楼层
    可怕,L.N.师傅
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-10-1 06:59
  • 签到天数: 308 天

    [LV.8]以坛为家I

    发表于 2016-5-25 20:42:37 | 显示全部楼层
    可怕。。。。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表