Beispiel #1
0
/****************************************************
 * traverse the binary AST to test if all nodes are there
 ****************************************************/
void RoseFile::visit(SgNode* node) {
  SgAsmFunction* funcDecl= isSgAsmFunction(node);
  SgAsmInstruction* instr= isSgAsmInstruction(node);
  //SgAsmBlock* block= isSgAsmBlock(node);
  nodes++;
  //cerr << " traversing node " << binNode << endl;
  if (funcDecl) { 
    trav_funcs++;
    // should have a parent
    SgAsmBlock* glob = isSgAsmBlock(funcDecl->get_parent());
    if (glob==NULL) {
      int address = funcDecl->get_address();
      ostringstream addrhex;
      addrhex << hex << setw(8) << address ;
      //cerr << " func with no global :: " << addrhex.str() << " " << address << endl; 
    }
    //    ROSE_ASSERT(glob);
  }
  /*
  if (block) {
    trav_blocks++;
    SgAsmFunction* func = isSgAsmFunction(block->get_parent());
    int address = block->get_address();
    ostringstream addrhex;
    addrhex << hex << setw(8) << address ;
    //if (func==NULL) {
    //cerr << trav_blocks << " block with no function :: " << addrhex.str() << " " << address << endl; 
    //} else 
    //cerr << trav_blocks << " block with no function :: " << addrhex.str() << " " << address << endl; 
    //ROSE_ASSERT(func);
  }
  */
  if (isSgAsmMemoryReferenceExpression(node)) {
    SgAsmMemoryReferenceExpression* n = isSgAsmMemoryReferenceExpression(node);
    // cerr << "Found a SgAsmMemoryReferenceExpression" << endl;
    ROSE_ASSERT(n->get_type());
  }
  if (instr) {
    trav_inst++;
    SgAsmFunction* ins = isSgAsmFunction(instr->get_parent());
    if (ins==NULL) {
      int address = ins->get_address();
      ostringstream addrhex;
      addrhex << hex << setw(8) << address ;
      cerr << " ERROR :: instr with no parent function :: " << addrhex.str() << " " << address << endl; 
    }
    //ROSE_ASSERT(ins);
  }
  SgAsmNode* asmNode = isSgAsmNode(node);
  if (asmNode)
    if (asmNode->get_parent()==NULL) {
      if (!isSgAsmBlock(asmNode)) {
        cerr << " PARENT == NULL :: " << asmNode->class_name() << endl;
        ROSE_ASSERT(asmNode->get_parent());
      }
    }
}
/****************************************************
 * traverse the binary AST
 ****************************************************/
void
RoseBin_FlowAnalysis::visit(SgNode* node) {

  //  cerr << " traversing node " << node->class_name() << endl;

  if (isSgAsmFunction(node) ) {
    SgAsmFunction* binDecl = isSgAsmFunction(node);
    string name = binDecl->get_name();
    ostringstream addrhex;
    addrhex << hex << setw(8) << binDecl->get_address() ;
    if (name=="") {
      name=addrhex.str();
      binDecl->set_name(name);
    }
    SgAsmStatement* stat = NULL;
    //    SgAsmStatementPtrList& list = binDecl->get_statementList();

    vector<SgAsmInstruction*> list;
    FindInstructionsVisitor vis;
    AstQueryNamespace::querySubTree(binDecl, std::bind2nd( vis, &list ));

    int sizeList = list.size();
    if (sizeList==0) {
      //cerr << " this function is empty!! " << endl;
      return;
    }

    //if ((func_nr % 1)==0)
    //  if (RoseBin_support::DEBUG_MODE())
    //    cout  << analysisName << " Func Nr: " << (++func_nr) << "  blocks:" <<
    //     sizeList << "  ***************** checking function : " << name << endl;

    if (forward_analysis) {
      stat = list.front();
    } else {
      // get the last instruction in a function (backward control flow)
      stat = list.back();
    }
    ROSE_ASSERT(stat);

    //   if (RoseBin_support::DEBUG_MODE())
    //cout << ">>>>>>>>>>>>>. checking statement in function : " << name << " .. " << stat->class_name() << endl;
    if (isSgAsmInstruction(stat)) {
      SgAsmInstruction* inst = isSgAsmInstruction(stat);
      ROSE_ASSERT(inst);
      // check the control flow of the first instruction in a function
      string typeFunction ="function";
      SgGraphNode* src=NULL;
      if (analysisName=="callgraph") {
        //      src = vizzGraph->createNode (name, typeFunction, binDecl->get_address(), vizzGraph->graph->get_graph_id(), false, binDecl);
        src = addCFNode (name, typeFunction, binDecl->get_address(), false, binDecl);
      } else {
        //src = vizzGraph->createNode (name, typeFunction, binDecl->get_address(), vizzGraph->graph->get_graph_id(), true, binDecl);
        //cerr << ">> adding node (f) src: " << RoseBin_support::HexToString(binDecl->get_address()) << endl;
        src = addCFNode (name, typeFunction, binDecl->get_address(), true, binDecl);
        string mnemonic=inst->get_mnemonic();
        //SgGraphNode* trg = vizzGraph->createNode (mnemonic, typeNode, inst->get_address(), vizzGraph->graph->get_graph_id(),false, inst);
        //cerr << ">> adding node (first) trg: " << RoseBin_support::HexToString(inst->get_address()) << endl;
        SgGraphNode* trg = addCFNode (mnemonic, typeNode, inst->get_address(), false, inst);
        string unp_name = unparseInstructionWithAddress(inst);
        trg->append_properties(SgGraph::name,unp_name);
        if (analysisName=="dfa")
          trg->append_properties(SgGraph::dfa_standard,unp_name);
        //cerr << "Create edge " << endl;
        //      SgDirectedGraphEdge* edge = vizzGraph->createEdge ( typeFunction, vizzGraph->graph->get_graph_id(), src, binDecl->get_address(), trg, inst->get_address());
        SgDirectedGraphEdge* edge = vizzGraph->addDirectedEdge ( src, trg, typeFunction);
        vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg));
      }

      local_visited.clear();
      worklist_forthisfunction.push(inst);

      funcDecl = binDecl;
      funcDeclNode = src;
      checkControlFlow(inst, sizeList, sizeList, name, func_nr);
    } else {
    if (RoseBin_support::DEBUG_MODE())
      cerr << "This is not an Instruction " << endl;
    }
  }
}