Пример #1
0
/**
 * 处理单个文件的静态检测
 * 输入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;
     }
 }