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::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, std::string comment)
{
  SymbolicElement *se = this->symEngine.newSymbolicElement(expr, comment);
  this->symEngine.symbolicReg[regID] = se->getID();
  inst.addElement(se);
  return se;
}
Beispiel #4
0
uint64 SymbolicEngine::convertRegToSymVar(uint64 regId, uint64 symVarSize)
{
  SymbolicVariable   *symVar  = nullptr;
  SymbolicElement    *element = nullptr;
  std::stringstream  newExpr;
  uint64             regSymId = UNSET;

  if (regId >= ID_LAST_ITEM)
    throw std::runtime_error("SymbolicEngine::convertRegToSymVar() - Invalid register ID");

  regSymId = this->getRegSymbolicID(regId);
  if (regSymId == UNSET)
    throw std::runtime_error("SymbolicEngine::convertRegToSymVar() - This register ID is UNSET");

  element = this->getElementFromId(regSymId);

  if (element == nullptr)
    return UNSET;

  if (symVarSize != BYTE_SIZE && symVarSize != WORD_SIZE && symVarSize != DWORD_SIZE && symVarSize != QWORD_SIZE && symVarSize != DQWORD_SIZE)
    throw std::runtime_error("SymbolicEngine::convertRegToSymVar() - Invalid symVarSize");

  symVar = this->addSymbolicVariable(SymVar::kind::REG, regId, symVarSize);

  newExpr << symVar->getSymVarName();
  element->setSrcExpr(newExpr);

  return symVar->getSymVarId();
}
Beispiel #5
0
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());

}
Beispiel #6
0
uint64 SymbolicEngine::convertMemToSymVar(uint64 memAddr, uint64 symVarSize)
{
  SymbolicVariable   *symVar  = nullptr;
  SymbolicElement    *element = nullptr;
  std::stringstream  newExpr;
  uint64             memSymId = UNSET;

  memSymId = this->getMemSymbolicID(memAddr);
  if (memSymId == UNSET)
    throw std::runtime_error("SymbolicEngine::convertMemToSymVar() - This memory address is UNSET");

  element = this->getElementFromId(memSymId);

  if (element == nullptr)
    return UNSET;

  if (symVarSize != BYTE_SIZE && symVarSize != WORD_SIZE && symVarSize != DWORD_SIZE && symVarSize != QWORD_SIZE && symVarSize != DQWORD_SIZE)
    throw std::runtime_error("SymbolicEngine::convertMemToSymVar() - Invalid symVarSize");

  symVar = this->addSymbolicVariable(SymVar::kind::MEM, memAddr, symVarSize);

  newExpr << symVar->getSymVarName();
  element->setSrcExpr(newExpr);

  return symVar->getSymVarId();
}
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());
}
Beispiel #8
0
/* Returns the symbolic expression backtracked from an ID. */
std::string SymbolicEngine::getBacktrackedExpressionFromId(uint64 id)
{
  SymbolicElement   *element;
  std::stringstream formula;

  element = this->getElementFromId(id);
  if (element == nullptr)
    return "";

  formula.str(element->getSource()->str());
  while (formula.str().find("#") != std::string::npos)
    formula.str(this->deepReplace(formula));

  return formula.str();
}
Beispiel #9
0
/*
 * Converts an expression ID to a symbolic variable.
 * e.g:
 * #43 = (_ bv10 8)
 * convertExprToSymVar(43, 8)
 * #43 = SymVar_4
 */
uint64 SymbolicEngine::convertExprToSymVar(uint64 exprId, uint64 symVarSize)
{
  SymbolicVariable   *symVar  = nullptr;
  SymbolicElement    *element = this->getElementFromId(exprId);
  std::stringstream  newExpr;

  if (element == nullptr)
    return UNSET;

  if (symVarSize != BYTE_SIZE && symVarSize != WORD_SIZE && symVarSize != DWORD_SIZE && symVarSize != QWORD_SIZE && symVarSize != DQWORD_SIZE)
    throw std::runtime_error("SymbolicEngine::convertExprToSymVar() - Invalid symVarSize");

  symVar = this->addSymbolicVariable(SymVar::kind::UNDEF, 0, symVarSize);

  newExpr << symVar->getSymVarName();
  element->setSrcExpr(newExpr);

  return symVar->getSymVarId();
}
Beispiel #10
0
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());
}