/** * 得到该文件的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; } } }
/** * 由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; }