SymbolicElement *AnalysisProcessor::createMemSE(Inst &inst, std::stringstream &expr, uint64_t address, uint64_t writeSize, std::string comment) { SymbolicElement *ret = nullptr; std::stringstream tmp; /* * As the x86's memory can be accessed without alignment, each byte of the * memory must be assigned to an unique reference. */ while (writeSize){ /* Extract each byte if the size > 1 byte (8 bits) */ if (writeSize > BYTE_SIZE){ tmp.str(smt2lib::extract(((writeSize * REG_SIZE) - 1), ((writeSize * REG_SIZE) - REG_SIZE), expr.str())); SymbolicElement *se = symEngine.newSymbolicElement(tmp, "byte reference"); inst.addElement(se); /* Assign memory with little endian */ this->symEngine.addMemoryReference((address + writeSize) - 1, se->getID()); } /* Otherwise keep the full formula */ else { SymbolicElement *se = symEngine.newSymbolicElement(expr, comment); inst.addElement(se); this->symEngine.addMemoryReference(address, se->getID()); ret = se; } writeSize--; } return ret; }
SymbolicElement *AnalysisProcessor::createRegSE(Inst &inst, std::stringstream &expr, uint64_t regID, uint64_t regSize, std::string comment) { std::stringstream finalExpr, origReg; origReg << this->buildSymbolicRegOperand(regID, REG_SIZE); switch (regSize) { case BYTE_SIZE: finalExpr << smt2lib::concat(smt2lib::extract(63, 8, origReg.str()), expr.str()); break; case WORD_SIZE: finalExpr << smt2lib::concat(smt2lib::extract(63, 16, origReg.str()), expr.str()); break; case DWORD_SIZE: /* In AMD64, if a reg32 is written, it clears the 32-bit MSB of the corresponding register (Thx Wisk!) */ finalExpr << smt2lib::zx(expr.str(), DWORD_SIZE_BIT); break; case QWORD_SIZE: finalExpr << expr.str(); break; case DQWORD_SIZE: finalExpr << expr.str(); break; } SymbolicElement *se = this->symEngine.newSymbolicElement(finalExpr, comment); this->symEngine.symbolicReg[regID] = se->getID(); inst.addElement(se); return se; }
SymbolicElement *AnalysisProcessor::createRegSE(Inst &inst, std::stringstream &expr, uint64_t regID, std::string comment) { SymbolicElement *se = this->symEngine.newSymbolicElement(expr, comment); this->symEngine.symbolicReg[regID] = se->getID(); inst.addElement(se); return se; }
void JnleIRBuilder::imm(AnalysisProcessor &ap, Inst &inst) const { SymbolicElement *se; std::stringstream expr, sf, of, zf; uint64 imm = this->operands[0].getValue(); /* Create the SMT semantic */ sf << ap.buildSymbolicFlagOperand(ID_SF); of << ap.buildSymbolicFlagOperand(ID_OF); zf << ap.buildSymbolicFlagOperand(ID_ZF); /* * Finale expr * JNLE: Jump if not less or equal ((SF^OF | ZF) == 0). * SMT: (= (bvor (bvxor sf of) zf) FALSE) */ expr << smt2lib::ite( smt2lib::equal( smt2lib::bvor(smt2lib::bvxor(sf.str(), of.str()), zf.str()), smt2lib::bvfalse() ), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic element */ se = ap.createRegSE(inst, expr, ID_RIP, REG_SIZE, "RIP"); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }
void JnbeIRBuilder::imm(AnalysisProcessor &ap, Inst &inst) const { SymbolicElement *se; std::stringstream expr, cf, zf; uint64 imm = this->operands[0].getValue(); /* Create the SMT semantic */ cf << ap.buildSymbolicFlagOperand(ID_CF); zf << ap.buildSymbolicFlagOperand(ID_ZF); /* * Finale expr * JNBE: Jump if not below or equal (CF=0 and ZF=0). * SMT: (= (bvand (bvnot zf) (bvnot cf)) (_ bv1 1)) */ expr << smt2lib::ite( smt2lib::equal( smt2lib::bvand( smt2lib::bvnot(cf.str()), smt2lib::bvnot(zf.str()) ), smt2lib::bvtrue() ), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic element */ se = ap.createRegSE(inst, expr, ID_RIP, REG_SIZE, "RIP"); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }
void JbIRBuilder::imm(AnalysisProcessor &ap, Inst &inst) const { SymbolicElement *se; std::stringstream expr, cf; uint64 imm = this->operands[0].getValue(); /* Create the SMT semantic */ cf << ap.buildSymbolicFlagOperand(ID_CF); /* Finale expr */ expr << smt2lib::ite( smt2lib::equal( cf.str(), smt2lib::bvtrue()), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic element */ se = ap.createRegSE(inst, expr, ID_RIP, REG_SIZE, "RIP"); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }