5 #include "SymbolicSemantics.h"
6 #include "SymbolicSemantics2.h"
7 #include "PartialSymbolicSemantics.h"
8 #include "DispatcherX86.h"
9 #include "YicesSolver.h"
17 return x86InstructionIsControlTransfer(
this);
24 static const size_t EXECUTION_LIMIT = 25;
40 SgAsmFunction *func = SageInterface::getEnclosingNode<SgAsmFunction>(last);
46 if (interp && insns.size()<=EXECUTION_LIMIT) {
47 using namespace BinaryAnalysis::InstructionSemantics2;
48 using namespace BinaryAnalysis::InstructionSemantics2::SymbolicSemantics;
51 SMTSolver *solver = NULL;
52 BaseSemantics::RiscOperatorsPtr ops = RiscOperators::instance(regdict, solver);
53 DispatcherX86Ptr dispatcher = DispatcherX86::instance(ops);
54 SValuePtr orig_esp = SValue::promote(ops->readRegister(dispatcher->REG_ESP));
56 for (
size_t i=0; i<insns.size(); ++i)
57 dispatcher->processInstruction(insns[i]);
58 }
catch (
const BaseSemantics::Exception &e) {
63 SValuePtr eip = SValue::promote(ops->readRegister(dispatcher->REG_EIP));
64 if (eip->is_number()) {
66 SgAsmFunction *target_func = SageInterface::getEnclosingNode<SgAsmFunction>(imap.get_value_or(target_va, NULL));
67 if (!target_func || target_va!=target_func->
get_entry_va())
72 SValuePtr esp = SValue::promote(ops->readRegister(dispatcher->REG_ESP));
73 SValuePtr stack_delta = SValue::promote(ops->add(esp, ops->negate(orig_esp)));
74 SValuePtr stack_delta_sign = SValue::promote(ops->extract(stack_delta, 31, 32));
75 if (stack_delta_sign->is_number() && 0==stack_delta_sign->get_number())
80 SValuePtr top = SValue::promote(ops->readMemory(dispatcher->REG_SS, esp, esp->boolean_(
true), 32));
81 if (top->is_number()) {
83 SgAsmFunction *return_func = SageInterface::getEnclosingNode<SgAsmFunction>(imap.get_value_or(va, NULL));
84 if (!return_func || return_func!=func) {
93 if (target && eip->is_number())
94 *target = eip->get_number();
95 if (return_va && top->is_number())
96 *return_va = top->get_number();
103 if (!interp && insns.size()<=EXECUTION_LIMIT) {
104 using namespace BinaryAnalysis::InstructionSemantics2;
105 using namespace BinaryAnalysis::InstructionSemantics2::SymbolicSemantics;
107 SMTSolver *solver = NULL;
108 BaseSemantics::RiscOperatorsPtr ops = RiscOperators::instance(regdict, solver);
109 DispatcherX86Ptr dispatcher = DispatcherX86::instance(ops);
111 for (
size_t i=0; i<insns.size(); ++i)
112 dispatcher->processInstruction(insns[i]);
113 }
catch (
const BaseSemantics::Exception &e) {
118 SValuePtr top = SValue::promote(ops->readMemory(dispatcher->REG_SS, ops->readRegister(dispatcher->REG_ESP),
119 ops->get_protoval()->boolean_(
true), 32));
122 SValuePtr eip = SValue::promote(ops->readRegister(dispatcher->REG_EIP));
123 if (eip->is_number())
124 *target = eip->get_number();
127 *return_va = top->get_number();
291 using namespace BinaryAnalysis::InstructionSemantics;
292 static const bool debug =
false;
296 <<
" for " <<insns.size() <<
" instruction" <<(1==insns.size()?
"":
"s") <<
"):" <<std::endl;
305 if (!*complete || successors.size()>1) {
310 # if defined(ROSE_YICES) || defined(ROSE_HAVE_LIBYICES)
312 if (yices.available_linkage() & YicesSolver::LM_LIBRARY) {
313 yices.set_linkage(YicesSolver::LM_LIBRARY);
315 yices.set_linkage(YicesSolver::LM_EXECUTABLE);
317 SMTSolver *solver = &yices;
319 SMTSolver *solver = NULL;
322 solver->set_debug(stderr);
323 typedef SymbolicSemantics::Policy<> Policy;
324 typedef SymbolicSemantics::ValueType<32> RegisterType;
325 typedef X86InstructionSemantics<Policy, SymbolicSemantics::ValueType> Semantics;
326 Policy policy(solver);
328 typedef PartialSymbolicSemantics::Policy<> Policy;
329 typedef PartialSymbolicSemantics::ValueType<32> RegisterType;
330 typedef X86InstructionSemantics<Policy, PartialSymbolicSemantics::ValueType> Semantics;
332 policy.set_map(initial_memory);
335 Semantics semantics(policy);
336 for (
size_t i=0; i<insns.size(); i++) {
338 semantics.processInstruction(insn);
340 std::cerr <<
" state after " <<unparseInstructionWithAddress(insn) <<std::endl
341 <<policy.get_state();
344 const RegisterType &newip = policy.get_ip();
345 if (newip.is_known()) {
347 successors.insert(newip.known_value());
350 }
catch(
const Semantics::Exception& e) {
353 std::cerr <<e <<
"\n";
354 }
catch(
const Policy::Exception& e) {
357 std::cerr <<e <<
"\n";
362 std::cerr <<
" successors:";
363 for (Disassembler::AddressSet::const_iterator si=successors.begin(); si!=successors.end(); ++si)
365 if (!*complete) std::cerr <<
"...";
366 std::cerr <<std::endl;
505 std::vector<SgAsmInstruction*> sequence;
506 sequence.push_back(
this);
533 bool relax_stack_semantics)
535 using namespace BinaryAnalysis::InstructionSemantics;
537 if (insns.empty())
return false;
539 typedef PartialSymbolicSemantics::Policy<> Policy;
540 typedef X86InstructionSemantics<Policy, PartialSymbolicSemantics::ValueType> Semantics;
542 Semantics semantics(policy);
543 if (relax_stack_semantics) policy.set_discard_popped_memory(
true);
545 for (std::vector<SgAsmInstruction*>::const_iterator ii=insns.begin(); ii!=insns.end(); ++ii) {
547 if (!insn)
return true;
548 semantics.processInstruction(insn);
549 if (!policy.get_ip().is_known())
return true;
551 }
catch (
const Semantics::Exception&) {
553 }
catch (
const Policy::Exception&) {
560 ROSE_ASSERT(policy.get_ip().is_known());
561 if (!allow_branch && policy.get_ip().known_value()!=insns.back()->get_address() + insns.back()->get_size())
566 policy.get_orig_state().registers.ip = policy.get_state().registers.ip = PartialSymbolicSemantics::ValueType<32>();
567 return !policy.equal_states(policy.get_orig_state(), policy.get_state());
581 std::vector< std::pair< size_t, size_t > >
583 bool relax_stack_semantics)
585 using namespace BinaryAnalysis::InstructionSemantics;
587 static const bool verbose =
false;
589 if (verbose) std::cerr <<
"find_noop_subsequences:\n";
590 std::vector< std::pair <
size_t,
size_t> > retval;
592 typedef PartialSymbolicSemantics::Policy<> Policy;
593 typedef X86InstructionSemantics<Policy, PartialSymbolicSemantics::ValueType> Semantics;
595 if (relax_stack_semantics) policy.set_discard_popped_memory(
true);
596 Semantics semantics(policy);
600 const PartialSymbolicSemantics::ValueType<32> common_ip;
604 std::vector<PartialSymbolicSemantics::State<PartialSymbolicSemantics::ValueType> > state;
605 state.push_back(policy.get_state());
606 state.back().registers.ip = common_ip;
608 for (std::vector<SgAsmInstruction*>::const_iterator ii=insns.begin(); ii!=insns.end(); ++ii) {
611 std::cerr <<
" insn #" <<(state.size()-1)
612 <<
" " <<(insn ? unparseInstructionWithAddress(insn) :
"<none>") <<
"\n";
613 if (!insn)
return retval;
614 semantics.processInstruction(insn);
615 state.push_back(policy.get_state());
616 if (verbose) std::cerr <<
" state:\n" <<policy.get_state();
618 }
catch (
const Semantics::Exception&) {
620 }
catch (
const Policy::Exception&) {
627 if (!policy.get_ip().is_known()) {
629 }
else if (!allow_branch &&
630 policy.get_ip().known_value()!=insns.back()->get_address() + insns.back()->get_size()) {
635 const size_t nstates = state.size();
636 for (
size_t i=0; i<nstates; i++)
637 state[i].registers.ip = common_ip;
640 if (verbose) std::cerr <<
" number of states: " <<nstates <<
"\n";
641 for (
size_t i=0; i<nstates-1; i++) {
642 for (
size_t j=i+1; j<nstates; j++) {
643 if (policy.equal_states(state[i], state[j])) {
644 if (verbose) std::cerr <<
" at instruction #"<<i <<
": no-op of length " <<(j-i) <<
"\n";
645 retval.push_back(std::make_pair(i, j-i));