예제 #1
0
파일: Lift.cpp 프로젝트: kumarak/mcsema
static bool LiftFunctionsIntoModule(NativeModulePtr natMod, llvm::Module *M) {
  // populate functions
  for (auto &func_info : natMod->get_funcs()) {
    NativeFunctionPtr f = func_info.second;
    if (!InsertFunctionIntoModule(natMod, f, M)) {
      std::string fname = f->get_name();
      std::cerr << "Could not insert function: " << fname
                << " into the LLVM module" << std::endl;
      return false;
    }
  }
  return true;
}
예제 #2
0
파일: Lift.cpp 프로젝트: kumarak/mcsema
void PrintCFGFunctionList(const NativeModulePtr native_module, const std::string &architecture) noexcept {
  std::ios::fmtflags original_stream_flags(std::cout.flags());
  int address_digit_count = (architecture == "amd64" ? 16 : 8);

  std::cout << "\nCFG Function List:\n";

  const auto &function_map = native_module->get_funcs();
  for (const auto &function_descriptor : function_map) {
    VA virtual_address = function_descriptor.first;
    const NativeFunctionPtr function = function_descriptor.second;

    std::cout << "  " << std::hex << std::setw(address_digit_count) << std::setfill('0') << virtual_address << " ";
    std::cout << function->get_name() << std::endl;
  }

  std::cout.flags(original_stream_flags);
}
예제 #3
0
NativeFunctionPtr getFunc(ExecutableContainer *c,
                          LLVMByteDecoder     &d,
                          stack<VA>           &funcs,
                          ExternalFunctionMap &f,
                          VA                  e,
                          raw_ostream         &out)
{
  NativeFunctionPtr F = NativeFunctionPtr(new NativeFunction(e));
  stack<VA>         toVisit;
  set<VA>           visited;

  toVisit.push(e);

  out << "getFunc: Starting at 0x" << to_string<VA>(e,hex) << "\n";
  out << "getFunc: toVisit size is: " << toVisit.size() << "\n";

  while(toVisit.size() > 0) {
    VA  curBlockHeader = toVisit.top();
    toVisit.pop();

    if(visited.find(curBlockHeader) != visited.end()) {
      continue;
    } else {
      visited.insert(curBlockHeader);
    }

    // funcs is new functions to visit later
    // toVisit is basic blocks of *this* function to visit now
    NativeBlockPtr  B = decodeBlock(c,
                                    f,
                                    d,
                                    toVisit,
                                    curBlockHeader,
                                    funcs,
                                    out);

    F->add_block(B);
  }

  out << "getFunc: Function recovery complete for ";
  out << " func at " << to_string<VA>(e,hex) << "\n";

  F->compute_graph();
  return F;
}
예제 #4
0
void doPrintModule(NativeModulePtr m) {
    string  pathBase = "./";

    list<NativeFunctionPtr>           mod_funcs = m->get_funcs();
    list<NativeFunctionPtr>::iterator it = mod_funcs.begin();

    for(; it != mod_funcs.end(); ++it) {
        NativeFunctionPtr f = *it;
        string n =
            pathBase+to_string<uint64_t>(f->get_start(), hex) + ".dot";

        ofstream    out(n.c_str());

        block_label_writer  bgl(f);
        CFG                 g = f->get_cfg();
        write_graphviz(out, g, bgl);
    }

    return;
}
예제 #5
0
파일: Lift.cpp 프로젝트: kumarak/mcsema
static bool InsertFunctionIntoModule(NativeModulePtr mod,
                                     NativeFunctionPtr func, llvm::Module *M) {
  auto &C = M->getContext();
  auto F = M->getFunction(func->get_name());
  if (!F) {
    throw TErr(__LINE__, __FILE__, "Could not get func " + func->get_name());
  }

  if (!F->empty()) {
    std::cout << "WARNING: Asking to re-insert function: " << func->get_name()
              << std::endl << "\tReturning current function instead"
              << std::endl;
    return true;
  }

  auto entryBlock = llvm::BasicBlock::Create(F->getContext(), "entry", F);
  ArchAllocRegisterVars(entryBlock);

  TranslationContext ctx;
  ctx.natM = mod;
  ctx.natF = func;
  ctx.natI = nullptr;
  ctx.M = M;
  ctx.F = F;

  // Create basic blocks for each basic block in the original function.
  for (auto block_info : func->get_blocks()) {
    ctx.va_to_bb[block_info.first] = llvm::BasicBlock::Create(
        C, block_info.second->get_name(), F);
  }

  // Create a branch from the end of the entry block to the first block
  llvm::BranchInst::Create(ctx.va_to_bb[func->get_start()], entryBlock);

  try {
    // Lift every basic block into the functions.
    auto error = false;
    for (auto block_info : func->get_blocks()) {
      ctx.natB = block_info.second;
      error = LiftBlockIntoFunction(ctx) || error;
      ctx.natB = nullptr;
    }

    // For ease of debugging generated code, don't allow lifted functions to
    // be inlined. This will make lifted and native call graphs one-to-one.
    F->addFnAttr(llvm::Attribute::NoInline);

    //we should be done, having inserted every block into the module
    return !error;

  } catch (std::exception &e) {
    std::cerr << "error: " << std::endl << e.what() << std::endl
              << "in function " << std::hex
              << ctx.natF->get_start() << std::endl;
    if (ctx.natB) {
      std::cerr << "in block " << std::hex << ctx.natB->get_base() << std::endl;
      if (ctx.natI) {
        std::cerr << "in inst " << std::hex << ctx.natI->get_loc() << std::endl;
      }
    }
    return false;
  }

  
}