/** * 处理单个文件的静态检测 * 输入PHP文件 * @param string $path */ function load_file($path) { $cfg = new CFGGenerator(); $cfg->getFileSummary()->setPath($path); $visitor = new MyVisitor(); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $code = file_get_contents($path); $stmts = $parser->parse($code); $traverser->addVisitor($visitor); $traverser->traverse($stmts); $nodes = $visitor->getNodes(); $pEntryBlock = new BasicBlock(); $pEntryBlock->is_entry = true; //开始分析 $cfg->CFGBuilder($nodes, NULL, NULL, NULL); }
public function leaveNode(Node $node) { global $SECURES_TYPE_ALL; if (!$node instanceof Node) { return null; } if ($node->getType() == 'Stmt_Return') { $part = $node->expr; if (SymbolUtils::isValue($part)) { //return value if (!is_array($this->sanitiInfo['type'])) { $this->sanitiInfo['type'] = array($this->sanitiInfo['type']); } $type = array_intersect($this->sanitiInfo['type'], $SECURES_TYPE_ALL); $this->sanitiInfo = array(true, 'type' => $type); } elseif (SymbolUtils::isVariable($part)) { //return variable $context = Context::getInstance(); $funcBody = $context->getFunctionBody($this->funcName); if (!$funcBody) { return null; } $nodes = $funcBody->stmts; $cfg = new CFGGenerator(); $block = $cfg->CFGBuilder($nodes, NULL, NULL, NULL); $ret = $this->sanitiMultiBlockHandler($node->expr, $block); if ($ret[0]) { $type = array_intersect($this->sanitiInfo['type'], $ret['type']); $this->sanitiInfo = array(true, 'type' => $type); } else { $this->sanitiInfo = null; } } elseif (SymbolUtils::isConstant($part)) { //return constant $type = array_intersect($this->sanitiInfo['type'], $SECURES_TYPE_ALL); $this->sanitiInfo = array(true, 'type' => $type); } elseif (SymbolUtils::isArrayDimFetch($part)) { //return array $context = Context::getInstance(); $funcBody = $context->getFunctionBody($this->funcName); if (!$funcBody) { return null; } $nodes = $funcBody->stmts; $cfg = new CFGGenerator(); $block = $cfg->CFGBuilder($nodes, NULL, NULL, NULL); $ret = $this->sanitiMultiBlockHandler($node->expr, $block); if ($ret[0]) { $type = array_intersect($this->sanitiInfo['type'], $ret['type']); $this->sanitiInfo = array(true, 'type' => $type); } else { $this->sanitiInfo = null; } } elseif (SymbolUtils::isConcat($part)) { //return concat $concat = new ConcatSymbol(); $concat->setItemByNode($part); $items = $concat->getItems(); if (!$items) { return null; } $context = Context::getInstance(); $funcBody = $context->getFunctionBody($this->funcName); if (!$funcBody) { return null; } $nodes = $funcBody->stmts; $cfg = new CFGGenerator(); $block = $cfg->CFGBuilder($nodes, NULL, NULL, NULL); $retarr = $SECURES_TYPE_ALL; foreach ($items as $item) { $ret = $this->sanitiMultiBlockHandler($item, $block); if ($ret[0]) { $retarr = array_intersect($retarr, $ret['type']); } else { $this->sanitiInfo = array(false); break; } } $this->sanitiInfo = array(true, 'type' => $retarr); } else { //处理函数调用 if ($part->getType() == 'Expr_FuncCall' || $part->getType() == 'Expr_MethodCall' || $part->getType() == 'Expr_StaticCall') { $ret = SanitizationHandler::SantiniFuncHandler($part, $this->fileSummary); if ($ret) { $saniType = $ret->getSanitiType(); if (is_array($saniType[0])) { $saniType = $saniType[0]; } $type = array_intersect($this->sanitiInfo['type'], $saniType); $this->sanitiInfo = array(true, 'type' => $type); } } } } else { return null; } }