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;
}
Beispiel #4
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());

}
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());
}