SymbolicExpression *AnalysisProcessor::createMemSE(Inst &inst, smt2lib::smtAstAbstractNode *expr, uint64 address, uint64 writeSize, std::string comment) { SymbolicExpression *ret = nullptr; smt2lib::smtAstAbstractNode *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 = smt2lib::extract(((writeSize * REG_SIZE) - 1), ((writeSize * REG_SIZE) - REG_SIZE), expr); SymbolicExpression *se = symEngine.newSymbolicExpression(tmp, "byte reference"); inst.addExpression(se); /* Assign memory with little endian */ this->symEngine.addMemoryReference((address + writeSize) - 1, se->getID()); } /* Otherwise keep the full formula */ else { SymbolicExpression *se = symEngine.newSymbolicExpression(expr, comment); inst.addExpression(se); this->symEngine.addMemoryReference(address, se->getID()); ret = se; } writeSize--; } return ret; }
SymbolicExpression *AnalysisProcessor::createRegSE(Inst &inst, smt2lib::smtAstAbstractNode *expr, uint64 regID, uint64 regSize) { smt2lib::smtAstAbstractNode *finalExpr = nullptr, *origReg = nullptr; origReg = this->buildSymbolicRegOperand(regID, REG_SIZE); switch (regSize) { case BYTE_SIZE: finalExpr = smt2lib::concat(smt2lib::extract(63, 8, origReg), expr); break; case WORD_SIZE: finalExpr = smt2lib::concat(smt2lib::extract(63, 16, origReg), expr); 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(DWORD_SIZE_BIT, expr); break; case QWORD_SIZE: case DQWORD_SIZE: finalExpr = expr; break; } SymbolicExpression *se = this->symEngine.newSymbolicExpression(finalExpr); this->symEngine.symbolicReg[regID] = se->getID(); inst.addExpression(se); return se; }
SymbolicExpression *AnalysisProcessor::createRegSE(Inst &inst, smt2lib::smtAstAbstractNode *expr, uint64 regID, std::string comment) { SymbolicExpression *se = this->symEngine.newSymbolicExpression(expr, comment); this->symEngine.symbolicReg[regID] = se->getID(); inst.addExpression(se); return se; }
SymbolicExpression *AnalysisProcessor::createMemSE(Inst &inst, smt2lib::smtAstAbstractNode *expr, MemoryOperand &mem, uint64 writeSize, std::string comment) { SymbolicExpression *se = nullptr; smt2lib::smtAstAbstractNode *tmp; std::list<smt2lib::smtAstAbstractNode *> ret; uint64 address = mem.getAddress(); /* * 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 of the memory */ tmp = smt2lib::extract(((writeSize * REG_SIZE) - 1), ((writeSize * REG_SIZE) - REG_SIZE), expr); se = symEngine.newSymbolicExpression(tmp, "byte reference"); ret.push_back(tmp); inst.addExpression(se); /* Assign memory with little endian */ this->symEngine.addMemoryReference((address + writeSize) - 1, se->getID()); writeSize--; } /* If there is only one reference, we return the symbolic expression */ if (ret.size() == 1) return se; /* Otherwise, we return the concatenation of all symbolic expressions */ return symEngine.newSymbolicExpression(smt2lib::concat(ret), "concat reference"); }
SymbolicExpression *AnalysisProcessor::createFlagSE(Inst &inst, smt2lib::smtAstAbstractNode *expr, RegisterOperand &flag, std::string comment) { uint64 flagId = flag.getTritonRegId(); SymbolicExpression *se = this->symEngine.newSymbolicExpression(expr, comment); this->symEngine.symbolicReg[flagId] = se->getID(); inst.addExpression(se); return se; }
SymbolicExpression *AnalysisProcessor::createRegSE(Inst &inst, smt2lib::smtAstAbstractNode *expr, RegisterOperand ®, uint64 regSize, std::string comment) { uint64 regId = reg.getTritonRegId(); smt2lib::smtAstAbstractNode *finalExpr = nullptr, *origReg = nullptr; origReg = this->buildSymbolicRegOperand(reg, REG_SIZE, 63, 0); switch (regSize) { case BYTE_SIZE: if (reg.getLow() == 0) finalExpr = smt2lib::concat(smt2lib::extract(63, 8, origReg), expr); else finalExpr = smt2lib::concat(smt2lib::extract(63, 16, origReg), smt2lib::concat(expr, smt2lib::extract(7, 0, origReg))); break; case WORD_SIZE: finalExpr = smt2lib::concat(smt2lib::extract(63, 16, origReg), expr); 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(DWORD_SIZE_BIT, expr); break; case QWORD_SIZE: case DQWORD_SIZE: finalExpr = expr; break; } SymbolicExpression *se = this->symEngine.newSymbolicExpression(finalExpr, comment); this->symEngine.symbolicReg[regId] = se->getID(); inst.addExpression(se); return se; }
void JlIRBuilder::imm(AnalysisProcessor &ap, Inst &inst) const { SymbolicExpression *se; smt2lib::smtAstAbstractNode *expr, *sf, *of; auto imm = this->operands[0].getImm().getValue(); /* Create the SMT semantic */ sf = ap.buildSymbolicFlagOperand(ID_SF); of = ap.buildSymbolicFlagOperand(ID_OF); /* * Finale expr * JL: Jump if less (SF^OF). * SMT: ( = (bvxor sf of) True) */ expr = smt2lib::ite( smt2lib::equal( smt2lib::bvxor(sf, of), smt2lib::bvtrue() ), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic expression */ se = ap.createRegSE(inst, expr, ID_RIP, REG_SIZE, "RIP"); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }
void JnsIRBuilder::imm(AnalysisProcessor &ap, Inst &inst) const { SymbolicExpression *se; smt2lib::smtAstAbstractNode *expr, *sf; auto imm = this->operands[0].getImm().getValue(); /* Create the SMT semantic */ sf = ap.buildSymbolicFlagOperand(ID_TMP_SF); /* Finale expr */ expr = smt2lib::ite( smt2lib::equal( sf, smt2lib::bvfalse()), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic expression */ se = ap.createRegSE(inst, expr, ID_TMP_RIP, REG_SIZE, "RIP"); /* Apply the taint */ ap.aluSpreadTaintRegReg(se, ID_TMP_RIP, ID_TMP_SF); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }
void JnbeIRBuilder::imm(AnalysisProcessor &ap, Inst &inst) const { SymbolicExpression *se; smt2lib::smtAstAbstractNode *expr, *cf, *zf; auto imm = this->operands[0].getImm().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), smt2lib::bvnot(zf) ), smt2lib::bvtrue() ), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic expression */ se = ap.createRegSE(inst, expr, ID_RIP, REG_SIZE, "RIP"); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }
SymbolicVariable *SymbolicEngine::convertRegToSymVar(uint64 regId, uint64 symVarSize, std::string symVarComment) { SymbolicVariable *symVar = nullptr; SymbolicExpression *expression = nullptr; uint64 regSymId = UNSET; if (regId >= ID_LAST_ITEM) throw std::runtime_error("SymbolicEngine::convertRegToSymVar() - Invalid register ID"); regSymId = this->getRegSymbolicID(regId); if (regSymId == UNSET) { symVar = this->addSymbolicVariable(SymVar::kind::REG, regId, symVarSize, symVarComment); smt2lib::smtAstAbstractNode *tmp = smt2lib::variable(symVar->getSymVarName()); if (tmp == nullptr) throw std::runtime_error("convertRegToSymVar can't create smtAstAbstractNode (nullptr)"); SymbolicExpression *se = this->newSymbolicExpression(tmp); if (se == nullptr) throw std::runtime_error("convertRegToSymVar can't create symbolic expression (nullptr)"); this->symbolicReg[regId] = se->getID(); } else { expression = this->getExpressionFromId(regSymId); if (expression == nullptr) return nullptr; symVar = this->addSymbolicVariable(SymVar::kind::REG, regId, symVarSize, symVarComment); expression->setExpression(smt2lib::variable(symVar->getSymVarName())); } return symVar; }
void JbeIRBuilder::imm(Inst &inst) const { SymbolicExpression *se; smt2lib::smtAstAbstractNode *expr, *cf, *zf; auto imm = this->operands[0].getImm().getValue(); /* Create the SMT semantic */ cf = ap.buildSymbolicFlagOperand(ID_TMP_CF); zf = ap.buildSymbolicFlagOperand(ID_TMP_ZF); /* * Finale expr * JNBE: Jump if below or equal (CF =1 or ZF =1). * SMT: ( = (bvor zf cf) (_ bv1 1)) */ expr = smt2lib::ite( smt2lib::equal( smt2lib::bvor( cf, zf ), smt2lib::bvtrue() ), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic expression */ se = ap.createRegSE(inst, expr, ID_TMP_RIP, REG_SIZE, "Program Counter"); /* Apply the taint */ ap.aluSpreadTaintRegReg(se, ID_TMP_RIP, ID_TMP_CF); ap.aluSpreadTaintRegReg(se, ID_TMP_RIP, ID_TMP_ZF); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }
void JleIRBuilder::imm(Inst &inst) const { SymbolicExpression *se; smt2lib::smtAstAbstractNode *expr, *sf, *of, *zf; auto imm = this->operands[0].getImm().getValue(); /* Create the SMT semantic */ sf = ap.buildSymbolicFlagOperand(ID_TMP_SF); of = ap.buildSymbolicFlagOperand(ID_TMP_OF); zf = ap.buildSymbolicFlagOperand(ID_TMP_ZF); /* * Finale expr * JLE: Jump if less or equal ((SF^OF | ZF) == 1). * SMT: ( = (bvor (bvxor sf of) zf) TRUE) */ expr = smt2lib::ite( smt2lib::equal( smt2lib::bvor(smt2lib::bvxor(sf, of), zf), smt2lib::bvtrue() ), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic expression */ se = ap.createRegSE(inst, expr, ID_TMP_RIP, REG_SIZE, "Program Counter"); /* Apply the taint */ ap.aluSpreadTaintRegReg(se, ID_TMP_RIP, ID_TMP_SF); ap.aluSpreadTaintRegReg(se, ID_TMP_RIP, ID_TMP_OF); ap.aluSpreadTaintRegReg(se, ID_TMP_RIP, ID_TMP_ZF); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }
// Note: symVarSize is in BYTE. SymbolicVariable *SymbolicEngine::convertMemToSymVar(uint64 memAddr, uint64 symVarSize, std::string symVarComment) { SymbolicVariable *symVar = nullptr; SymbolicExpression *expression = nullptr; smt2lib::smtAstAbstractNode *tmp = nullptr; uint64 memSymId = UNSET; uint64 size_quotient = symVarSize; memSymId = this->getMemSymbolicID(memAddr); // First we create a symbolic variable symVar = this->addSymbolicVariable(SymVar::kind::MEM, memAddr, symVarSize * 8, symVarComment); smt2lib::smtAstAbstractNode *symVarNode = smt2lib::variable(symVar->getSymVarName()); if (symVarNode == nullptr) throw std::runtime_error("convertMemToSymVar can't create smtAstAbstractNode (nullptr)"); std::list<smt2lib::smtAstAbstractNode *> symMemChunk; while (size_quotient) { tmp = smt2lib::extract((REG_SIZE * size_quotient - 1), (REG_SIZE * size_quotient - REG_SIZE), symVarNode); symMemChunk.push_back(tmp); if (tmp == nullptr) throw std::runtime_error("convertMemToSymVar can't create extract (nullptr)"); if (memSymId == UNSET) { if (size_quotient > 1 or symVarSize == 1) { expression = this->newSymbolicExpression(tmp, "byte reference"); } else { smt2lib::smtAstAbstractNode *concat = smt2lib::concat(symMemChunk); expression = this->newSymbolicExpression(concat); } } else { expression = this->getExpressionFromId(memSymId); expression->setExpression(tmp); } if (expression == nullptr) throw std::runtime_error("convertMemToSymVar can't create symbolic expression (nullptr)"); this->addMemoryReference((memAddr + size_quotient) - 1, expression->getID()); size_quotient--; } return symVar; }
void JbIRBuilder::imm(AnalysisProcessor &ap, Inst &inst) const { SymbolicExpression *se; smt2lib::smtAstAbstractNode *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, smt2lib::bvtrue()), smt2lib::bv(imm, REG_SIZE_BIT), smt2lib::bv(this->nextAddress, REG_SIZE_BIT)); /* Create the symbolic expression */ se = ap.createRegSE(inst, expr, ID_RIP, REG_SIZE, "RIP"); /* Add the constraint in the PathConstraints list */ ap.addPathConstraint(se->getID()); }
static PyObject *SymbolicExpression_getId(PyObject *self, PyObject *noarg) { SymbolicExpression *expression = PySymbolicExpression_AsSymbolicExpression(self); return Py_BuildValue("k", expression->getID()); }