/**
  * 得到该文件的dataFlows
  * @param Nodes $nodes
  */
 public function simulate($block, $fileSummary)
 {
     $nodes = $block->getContainedNodes();
     //循环nodes集合,搜集信息加入到中
     foreach ($nodes as $node) {
         //搜集节点中的require include require_once include_once的PHP文件名称
         $fileSummary->addIncludeToMap(NodeUtils::getNodeIncludeInfo($node));
         switch ($node->getType()) {
             //处理赋值语句
             case 'Expr_Assign':
                 $dataFlow = new DataFlow();
                 $this->assignHandler($node, $dataFlow, "left", $block, $fileSummary);
                 $this->assignHandler($node, $dataFlow, "right", $block, $fileSummary);
                 //处理完一条赋值语句,加入DataFlowMap
                 $fileSummary->addDataFlow($dataFlow);
                 $block->getBlockSummary()->addDataFlowItem($dataFlow);
                 break;
                 //处理字符串连接赋值
                 //$sql .= "from users where"生成sql => "from users where"
             //处理字符串连接赋值
             //$sql .= "from users where"生成sql => "from users where"
             case 'Expr_AssignOp_Concat':
                 $dataFlow = new DataFlow();
                 $this->assignConcatHandler($node, $dataFlow, "left", $block, $fileSummary);
                 $this->assignConcatHandler($node, $dataFlow, "right", $block, $fileSummary);
                 //处理完一条赋值语句,加入DataFlowMap
                 $fileSummary->addDataFlow($dataFlow);
                 $block->getBlockSummary()->addDataFlowItem($dataFlow);
                 break;
             default:
                 break;
         }
     }
 }
Ejemplo n.º 2
0
 /**
  * 由AST节点创建相应的CFG,用于后续分析
  * 
  * @param Node $nodes  传入的PHP file的所有nodes
  * @param $condition   构建CFGNode时的跳转信息
  * @param BasicBlock $pEntryBlock   入口基本块
  * @param $pNextBlock   下一个基本块
  */
 public function CFGBuilder($nodes, $condition, $pEntryBlock, $pNextBlock)
 {
     //此文件的fileSummary
     global $JUMP_STATEMENT, $LOOP_STATEMENT, $STOP_STATEMENT, $RETURN_STATEMENT;
     $currBlock = new BasicBlock();
     //创建一个CFG节点的边
     if ($pEntryBlock) {
         $block_edge = new CFGEdge($pEntryBlock, $currBlock, $condition);
         $pEntryBlock->addOutEdge($block_edge);
         $currBlock->addInEdge($block_edge);
     }
     //处理只有一个node节点,不是数组
     if (!is_array($nodes)) {
         $nodes = array($nodes);
     }
     //迭代每个AST node
     foreach ($nodes as $node) {
         //搜集节点中的require include require_once include_once的PHP文件名称
         $this->fileSummary->addIncludeToMap(NodeUtils::getNodeIncludeInfo($node));
         if (!is_object($node)) {
             continue;
         }
         //不分析函数定义
         if ($node->getType() == "Stmt_Function") {
             continue;
         }
         //如果节点是跳转类型的语句
         if (in_array($node->getType(), $JUMP_STATEMENT)) {
             //生成基本块的摘要
             $this->simulate($currBlock);
             $nextBlock = new BasicBlock();
             //对每个分支,建立相应的基本块
             $branches = $this->getBranches($node);
             foreach ($branches as $b) {
                 $this->CFGBuilder($b->nodes, $b->condition, $currBlock, $nextBlock);
             }
             $currBlock = $nextBlock;
             //如果节点是循环语句
         } elseif (in_array($node->getType(), $LOOP_STATEMENT)) {
             //加入循环条件
             $this->addLoopVariable($node, $currBlock);
             $this->simulate($currBlock);
             //处理循环体
             $nextBlock = new BasicBlock();
             $this->CFGBuilder($node->stmts, NULL, $currBlock, $nextBlock);
             $currBlock = $nextBlock;
             //如果节点是结束语句 throw break continue
         } elseif (in_array($node->getType(), $STOP_STATEMENT)) {
             $currBlock->is_exit = true;
             break;
             //如果节点是return
         } elseif (in_array($node->getType(), $RETURN_STATEMENT)) {
             $currBlock->addNode($node);
             $this->simulate($currBlock);
             //print_r($currBlock->getBlockSummary()) ;
             return $currBlock;
         } else {
             $currBlock->addNode($node);
             //print_r($currBlock->getBlockSummary()) ;
         }
     }
     $this->simulate($currBlock);
     //echo  "当前基本块:<br/>" ;
     //print_r($currBlock) ;
     //echo "前驱基本块:<br/>" ;
     //$analyser = new TaintAnalyser() ;
     //$analyser->getPrevBlocks($currBlock) ;
     //print_r($analyser->getPathArr()) ;
     if ($pNextBlock && !$currBlock->is_exit) {
         $block_edge = new CFGEdge($currBlock, $pNextBlock);
         $currBlock->addOutEdge($block_edge);
         $pNextBlock->addInEdge($block_edge);
     }
     return $currBlock;
 }