/** * 处理函数调用 * @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); } } } } }