BtorTranslationPolicy::BtorTranslationPolicy(BtorTranslationHooks* hooks, uint32_t minNumStepsToFindError, uint32_t maxNumStepsToFindError, SgProject* proj): problem(), hooks(hooks), regdict(NULL) { assert (minNumStepsToFindError >= 1); // Can't find an error on the first step assert (maxNumStepsToFindError < 0xFFFFFFFFU); // Prevent overflows assert (minNumStepsToFindError <= maxNumStepsToFindError || maxNumStepsToFindError == 0); makeRegMap(origRegisterMap, ""); makeRegMapZero(newRegisterMap); isValidIp = false_(); validIPs.clear(); Comp stepCount = problem.build_var(32, "stepCount_saturating_at_" + boost::lexical_cast<std::string>(maxNumStepsToFindError + 1)); addNext(stepCount, ite(problem.build_op_eq(stepCount, number<32>(maxNumStepsToFindError + 1)), number<32>(maxNumStepsToFindError + 1), problem.build_op_inc(stepCount))); resetState = problem.build_op_eq(stepCount, zero(32)); errorsEnabled = problem.build_op_and( problem.build_op_ugte(stepCount, number<32>(minNumStepsToFindError)), (maxNumStepsToFindError == 0 ? true_() : problem.build_op_ulte(stepCount, number<32>(maxNumStepsToFindError)))); { vector<SgNode*> functions = NodeQuery::querySubTree(proj, V_SgAsmFunction); for (size_t i = 0; i < functions.size(); ++i) { functionStarts.push_back(isSgAsmFunction(functions[i])->get_address()); // fprintf(stderr, "functionStarts 0x%"PRIx64"\n", isSgAsmFunction(functions[i])->get_address()); } } { vector<SgNode*> blocks = NodeQuery::querySubTree(proj, V_SgAsmBlock); for (size_t i = 0; i < blocks.size(); ++i) { SgAsmBlock* b = isSgAsmBlock(blocks[i]); if (!b->get_statementList().empty() && isSgAsmX86Instruction(b->get_statementList().front())) { blockStarts.push_back(b->get_address()); // fprintf(stderr, "blockStarts 0x%"PRIx64"\n", b->get_address()); } } } { vector<SgNode*> calls = NodeQuery::querySubTree(proj, V_SgAsmX86Instruction); for (size_t i = 0; i < calls.size(); ++i) { SgAsmX86Instruction* b = isSgAsmX86Instruction(calls[i]); if (b->get_kind() != x86_call) continue; returnPoints.push_back(b->get_address() + b->get_raw_bytes().size()); // fprintf(stderr, "returnPoints 0x%"PRIx64"\n", b->get_address() + b->get_raw_bytes().size()); } } { vector<SgNode*> instructions = NodeQuery::querySubTree(proj, V_SgAsmX86Instruction); for (size_t i = 0; i < instructions.size(); ++i) { SgAsmX86Instruction* b = isSgAsmX86Instruction(instructions[i]); validIPs.push_back(b->get_address()); } } }
SgAsmBlock* buildBasicBlock(const std::vector<SgAsmInstruction*> &insns) { SgAsmBlock *bb = new SgAsmBlock; if (!insns.empty()) { bb->set_id(insns.front()->get_address()); bb->set_address(insns.front()->get_address()); BOOST_FOREACH (SgAsmInstruction *insn, insns) { bb->get_statementList().push_back(insn); insn->set_parent(bb); }
void CountTraversal::visit ( SgNode* n ) { SgAsmInstruction* asmInstruction = isSgAsmInstruction(n); if (asmInstruction != NULL) { // Use the new interface support for this (this detects all multi-byte nop instructions). if (SageInterface::isNOP(asmInstruction) == true) { if (previousInstructionWasNop == true) { // Increment the length of the identified NOP sequence count++; } else { count = 1; // Record the starting address of the NOP sequence nopSequenceStart = asmInstruction; } previousInstructionWasNop = true; } else { if (count > 0) { // Report the sequence when we have detected the end of the sequence. SgAsmFunction* functionDeclaration = getAsmFunction(asmInstruction); printf ("Reporting NOP sequence of length %3d at address %zu in function %s (reason for this being a function = %u = %s) \n", count,nopSequenceStart->get_address(),functionDeclaration->get_name().c_str(), functionDeclaration->get_reason(), stringifySgAsmFunctionFunctionReason(functionDeclaration->get_reason()).c_str()); nopSequences.push_back(pair<SgAsmInstruction*,int>(nopSequenceStart,count)); SgAsmBlock* block = isSgAsmBlock(nopSequenceStart->get_parent()); ROSE_ASSERT(block != NULL); SgAsmStatementPtrList & l = block->get_statementList(); // Now iterate over the nop instructions in the sequence and report the lenght of each (can be multi-byte nop instructions). SgAsmStatementPtrList::iterator i = find(l.begin(),l.end(),nopSequenceStart); ROSE_ASSERT(i != l.end()); int counter = 0; while ( (*i != asmInstruction) && (i != l.end()) ) { printf ("--- NOP #%2d is length = %2d \n",counter++,(int)isSgAsmInstruction(*i)->get_raw_bytes().size()); i++; } } count = 0; previousInstructionWasNop = false; } } }
/** Add edges to graph from functions that call system calls to system calls. * * The first 1000 vertexes (0 to 999) in the graph is reserved for system calls, which is many more than the actual system * calls in linux. */ void add_syscall_edges(DirectedGraph* G, std::vector<SgAsmFunction*>& all_functions) { // Detect all system calls and add an edge from the function to the function to the system call for (unsigned int caller_id = 0; caller_id < all_functions.size(); ++caller_id) { SgAsmFunction *func = all_functions[caller_id]; std::vector<SgAsmInstruction*> insns = SageInterface::querySubTree<SgAsmInstruction>(func); for (std::vector<SgAsmInstruction*>::iterator inst_it = insns.begin(); inst_it != insns.end(); ++inst_it) { SgAsmX86Instruction *insn = isSgAsmX86Instruction(*inst_it); if (insn == NULL) continue; SgAsmBlock *block = SageInterface::getEnclosingNode<SgAsmBlock>(insn); // On linux system calls are always interrups and all interrupts are system calls if (insn && block && insn->get_kind()==x86_int) { const SgAsmExpressionPtrList &opand_list = insn->get_operandList()->get_operands(); SgAsmExpression *expr = opand_list.size()==1 ? opand_list[0] : NULL; //semantically execute the basic block to find out which sytem call was called if (expr && expr->variantT()==V_SgAsmIntegerValueExpression && 0x80==isSgAsmIntegerValueExpression(expr)->get_value()) { const SgAsmStatementPtrList &stmts = block->get_statementList(); size_t int_n; for (int_n=0; int_n<stmts.size(); int_n++) { if (isSgAsmInstruction(stmts[int_n])==insn) break; } typedef PartialSymbolicSemantics::Policy<PartialSymbolicSemantics::State, PartialSymbolicSemantics::ValueType> Policy; typedef X86InstructionSemantics<Policy, PartialSymbolicSemantics::ValueType> Semantics; Policy policy; Semantics semantics(policy); try { semantics.processBlock(stmts, 0, int_n); if (policy.readRegister<32>("eax").is_known()) { int nr = policy.readRegister<32>("eax").known_value(); boost::add_edge(caller_id, nr, *G); } } catch (const Semantics::Exception&) { } catch (const Policy::Exception&) { } } } } } }
void visit(SgNode *node) { SgAsmBlock *block = isSgAsmBlock(node); if (block && block->has_instructions()) { using namespace rose::BinaryAnalysis::InstructionSemantics2; const RegisterDictionary *regdict = RegisterDictionary::dictionary_i386(); SymbolicSemantics::RiscOperatorsPtr ops = SymbolicSemantics::RiscOperators::instance(regdict); ops->computingDefiners(SymbolicSemantics::TRACK_ALL_DEFINERS); // only used so we can test that it works BaseSemantics::DispatcherPtr dispatcher = DispatcherX86::instance(ops, 32); const SgAsmStatementPtrList &stmts = block->get_statementList(); for (SgAsmStatementPtrList::const_iterator si=stmts.begin(); si!=stmts.end(); ++si) { SgAsmX86Instruction *insn = isSgAsmX86Instruction(*si); if (insn) { std::cout <<unparseInstructionWithAddress(insn) <<"\n"; dispatcher->processInstruction(insn); std::cout <<*ops <<"\n"; } } } }
void visit(SgNode *node) { SgAsmBlock *block = isSgAsmBlock(node); if (block && block->has_instructions()) { using namespace BinaryAnalysis::InstructionSemantics; typedef SymbolicSemantics::Policy<SymbolicSemantics::State, SymbolicSemantics::ValueType> Policy; typedef X86InstructionSemantics<Policy, SymbolicSemantics::ValueType> Semantics; Policy policy(NULL/*no SMT solver*/); Semantics semantics(policy); const SgAsmStatementPtrList &stmts = block->get_statementList(); for (SgAsmStatementPtrList::const_iterator si=stmts.begin(); si!=stmts.end(); ++si) { SgAsmX86Instruction *insn = isSgAsmX86Instruction(*si); if (insn) { std::cout <<unparseInstructionWithAddress(insn) <<"\n"; semantics.processInstruction(insn); std::cout <<policy; } } } }