// use libudis to give human readable output of ASM void DasosPreproc::printDisasm_viaLib (uint8_t* raw, unsigned len) { ud_t ud_obj; ud_init (&ud_obj); ud_set_mode (&ud_obj, 32); ud_set_syntax (&ud_obj, UD_SYN_INTEL); ud_set_input_buffer(&ud_obj, raw, len); unsigned insn_len = 0; if ((insn_len = ud_disassemble (&ud_obj) ) != len) { s2e()->getDebugStream() << "disasm didn't do all insn bytes: " << insn_len << "/" << len << "\n"; return; } char buf[64]; snprintf (buf, sizeof (buf), " %-24s", ud_insn_asm (&ud_obj) ); s2e()->getDebugStream() << buf; return; } // end fn printDisasm_viaLib
void MemoryManager::onMemcpyExecute(S2EExecutionState *state, uint64_t pc) { uint64_t get_pc; //uint32_t eip; get_pc = state->getPc(); // state->readCpuRegisterConcrete(offsetof(CPUX86State, regs[R_EIP]), &eip, sizeof(eip)); if(get_pc>=0xc0265350 && get_pc < 0xc02653b7) { s2e()->getMessagesStream(state) << "pc is " << hexval(get_pc) << "\n" ; state->dumpX86State(s2e()->getMessagesStream(state)); } //get edi // state->readCpuRegisterConcrete(offsetof(CPUX86State, regs[R_EDI]), &edi, sizeof(edi)); //get ecx // ecx = state->readCpuRegister(offsetof(CPUX86State, regs[R_ECX]), klee::Expr::Int32); //check // check_rep(edi,ecx,state); }
void Annotation::onStateKill(S2EExecutionState* state) { lua_State *L = s2e()->getConfig()->getState(); LUAAnnotation luaAnnotation(this, state); S2ELUAExecutionState lua_s2e_state(state); lua_getfield(L, LUA_GLOBALSINDEX, m_onStateKill.c_str()); Lunar<S2ELUAExecutionState>::push(L, &lua_s2e_state); Lunar<LUAAnnotation>::push(L, &luaAnnotation); lua_call(L, 2, 0); }
void ModuleTracer::initialize() { m_Tracer = (ExecutionTracer*)s2e()->getPlugin("ExecutionTracer"); assert(m_Tracer); OSMonitor *monitor = (OSMonitor*)s2e()->getPlugin("Interceptor"); assert(monitor); monitor->onModuleLoad.connect( sigc::mem_fun(*this, &ModuleTracer::moduleLoadListener) ); monitor->onModuleUnload.connect( sigc::mem_fun(*this, &ModuleTracer::moduleUnloadListener) ); monitor->onProcessUnload.connect( sigc::mem_fun(*this, &ModuleTracer::processUnloadListener) ); }
void FunctionMonitor::slotTraceCall(S2EExecutionState *state, FunctionMonitorState *fns) { static int f = 0; FunctionMonitor::ReturnSignal returnSignal; returnSignal.connect(sigc::bind(sigc::mem_fun(*this, &FunctionMonitor::slotTraceRet), f)); fns->registerReturnSignal(state, returnSignal); s2e()->getMessagesStream(state) << "Calling function " << f << " at " << hexval(state->getPc()) << std::endl; ++f; }
void MemoryTracer::enableTracing() { if (m_monitorMemory) { s2e()->getMessagesStream() << "MemoryTracer Plugin: Enabling memory tracing" << '\n'; m_memoryMonitor.disconnect(); if (m_monitorModules) { m_execDetector->onModuleTransition.connect( sigc::mem_fun(*this, &MemoryTracer::onModuleTransition) ); } else { m_memoryMonitor = s2e()->getCorePlugin()->onDataMemoryAccess.connect( sigc::mem_fun(*this, &MemoryTracer::onDataMemoryAccess)); } } if (m_monitorPageFaults) { s2e()->getMessagesStream() << "MemoryTracer Plugin: Enabling page fault tracing" << '\n'; m_pageFaultsMonitor.disconnect(); m_pageFaultsMonitor = s2e()->getCorePlugin()->onPageFault.connect( sigc::mem_fun(*this, &MemoryTracer::onPageFault)); } if (m_monitorTlbMisses) { s2e()->getMessagesStream() << "MemoryTracer Plugin: Enabling TLB miss tracing" << '\n'; m_tlbMissesMonitor.disconnect(); m_tlbMissesMonitor = s2e()->getCorePlugin()->onTlbMiss.connect( sigc::mem_fun(*this, &MemoryTracer::onTlbMiss)); } }
void MemoryTracer::onModuleTransition(S2EExecutionState *state, const ModuleDescriptor *prevModule, const ModuleDescriptor *nextModule) { if (nextModule && !m_memoryMonitor.connected()) { m_memoryMonitor = s2e()->getCorePlugin()->onDataMemoryAccess.connect( sigc::mem_fun(*this, &MemoryTracer::onDataMemoryAccess) ); } else { m_memoryMonitor.disconnect(); } }
void DasosPreproc::fuzzFork1 (S2EExecutionState* state, unsigned int value) { /** Emulate fork via WindowsApi forkRange Code */ klee::ref<klee::Expr> symb = state->createSymbolicValue (klee::Expr::Int32, "fuzz_symb"); klee::ref<klee::Expr> cond = klee::NeExpr::create (symb, klee::ConstantExpr::create (value, klee::Expr::Int32) ); klee::Executor::StatePair sp = s2e()->getExecutor()->fork (*state, cond, false); S2EExecutionState *fs = static_cast<S2EExecutionState *>(sp.second); // set the return value for state 1 to given value fs->writeCpuRegisterConcrete (CPU_OFFSET(regs[R_EAX]), &(value), 4); // set the return value for state 0 to a canary value = 0xffffffff; state->writeCpuRegisterConcrete (CPU_OFFSET(regs[R_EAX]), &(value), 4); return; } // end fn fuzzFork1
void BaseInstructions::concretize(S2EExecutionState *state, bool addConstraint) { uint32_t address, size; bool ok = true; ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EAX]), &address, 4); ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EBX]), &size, 4); if(!ok) { s2e()->getWarningsStream(state) << "ERROR: symbolic argument was passed to s2e_op " " get_example opcode" << std::endl; return; } for(unsigned i = 0; i < size; ++i) { ref<Expr> expr = state->readMemory8(address + i); if(!expr.isNull()) { if(addConstraint) { /* concretize */ expr = s2e()->getExecutor()->toConstant(*state, expr, "request from guest"); } else { /* example */ expr = s2e()->getExecutor()->toConstantSilent(*state, expr); } if(!state->writeMemory(address + i, expr)) { s2e()->getWarningsStream(state) << "Can not write to memory" << " at " << hexval(address + i) << std::endl; } } else { s2e()->getWarningsStream(state) << "Can not read from memory" << " at " << hexval(address + i) << std::endl; } } }
void BaseInstructions::sleep(S2EExecutionState *state) { uint32_t duration = 0; state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EAX]), &duration, sizeof(uint32_t)); s2e()->getDebugStream() << "Sleeping " << duration << " seconds\n"; llvm::sys::TimeValue startTime = llvm::sys::TimeValue::now(); while (llvm::sys::TimeValue::now().seconds() - startTime.seconds() < duration) { #ifdef _WIN32 Sleep(1000); #else ::sleep(1); #endif } }
void UCoreUtils::parseSymbolMap(){ ifstream system_map_stream; system_map_stream.open(system_map_file.c_str()); if(!system_map_stream){ s2e()->getWarningsStream() << "Unable to open System.map file" << system_map_file << ".\n"; exit(-1); } char line[255]; uint64_t addr; string kernel_symbol; while(system_map_stream){ system_map_stream.getline(line, 255); char temp[200]; sscanf(line, "%lx %s", &addr, temp); Addr2Sym[addr] = temp; Sym2Addr[temp] = addr; } return; }
void DasosPreproc::fuzzFork (S2EExecutionState* state, unsigned int start, unsigned int end) { /** Emulate fork via WindowsApi forkRange Code */ unsigned int i; //assert(m_functionMonitor); klee::ref<klee::Expr> symb = state->createSymbolicValue (klee::Expr::Int32, "fuzz_symb"); S2EExecutionState *curState = state; // by making this 1 shy of iterations you can leverage i value afterwards and the first input state so it doesn't go to waste for (i = start; i < end; i++) { //s2e()->getDebugStream () << "fuzzClone: 2 " << std::endl; klee::ref<klee::Expr> cond = klee::NeExpr::create (symb, klee::ConstantExpr::create (i, klee::Expr::Int32) ); //s2e()->getDebugStream () << "fuzzClone: 3 " << std::endl; klee::Executor::StatePair sp = s2e()->getExecutor()->fork (*curState, cond, false); //s2e()->getDebugStream () << "fuzzClone: 4 " << std::endl; S2EExecutionState *ts = static_cast<S2EExecutionState *>(sp.first); S2EExecutionState *fs = static_cast<S2EExecutionState *>(sp.second); fs->writeCpuRegisterConcrete (CPU_OFFSET(regs[R_EAX]), &(i), 4); // set the return value curState = ts; } state->writeCpuRegisterConcrete (CPU_OFFSET(regs[R_EAX]), &(i), 4); // set the return value return; } // end fn fuzzFork
void MemoryTracer::onCustomInstruction(S2EExecutionState* state, uint64_t opcode) { if (!OPCODE_CHECK(opcode, MEMORY_TRACER_OPCODE)) { return; } uint64_t subfunction = OPCODE_GETSUBFUNCTION(opcode); MemoryTracerOpcodes opc = (MemoryTracerOpcodes)subfunction; switch(opc) { case Enable: enableTracing(); break; case Disable: disableTracing(); break; default: s2e()->getWarningsStream() << "MemoryTracer: unsupported opcode " << hexval(opc) << '\n'; break; } }
void BaseInstructions::printMemory(S2EExecutionState *state) { uint32_t address, size, name; // XXX should account for 64 bits archs bool ok = true; ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EAX]), &address, 4); ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EBX]), &size, 4); ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_ECX]), &name, 4); if(!ok) { s2e()->getWarningsStream(state) << "ERROR: symbolic argument was passed to s2e_op " "print_expression opcode\n"; return; } std::string nameStr = "<NO NAME>"; if(name && !state->readString(name, nameStr)) { s2e()->getWarningsStream(state) << "Error reading string from the guest\n"; } s2e()->getMessagesStream() << "Symbolic memory dump of " << nameStr << '\n'; for (uint32_t i=0; i<size; ++i) { s2e()->getMessagesStream() << hexval(address+i) << ": "; ref<Expr> res = state->readMemory8(address+i); if (res.isNull()) { s2e()->getMessagesStream() << "Invalid pointer\n"; }else { s2e()->getMessagesStream() << res << '\n'; } } }
void DasosPreproc::onTranslateInstructionEnd (ExecutionSignal *signal, S2EExecutionState* state, TranslationBlock *tb, uint64_t pc) { DECLARE_PLUGINSTATE (DasosPreprocState, state); if (!isInShell (pc) ) { return; } // There are multiple calls to this fn per PC. // -Could it be due to LLVM translating multiple insns per ASM insns? // -Could it be caused by connections not being properly disconnected in previously killed states? // if there is a trace and the last insn_instance has the same pc as this insn_instance, then it is duplicate, filter it out if (plgState->trace.size () != 0 && pc == plgState->trace.back().pc ) { //s2e()->getDebugStream() << "!!* pc == plgState->pcs.back @ 0x" << std::hex << pc << std::dec << " of len " << tb->size << "B, the 1st is 0x" << ((unsigned) (tb->tc_ptr)[0] & 0x000000ff) << std::endl; return; } // check if the memory map has been initialized before we try to access it if (plgState->mem_map.size () == 0) { plgState->pushSnapshot (cfg.byte_len); } struct Snapshot* s = &(plgState->mem_map.back () ); // get the raw insn bytes from the guest memory unsigned insn_raw_len = tb->lenOfLastInstr; char insn_raw[insn_raw_len]; if (!state->readMemoryConcrete (pc, insn_raw, insn_raw_len) ) { s2e()->getWarningsStream (state) << "ERROR: could not read guest memory @0x" << std::hex << pc << " to gather ASM insns\n"; s2e()->getExecutor()->terminateStateEarly (*state, "eliminated a state with an invalid read"); } // check to make sure that this insn isn't diff at any bytes prev called // saves peddling back on execution path // ie redoing beginning bytes (decrementing times_execed and then putting into new snapshot) if changed byte is in middle of insn bool changed = false; for (unsigned i = 0; !changed && i < insn_raw_len; i++) { // if byte at pc + i is in mem_map (has been execed at least once), then see if it matches the raw byte in guest memory at pc + i if (times_execed (s, pc - cfg.base_addr + i) > 0 && byte (s, pc - cfg.base_addr + i) != insn_raw[i]) { plgState->pushSnapshot (cfg.byte_len); changed = true; //i = insn_raw_len; // end forloop } } if (changed) { // in case the current snapshot has been changed s = &(plgState->mem_map.back () ); } // at this point mem_map.back() is the proper snapshot and we have read the bytes from memory // do two things: // 1) store the instance into the trace; and // 2) store the bytes into the mem_map/snapshot //plgState->trace.push_back ({plgState->mem_map.size() - 1, pc - cfg.base_addr, insn_raw_len}); struct insn_instance insn; insn.snapshot_idx = plgState->mem_map.size () - 1; insn.pc = pc - cfg.base_addr; insn.len = insn_raw_len; plgState->trace.push_back (insn); // write the bytes into the mem_map/snapshot // update any statistics as needed for (unsigned i = 0; i < insn_raw_len; i++) { unsigned pc_i = pc - cfg.base_addr + i; if (times_execed (s, pc_i) == 0) { byteWrite (s, pc_i, insn_raw[i]); if (pc_i < s->min_addr) { s->min_addr = pc_i; } if (pc_i > s->max_addr) { s->max_addr = pc_i; } s->num_execed_bytes++; } times_execedInc (s, pc_i); } // infinite loop check // see insn executed more than 3 times for this snapshot (no modified code anywhere within duration of past 3 executions) if (times_execed (s, pc - cfg.base_addr) > 3) { // if we are here, then we can assume activateModule has been called, disconnect signal if (plgState->oTICE_connected) { plgState->oTICE_connection.disconnect (); } s2e()->getWarningsStream (state) << "!! Potential inifinite loop caught at 0x" << std::hex << pc << std::endl; s2e()->getExecutor()->terminateStateEarly (*state, "eliminated this potential infinite loop"); } //s2e()->getDebugStream() << ">> Printing PC Trace Instance "; //printInsn_instance (state, plgState->trace.size () - 1, false); return; } // end fn onTranslateInstructionEnd
void FunctionMonitor::slotTraceRet(S2EExecutionState *state, int f) { s2e()->getMessagesStream(state) << "Returning from function " << f << std::endl; }
/* Uses a custom instruction within the binary * must #include s2e.h in guest code source * (our custom insns start around line 350 in s2e.h * Also must #define DASOS_PREPROC_OPCODE 0xFA line 49 in Opcodes.h */ void DasosPreproc::onCustomInstruction (S2EExecutionState* state, uint64_t opcode) { if (!OPCODE_CHECK(opcode, DASOS_PREPROC_OPCODE)) { return; } bool ok = true; opcode >>= 16; uint8_t op = opcode & 0xFF; opcode >>= 8; switch (op) { case 1: //static inline void s2e_dasospreproc_init (unsigned base, unsigned size, unsigned eip, unsigned sysc) // Module load // eax = runtime load base // ebx = length of memory // ecx = goal eip ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EAX]), &(cfg.base_addr), 4); cfg.base_addr = cfg.base_addr & 0xffffffff; ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EBX]), &(cfg.byte_len), 4); cfg.byte_len = cfg.byte_len & 0xffffffff; ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_ECX]), &(cfg.eip_addr), 4); cfg.eip_addr = cfg.eip_addr & 0xffffffff; ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EDX]), &(cfg.sysc), 4); cfg.sysc = cfg.sysc & 0xffffffff; cfg.end_addr = cfg.base_addr + cfg.byte_len; if (!ok) { s2e()->getWarningsStream (state) << "ERROR: symbolic argument was passed to s2e_op in DasosPreproc loadmodule" << std::endl; return; } onActivateModule (state); break; case 2: // static inline unsigned int s2e_dasospreproc_fuzz (unsigned int start, unsigned int end) // time to start fuzzing a particular variable // eax = return value // ebx = start of range value // ecx = end of range value uint64_t start; uint64_t end; ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EBX]), &(start), 4); start = start & 0xffffffff; if (!ok) s2e()->getWarningsStream (state) << "ERROR: bad argument was passed to s2e_op: start " << start << " in DasosPreproc start fuzzing" << std::endl; ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_ECX]), &(end), 4); end = end & 0xffffffff; if (!ok) s2e()->getWarningsStream (state) << "ERROR: bad argument was passed to s2e_op: end " << end << " in DasosPreproc start fuzzing" << std::endl; if (!ok) return; if (start > end) { s2e()->getWarningsStream (state) << "ERROR: start (" << start << ") > end (" << end << ") is invalid range in DasosPreproc start fuzzing" << std::endl; return; } s2e()->getDebugStream () << ">> fuzzInit: datum to be iterated from " << start << " to " << end << std::endl; // if there is no need to fork if (start == end) { state->writeCpuRegisterConcrete (CPU_OFFSET(regs[R_EAX]), &(start), 4); break; } // the following functions found in S2EExecutionState if (state->needToJumpToSymbolic () ) { // the state must be symbolic in order to fork state->jumpToSymbolic (); } // in case forking isn't enabled, enable it here if (!(state->isForkingEnabled () ) ) { state->enableForking (); } fuzzFork (state, start, end); break; case 4: // static inline unsigned int s2e_dasospreproc_createFork (unsigned int value) // return 2 states, 0 set to 0xffffffff and 1 set to value // eax = return value // ebx = value uint64_t value; ok &= state->readCpuRegisterConcrete(CPU_OFFSET(regs[R_EBX]), &(value), 4); value = value & 0xffffffff; if (!ok) { s2e()->getWarningsStream (state) << "ERROR: bad argument was passed to s2e_op: start " << value << " in DasosPreproc start fuzzing" << std::endl; return; } s2e()->getDebugStream () << ">> fuzzInit: datum forking for value " << value << std::endl; // the following functions found in S2EExecutionState if (state->needToJumpToSymbolic () ) { // the state must be symbolic in order to fork state->jumpToSymbolic (); } // in case forking isn't enabled, enable it here if (!(state->isForkingEnabled () ) ) { state->enableForking (); } fuzzFork1 (state, value); break; case 6 : onFini (state); break; default : s2e()->getWarningsStream (state) << "ERROR: invalid opcode" << std::endl; } return; } // end fn DasosPreproc::onCustomInstruction
/** Handle s2e_op instruction. Instructions: 0f 3f XX XX XX XX XX XX XX XX XX: opcode */ void BaseInstructions::handleBuiltInOps(S2EExecutionState* state, uint64_t opcode) { switch((opcode>>8) & 0xFF) { case 0: { /* s2e_check */ uint32_t v = 1; state->writeCpuRegisterConcrete(CPU_OFFSET(regs[R_EAX]), &v, 4); } break; case 1: state->enableSymbolicExecution(); break; case 2: state->disableSymbolicExecution(); break; case 3: { /* s2e_make_symbolic */ makeSymbolic(state, false); break; } case 4: { /* s2e_is_symbolic */ isSymbolic(state); break; } case 5: { /* s2e_get_path_id */ state->writeCpuRegister(offsetof(CPUX86State, regs[R_EAX]), klee::ConstantExpr::create(state->getID(), klee::Expr::Int32)); break; } case 6: { /* s2e_kill_state */ killState(state); break; } case 7: { /* s2e_print_expression */ printExpression(state); break; } case 8: { //Print memory contents printMemory(state); break; } case 9: state->enableForking(); break; case 10: state->disableForking(); break; case 0x10: { /* s2e_print_message */ printMessage(state, opcode >> 16); break; } case 0x11: { /* s2e_make_concolic */ makeSymbolic(state, true); break; } case 0x20: /* concretize */ concretize(state, true); break; case 0x21: { /* replace an expression by one concrete example */ concretize(state, false); break; } case 0x30: { /* Get number of active states */ uint32_t count = s2e()->getExecutor()->getStatesCount(); state->writeCpuRegisterConcrete(CPU_OFFSET(regs[R_EAX]), &count, sizeof(uint32_t)); break; } case 0x31: { /* Get number of active S2E instances */ uint32_t count = s2e()->getCurrentProcessCount(); state->writeCpuRegisterConcrete(CPU_OFFSET(regs[R_EAX]), &count, sizeof(uint32_t)); break; } case 0x32: { /* Sleep for a given number of seconds */ sleep(state); break; } case 0x50: { /* disable/enable timer interrupt */ uint64_t disabled = opcode >> 16; if(disabled) s2e()->getMessagesStream(state) << "Disabling timer interrupt\n"; else s2e()->getMessagesStream(state) << "Enabling timer interrupt\n"; state->writeCpuState(CPU_OFFSET(timer_interrupt_disabled), disabled, 8); break; } case 0x51: { /* disable/enable all apic interrupts */ uint64_t disabled = opcode >> 16; if(disabled) s2e()->getMessagesStream(state) << "Disabling all apic interrupt\n"; else s2e()->getMessagesStream(state) << "Enabling all apic interrupt\n"; state->writeCpuState(CPU_OFFSET(all_apic_interrupts_disabled), disabled, 8); break; } case 0x52: { /* Gets the current S2E memory object size (in power of 2) */ uint32_t size = S2E_RAM_OBJECT_BITS; state->writeCpuRegisterConcrete(CPU_OFFSET(regs[R_EAX]), &size, 4); break; } case 0x70: /* merge point */ state->jumpToSymbolicCpp(); s2e()->getExecutor()->queueStateForMerge(state); break; default: s2e()->getWarningsStream(state) << "BaseInstructions: Invalid built-in opcode " << hexval(opcode) << '\n'; break; } }
void CooperativeSearcher::onCustomInstruction(S2EExecutionState* state, uint64_t opcode) { //XXX: find a better way of allocating custom opcodes if (!OPCODE_CHECK(opcode, COOPSEARCHER_OPCODE)) { return; } uint8_t op = OPCODE_GETSUBFUNCTION(opcode); bool ok = true; target_ulong nextState = 0; CoopSchedulerOpcodes opc = (CoopSchedulerOpcodes)op; switch(opc) { //Pick the next state specified as input ergument case ScheduleNext: { ok &= state->readCpuRegisterConcrete(CPU_OFFSET(COOPSEARCHER_NEXTSTATE), &nextState, sizeof nextState); if(!ok) { s2e()->getWarningsStream(state) << "ERROR: symbolic argument was passed to s2e_op " "CooperativeSearcher ScheduleNext" << '\n'; break; } States::iterator it = m_states.find(nextState); if (it == m_states.end()) { s2e()->getWarningsStream(state) << "ERROR: Invalid state passed to " << "CooperativeSearcher ScheduleNext: " << nextState << '\n'; } m_currentState = (*it).second; s2e()->getMessagesStream(state) << "CooperativeSearcher picked the state " << nextState << '\n'; //Force rescheduling state->setPc(state->getPc() + S2E_OPCODE_SIZE); throw CpuExitException(); break; } //Deschedule the current state. Will pick the state with strictly lower id. case Yield: { if (m_states.size() == 1) { break; } States::iterator it = m_states.find(m_currentState->getID()); if (it == m_states.begin()) { m_currentState = (*m_states.rbegin()).second; }else { --it; m_currentState = (*it).second; } //Force rescheduling state->setPc(state->getPc() + S2E_OPCODE_SIZE); throw CpuExitException(); break; } } }
void DasosPreproc::printSnapshot (struct Snapshot s, uint64_t base, unsigned len) { // Print dump as already coded using snapshot.mem_bytes[i].byte unsigned int curr_addr, end_addr, i, j; char buf[1024]; unsigned min_addr = s.min_addr + base; unsigned max_addr = s.max_addr + base; // align for print out curr_addr = min_addr & 0xfffffff0; end_addr = max_addr; s2e()->getDebugStream() << ">> The density (0 to 1) of this state's path is (" << std::dec << s.num_execed_bytes << "/" << (end_addr - min_addr + 1) << ") = " << s.density << std::endl; snprintf (buf, sizeof (buf), ">> Mem_map start_addr: 0x%08x, length: %uB, exec'ed bytes: %u, range: %uB, end_addr: 0x%08x\n", min_addr, len, s.num_execed_bytes, end_addr - min_addr + 1, end_addr); s2e()->getDebugStream() << buf; // for loop printing out dump in words with address grid like in gdb s2e()->getDebugStream() << " 0 1 2 3 4 5 6 7 8 9 a b c d e f ASCII\n"; // for each row while (curr_addr < end_addr) { snprintf (buf, sizeof (buf), "0x%08x", curr_addr); s2e()->getDebugStream() << buf; char ascii_out[17]; memset (ascii_out, ' ', 16); ascii_out[16] = '\0'; // for each of the 4 words in the row for (i = 0; i < 4; i++) { snprintf (buf, sizeof (buf), " "); s2e()->getDebugStream() << buf; // for each of the 4 bytes in the word for (j = 0; j < 4; j++) { if (curr_addr < min_addr) { snprintf (buf, sizeof (buf), " "); s2e()->getDebugStream() << buf; } else if (curr_addr <= end_addr) { if (times_execed (&s, (curr_addr - base) ) == 0) { s2e()->getDebugStream() << "--"; ascii_out[(i * 4) + j] = '.'; } else { char tmp = byte (&s, (curr_addr - base) ); snprintf (buf, sizeof (buf), "%02x", (unsigned int) tmp & 0x000000ff); s2e()->getDebugStream() << buf; ascii_out[(i * 4) + j] = isprint (tmp) ? tmp : '.'; } } else { s2e()->getDebugStream() << " "; } curr_addr++; } // end for each byte } // end for each word s2e()->getDebugStream() << " " << ascii_out << std::endl; } // end while each row s2e()->getDebugStream() << std::endl; return; } // end fn printSnapshot
bool Annotation::initSection(const std::string &entry, const std::string &cfgname) { AnnotationCfgEntry e, *ne; ConfigFile *cfg = s2e()->getConfig(); llvm::raw_ostream &os = s2e()->getWarningsStream(); std::vector<std::string> cfgkeys = s2e()->getConfig()->getListKeys(entry); e.cfgname = cfgname; bool ok; e.isActive = cfg->getBool(entry + ".active", false, &ok); if (!ok) { os << "You must specify whether the entry is active in " << entry << ".active!" << '\n'; return false; } e.module = cfg->getString(entry + ".module", "", &ok); if (!ok) { os << "You must specify a valid module for " << entry << ".module!" << '\n'; return false; }else { if (!m_moduleExecutionDetector->isModuleConfigured(e.module)) { os << "The module " << e.module << " is not configured in ModuleExecutionDetector!" << '\n'; return false; } } e.address = cfg->getInt(entry + ".address", 0, &ok); if (!ok) { os << "You must specify a valid address for " << entry << ".address!" << '\n'; return false; } if (!m_functionMonitor || !m_moduleExecutionDetector || !m_osMonitor) { os << "You must enable FunctionMonitor, ModuleExecutionDetector, and an OS monitor plugin\n"; return false; } // Check if this is a call or an instruction annotation e.annotation = ""; if (std::find(cfgkeys.begin(), cfgkeys.end(), "callAnnotation") != cfgkeys.end()) { e.annotation = cfg->getString(entry + ".callAnnotation", e.annotation, &ok); e.isCallAnnotation = true; } else if (std::find(cfgkeys.begin(), cfgkeys.end(), "instructionAnnotation") != cfgkeys.end()) { e.annotation = cfg->getString(entry + ".instructionAnnotation", e.annotation, &ok); e.isCallAnnotation = false; } // Assert that this is a properly attached annotation if (!ok || e.annotation=="") { os << "You must specify either " << entry << ".callAnnotation or .instructionAnnotation!" << '\n'; return false; } // Get additional annotation-specific options e.paramCount = 0; e.beforeInstruction = false; e.switchInstructionToSymbolic = false; if (e.isCallAnnotation) { // Get the number of arguments of the annotated subroutine e.paramCount = cfg->getInt(entry + ".paramcount", e.paramCount, &ok); if (!ok) { os << "You must specify a valid number of function parameters for " << entry << ".paramcount!" << '\n'; return false; } } else { // Whether to call the annotation before or after the instruction e.beforeInstruction = cfg->getBool(entry + ".beforeInstruction", e.beforeInstruction, &ok); e.switchInstructionToSymbolic = cfg->getBool(entry + ".switchInstructionToSymbolic", e.switchInstructionToSymbolic, &ok); } ne = new AnnotationCfgEntry(e); m_entries.insert(ne); return true; }
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 DasosPreproc::onSyscall (S2EExecutionState* state, uint64_t pc, LinuxSyscallMonitor::SyscallType sysc_type, uint32_t sysc_number, LinuxSyscallMonitor::SyscallReturnSignal& returnsignal) { uint64_t pid = state->getPid(); std::ostream& stream = s2e()->getDebugStream(); // since onSyscall isn't hooked until onCustomInstruction, this first condition should never be met if (!cfg.is_loaded) { //stream << "ignore this preload Syscall " << std::hex << sysc_number << " at addr 0x" << pc << " from pid: " << std::dec << pid << std::endl; return; } // if here then loaded, see if not PID else if (pid != cfg.proc_id) { //stream << "ignore this postload, non-pid Syscall " << std::hex << sysc_number << " at addr 0x" << pc << " from pid: " << std::dec << pid << std::endl; return; } // if here then loaded and pid matches, see if not within memory address else if (!isInShell (pc) ) { //stream << "ignore this postload, pid, out of mem range Syscall " << std::hex << sysc_number << " at addr 0x" << pc << " from pid: " << std::dec << pid << std::endl; return; } // if here then loaded, pid matches, and within address range // at this point all paths result in an terminateStateEarly, so disconnect the onTranslateInstruction DECLARE_PLUGINSTATE (DasosPreprocState, state); // if here we can assume that activateModule was called, so oTICS_connection was connected /*if (plgState->oTICS_connected) { p lgState->oTICS*_connection.disconnect (); plgState->oTICS_connected = false; }*/ if (plgState->oTICE_connected) { plgState->oTICE_connection.disconnect (); plgState->oTICE_connected = false; } // see if not aligned to EIP if (pc != (cfg.eip_addr - 2) ) { // you shouldn't get here if you have correct offset, but if the range is invalid, then you will // this catches other syscalls in the monitored memory range, eg when you use an offset that follows a different execution branch stream << "!! Wrong syscall insn found in memory range. It's postload, pid, in range, yet not eip-2, syscall " << std::hex << sysc_number << " at addr 0x" << pc << " from pid: " << std::dec << pid << std::endl; //stream << "DEBUG: postload, pid, in range, unaligned syscall " << std::hex << sysc_number << " at addr 0x" << pc << " base 0x" << cfg.base_addr << " end 0x" << cfg.end_addr << " eip-2 0x" << (cfg.eip_addr - 2) << " len " << std::dec << cfg.byte_len << " from pid " << pid << std::endl; s2e()->getExecutor()->terminateStateEarly (*state, "wrong syscall found in memory range"); return; } // aligns with EIP, see if syscall not within range else if (sysc_number > MAX_SYSCALL_NUM) { stream << "!! Wrong syscall number makes no sense (>" << MAX_SYSCALL_NUM << ") " << sysc_number << ":0x" << std::hex << sysc_number << std::endl; s2e()->getExecutor()->terminateStateEarly (*state, "eliminated this false positive, out of range syscall number found at eip"); return; } // see if cfg.sysc is not being used if (cfg.sysc == 1024) { stream << ">> Be aware that sysc is not set; is the shell read from file vs libDasosFdump struct?" << std::endl; } // see if this syscall does not match the goal syscall else if (sysc_number != cfg.sysc) { stream << "!! Not matching syscall number " << sysc_number << "!=" << cfg.sysc << std::endl; s2e()->getExecutor()->terminateStateEarly (*state, "eliminated this false positive, incorrect syscall number found at eip"); return; } // you could enforce a minimum instruction count here like: // if (plgState->trace.size() < 10) { terminateStateEarly } // All conditions to ignore are ignored, so if it's here, then it must be a positive match... // but is it a false positive? // we need to see if the trace is a subset of a previous successful pcs if (!isTraceUnique (plgState->trace, plgState->mem_map) ) { stream << "!! Unfortunately this execution path is a subset of a previously found success. This path has " << plgState->trace.size () << " instructions, PCs: "; // print out all the PCs for each insn for (unsigned int i = 0; i < plgState->trace.size (); i++) { stream << std::hex << (plgState->trace[i].pc + cfg.base_addr) << " "; } stream << std::endl; s2e()->getExecutor()->terminateStateEarly (*state, "eliminated this false positive, execution path subset of another success"); return; } stream << ">> EIP Found. Syscall number " << std::hex << sysc_number << " at addr 0x" << pc << " from pid: " << std::dec << pid << " number of instructions: " << plgState->trace.size () << std::endl; // get the stats per snapshot for (unsigned i = 0; i < plgState->mem_map.size (); i++) { getStats (&(plgState->mem_map[i]), cfg.byte_len); } Success s; s.trace = plgState->trace; s.mem_map = plgState->mem_map; getSuccessStats (&s); printSuccess (s); cfg.successes.push_back (s); s2e()->getExecutor()->terminateStateEarly (*state, "EIP reached, success"); return; } // end fn onSyscall
ModelData<real_t> readModel(reader_t& reader) { ModelData<real_t> data; reader.setGroup(e2s(GRP_IN_MODEL)); s2e(reader.template scalar<std::string>(e2s(ADSORPTION_TYPE)), data.bindingModel); data.nComponents = reader.template scalar<int>(e2s(NCOMP)); reader.setGroup(e2s(GRP_IN_INLET)); data.nInletSections = reader.template scalar<int>(e2s(NSEC)); // Reserve space data.initialLiquidConcentration.reserve(data.nComponents); data.initialSolidConcentration.reserve(data.nComponents); data.filmDiffusion.reserve(data.nComponents); data.particleDiffusion.reserve(data.nComponents); data.surfaceDiffusion.reserve(data.nComponents); data.linearKA.reserve(data.nComponents); data.linearKD.reserve(data.nComponents); data.sectionTimes.reserve(data.nInletSections); data.constCoeff.reserve(data.nInletSections * data.nComponents); data.linCoeff.reserve(data.nInletSections * data.nComponents); data.quadCoeff.reserve(data.nInletSections * data.nComponents); data.cubicCoeff.reserve(data.nInletSections * data.nComponents); // Read inlet specs reader.setGroup(e2s(GRP_IN_INLET)); const std::vector<double> sectionTimes = reader.template vector<double>(e2s(SECTION_TIMES)); for(std::vector<double>::const_iterator it = sectionTimes.begin(); it != sectionTimes.end(); ++it) { data.sectionTimes.push_back(real_t(*it)); } for (std::size_t sec = 0; sec < data.nInletSections; ++sec) { std::ostringstream oss; oss.str(""); oss << e2s(GRP_IN_INLET) << "/sec_" << std::setfill('0') << std::setw(3) << std::setprecision(0) << sec; reader.setGroup(oss.str()); const std::vector<double> const_coeff = reader.template vector<double>("CONST_COEFF"); const std::vector<double> linear_coeff = reader.template vector<double>("LIN_COEFF"); const std::vector<double> quad_coeff = reader.template vector<double>("QUAD_COEFF"); const std::vector<double> cubic_coeff = reader.template vector<double>("CUBE_COEFF"); for(std::size_t i = 0; i < const_coeff.size(); ++i) { data.constCoeff.push_back(real_t(const_coeff[i])); data.linCoeff.push_back(real_t(linear_coeff[i])); data.quadCoeff.push_back(real_t(quad_coeff[i])); data.cubicCoeff.push_back(real_t(cubic_coeff[i])); } } // Read binding model specs reader.setGroup(e2s(GRP_IN_ADSORPTION)); data.kineticBinding = reader.template scalar<int>(e2s(IS_KINETIC)); if (data.bindingModel == LINEAR) { const std::vector<double> linKA = reader.template vector<double>(e2s(LIN_KA)); const std::vector<double> linKD = reader.template vector<double>(e2s(LIN_KD)); for(std::size_t i = 0; i < data.nComponents; ++i) { data.linearKA.push_back(real_t(linKA[i])); data.linearKD.push_back(real_t(linKD[i])); } } // Chromatography model parameters reader.setGroup(e2s(GRP_IN_MODEL)); data.colDispersion = real_t(reader.template scalar<double>(e2s(COL_DISPERSION))); data.velocity = real_t(reader.template scalar<double>(e2s(VELOCITY))); data.colLength = real_t(reader.template scalar<double>(e2s(COL_LENGTH))); data.colPorosity = real_t(reader.template scalar<double>(e2s(COL_POROSITY))); data.parRadius = real_t(reader.template scalar<double>(e2s(PAR_RADIUS))); data.parPorosity = real_t(reader.template scalar<double>(e2s(PAR_POROSITY))); // Vectorial parameters const std::vector<double> initialSolid = reader.template vector<double>(e2s(INIT_Q)); const std::vector<double> initialLiquid = reader.template vector<double>(e2s(INIT_C)); const std::vector<double> filmDiff = reader.template vector<double>(e2s(FILM_DIFFUSION)); const std::vector<double> parDiff = reader.template vector<double>(e2s(PAR_DIFFUSION)); const std::vector<double> parSurfDiff = reader.template vector<double>(e2s(PAR_SURFDIFFUSION)); for(std::size_t i = 0; i < data.nComponents; ++i) { data.initialSolidConcentration.push_back(real_t(initialSolid[i])); data.initialLiquidConcentration.push_back(real_t(initialLiquid[i])); data.filmDiffusion.push_back(real_t(filmDiff[i])); data.particleDiffusion.push_back(real_t(parDiff[i])); data.surfaceDiffusion.push_back(real_t(parSurfDiff[i])); } // Read outlet times reader.setGroup(e2s(GRP_IN_SOLVER)); data.writeUserTimes = reader.template scalar<int>(e2s(WRITE_AT_USER_TIMES)); if (data.writeUserTimes) { const std::vector<double> out = reader.template vector<double>(e2s(USER_SOLUTION_TIMES)); data.outletTimes.reserve(out.size()); for(std::vector<double>::const_iterator it = out.begin(); it != out.end(); ++it) { data.outletTimes.push_back(real_t(*it)); } } return data; }
bool MemoryManager::check_rep(uint32_t edi, klee::ref<klee::Expr> ecx, S2EExecutionState *state) { bool isok = true; //检查memcpy size访问是否合法 //concrete if(isa<klee::ConstantExpr>(ecx)) { int ecx_con = cast<klee::ConstantExpr>(ecx)->getZExtValue(); if(ecx_con < 0 || ecx_con > 0xf0000) { s2e()->getWarningsStream() << "============================================================" << '\n'; s2e()->getWarningsStream() << "BUG: memcpy [Size < 0||Size > 0xf0000] Size: " << hexval(ecx_con) << '\n'; s2e()->getWarningsStream() << "============================================================" << '\n'; //打印完整路径约束 printConstraintExpr(state); isok = false; if(m_terminateOnBugs) { s2e()->getExecutor()->terminateStateEarly(*state, "Killed by MemoryManager: memcpy lenth is not valid\n"); } } } //symbolic else { bool isTrue; klee::ref<klee::Expr> cond = klee::SgeExpr::create(ecx, klee::ConstantExpr::create( 0xf0000, size.get()->getWidth())); if (!(s2e()->getExecutor()->getSolver()->mayBeTrue(klee::Query(state->constraints, cond), isTrue))) { s2e()->getWarningsStream() << "failed to assert the condition" << '\n'; return false; } 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 memcpy size will >= 0xf0000" << '\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() << "======================================================" << '\n'; //************************************************************************************************** //删除修改过的约束;恢复原来的正确约束 tmp_constraints->empty(); state->constraints = constraints_before; //打印完整路径约束 printConstraintExpr(state); isok = false; if(m_terminateOnBugs) { s2e()->getExecutor()->terminateStateEarly(*state, "Killed by MemoryManager: memcpy size is not valid\n"); } } } return isok; }
void MemoryTracer::initialize() { m_tracer = static_cast<ExecutionTracer*>(s2e()->getPlugin("ExecutionTracer")); m_execDetector = static_cast<ModuleExecutionDetector*>(s2e()->getPlugin("ModuleExecutionDetector")); //Retrict monitoring to configured modules only m_monitorModules = s2e()->getConfig()->getBool(getConfigKey() + ".monitorModules"); if (m_monitorModules && !m_execDetector) { s2e()->getWarningsStream() << "MemoryTracer: The monitorModules option requires ModuleExecutionDetector\n"; exit(-1); } //Catch all accesses to the stack m_monitorStack = s2e()->getConfig()->getBool(getConfigKey() + ".monitorStack"); //Catch accesses that are above the specified address m_catchAbove = s2e()->getConfig()->getInt(getConfigKey() + ".catchAccessesAbove"); m_catchBelow = s2e()->getConfig()->getInt(getConfigKey() + ".catchAccessesBelow"); //Whether or not to include host addresses in the trace. //This is useful for debugging, bug yields larger traces m_traceHostAddresses = s2e()->getConfig()->getBool(getConfigKey() + ".traceHostAddresses"); //Check that the current state is actually allowed to write to //the object state. Can be useful to debug the engine. m_debugObjectStates = s2e()->getConfig()->getBool(getConfigKey() + ".debugObjectStates"); //Start monitoring after the specified number of seconds bool hasTimeTrigger = false; m_timeTrigger = s2e()->getConfig()->getInt(getConfigKey() + ".timeTrigger", 0, &hasTimeTrigger); m_elapsedTics = 0; bool manualMode = s2e()->getConfig()->getBool(getConfigKey() + ".manualTrigger"); m_monitorMemory = s2e()->getConfig()->getBool(getConfigKey() + ".monitorMemory"); m_monitorPageFaults = s2e()->getConfig()->getBool(getConfigKey() + ".monitorPageFaults"); m_monitorTlbMisses = s2e()->getConfig()->getBool(getConfigKey() + ".monitorTlbMisses"); s2e()->getDebugStream() << "MonitorMemory: " << m_monitorMemory << " PageFaults: " << m_monitorPageFaults << " TlbMisses: " << m_monitorTlbMisses << '\n'; if (hasTimeTrigger) { m_timerConnection = s2e()->getCorePlugin()->onTimer.connect( sigc::mem_fun(*this, &MemoryTracer::onTimer)); } else if (manualMode) { s2e()->getCorePlugin()->onCustomInstruction.connect( sigc::mem_fun(*this, &MemoryTracer::onCustomInstruction)); } else { enableTracing(); } }
void SkyriseAnalyst::slot_onEntryExecution(S2EExecutionState *state, uint64_t pc) { assert(m_module.EntryPoint == pc); assert(!(b_targetModule_exec)); // Disconnect entry point signals regEntryHook.disconnect(); sig_EntryExec.disconnect(); // Set running flag b_targetModule_exec = true; // Parse PE import table of target module if (!(m_monitor->getImports(state, m_module, imports))) { std::cout << "[State " << std::dec << state->getID() << "] Error: Could not retrieve " << "imports from " << m_module.Name << '\n'; exit(1); } // Print APIs in import table print_imports(); // Register imported API hooks regImportHooks = s2e()->getCorePlugin()->onTranslateInstructionEnd.connect( sigc::mem_fun(*this, &SkyriseAnalyst::slot_registerImportHooks) ); std::cout << "[+] Starting program execution at address 0x" << std::hex << pc << std::endl << std::endl; /* State forking/switching * */ s2e()->getCorePlugin()->onStateFork.connect( sigc::mem_fun(*this, &SkyriseAnalyst::slot_onStateFork) ); s2e()->getCorePlugin()->onStateSwitch.connect( sigc::mem_fun(*this, &SkyriseAnalyst::slot_onStateSwitch) ); /* Attempt to force re-translation so we can hook * import functions. Surely adds less overhead than * instrumenting *every* instruction. */ tb_flush(env); throw CpuExitException(); }
void DasosPreproc::printSuccess (struct Success s) { s2e()->getDebugStream() << ">> Success densities, overlay: " << s.overlay_density << "; avg: " << s.avg_density << "\n"; printTrace (s.trace, s.mem_map); printMemMap (s.mem_map, cfg.base_addr, cfg.byte_len); return; } // end fn printSuccess