コード例 #1
0
 /**
  * 处理函数调用
  * @param node $node 调用方法的节点
  * @param BasicBlock $block 当前基本块
  * @param fileSummary $fileSummary  当前文件摘要
  */
 public function functionHandler($node, $block, $fileSummary)
 {
     //根据用户指定的扫描类型,查找相类型的sink函数
     global $scan_type;
     //获取调用的函数名判断是否是sink调用
     $funcName = NodeUtils::getNodeFunctionName($node);
     //判断是否为sink函数,返回格式为array(true,funcname) or array(false)
     $ret = NodeUtils::isSinkFunction($funcName, $scan_type);
     if ($ret[0] != null && $ret[0] === true) {
         //如果发现了sink调用,启动污点分析
         $analyser = new TaintAnalyser();
         //获取危险参数的位置
         $argPosition = NodeUtils::getVulArgs($node);
         if (count($argPosition) == 0) {
             return;
         }
         //获取到危险参数位置的变量
         $argArr = NodeUtils::getFuncParamsByPos($node, $argPosition);
         //遍历危险参数名,调用污点分析函数
         if (count($argArr) > 0) {
             foreach ($argArr as $item) {
                 if (is_array($item)) {
                     foreach ($item as $v) {
                         $analyser->analysis($block, $node, $v, $fileSummary);
                     }
                 } else {
                     $analyser->analysis($block, $node, $item, $fileSummary);
                 }
             }
         }
     } else {
         //如果不是sink调用,启动过程间分析
         $context = Context::getInstance();
         $funcBody = $context->getClassMethodBody($funcName, $this->fileSummary->getPath(), $this->fileSummary->getIncludeMap());
         //check
         if (!$funcBody || !is_object($funcBody)) {
             return;
         }
         if ($funcBody->getType() == "Stmt_ClassMethod") {
             $funcBody->stmts = $funcBody->stmts[0];
         }
         //构建相应方法体的block和summary
         $nextblock = $this->CFGBuilder($funcBody->stmts, NULL, NULL, NULL);
         //ret危险参数的位置比如:array(0)
         $ret = $this->sinkFunctionHandler($funcBody, $nextblock, $block);
         if (!$ret) {
             return;
         }
         //找到了array('del',array(0)) ;
         $userDefinedSink = UserDefinedSinkContext::getInstance();
         //$type应该从visitor中获取,使用$ret返回
         $type = $ret['type'];
         unset($ret['type']);
         //加入用户sink上下文
         $item = array($funcName, $ret);
         $userDefinedSink->addByTagName($item, $type);
         //开始污点分析
         $argPosition = NodeUtils::getVulArgs($node);
         $argArr = NodeUtils::getFuncParamsByPos($node, $argPosition);
         if (count($argArr) > 0) {
             $analyser = new TaintAnalyser();
             foreach ($argArr as $item) {
                 if (is_array($item)) {
                     foreach ($item as $v) {
                         $analyser->analysis($block, $node, $v, $this->fileSummary);
                     }
                 } else {
                     $analyser->analysis($block, $node, $item, $this->fileSummary);
                 }
             }
         }
     }
 }