void MemoryTracer::traceDataMemoryAccess(S2EExecutionState *state, klee::ref<klee::Expr> &address, klee::ref<klee::Expr> &hostAddress, klee::ref<klee::Expr> &value, bool isWrite, bool isIO) { if (m_catchAbove || m_catchBelow) { if (m_catchAbove && (m_catchAbove >= state->getPc())) { return; } if (m_catchBelow && (m_catchBelow < state->getPc())) { return; } } bool isAddrCste = isa<klee::ConstantExpr>(address); bool isValCste = isa<klee::ConstantExpr>(value); bool isHostAddrCste = isa<klee::ConstantExpr>(hostAddress); //Output to the trace entry here ExecutionTraceMemory e; e.flags = 0; e.pc = state->getPc(); uint64_t concreteAddress = 0xdeadbeef; uint64_t concreteValue = 0xdeadbeef; if (ConcolicMode) { klee::ref<klee::ConstantExpr> ce = dyn_cast<klee::ConstantExpr>(state->concolics.evaluate(address)); concreteAddress = ce->getZExtValue(); ce = dyn_cast<klee::ConstantExpr>(state->concolics.evaluate(value)); concreteValue = ce->getZExtValue(); } e.address = isAddrCste ? cast<klee::ConstantExpr>(address)->getZExtValue(64) : concreteAddress; e.value = isValCste ? cast<klee::ConstantExpr>(value)->getZExtValue(64) : concreteValue; e.size = klee::Expr::getMinBytesForWidth(value->getWidth()); e.flags = isWrite*EXECTRACE_MEM_WRITE | isIO*EXECTRACE_MEM_IO; e.hostAddress = isHostAddrCste ? cast<klee::ConstantExpr>(hostAddress)->getZExtValue(64) : 0xDEADBEEF; if (m_traceHostAddresses) { e.flags |= EXECTRACE_MEM_HASHOSTADDR; e.flags |= EXECTRACE_MEM_OBJECTSTATE; klee::ObjectPair op = state->addressSpace.findObject(e.hostAddress & S2E_RAM_OBJECT_MASK); e.concreteBuffer = 0; if (op.first && op.second) { e.concreteBuffer = (uint64_t) op.second->getConcreteStore(); if (isWrite && m_debugObjectStates) { assert(state->addressSpace.isOwnedByUs(op.second)); } } } if (!isAddrCste) { e.flags |= EXECTRACE_MEM_SYMBADDR; } if (!isValCste) { e.flags |= EXECTRACE_MEM_SYMBVAL; } if (!isHostAddrCste) { e.flags |= EXECTRACE_MEM_SYMBHOSTADDR; } unsigned strucSize = sizeof(e); if (!(e.flags & EXECTRACE_MEM_HASHOSTADDR) && !(e.flags & EXECTRACE_MEM_OBJECTSTATE)) { strucSize -= (sizeof(e.hostAddress) + sizeof(e.concreteBuffer)); } m_tracer->writeData(state, &e, sizeof(e), TRACE_MEMORY); }
bool MemoryManager::check___kmalloc_size(klee::ref<klee::Expr> size, S2EExecutionState *state) { bool isok = true; //size具体值 if (isa<klee::ConstantExpr>(size)) { int value = cast<klee::ConstantExpr>(size)->getZExtValue(); if (value <= 0 || value >= 0xf0000) { s2e()->getWarningsStream() << "============================================================" << '\n'; s2e()->getWarningsStream() << "BUG: __kmalloc [Size <= 0||Size >= 0xf0000] Size: " << value << '\n'; state->dumpStack(5); //print the 5 stackframe addbyxqx s2e()->getWarningsStream() << "============================================================" << '\n'; //打印完整路径约束 printConstraintExpr(state); if(m_terminateOnBugs) { s2e()->getExecutor()->terminateStateEarly(*state, "Killed by MemoryManager: __kmalloc size is not valid\n"); } isok = false; } } //如果size是符号值 else { bool isTrue; //求解出size=0的时候外界的输入是多少,也就是外界传入什么值的时候可以造成size会为=0 isTrue = false; //klee::ref<klee::Expr> cond = klee::SleExpr::create(size, klee::ref<klee::Expr> cond = klee::EqExpr::create(size, klee::ConstantExpr::create( 0, size.get()->getWidth())); if (!(s2e()->getExecutor()->getSolver()->mayBeTrue(klee::Query(state->constraints, cond), isTrue))) { s2e()->getWarningsStream() << "failed to assert the condition" << '\n'; return false; } ConcreteInputs inputs; ConcreteInputs::iterator it; if (isTrue) { //ConcreteInputs inputs; //ConcreteInputs::iterator it; //把state的正确约束保存到constraints_before klee::ConstraintManager constraints_before(state->constraints); klee::ConstraintManager *tmp_constraints; tmp_constraints = &state->constraints; //*****************************************输入值求解*********************************************** s2e()->getExecutor()->addConstraint(*state, cond); s2e()->getExecutor()->getSymbolicSolution(*state, inputs); s2e()->getWarningsStream() << "======================================================" << '\n'; //s2e()->getWarningsStream() << "BUG:on this condition __kmalloc size will <= 0" << '\n'; s2e()->getWarningsStream() << "BUG:on this condition __kmalloc size will = 0" << '\n'; s2e()->getWarningsStream() << "Condition: " << '\n'; for (it = inputs.begin(); it != inputs.end(); ++it) { const VarValuePair &vp = *it; s2e()->getWarningsStream() << vp.first << " : "; for (unsigned i=0; i<vp.second.size(); ++i) { s2e()->getWarningsStream() << hexval((unsigned char) vp.second[i]) << " "; } s2e()->getWarningsStream() << '\n'; } ///added by xyj 05.23 /* for (int i = 0; i < int((state->symbolics).size()); i++) { if((state->addressSpace).findObject((state->symbolics[i]).first) == NULL) { s2e()->getMessagesStream() << "没有找到memoryObject对应的objectState"<<'\n'; continue; } const klee::ObjectState *ob = (state->addressSpace).findObject((state->symbolics[i]).first); uint64_t address_par = state->symbolics[i].first->address; unsigned size_par = state->symbolics[i].first->size; for (int j = 0; j < size_par; j++) { klee::ref<klee::Expr> para = state->readMemory(address_par+j,1); cond = klee::NeExpr::create(para, klee::ConstantExpr::create(uint64_t(inputs[i].second[j]), para.get()->getWidth())); if (!(s2e()->getExecutor()->getSolver()->mayBeTrue(klee::Query(state->constraints, cond), isTrue))) { s2e()->getMessagesStream() << "failed to assert the condition" << '\n'; return false; } //s2e()->getExecutor()->addConstraint(*state, cond); } } inputs.clear(); s2e()->getExecutor()->getSymbolicSolution(*state, inputs); for (it = inputs.begin(); it != inputs.end(); ++it) { const VarValuePair &vp = *it; s2e()->getMessagesStream() << vp.first << " : "; for (unsigned i=0; i<vp.second.size(); ++i) { s2e()->getMessagesStream() << hexval((unsigned char) vp.second[i]) << " "; } s2e()->getMessagesStream() << '\n'; } */ s2e()->getWarningsStream() << "======================================================" << '\n'; //********************************************************************************************* //删除修改过的约束;恢复原来的正确约束 tmp_constraints->empty(); state->constraints = constraints_before; //打印完整路径约束 printConstraintExpr(state); isok = false; if(m_terminateOnBugs) { //s2e()->getExecutor()->terminateStateEarly(*state, "Killed by MemoryManager: __kmalloc size is not valid[size<=0]\n"); s2e()->getExecutor()->terminateStateEarly(*state, "Killed by MemoryManager: __kmalloc size is not valid[size=0]\n"); } } if(m_terminateOnBugs) { s2e()->getExecutor()->getSymbolicSolution(*state, inputs); s2e()->getWarningsStream() << "======================================================" << '\n'; //s2e()->getWarningsStream() << "BUG:on this condition __kmalloc size will <= 0" << '\n'; s2e()->getWarningsStream() << "MaybeBUG:on this condition __kmalloc size could be impact" << '\n'; s2e()->getWarningsStream() << "Condition: " << '\n'; for (it = inputs.begin(); it != inputs.end(); ++it) { const VarValuePair &vp = *it; s2e()->getWarningsStream() << vp.first << " : "; for (unsigned i=0; i<vp.second.size(); ++i) { s2e()->getWarningsStream() << hexval((unsigned char) vp.second[i]) << " "; } s2e()->getWarningsStream() << '\n'; } s2e()->getWarningsStream() << "=================dumpStack=====================================" << '\n'; state->dumpStack(5); //print the 5 stackframe addbyxqx s2e()->getWarningsStream() << "======================dumpStack-end================================" << '\n'; //s2e()->getExecutor()->terminateStateEarly(*state, "Killed by MemoryManager: __kmalloc size is not valid[size<=0]\n"); s2e()->getExecutor()->terminateStateEarly(*state, "Killed by MemoryManager: __kmalloc size is not valid[size=0]\n"); } } return isok; }
void MemoryTracer::traceDataMemoryAccess(S2EExecutionState *state, klee::ref<klee::Expr> &address, klee::ref<klee::Expr> &hostAddress, klee::ref<klee::Expr> &value, bool isWrite, bool isIO) { if (m_catchAbove || m_catchBelow) { if (m_catchAbove && (m_catchAbove >= state->getPc())) { return; } if (m_catchBelow && (m_catchBelow < state->getPc())) { return; } } bool isAddrCste = isa<klee::ConstantExpr>(address); bool isValCste = isa<klee::ConstantExpr>(value); bool isHostAddrCste = isa<klee::ConstantExpr>(hostAddress); //Output to the trace entry here ExecutionTraceMemory e; e.flags = 0; e.pc = state->getPc(); uint64_t concreteAddress = 0xdeadbeef; uint64_t concreteValue = 0xdeadbeef; if (ConcolicMode) { klee::ref<klee::ConstantExpr> ce = dyn_cast<klee::ConstantExpr>(state->concolics.evaluate(address)); concreteAddress = ce->getZExtValue(); ce = dyn_cast<klee::ConstantExpr>(state->concolics.evaluate(value)); concreteValue = ce->getZExtValue(); } e.address = isAddrCste ? cast<klee::ConstantExpr>(address)->getZExtValue(64) : concreteAddress; e.value = isValCste ? cast<klee::ConstantExpr>(value)->getZExtValue(64) : concreteValue; e.size = klee::Expr::getMinBytesForWidth(value->getWidth()); e.flags = isWrite*EXECTRACE_MEM_WRITE | isIO*EXECTRACE_MEM_IO; e.hostAddress = isHostAddrCste ? cast<klee::ConstantExpr>(hostAddress)->getZExtValue(64) : 0xDEADBEEF; if (m_traceHostAddresses) { e.flags |= EXECTRACE_MEM_HASHOSTADDR; } if (!isAddrCste) { e.flags |= EXECTRACE_MEM_SYMBADDR; } if (!isValCste) { e.flags |= EXECTRACE_MEM_SYMBVAL; } if (!isHostAddrCste) { e.flags |= EXECTRACE_MEM_SYMBHOSTADDR; } unsigned strucSize = sizeof(e); if (!(e.flags & EXECTRACE_MEM_HASHOSTADDR)) { strucSize -= sizeof(e.hostAddress); } m_tracer->writeData(state, &e, sizeof(e), TRACE_MEMORY); }