├── CMakeLists.txt ├── LIBS2EPLUGINSConfig.cmake.in ├── LICENSE └── src ├── CMakeLists.txt └── s2e └── Plugins ├── Analyzers ├── CacheSim.cpp └── CacheSim.h ├── Core ├── BaseInstructions.cpp ├── BaseInstructions.h ├── Events.h ├── HostFiles.cpp ├── HostFiles.h ├── Vmi.cpp └── Vmi.h ├── Coverage ├── BasicBlockCoverage.cpp ├── BasicBlockCoverage.h ├── EdgeCoverage.cpp ├── EdgeCoverage.h ├── TranslationBlockCoverage.cpp └── TranslationBlockCoverage.h ├── Example.cpp ├── Example.h ├── ExecutionMonitors ├── CallSiteMonitor.cpp ├── CallSiteMonitor.h ├── CallTree.h ├── FunctionMonitor.cpp ├── FunctionMonitor.h ├── LibraryCallMonitor.cpp ├── LibraryCallMonitor.h ├── StackClustering.cpp ├── StackClustering.h ├── StackMonitor.cpp └── StackMonitor.h ├── ExecutionTracers ├── EventTracer.cpp ├── EventTracer.h ├── ExceptionTracer.cpp ├── ExceptionTracer.h ├── ExecutionTracer.cpp ├── ExecutionTracer.h ├── InstructionCounter.cpp ├── InstructionCounter.h ├── MemoryTracer.cpp ├── MemoryTracer.h ├── ModuleTracer.cpp ├── ModuleTracer.h ├── ModuleTracing.h ├── StateSwitchTracer.cpp ├── StateSwitchTracer.h ├── TBCoverageTracer.cpp ├── TBCoverageTracer.h ├── TestCaseGenerator.cpp ├── TestCaseGenerator.h ├── TraceEntries.proto ├── TranslationBlockTracer.cpp ├── TranslationBlockTracer.h ├── UserSpaceTracer.cpp └── UserSpaceTracer.h ├── Lua ├── Lua.h ├── LuaBindings.cpp ├── LuaBindings.h ├── LuaCoreEvents.cpp ├── LuaCoreEvents.h ├── LuaExpression.cpp ├── LuaExpression.h ├── LuaFunctionInstrumentation.cpp ├── LuaFunctionInstrumentation.h ├── LuaFunctionInstrumentationState.cpp ├── LuaFunctionInstrumentationState.h ├── LuaInstructionInstrumentation.cpp ├── LuaInstructionInstrumentation.h ├── LuaInstructionInstrumentationState.cpp ├── LuaInstructionInstrumentationState.h ├── LuaInstrumentationState.cpp ├── LuaInstrumentationState.h ├── LuaModuleDescriptor.cpp ├── LuaModuleDescriptor.h ├── LuaPlugin.h ├── LuaS2E.cpp ├── LuaS2E.h ├── LuaS2EExecutionState.cpp ├── LuaS2EExecutionState.h ├── LuaS2EExecutionStateMemory.cpp ├── LuaS2EExecutionStateMemory.h ├── LuaS2EExecutionStateRegisters.cpp └── LuaS2EExecutionStateRegisters.h ├── Models ├── BaseFunctionModels.cpp ├── BaseFunctionModels.h ├── CRC.cpp ├── FunctionModels.cpp ├── FunctionModels.h ├── StaticFunctionModels.cpp └── StaticFunctionModels.h ├── OSMonitors ├── Linux │ ├── BaseLinuxMonitor.cpp │ ├── BaseLinuxMonitor.h │ ├── DecreeMonitor.cpp │ ├── DecreeMonitor.h │ ├── LinuxMonitor.cpp │ └── LinuxMonitor.h ├── ModuleDescriptor.cpp ├── ModuleDescriptor.h ├── OSMonitor.cpp ├── OSMonitor.h ├── Raw │ ├── RawMonitor.cpp │ └── RawMonitor.h ├── Support │ ├── GuestCodeHooking.cpp │ ├── GuestCodeHooking.h │ ├── MemUtils.cpp │ ├── MemUtils.h │ ├── MemoryMap.cpp │ ├── MemoryMap.h │ ├── ModuleExecutionDetector.cpp │ ├── ModuleExecutionDetector.h │ ├── ModuleMap.cpp │ ├── ModuleMap.h │ ├── ProcessExecutionDetector.cpp │ └── ProcessExecutionDetector.h ├── ThreadDescriptor.h └── Windows │ ├── BlueScreenInterceptor.cpp │ ├── BlueScreenInterceptor.h │ ├── WindowsCrashDumpGenerator.cpp │ ├── WindowsCrashDumpGenerator.h │ ├── WindowsCrashMonitor.cpp │ ├── WindowsCrashMonitor.h │ ├── WindowsMonitor.cpp │ └── WindowsMonitor.h ├── PathLimiters ├── EdgeKiller.cpp ├── EdgeKiller.h ├── ForkLimiter.cpp ├── ForkLimiter.h ├── ResourceMonitor.cpp └── ResourceMonitor.h ├── Searchers ├── CUPASearcher.cpp ├── CUPASearcher.h ├── Common.h ├── CooperativeSearcher.cpp ├── CooperativeSearcher.h ├── LoopExitSearcher.cpp ├── LoopExitSearcher.h ├── MergingSearcher.cpp ├── MergingSearcher.h ├── MultiSearcher.cpp ├── MultiSearcher.h ├── SeedScheduler.cpp ├── SeedScheduler.h ├── SeedSearcher.cpp └── SeedSearcher.h ├── StaticAnalysis ├── ControlFlowGraph.cpp ├── ControlFlowGraph.h ├── EdgeDetector.cpp ├── EdgeDetector.h ├── LoopDetector.cpp └── LoopDetector.h ├── Support ├── Database.cpp ├── Database.h ├── KeyValueStore.cpp ├── KeyValueStore.h ├── KeyValueStore.py ├── KeyValueStoreTest.py ├── WebServiceInterface.cpp └── WebServiceInterface.h ├── SymbolicHardware ├── SymbolicHardware.cpp └── SymbolicHardware.h └── VulnerabilityAnalysis ├── CGCInterface.cpp ├── CGCInterface.h ├── DecreePovGenerator.cpp ├── DecreePovGenerator.h ├── FilePovGenerator.cpp ├── FilePovGenerator.h ├── PovGenerationPolicy.cpp ├── PovGenerationPolicy.h ├── PovGenerator.cpp ├── PovGenerator.h └── Recipe ├── Recipe.cpp ├── Recipe.h ├── RecipeDescriptor.cpp ├── RecipeDescriptor.h ├── Register.cpp └── Register.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Cyberhaven 2 | # All rights reserved. 3 | # 4 | # Licensed under the Cyberhaven Research License Agreement. 5 | 6 | cmake_minimum_required(VERSION 3.4.3) 7 | 8 | project(LIBS2EPLUGINS) 9 | set(LIBS2EPLUGINS_VERSION_MAJOR 2) 10 | set(LIBS2EPLUGINS_VERSION_MINOR 0) 11 | set(LIBS2EPLUGINS_VERSION_PATCH 0) 12 | set(LIBS2EPLUGINS_PACKAGE_VERSION 13 | "${LIBS2EPLUGINS_VERSION_MAJOR}.${LIBS2EPLUGINS_VERSION_MINOR}.${LIBS2EPLUGINS_VERSION_PATCH}") 14 | 15 | include(CMakePackageConfigHelpers) 16 | set(CMAKE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake") 17 | write_basic_package_version_file(${CMAKE_VERSION_FILE} 18 | VERSION ${LIBS2EPLUGINS_PACKAGE_VERSION} 19 | COMPATIBILITY AnyNewerVersion) 20 | 21 | set(CMAKE_CONFIG_FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake") 22 | set(LIBS2EPLUGINS_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include") 23 | set(LIBS2EPLUGINS_LIBRARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/src") 24 | configure_file(LIBS2EPLUGINSConfig.cmake.in ${CMAKE_CONFIG_FILE} @ONLY) 25 | 26 | find_package(PkgConfig REQUIRED) 27 | 28 | pkg_check_modules(GLIB_PKG glib-2.0) 29 | include_directories(${GLIB_PKG_INCLUDE_DIRS}) 30 | 31 | ##### libdwarf ##### 32 | find_path(LIBDWARF_INCLUDE_DIRS 33 | NAMES libdwarf.h dwarf.h 34 | PATHS /usr/include 35 | /usr/include/libdwarf 36 | /usr/local/include 37 | /usr/local/include/libdwarf) 38 | 39 | include_directories(${LIBDWARF_INCLUDE_DIRS}) 40 | 41 | ##### LLVM ##### 42 | find_package(LLVM REQUIRED) 43 | message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") 44 | 45 | add_definitions(${LLVM_DEFINITIONS}) 46 | 47 | include_directories("include" ${LLVM_INCLUDE_DIRS}) 48 | 49 | llvm_map_components_to_libnames(LLVM_LIBS core) 50 | 51 | set(LLVM_CONFIG "${LLVM_TOOLS_BINARY_DIR}/llvm-config" 52 | CACHE PATH "Path to llvm-config") 53 | execute_process(COMMAND ${LLVM_CONFIG} "--cxxflags" 54 | RESULT_VARIABLE LLVM_CONFIG_RESULT 55 | OUTPUT_VARIABLE LLVM_CXXFLAGS 56 | OUTPUT_STRIP_TRAILING_WHITESPACE) 57 | 58 | ################## 59 | 60 | include(FindProtobuf) 61 | find_package(Protobuf REQUIRED) 62 | 63 | find_package(LIBQ REQUIRED) 64 | message(STATUS "Found libq ${LIBQ_PACKAGE_VERSION}") 65 | 66 | find_package(LIBCPU REQUIRED) 67 | message(STATUS "Found libcpu ${LIBCPU_PACKAGE_VERSION}") 68 | 69 | find_package(LIBTCG REQUIRED) 70 | message(STATUS "Found libtcg ${LIBTCG_PACKAGE_VERSION}") 71 | 72 | find_package(FSIGCXX REQUIRED) 73 | message(STATUS "Found fsigc++ ${FSIGCXX_PACKAGE_VERSION}") 74 | 75 | find_package(VMI REQUIRED) 76 | message(STATUS "Found libvmi ${VMI_PACKAGE_VERSION}") 77 | 78 | find_package(LIBS2ECORE REQUIRED) 79 | message(STATUS "Found s2e core ${LIBS2ECORE_PACKAGE_VERSION}") 80 | 81 | find_package(KLEE REQUIRED) 82 | message(STATUS "Found klee ${KLEE_PACKAGE_VERSION}") 83 | 84 | include_directories(${GLIB_PKG_INCLUDE_DIRS} 85 | ${LIBQ_INCLUDE_DIR} 86 | ${LIBTCG_INCLUDE_DIR} 87 | ${LIBCPU_INCLUDE_DIR} 88 | ${VMI_INCLUDE_DIR} 89 | ${LIBS2ECORE_INCLUDE_DIR} 90 | ${LIBS2EPLUGINS_INCLUDE_DIR} 91 | ${FSIGCXX_INCLUDE_DIR} 92 | ${KLEE_INCLUDE_DIR} 93 | ${LUA_DIR} 94 | ${S2EGUEST_INCLUDE_DIR}) 95 | 96 | add_subdirectory(src) 97 | -------------------------------------------------------------------------------- /LIBS2EPLUGINSConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Cyberhaven 2 | # All rights reserved. 3 | # 4 | # Licensed under the Cyberhaven Research License Agreement. 5 | 6 | set(LIBS2EPLUGINS_VERSION_MAJOR @LIBS2EPLUGINS_VERSION_MAJOR@) 7 | set(LIBS2EPLUGINS_VERSION_MINOR @LIBS2EPLUGINS_VERSION_MINOR@) 8 | set(LIBS2EPLUGINS_VERSION_PATCH @LIBS2EPLUGINS_VERSION_PATCH@) 9 | set(LIBS2EPLUGINS_PACKAGE_VERSION @LIBS2EPLUGINS_PACKAGE_VERSION@) 10 | 11 | set(LIBS2EPLUGINS_INCLUDE_DIR "@LIBS2EPLUGINS_INCLUDE_DIR@") 12 | set(LIBS2EPLUGINS_LIBRARY_DIR "@LIBS2EPLUGINS_LIBRARY_DIR@") 13 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Analyzers/CacheSim.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2016, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_CACHESIM_H 9 | #define S2E_PLUGINS_CACHESIM_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace s2e { 25 | 26 | class S2EExecutionState; 27 | 28 | namespace plugins { 29 | 30 | class Cache; 31 | class CacheSimState; 32 | 33 | class CacheSim : public Plugin { 34 | S2E_PLUGIN 35 | protected: 36 | struct CacheLogEntry { 37 | uint64_t timestamp; 38 | uint64_t pc; 39 | uint64_t address; 40 | unsigned size; 41 | bool isWrite; 42 | bool isCode; 43 | const char *cacheName; 44 | uint32_t missCount; 45 | }; 46 | 47 | std::vector m_cacheLog; 48 | 49 | ModuleExecutionDetector *m_execDetector; 50 | ExecutionTracer *m_Tracer; 51 | 52 | bool m_reportWholeSystem; 53 | bool m_reportZeroMisses; 54 | bool m_profileModulesOnly; 55 | bool m_cacheStructureWrittenToLog; 56 | bool m_startOnModuleLoad; 57 | bool m_physAddress; 58 | sigc::connection m_ModuleConnection; 59 | 60 | sigc::connection m_d1_connection; 61 | sigc::connection m_i1_connection; 62 | 63 | void onModuleTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, const ModuleDescriptor &desc, 64 | TranslationBlock *tb, uint64_t pc); 65 | 66 | void onMemoryAccess(S2EExecutionState *state, uint64_t address, unsigned size, bool isWrite, bool isIO, 67 | bool isCode); 68 | 69 | void onAfterSymbolicDataMemoryAccess(S2EExecutionState *state, klee::ref address, 70 | klee::ref hostAddress, klee::ref value, 71 | unsigned flags); 72 | 73 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *, TranslationBlock *, uint64_t); 74 | 75 | void onExecuteBlockStart(S2EExecutionState *state, uint64_t pc, TranslationBlock *tb, uint64_t hostAddress); 76 | 77 | void writeCacheDescriptionToLog(S2EExecutionState *state); 78 | 79 | bool profileAccess(S2EExecutionState *state) const; 80 | bool reportAccess(S2EExecutionState *state) const; 81 | 82 | public: 83 | CacheSim(S2E *s2e) : Plugin(s2e) { 84 | } 85 | ~CacheSim(); 86 | 87 | void initialize(); 88 | 89 | friend class CacheSimState; 90 | }; 91 | 92 | class CacheSimState : public PluginState { 93 | private: 94 | typedef std::map CachesMap; 95 | CachesMap m_caches; 96 | 97 | unsigned m_i1_length; 98 | unsigned m_d1_length; 99 | 100 | Cache *m_i1; 101 | Cache *m_d1; 102 | 103 | public: 104 | CacheSimState(); 105 | CacheSimState(S2EExecutionState *s, Plugin *p); 106 | virtual ~CacheSimState(); 107 | virtual PluginState *clone() const; 108 | static PluginState *factory(Plugin *p, S2EExecutionState *s); 109 | 110 | Cache *getCache(const std::string &name); 111 | 112 | friend class CacheSim; 113 | }; 114 | 115 | } // namespace plugins 116 | } // namespace s2e 117 | 118 | #endif // S2E_PLUGINS_CACHESIM_H 119 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Core/BaseInstructions.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2014-2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_CUSTINST_H 10 | 11 | #define S2E_PLUGINS_CUSTINST_H 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | class OSMonitor; 21 | 22 | class IPluginInvoker { 23 | public: 24 | virtual ~IPluginInvoker() { 25 | } 26 | virtual void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize) = 0; 27 | }; 28 | 29 | typedef enum S2E_BASEINSTRUCTION_COMMANDS { ALLOW_CURRENT_PID, GET_HOST_CLOCK_MS } S2E_BASEINSTRUCTION_COMMANDS; 30 | 31 | typedef struct S2E_BASEINSTRUCTION_COMMAND { 32 | S2E_BASEINSTRUCTION_COMMANDS Command; 33 | union { 34 | uint64_t Milliseconds; 35 | }; 36 | } S2E_BASEINSTRUCTION_COMMAND; 37 | 38 | class BaseInstructions : public Plugin, public IPluginInvoker { 39 | S2E_PLUGIN 40 | public: 41 | BaseInstructions(S2E *s2e) : Plugin(s2e) { 42 | } 43 | virtual ~BaseInstructions() { 44 | } 45 | 46 | void initialize(); 47 | 48 | void handleBuiltInOps(S2EExecutionState *state, uint64_t opcode); 49 | 50 | void makeSymbolic(S2EExecutionState *state, uintptr_t address, unsigned size, const std::string &nameStr, 51 | std::vector> *varData = nullptr, std::string *varName = nullptr); 52 | 53 | virtual void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 54 | 55 | private: 56 | OSMonitor *m_monitor; 57 | 58 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 59 | 60 | void forkCount(S2EExecutionState *state); 61 | void allowCurrentPid(S2EExecutionState *state); 62 | void onCustomInstruction(S2EExecutionState *state, uint64_t opcode); 63 | void checkPlugin(S2EExecutionState *state) const; 64 | void invokePlugin(S2EExecutionState *state); 65 | void makeSymbolic(S2EExecutionState *state); 66 | void isSymbolic(S2EExecutionState *state); 67 | void killState(S2EExecutionState *state); 68 | void printExpression(S2EExecutionState *state); 69 | void printMessage(S2EExecutionState *state, bool isWarning); 70 | void printMemory(S2EExecutionState *state); 71 | void hexDump(S2EExecutionState *state); 72 | void concretize(S2EExecutionState *state, bool addConstraint); 73 | void sleep(S2EExecutionState *state); 74 | void assume(S2EExecutionState *state); 75 | void assumeRange(S2EExecutionState *state); 76 | void assumeDisjunction(S2EExecutionState *state); 77 | void assumeInternal(S2EExecutionState *state, klee::ref expr); 78 | void writeBuffer(S2EExecutionState *state); 79 | void getRange(S2EExecutionState *state); 80 | void getConstraintsCountForExpression(S2EExecutionState *state); 81 | }; 82 | 83 | } // namespace plugins 84 | } // namespace s2e 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Core/Events.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2014-2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_QMUEVENTS_H 10 | #define S2E_PLUGINS_QMUEVENTS_H 11 | 12 | extern "C" { 13 | 14 | #include 15 | 16 | #include "qdict.h" 17 | #include "qint.h" 18 | #include "qobject.h" 19 | } 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | namespace s2e { 28 | namespace plugins { 29 | 30 | struct Events { 31 | typedef std::vector> PluginData; 32 | 33 | /** 34 | * Puts the following structure into ret: 35 | * "PluginName" : { } 36 | * The structure { } is returned. 37 | */ 38 | static QDict *createResult(const Plugin *p, QDict *ret) { 39 | const char *pluginName = p->getPluginInfo()->name.c_str(); 40 | QDict *dict = qdict_new(); 41 | qdict_put(ret, pluginName, dict); 42 | return dict; 43 | } 44 | 45 | /** 46 | * Emits the following structure: 47 | * { 48 | "s2e-event" : { 49 | "plugin0" : { ... }, 50 | "plugin1" : { ... }, 51 | } 52 | * } 53 | * 54 | * The name of the plugin and the plugin's specific data is passed 55 | * in the vector as a parameter. 56 | */ 57 | static void emitQMPEvent(const Plugin *p, const PluginData &results) { 58 | QDict *s2e_event = qdict_new(); 59 | QDict *allPluginData = qdict_new(); 60 | QDict *pluginData = createResult(p, allPluginData); 61 | 62 | foreach2 (it, results.begin(), results.end()) { qdict_put_obj(pluginData, (*it).first, (*it).second); } 63 | 64 | qdict_put(s2e_event, "s2e-event", allPluginData); 65 | monitor_emit_json(QOBJECT(s2e_event)); 66 | } 67 | 68 | static QDict *prepareData(const Plugin *p, QObject *data) { 69 | const char *pluginName = p->getPluginInfo()->name.c_str(); 70 | QDict *plugin = qdict_new(); 71 | qdict_put_obj(plugin, pluginName, data); 72 | return plugin; 73 | } 74 | 75 | static void prepareData(QDict *out, const Plugin *p, QObject *data) { 76 | const char *pluginName = p->getPluginInfo()->name.c_str(); 77 | qdict_put_obj(out, pluginName, data); 78 | } 79 | 80 | static QDict *prepareEvent(const Plugin *p, QObject *data) { 81 | QDict *s2e_event = qdict_new(); 82 | qdict_put(s2e_event, "s2e-event", prepareData(p, data)); 83 | return s2e_event; 84 | } 85 | 86 | static void emitQMPEvent(const Plugin *p, QObject *data) { 87 | 88 | monitor_emit_json(QOBJECT(prepareEvent(p, data))); 89 | } 90 | 91 | /** 92 | * Given the following structure in command: 93 | { 94 | "plugin0" : { ... }, 95 | "plugin1" : { ... }, 96 | } 97 | * 98 | * Returns the one corresponding to the specified plugin. 99 | */ 100 | static QDict *getPluginData(const Plugin *p, const QDict *command) { 101 | const char *pluginName = p->getPluginInfo()->name.c_str(); 102 | QObject *plg = qdict_get(command, pluginName); 103 | if (!plg) { 104 | return nullptr; 105 | } 106 | 107 | return qobject_to_qdict(plg); 108 | } 109 | 110 | static void requestSessionId() { 111 | QDict *dict = qdict_new(); 112 | qdict_put_obj(dict, "get-session-id", QOBJECT(qint_from_int(0))); 113 | monitor_emit_json(QOBJECT(dict)); 114 | } 115 | 116 | static void printDict(const Plugin *p, const QDict *dict) { 117 | llvm::raw_ostream &os = p->getDebugStream() << "\n"; 118 | 119 | const QDictEntry *ent = qdict_first(dict); 120 | int idx = 0; 121 | for (ent = qdict_first(dict); ent; ent = qdict_next(dict, ent), ++idx) { 122 | const char *name = qdict_entry_key(ent); 123 | const QObject *value = qdict_entry_value(ent); 124 | 125 | const QInt *i = qobject_to_qint(value); 126 | if (i) { 127 | os << name << ": " << hexval(i->value) << " "; 128 | if ((idx % 4) == 3) { 129 | os << "\n"; 130 | } 131 | } 132 | } 133 | 134 | os << "\n"; 135 | } 136 | }; 137 | 138 | } // namespace plugins 139 | } // namespace s2e 140 | 141 | #endif // S2E_PLUGINS_QMUEVENTS_H 142 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Core/HostFiles.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2013, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2014, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_HOSTFILES_H 10 | #define S2E_PLUGINS_HOSTFILES_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace s2e { 19 | namespace plugins { 20 | 21 | enum HOSTFILESACTION { READ, WRITE }; 22 | 23 | struct HostFD { 24 | int fd; 25 | HOSTFILESACTION type; 26 | }; 27 | 28 | class HostFiles : public Plugin { 29 | S2E_PLUGIN 30 | public: 31 | HostFiles(S2E *s2e) : Plugin(s2e) { 32 | } 33 | 34 | void initialize(); 35 | 36 | private: 37 | std::vector m_baseDirectories; 38 | bool m_allowWrite; 39 | 40 | void open(S2EExecutionState *state); 41 | void close(S2EExecutionState *state); 42 | void read(S2EExecutionState *state); 43 | void create(S2EExecutionState *state); 44 | void write(S2EExecutionState *state); 45 | 46 | void onCustomInstruction(S2EExecutionState *state, uint64_t opcode); 47 | void onStateFork(S2EExecutionState *state, const std::vector &newStates, 48 | const std::vector> &newConditions); 49 | }; 50 | 51 | //////////////////////////////////////////////////////////////////////////////// 52 | 53 | class HostFilesState : public PluginState { 54 | private: 55 | std::vector m_openFiles; 56 | 57 | int nb_open; // Number of files that have been open and not closed 58 | 59 | public: 60 | HostFilesState(); 61 | HostFilesState(S2EExecutionState *s, Plugin *p); 62 | virtual ~HostFilesState(); 63 | virtual PluginState *clone() const; 64 | static PluginState *factory(Plugin *p, S2EExecutionState *s); 65 | 66 | friend class HostFiles; 67 | }; 68 | 69 | } // namespace plugins 70 | } // namespace s2e 71 | 72 | #endif // S2E_PLUGINS_HOSTFILES_H 73 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Core/Vmi.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2012-2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015-2019, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_Vmi_H 10 | #define S2E_PLUGINS_Vmi_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace s2e { 28 | 29 | class ConfigFile; 30 | 31 | namespace plugins { 32 | 33 | class Vmi : public Plugin { 34 | S2E_PLUGIN 35 | public: 36 | Vmi(S2E *s2e) : Plugin(s2e) { 37 | } 38 | 39 | ~Vmi() { 40 | } 41 | 42 | void initialize(); 43 | 44 | static bool readGuestVirtual(void *opaque, uint64_t address, void *dest, unsigned size); 45 | static bool writeGuestVirtual(void *opaque, uint64_t address, const void *source, unsigned size); 46 | 47 | static bool readGuestPhysical(void *opaque, uint64_t address, void *dest, unsigned size); 48 | static bool writeGuestPhysical(void *opaque, uint64_t address, const void *source, unsigned size); 49 | 50 | static bool readX86Register(void *opaque, unsigned reg, void *value, unsigned size); 51 | static bool writeX86Register(void *opaque, unsigned reg, const void *value, unsigned size); 52 | 53 | static std::string stripWindowsModulePath(const std::string &path); 54 | 55 | std::shared_ptr getFromDisk(const std::string &modulePath, const std::string &moduleName, 56 | bool caseInsensitive); 57 | 58 | bool readModuleData(const ModuleDescriptor &module, uint64_t addr, uint8_t &val); 59 | 60 | bool getResolvedImports(S2EExecutionState *state, const ModuleDescriptor &module, vmi::Imports &imports); 61 | 62 | private: 63 | std::vector m_baseDirectories; 64 | std::unordered_map> m_cache; 65 | 66 | bool findModule(const std::string &module, std::string &path); 67 | bool parseDirectories(ConfigFile *cfg, const std::string &baseDirsKey); 68 | 69 | bool getHostPathForModule(const std::string &modulePath, const std::string &moduleName, bool caseInsensitive, 70 | std::string &hostPath); 71 | vmi::Imports resolveImports(S2EExecutionState *state, uint64_t loadBase, const vmi::Imports &imports); 72 | }; 73 | 74 | } // namespace plugins 75 | } // namespace s2e 76 | 77 | #endif // S2E_PLUGINS_Vmi_H 78 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Coverage/BasicBlockCoverage.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2013, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_BasicBlockCoverage_H 10 | #define S2E_PLUGINS_BasicBlockCoverage_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | namespace s2e { 27 | namespace plugins { 28 | namespace coverage { 29 | 30 | class BasicBlockCoverage : public Plugin { 31 | S2E_PLUGIN 32 | public: 33 | // Use an immutable set to share as much information between the states. 34 | // This also avoids costly copying when forking. 35 | typedef klee::ImmutableSet BasicBlocks; 36 | typedef std::map ModuleBasicBlocks; 37 | 38 | struct StateBB { 39 | S2EExecutionState *state; 40 | uint64_t pc; 41 | }; 42 | 43 | struct state_t {}; 44 | struct pc_t {}; 45 | 46 | typedef boost::multi_index_container< 47 | StateBB, boost::multi_index::indexed_by< 48 | boost::multi_index::ordered_unique, 49 | BOOST_MULTI_INDEX_MEMBER(StateBB, S2EExecutionState *, state)>, 50 | boost::multi_index::ordered_non_unique, 51 | BOOST_MULTI_INDEX_MEMBER(StateBB, uint64_t, pc)>>> 52 | MultiStatesBB; 53 | 54 | typedef MultiStatesBB::index::type StatesByPointer; 55 | typedef MultiStatesBB::index::type StatesByPc; 56 | typedef std::map StateLocations; 57 | 58 | typedef llvm::DenseSet CoveredBlocks; 59 | typedef std::map Coverage; 60 | 61 | BasicBlockCoverage(S2E *s2e) : Plugin(s2e) { 62 | } 63 | 64 | void initialize(); 65 | 66 | sigc::signal onNewBlockCovered; 67 | 68 | bool isCovered(const std::string &module, uint64_t block) { 69 | Coverage::iterator mit = m_coveredBlocks.find(module); 70 | if (mit == m_coveredBlocks.end()) { 71 | return false; 72 | } 73 | 74 | const ControlFlowGraph::BasicBlock *bb = m_cfg->findBasicBlock(module, block); 75 | if (!bb) { 76 | return false; 77 | } 78 | 79 | return (*mit).second.find(bb->start_pc) != (*mit).second.end(); 80 | } 81 | 82 | // block is a BASIC BLOCK start, not a random address 83 | void addNonCoveredBlock(S2EExecutionState *state, const std::string &module, uint64_t block); 84 | void printNonCoveredBlocks(); 85 | 86 | std::string generateJsonCoverageFile(S2EExecutionState *state); 87 | void generateJsonCoverageFile(S2EExecutionState *state, const std::string &filePath); 88 | void generateJsonCoverage(S2EExecutionState *state, std::stringstream &ss); 89 | 90 | S2EExecutionState *getNonCoveredState(llvm::DenseSet &filter); 91 | const ModuleBasicBlocks &getCoverage(S2EExecutionState *state); 92 | 93 | private: 94 | ModuleExecutionDetector *m_detector; 95 | ControlFlowGraph *m_cfg; 96 | 97 | void onCfgReload(); 98 | void onStateKill(S2EExecutionState *state); 99 | void onModuleTranslateBlockComplete(S2EExecutionState *state, const ModuleDescriptor &module, TranslationBlock *tb, 100 | uint64_t pc); 101 | 102 | void onTimer(); 103 | 104 | void onUpdateStates(S2EExecutionState *state, const klee::StateSet &addedStates, 105 | const klee::StateSet &removedStates); 106 | 107 | Coverage m_coveredBlocks; 108 | StateLocations m_nonCoveredBasicBlocks; 109 | }; 110 | 111 | } // namespace coverage 112 | } // namespace plugins 113 | } // namespace s2e 114 | 115 | #endif // S2E_PLUGINS_BasicBlockCoverage_H 116 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Coverage/EdgeCoverage.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "EdgeCoverage.h" 15 | 16 | namespace s2e { 17 | namespace plugins { 18 | 19 | S2E_DEFINE_PLUGIN(EdgeCoverage, "EdgeCoverage S2E plugin", "", "EdgeDetector", "ModuleExecutionDetector"); 20 | 21 | void EdgeCoverage::initialize() { 22 | m_edgeDetector = s2e()->getPlugin(); 23 | m_exec = s2e()->getPlugin(); 24 | 25 | s2e()->getCorePlugin()->onUpdateStates.connect(sigc::mem_fun(*this, &EdgeCoverage::onUpdateStates)); 26 | 27 | m_edgeDetector->onEdge.connect(sigc::mem_fun(*this, &EdgeCoverage::onEdge)); 28 | } 29 | 30 | void EdgeCoverage::onUpdateStates(S2EExecutionState *state, const klee::StateSet &addedStates, 31 | const klee::StateSet &removedStates) { 32 | foreach2 (it, removedStates.begin(), removedStates.end()) { 33 | S2EExecutionState *state = static_cast(*it); 34 | // XXX: avoid the loop 35 | foreach2 (mit, m_nonCoveredEdges.begin(), m_nonCoveredEdges.end()) { 36 | MultiStatesEdges &bbs = (*mit).second; 37 | StatesByPointer &byptr = bbs.get(); 38 | byptr.erase(state); 39 | } 40 | } 41 | } 42 | 43 | void EdgeCoverage::onEdge(S2EExecutionState *state, uint64_t source, EdgeType type) { 44 | auto sm = m_exec->getModule(state, source); 45 | auto dm = m_exec->getModule(state, state->regs()->getPc()); 46 | if (sm != dm) { 47 | return; 48 | } 49 | 50 | bool ok = true; 51 | uint64_t s, d; 52 | 53 | ok &= sm->ToNativeBase(source, s); 54 | ok &= sm->ToNativeBase(state->regs()->getPc(), d); 55 | 56 | if (!ok) { 57 | getWarningsStream(state) << "Could not get source/destination address for edge\n"; 58 | return; 59 | } 60 | 61 | Edge e = std::make_pair(s, d); 62 | 63 | StateLocations::iterator cit = m_nonCoveredEdges.find(sm->Name); 64 | if (cit == m_nonCoveredEdges.end()) { 65 | return; 66 | } 67 | 68 | MultiStatesEdges &edges = (*cit).second; 69 | StatesByEdge &bye = edges.get(); 70 | 71 | bool found = false; 72 | while (bye.find(e) != bye.end()) { 73 | bye.erase(e); 74 | found = true; 75 | } 76 | 77 | if (found) { 78 | getDebugStream(state) << "Covered edge " << hexval(e.first) << " " << hexval(e.second) << "\n"; 79 | m_coveredEdges[sm->Name].insert(e); 80 | } 81 | } 82 | 83 | void EdgeCoverage::addNonCoveredEdge(S2EExecutionState *state, const std::string &module, uint64_t source, 84 | uint64_t dest) { 85 | if (isCovered(module, source, dest)) { 86 | return; 87 | } 88 | 89 | StateEdge info; 90 | info.state = state; 91 | info.edge = std::make_pair(source, dest); 92 | m_nonCoveredEdges[module].insert(info); 93 | 94 | getDebugStream(state) << "Adding non-covered edge " << hexval(info.edge.first) << " " << hexval(info.edge.second) 95 | << "\n"; 96 | 97 | EdgeType type; 98 | if (!m_edgeDetector->findEdge(module, source, dest, &type)) { 99 | m_edgeDetector->addEdge(module, source, dest, EDGE_NONE); 100 | se_tb_safe_flush(); 101 | } 102 | } 103 | 104 | S2EExecutionState *EdgeCoverage::getNonCoveredState(llvm::DenseSet &filter) { 105 | foreach2 (it, m_nonCoveredEdges.begin(), m_nonCoveredEdges.end()) { 106 | MultiStatesEdges &bbs = (*it).second; 107 | StatesByEdge &bypc = bbs.get(); 108 | 109 | foreach2 (bit, bypc.begin(), bypc.end()) { 110 | S2EExecutionState *state = (*bit).state; 111 | if (filter.find(state) != filter.end()) { 112 | getDebugStream() << "State id " << (*bit).state->getID() << " has not covered edge " 113 | << hexval((*bit).edge.first) << ", " << hexval((*bit).edge.second) << " yet\n"; 114 | return (*bit).state; 115 | } 116 | } 117 | } 118 | 119 | return nullptr; 120 | } 121 | 122 | } // namespace plugins 123 | } // namespace s2e 124 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Coverage/EdgeCoverage.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_EdgeCoverage_H 9 | #define S2E_PLUGINS_EdgeCoverage_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace s2e { 23 | namespace plugins { 24 | 25 | class EdgeCoverage : public Plugin { 26 | S2E_PLUGIN 27 | private: 28 | typedef std::pair Edge; 29 | struct StateEdge { 30 | S2EExecutionState *state; 31 | Edge edge; 32 | }; 33 | 34 | struct state_t {}; 35 | struct edge_t {}; 36 | 37 | typedef boost::multi_index_container< 38 | StateEdge, 39 | boost::multi_index::indexed_by< 40 | boost::multi_index::ordered_unique, 41 | BOOST_MULTI_INDEX_MEMBER(StateEdge, S2EExecutionState *, state)>, 42 | boost::multi_index::ordered_non_unique, 43 | BOOST_MULTI_INDEX_MEMBER(StateEdge, Edge, edge)>>> 44 | MultiStatesEdges; 45 | 46 | typedef MultiStatesEdges::index::type StatesByPointer; 47 | typedef MultiStatesEdges::index::type StatesByEdge; 48 | typedef std::map StateLocations; 49 | 50 | typedef llvm::DenseSet CoveredEdges; 51 | typedef std::map Coverage; 52 | 53 | Coverage m_coveredEdges; 54 | StateLocations m_nonCoveredEdges; 55 | 56 | public: 57 | EdgeCoverage(S2E *s2e) : Plugin(s2e) { 58 | } 59 | 60 | void initialize(); 61 | 62 | bool isCovered(const std::string &module, uint64_t source, uint64_t dest) { 63 | Coverage::iterator mit = m_coveredEdges.find(module); 64 | if (mit == m_coveredEdges.end()) { 65 | return false; 66 | } 67 | 68 | Edge edge = std::make_pair(source, dest); 69 | return (*mit).second.find(edge) != (*mit).second.end(); 70 | } 71 | 72 | void addNonCoveredEdge(S2EExecutionState *state, const std::string &module, uint64_t source, uint64_t dest); 73 | S2EExecutionState *getNonCoveredState(llvm::DenseSet &filter); 74 | 75 | private: 76 | EdgeDetector *m_edgeDetector; 77 | ModuleExecutionDetector *m_exec; 78 | 79 | void onUpdateStates(S2EExecutionState *state, const klee::StateSet &addedStates, 80 | const klee::StateSet &removedStates); 81 | 82 | void onEdge(S2EExecutionState *state, uint64_t source, EdgeType type); 83 | }; 84 | 85 | } // namespace plugins 86 | } // namespace s2e 87 | 88 | #endif // S2E_PLUGINS_EdgeCoverage_H 89 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Example.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2015, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "Example.h" 13 | 14 | namespace s2e { 15 | namespace plugins { 16 | 17 | S2E_DEFINE_PLUGIN(Example, "Example S2E plugin", "", ); 18 | 19 | void Example::initialize() { 20 | m_traceBlockTranslation = s2e()->getConfig()->getBool(getConfigKey() + ".traceBlockTranslation"); 21 | 22 | m_traceBlockExecution = s2e()->getConfig()->getBool(getConfigKey() + ".traceBlockExecution"); 23 | 24 | s2e()->getCorePlugin()->onTranslateBlockStart.connect(sigc::mem_fun(*this, &Example::slotTranslateBlockStart)); 25 | } 26 | 27 | void Example::slotTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, 28 | uint64_t pc) { 29 | if (m_traceBlockTranslation) { 30 | getDebugStream(state) << "Translating block at " << hexval(pc) << "\n"; 31 | } 32 | 33 | if (m_traceBlockExecution) { 34 | signal->connect(sigc::mem_fun(*this, &Example::slotExecuteBlockStart)); 35 | } 36 | } 37 | 38 | void Example::slotExecuteBlockStart(S2EExecutionState *state, uint64_t pc) { 39 | getDebugStream(state) << "Executing block at " << hexval(pc) << "\n"; 40 | } 41 | 42 | } // namespace plugins 43 | } // namespace s2e 44 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Example.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2013, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_EXAMPLE_H 9 | #define S2E_PLUGINS_EXAMPLE_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace s2e { 16 | namespace plugins { 17 | 18 | class Example : public Plugin { 19 | S2E_PLUGIN 20 | public: 21 | Example(S2E *s2e) : Plugin(s2e) { 22 | } 23 | 24 | void initialize(); 25 | 26 | void slotTranslateBlockStart(ExecutionSignal *, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 27 | 28 | void slotExecuteBlockStart(S2EExecutionState *state, uint64_t pc); 29 | 30 | private: 31 | bool m_traceBlockTranslation; 32 | bool m_traceBlockExecution; 33 | }; 34 | 35 | } // namespace plugins 36 | } // namespace s2e 37 | 38 | #endif // S2E_PLUGINS_EXAMPLE_H 39 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionMonitors/CallSiteMonitor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_CallSiteMonitor_H 9 | #define S2E_PLUGINS_CallSiteMonitor_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace s2e { 20 | namespace plugins { 21 | 22 | class OSMonitor; 23 | 24 | /// 25 | /// \brief The CallSiteMonitor class instruments calls, indirect calls, 26 | /// and indirect jumps in order to track their target. 27 | 28 | /// This plugin can be used to discover function entry points dynamically 29 | /// (called directly or indirectly) as well as analyze jump tables (indirect 30 | /// jumps). 31 | /// 32 | /// Client plugins can request a json file with a dump of all call sites. 33 | /// The json file is structured as follows: 34 | /// 35 | /// \code{.json} 36 | /// {"module1": [[source, target, flags], ...], "module2":[[...], ...]} 37 | /// \endcode 38 | /// 39 | /// flags can be 0 (direct call), 1 (indirect call), 2 (indirect jump). 40 | /// Bit 2-3 indicate that the source and/or the target is a JIT region. 41 | /// 42 | /// 43 | /// TODO: 44 | /// 45 | /// \li api to retrieve the information in various forms (e.g., signals) 46 | /// \li per-path call site information 47 | /// 48 | ///

Configuration Options:

49 | /// 50 | /// \li dumpInfoInterval: when set to n > 0, 51 | /// the plugin will dump call site information every n seconds 52 | /// to a json file in the S2E output folder. 53 | /// 54 | class CallSiteMonitor : public Plugin { 55 | S2E_PLUGIN 56 | public: 57 | CallSiteMonitor(S2E *s2e) : Plugin(s2e) { 58 | } 59 | 60 | void initialize(); 61 | 62 | /// Generate a json file with call site information and return the file name 63 | /// \return path to the generated file 64 | std::string generateJsonFile(); 65 | 66 | /// Stores call site information in a json file specified in \p path 67 | /// \param path the path of the json file 68 | void generateJsonFile(const std::string &path); 69 | 70 | /// Stores call site information in a json string 71 | /// \param callSiteInfo the json string output 72 | void generateJson(std::stringstream &callSiteInfo); 73 | 74 | private: 75 | // Do not modify the ordering, the values 76 | // are used in json output. 77 | enum CallSiteType { 78 | // Bits 0-1 indicate the type of call site 79 | CALL = 0, 80 | INDIRECT_CALL = 1, 81 | INDIRECT_JUMP = 2, 82 | 83 | // Bit 2-3 indicate whether the source and/or dest 84 | // are outside any text section 85 | JIT_SOURCE = 4, 86 | JIT_TARGET = 8 87 | }; 88 | 89 | struct CallSite { 90 | CallSiteType type; 91 | uint64_t source; 92 | uint64_t target; 93 | 94 | CallSite() : type(CALL), source(0), target(0) { 95 | } 96 | 97 | bool operator()(const CallSite &a, const CallSite &b) const { 98 | if (a.source != b.source) { 99 | return a.source < b.source; 100 | } 101 | if (a.target != b.target) { 102 | return a.target < b.target; 103 | } 104 | return a.type < b.type; 105 | } 106 | }; 107 | 108 | // Use an immutable set to share as much information between the states. 109 | // This also avoids costly copying when forking. 110 | typedef std::set CallSites; 111 | typedef std::unordered_map PidCallSites; 112 | 113 | PidCallSites m_callSites; 114 | 115 | ProcessExecutionDetector *m_procDetector; 116 | OSMonitor *m_monitor; 117 | ModuleExecutionDetector *m_detector; 118 | 119 | unsigned m_dumpPeriod; 120 | unsigned m_lastDumpedTime; 121 | 122 | void onTranslateBlockEnd(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc, 123 | bool isStatic, uint64_t staticTarget); 124 | 125 | void onInstruction(S2EExecutionState *state, uint64_t source_pc, unsigned source_type); 126 | void onTimer(); 127 | }; 128 | 129 | } // namespace plugins 130 | } // namespace s2e 131 | 132 | #endif // S2E_PLUGINS_CallSiteMonitor_H 133 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionMonitors/FunctionMonitor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015-2019, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_FunctionMonitor_H 9 | #define S2E_PLUGINS_FunctionMonitor_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace s2e { 16 | 17 | class S2EExecutionState; 18 | struct ThreadDescriptor; 19 | 20 | namespace plugins { 21 | 22 | class ModuleMap; 23 | class OSMonitor; 24 | class ProcessExecutionDetector; 25 | 26 | /// 27 | /// \brief The FunctionMonitor class tracks call/return instruction pairs. 28 | /// 29 | /// Clients use the onCall signal to be notified of call instructions and 30 | /// optionally of return instructions in case they choose to register the corresponding 31 | /// return signal. Call/return signals are paired and work for recursive functions too. 32 | /// Note that compilers may introduce various optimizations (e.g., tail calls), which 33 | /// may interfere with return signals. 34 | /// 35 | /// This plugin only tracks modules in processes registered with ProcessExecutionDetector. 36 | /// 37 | class FunctionMonitor : public Plugin { 38 | S2E_PLUGIN 39 | 40 | public: 41 | FunctionMonitor(S2E *s2e) : Plugin(s2e) { 42 | } 43 | 44 | void initialize(); 45 | 46 | // Source and/or dest module can be null 47 | typedef sigc::signal 52 | ReturnSignal; 53 | 54 | typedef std::shared_ptr ReturnSignalPtr; 55 | 56 | /// 57 | /// \brief onCall 58 | /// 59 | sigc::signal 62 | onCall; 63 | 64 | private: 65 | OSMonitor *m_monitor; 66 | ProcessExecutionDetector *m_processDetector; 67 | ModuleMap *m_map; 68 | 69 | void onProcessUnload(S2EExecutionState *state, uint64_t addressSpace, uint64_t pid, uint64_t returnCode); 70 | void onThreadExit(S2EExecutionState *state, const ThreadDescriptor &thread); 71 | void onFunctionCall(S2EExecutionState *state, uint64_t pc); 72 | void onFunctionReturn(S2EExecutionState *state, uint64_t pc); 73 | void onTranslateBlockEnd(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc, 74 | bool isStatic, uint64_t staticTarget); 75 | }; 76 | 77 | } // namespace plugins 78 | } // namespace s2e 79 | 80 | #endif // S2E_PLUGINS_FunctionMonitor_H 81 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionMonitors/LibraryCallMonitor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2011-2017, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_LibraryCallMonitor_H 10 | #define S2E_PLUGINS_LibraryCallMonitor_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace s2e { 17 | 18 | class S2E; 19 | class S2EExecutionState; 20 | 21 | namespace plugins { 22 | 23 | class ModuleMap; 24 | class OSMonitor; 25 | class ProcessExecutionDetector; 26 | class Vmi; 27 | 28 | /// 29 | /// \brief Monitors external library function calls. 30 | /// 31 | /// This plugin can be used to determine what external library calls a particular module makes at run time (including 32 | /// both libraries and process main binaries). The modules to monitor are those defined in the 33 | /// \code ProcessExecutionDetector plugin's config. 34 | /// 35 | /// The plugin works as follows: 36 | /// \li All indirect calls are monitored. Library calls are always made indirectly (via either the PLT in ELF 37 | /// binaries or the IAT in PE binaries) 38 | /// \li When an indirect call is made, we look up the module that contains the call target address 39 | /// \li Once we find that module, we can search its export table to find an entry that matches the call target 40 | /// address. If a match is found, report it 41 | /// 42 | /// Note that this approach does not use the callee module's import table. This means that library calls that are not 43 | /// listed in the import table are still monitored. This is beneficial for malware analysis, where the import table 44 | /// is often destroyed and library calls are made "indirectly" (e.g. via \code LoadLibrary and \code GetProcAddress). 45 | /// 46 | ///

Configuration Options

47 | /// 48 | /// \li \code monitorAllModules: enable if you want to track library calls from \a all modules used by the module 49 | /// specified in the \code ProcessExecutionDetector plugin config. 50 | /// \li \code monitorIndirectJumps: enable if you want to track library calls that are made via jumps, not just via 51 | /// calls. For example, malware might do this as an obfuscation technique. 52 | /// 53 | class LibraryCallMonitor : public Plugin { 54 | S2E_PLUGIN 55 | 56 | public: 57 | LibraryCallMonitor(S2E *s2e) : Plugin(s2e) { 58 | } 59 | 60 | void initialize(); 61 | 62 | /// Emitted on an external library function call. 63 | sigc::signal /* The called function's address */ 66 | onLibraryCall; 67 | 68 | private: 69 | ModuleMap *m_map; 70 | OSMonitor *m_monitor; 71 | ProcessExecutionDetector *m_procDetector; 72 | Vmi *m_vmi; 73 | 74 | bool m_monitorAllModules; 75 | bool m_monitorIndirectJumps; 76 | 77 | void onModuleUnload(S2EExecutionState *state, const ModuleDescriptor &module); 78 | void onProcessUnload(S2EExecutionState *state, uint64_t addressSpace, uint64_t pid, uint64_t returnCode); 79 | 80 | void logLibraryCall(S2EExecutionState *state, const ModuleDescriptor &sourceMod, const ModuleDescriptor &destMod, 81 | uint64_t sourcePcAbsolute, uint64_t destPcAbsolute, unsigned sourceType, 82 | const std::string &function) const; 83 | 84 | void onTranslateBlockEnd(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc, 85 | bool isStatic, uint64_t staticTarget); 86 | void onIndirectCallOrJump(S2EExecutionState *state, uint64_t pc, unsigned sourceType); 87 | }; 88 | 89 | } // namespace plugins 90 | } // namespace s2e 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionMonitors/StackClustering.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2013-2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_StackClustering_H 10 | #define S2E_PLUGINS_StackClustering_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "CallTree.h" 21 | 22 | namespace s2e { 23 | namespace plugins { 24 | 25 | class OSMonitor; 26 | 27 | class StackClustering : public Plugin { 28 | S2E_PLUGIN 29 | public: 30 | StackClustering(S2E *s2e) : Plugin(s2e) { 31 | } 32 | 33 | void initialize(); 34 | 35 | private: 36 | typedef calltree::CallTree StateCallTree; 37 | 38 | StackMonitor *m_stackMonitor; 39 | ModuleExecutionDetector *m_detector; 40 | ControlFlowGraph *m_cfg; 41 | StateCallTree m_callTree; 42 | OSMonitor *m_monitor; 43 | 44 | unsigned m_timer; 45 | unsigned m_interval; 46 | 47 | void computeCallStack(S2EExecutionState *originalState, calltree::CallStack &cs, calltree::Location &loc); 48 | 49 | void onStateFork(S2EExecutionState *originalState, const std::vector &newStates, 50 | const std::vector> &newConditions); 51 | 52 | void onTimer(); 53 | 54 | void onUpdateStates(S2EExecutionState *state, const klee::StateSet &addedStates, 55 | const klee::StateSet &removedStates); 56 | 57 | public: 58 | StateCallTree &getCallTree() { 59 | return m_callTree; 60 | } 61 | 62 | void add(S2EExecutionState *state); 63 | 64 | void print(); 65 | }; 66 | 67 | } // namespace plugins 68 | } // namespace s2e 69 | 70 | #endif // S2E_PLUGINS_StackClustering_H 71 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionMonitors/StackMonitor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2012-2016, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_STACKMONITOR_H 9 | #define S2E_PLUGINS_STACKMONITOR_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace s2e { 17 | 18 | struct ThreadDescriptor; 19 | 20 | namespace plugins { 21 | 22 | class OSMonitor; 23 | 24 | struct StackFrameInfo { 25 | uint64_t StackBound; 26 | uint64_t FrameTop; 27 | uint64_t FrameSize; 28 | 29 | /** 30 | * Program counter that opened the frame. 31 | * This is usually the return address. 32 | */ 33 | uint64_t FramePc; 34 | 35 | /** 36 | * Function to which this frame belongs. 37 | * Points to the first instruction of the function. 38 | */ 39 | uint64_t FrameFunction; 40 | }; 41 | 42 | class StackMonitorState; 43 | 44 | class StackMonitor : public Plugin { 45 | S2E_PLUGIN 46 | public: 47 | typedef std::vector CallStack; 48 | typedef std::vector CallStacks; 49 | 50 | friend class StackMonitorState; 51 | StackMonitor(S2E *s2e) : Plugin(s2e) { 52 | } 53 | 54 | void initialize(); 55 | 56 | void registerNoframeFunction(S2EExecutionState *state, uint64_t pid, uint64_t callAddr); 57 | 58 | bool getFrameInfo(S2EExecutionState *state, uint64_t sp, bool &onTheStack, StackFrameInfo &info) const; 59 | bool getCallStack(S2EExecutionState *state, uint64_t pid, uint64_t tid, CallStack &callStack) const; 60 | bool getCallStacks(S2EExecutionState *state, CallStacks &callStacks) const; 61 | 62 | void dump(S2EExecutionState *state); 63 | 64 | void update(S2EExecutionState *state, uint64_t sp, uint64_t pc, bool createNewFrame); 65 | 66 | /** 67 | * Emitted when a new stack frame is setup (e.g., when execution enters a module of interest). 68 | */ 69 | sigc::signal onStackCreation; 70 | 71 | /** 72 | * Emitted when there are no more stack frames anymore. 73 | */ 74 | sigc::signal onStackDeletion; 75 | 76 | /** 77 | * Emitted when stack is modified. 78 | */ 79 | sigc::signal onStackFrameCreate; 80 | sigc::signal 81 | onStackFrameGrow; 82 | sigc::signal 83 | onStackFrameShrink; 84 | sigc::signal 86 | onStackFrameDelete; 87 | 88 | private: 89 | OSMonitor *m_monitor; 90 | ProcessExecutionDetector *m_processDetector; 91 | 92 | typedef enum { DEBUGLEVEL_PRINT_MESSAGES = 1, DEBUGLEVEL_DUMP_STACK = 2 } DebugLevel; 93 | DebugLevel m_debugLevel; 94 | 95 | sigc::connection m_onTranslateRegisterAccessConnection; 96 | 97 | void onThreadExit(S2EExecutionState *state, const ThreadDescriptor &thread); 98 | void onProcessUnload(S2EExecutionState *state, uint64_t pageDir, uint64_t pid, uint64_t returnCode); 99 | 100 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 101 | 102 | void onTranslateBlockComplete(S2EExecutionState *state, TranslationBlock *tb, uint64_t endPc); 103 | 104 | void onTranslateRegisterAccess(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc, 105 | uint64_t rmask, uint64_t wmask, bool accessesMemory); 106 | 107 | void onStackPointerModification(S2EExecutionState *state, uint64_t pc, bool isCall, uint64_t callEip); 108 | }; 109 | 110 | } // namespace plugins 111 | } // namespace s2e 112 | 113 | #endif // S2E_PLUGINS_STACKMONITOR_H 114 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/EventTracer.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2015, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include "EventTracer.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | namespace s2e { 20 | namespace plugins { 21 | 22 | EventTracer::EventTracer(S2E *s2e) : Plugin(s2e) { 23 | } 24 | 25 | EventTracer::~EventTracer() { 26 | } 27 | 28 | void EventTracer::initialize() { 29 | // Check that the tracer is there 30 | m_Tracer = s2e()->getPlugin(); 31 | assert(m_Tracer); 32 | 33 | m_Detector = s2e()->getPlugin(); 34 | assert(m_Detector); 35 | 36 | m_TraceAll = false; 37 | m_TraceAllCfg = nullptr; 38 | m_Debug = false; 39 | } 40 | 41 | bool EventTracer::initSections(TracerConfigEntryFactory cfgFactory) { 42 | m_Debug = s2e()->getConfig()->getBool(getConfigKey() + ".enableDebug"); 43 | 44 | std::vector Sections; 45 | Sections = s2e()->getConfig()->getListKeys(getConfigKey()); 46 | bool noErrors = true; 47 | 48 | foreach2 (it, Sections.begin(), Sections.end()) { 49 | if (*it == "enableDebug") { 50 | continue; 51 | } 52 | 53 | getInfoStream() << "Scanning section " << getConfigKey() << "." << *it << '\n'; 54 | std::stringstream sk; 55 | sk << getConfigKey() << "." << *it; 56 | 57 | TracerConfigEntry *cfgEntry = cfgFactory(); 58 | assert(cfgEntry); 59 | 60 | if (!initBaseParameters(cfgEntry, sk.str(), *it)) { 61 | noErrors = false; 62 | } 63 | 64 | if (!initSection(cfgEntry, sk.str(), *it)) { 65 | noErrors = false; 66 | } 67 | 68 | if (!registerConfigEntry(cfgEntry)) { 69 | noErrors = false; 70 | break; 71 | } 72 | } 73 | 74 | if (!noErrors) { 75 | getWarningsStream() << "Errors while scanning the " << getConfigKey() << " sections" << '\n'; 76 | return false; 77 | } 78 | 79 | return true; 80 | } 81 | 82 | bool EventTracer::initBaseParameters(TracerConfigEntry *cfgEntry, const std::string &cfgKey, 83 | const std::string &entryId) { 84 | bool ok; 85 | cfgEntry->traceAll = s2e()->getConfig()->getBool(cfgKey + ".traceAll"); 86 | 87 | cfgEntry->moduleId = s2e()->getConfig()->getString(cfgKey + ".moduleId", "", &ok); 88 | if (!ok && !cfgEntry->traceAll) { 89 | getWarningsStream() << "You must specify " << cfgKey << ".moduleId" << '\n'; 90 | return false; 91 | } 92 | return true; 93 | } 94 | 95 | bool EventTracer::registerConfigEntry(TracerConfigEntry *cfgEntry) { 96 | if (cfgEntry->traceAll) { 97 | if (m_Modules.size() > 0) { 98 | getWarningsStream() << "EventTracer: There can be only one entry when tracing everything" << '\n'; 99 | return false; 100 | } 101 | 102 | m_TraceAll = true; 103 | m_TraceAllCfg = cfgEntry; 104 | return true; 105 | } 106 | 107 | EventTracerCfgMap::iterator it = m_Modules.find(cfgEntry->moduleId); 108 | if (it != m_Modules.end()) { 109 | getWarningsStream() << "EventTracer: " << cfgEntry->moduleId << " defined multiple times" << '\n'; 110 | return false; 111 | } 112 | 113 | m_Modules[cfgEntry->moduleId] = cfgEntry; 114 | return true; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/EventTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2013, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_EVENTTRACER_H 9 | #define S2E_PLUGINS_EVENTTRACER_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "ExecutionTracer.h" 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace s2e { 24 | namespace plugins { 25 | 26 | struct TracerConfigEntry { 27 | std::string moduleId; 28 | bool traceAll; 29 | 30 | TracerConfigEntry() { 31 | traceAll = false; 32 | } 33 | 34 | virtual ~TracerConfigEntry() { 35 | } 36 | }; 37 | 38 | typedef TracerConfigEntry *(*TracerConfigEntryFactory)(); 39 | 40 | // Maps a module name to a configuration entry 41 | typedef std::map EventTracerCfgMap; 42 | 43 | /** 44 | * Base class for all types of tracers. 45 | * Handles the basic boilerplate (e.g., common config options). 46 | */ 47 | class EventTracer : public Plugin { 48 | 49 | protected: 50 | ModuleExecutionDetector *m_Detector; 51 | ExecutionTracer *m_Tracer; 52 | EventTracerCfgMap m_Modules; 53 | bool m_TraceAll; 54 | TracerConfigEntry *m_TraceAllCfg; 55 | bool m_Debug; 56 | 57 | EventTracer(S2E *s2e); 58 | virtual ~EventTracer(); 59 | 60 | void initialize(); 61 | 62 | private: 63 | bool initBaseParameters(TracerConfigEntry *cfgEntry, const std::string &cfgKey, const std::string &entryId); 64 | 65 | bool registerConfigEntry(TracerConfigEntry *cfgEntry); 66 | 67 | protected: 68 | bool initSections(TracerConfigEntryFactory cfgFactory); 69 | 70 | virtual bool initSection(TracerConfigEntry *cfgEntry, const std::string &cfgKey, const std::string &entryId) = 0; 71 | }; 72 | } 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/ExceptionTracer.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2019, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #include "ExceptionTracer.h" 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace s2e { 17 | namespace plugins { 18 | 19 | S2E_DEFINE_PLUGIN(ExceptionTracer, "Traces CPU exception", "", "ExecutionTracer"); 20 | 21 | void ExceptionTracer::initialize() { 22 | m_tracer = s2e()->getPlugin(); 23 | 24 | s2e()->getCorePlugin()->onException.connect(sigc::mem_fun(*this, &ExceptionTracer::onException)); 25 | } 26 | 27 | void ExceptionTracer::onException(S2EExecutionState *state, unsigned vec, uint64_t pc) { 28 | s2e_trace::PbTraceException item; 29 | item.set_pc(state->regs()->getPc()); 30 | item.set_vector(vec); 31 | m_tracer->writeData(state, item, s2e_trace::TRACE_EXCEPTION); 32 | } 33 | 34 | } // namespace plugins 35 | } // namespace s2e 36 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/ExceptionTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2019, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_ExceptionTracer_H 10 | #define S2E_PLUGINS_ExceptionTracer_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include "ExecutionTracer.h" 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | class ExceptionTracer : public Plugin { 21 | S2E_PLUGIN 22 | public: 23 | ExceptionTracer(S2E *s2e) : Plugin(s2e) { 24 | } 25 | 26 | void initialize(); 27 | 28 | private: 29 | ExecutionTracer *m_tracer; 30 | 31 | void onException(S2EExecutionState *state, unsigned vec, uint64_t pc); 32 | }; 33 | 34 | } // namespace plugins 35 | } // namespace s2e 36 | 37 | #endif // S2E_PLUGINS_ExceptionTracer_H 38 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/ExecutionTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_EXECTRACER_H 10 | #define S2E_PLUGINS_EXECTRACER_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace s2e_trace { 20 | class PbTraceItemHeader; 21 | } 22 | 23 | namespace s2e { 24 | namespace plugins { 25 | 26 | class OSMonitor; 27 | 28 | /// This plugin manages the binary execution trace file. 29 | /// It makes sure that all the writes properly go through it. 30 | class ExecutionTracer : public Plugin { 31 | S2E_PLUGIN 32 | 33 | private: 34 | std::string m_fileName; 35 | FILE *m_logFile; 36 | uint32_t m_currentIndex; 37 | OSMonitor *m_monitor; 38 | 39 | void onTimer(); 40 | void createNewTraceFile(bool append); 41 | 42 | bool appendToTraceFile(const s2e_trace::PbTraceItemHeader &header, const void *data, unsigned size); 43 | 44 | void onStateGuidAssignment(S2EExecutionState *state, uint64_t newGuid); 45 | 46 | void onFork(S2EExecutionState *state, const std::vector &newStates, 47 | const std::vector> &newConditions); 48 | 49 | void onProcessFork(bool preFork, bool isChild, unsigned parentProcId); 50 | 51 | void onMonitorLoad(S2EExecutionState *state); 52 | 53 | void onEngineShutdown(); 54 | 55 | public: 56 | ExecutionTracer(S2E *s2e) : Plugin(s2e) { 57 | } 58 | ~ExecutionTracer(); 59 | void initialize(); 60 | 61 | template uint32_t writeData(S2EExecutionState *state, const T &item, uint32_t type) { 62 | std::string data; 63 | if (!item.AppendToString(&data)) { 64 | getWarningsStream(state) << "Could not serialize protobuf data\n"; 65 | exit(-1); 66 | } 67 | return writeData(state, data.c_str(), data.size(), type); 68 | } 69 | 70 | uint32_t writeData(S2EExecutionState *state, const void *data, unsigned size, 71 | uint32_t type /* s2e_trace::PbTraceItemHeaderType */); 72 | 73 | void flush(); 74 | }; 75 | 76 | } // namespace plugins 77 | } // namespace s2e 78 | 79 | #endif // S2E_PLUGINS_EXAMPLE_H 80 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/InstructionCounter.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2013, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E__INSTRUCTION_COUNTER_H 9 | #define S2E__INSTRUCTION_COUNTER_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "ExecutionTracer.h" 17 | #include "ModuleTracing.h" 18 | 19 | namespace s2e { 20 | namespace plugins { 21 | 22 | class ProcessExecutionDetector; 23 | class ModuleMap; 24 | 25 | class InstructionCounter : public Plugin { 26 | S2E_PLUGIN 27 | private: 28 | ExecutionTracer *m_tracer; 29 | ProcessExecutionDetector *m_detector; 30 | 31 | ModuleTracing m_modules; 32 | 33 | sigc::connection m_tbConnection; 34 | 35 | public: 36 | InstructionCounter(S2E *s2e) : Plugin(s2e) { 37 | } 38 | 39 | void initialize(); 40 | 41 | private: 42 | void onInitializationComplete(S2EExecutionState *state); 43 | void onStateKill(S2EExecutionState *state); 44 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 45 | 46 | void onTranslateInstructionStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, 47 | uint64_t pc); 48 | 49 | void onInstruction(S2EExecutionState *state, uint64_t pc); 50 | }; 51 | 52 | } // namespace plugins 53 | } // namespace s2e 54 | 55 | #endif // S2E_PLUGINS_EXAMPLE_H 56 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/MemoryTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_MEMTRACER_H 10 | #define S2E_PLUGINS_MEMTRACER_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #include "ExecutionTracer.h" 19 | #include "ModuleTracing.h" 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | 24 | /** Handler required for KLEE interpreter */ 25 | class MemoryTracer : public Plugin { 26 | S2E_PLUGIN 27 | 28 | private: 29 | public: 30 | MemoryTracer(S2E *s2e); 31 | 32 | void initialize(); 33 | 34 | enum MemoryTracerOpcodes { Enable = 0, Disable = 1 }; 35 | 36 | enum TraceType { MEMORY = 0, TLB_MISSES = 1, PAGE_FAULT = 2, MAX_ITEMS = 3 }; 37 | 38 | private: 39 | bool m_tracePageFaults; 40 | bool m_traceTlbMisses; 41 | bool m_traceMemory; 42 | 43 | bool m_traceHostAddresses; 44 | bool m_debugObjectStates; 45 | 46 | ExecutionTracer *m_tracer; 47 | ProcessExecutionDetector *m_detector; 48 | 49 | ModuleTracing m_modules; 50 | 51 | void onTlbMiss(S2EExecutionState *state, uint64_t addr, bool is_write); 52 | void onPageFault(S2EExecutionState *state, uint64_t addr, bool is_write); 53 | 54 | void onAfterSymbolicDataMemoryAccess(S2EExecutionState *state, klee::ref address, 55 | klee::ref hostAddress, klee::ref value, 56 | unsigned flags); 57 | 58 | void onConcreteDataMemoryAccess(S2EExecutionState *state, uint64_t vaddr, uint64_t value, uint8_t size, 59 | unsigned flags); 60 | 61 | void onExecuteBlockStart(S2EExecutionState *state, uint64_t pc); 62 | 63 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 64 | 65 | void onBlockStart(S2EExecutionState *state, uint64_t pc, bool traced_module); 66 | void onInitializationComplete(S2EExecutionState *state); 67 | 68 | public: 69 | bool getProperty(S2EExecutionState *state, const std::string &name, std::string &value); 70 | bool setProperty(S2EExecutionState *state, const std::string &name, const std::string &value); 71 | 72 | // May be called directly by other plugins 73 | void traceSymbolicDataMemoryAccess(S2EExecutionState *state, klee::ref &address, 74 | klee::ref &hostAddress, klee::ref &value, 75 | unsigned flags); 76 | 77 | void traceConcreteDataMemoryAccess(S2EExecutionState *state, uint64_t address, uint64_t value, uint8_t size, 78 | unsigned flags); 79 | 80 | void enable(S2EExecutionState *state, TraceType type, bool v); 81 | }; 82 | } 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/ModuleTracer.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include "ModuleTracer.h" 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | 24 | S2E_DEFINE_PLUGIN(ModuleTracer, "Module load/unload tracer plugin", "ModuleTracer" 25 | "ExecutionTracer", 26 | "OSMonitor"); 27 | 28 | ModuleTracer::ModuleTracer(S2E *s2e) : EventTracer(s2e) { 29 | } 30 | 31 | ModuleTracer::~ModuleTracer() { 32 | } 33 | 34 | void ModuleTracer::initialize() { 35 | m_tracer = s2e()->getPlugin(); 36 | 37 | OSMonitor *monitor = static_cast(s2e()->getPlugin("OSMonitor")); 38 | 39 | monitor->onModuleLoad.connect(sigc::mem_fun(*this, &ModuleTracer::moduleLoadListener)); 40 | monitor->onModuleUnload.connect(sigc::mem_fun(*this, &ModuleTracer::moduleUnloadListener)); 41 | monitor->onProcessUnload.connect(sigc::mem_fun(*this, &ModuleTracer::processUnloadListener)); 42 | } 43 | 44 | bool ModuleTracer::initSection(TracerConfigEntry *cfgEntry, const std::string &cfgKey, const std::string &entryId) { 45 | return true; 46 | } 47 | 48 | bool ModuleTracer::moduleToProtobuf(const ModuleDescriptor &module, std::string &data) { 49 | s2e_trace::PbTraceModuleLoadUnload te; 50 | te.set_name(module.Name.c_str()); 51 | te.set_path(module.Path.c_str()); 52 | te.set_pid(module.Pid); 53 | te.set_address_space(module.AddressSpace); 54 | 55 | for (const auto §ion : module.Sections) { 56 | auto s = te.add_sections(); 57 | s->set_name(section.name.c_str()); 58 | s->set_runtime_load_base(section.runtimeLoadBase); 59 | s->set_native_load_base(section.nativeLoadBase); 60 | s->set_size(section.size); 61 | s->set_readable(section.readable); 62 | s->set_writable(section.writable); 63 | s->set_executable(section.executable); 64 | } 65 | 66 | return te.AppendToString(&data); 67 | } 68 | 69 | void ModuleTracer::moduleLoadListener(S2EExecutionState *state, const ModuleDescriptor &module) { 70 | 71 | std::string data; 72 | if (moduleToProtobuf(module, data)) { 73 | m_tracer->writeData(state, data.c_str(), data.size(), s2e_trace::TRACE_MOD_LOAD); 74 | } 75 | } 76 | 77 | void ModuleTracer::moduleUnloadListener(S2EExecutionState *state, const ModuleDescriptor &module) { 78 | std::string data; 79 | if (moduleToProtobuf(module, data)) { 80 | m_tracer->writeData(state, data.c_str(), data.size(), s2e_trace::TRACE_MOD_UNLOAD); 81 | } 82 | } 83 | 84 | void ModuleTracer::processUnloadListener(S2EExecutionState *state, uint64_t pageDir, uint64_t pid, 85 | uint64_t returnCode) { 86 | s2e_trace::PbTraceProcessUnload item; 87 | item.set_return_code(returnCode); 88 | m_tracer->writeData(state, item, s2e_trace::TRACE_PROC_UNLOAD); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/ModuleTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2014, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_MODULETRACER_H 9 | #define S2E_PLUGINS_MODULETRACER_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include "EventTracer.h" 18 | #include "ExecutionTracer.h" 19 | 20 | namespace s2e { 21 | namespace plugins { 22 | 23 | class ModuleTracer : public EventTracer { 24 | S2E_PLUGIN 25 | 26 | ExecutionTracer *m_tracer; 27 | 28 | public: 29 | ModuleTracer(S2E *s2e); 30 | virtual ~ModuleTracer(); 31 | void initialize(); 32 | 33 | protected: 34 | virtual bool initSection(TracerConfigEntry *cfgEntry, const std::string &cfgKey, const std::string &entryId); 35 | 36 | static bool moduleToProtobuf(const ModuleDescriptor &module, std::string &data); 37 | 38 | void moduleLoadListener(S2EExecutionState *state, const ModuleDescriptor &module); 39 | 40 | void moduleUnloadListener(S2EExecutionState *state, const ModuleDescriptor &desc); 41 | 42 | void processUnloadListener(S2EExecutionState *state, uint64_t pageDir, uint64_t pid, uint64_t returnCode); 43 | }; 44 | } 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/ModuleTracing.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2020, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_IMODTRACE_H 9 | 10 | #define S2E_PLUGINS_IMODTRACE_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | /// 21 | /// \brief This is a helper class that can be used by plugins 22 | /// that need to trace specific modules. 23 | /// 24 | class ModuleTracing { 25 | private: 26 | ModuleMap *m_modules; 27 | std::unordered_set m_enabledModules; 28 | 29 | public: 30 | void initialize(S2E *s2e, const std::string &cfgKey) { 31 | m_modules = s2e->getPlugin(); 32 | auto modules = s2e->getConfig()->getStringList(cfgKey + ".moduleNames"); 33 | m_enabledModules.insert(modules.begin(), modules.end()); 34 | } 35 | 36 | bool isModuleTraced(S2EExecutionState *state, uint64_t pc) { 37 | // If no modules are specified, trace the entire process 38 | bool tracedModule = true; 39 | if (m_enabledModules.size()) { 40 | auto mod = m_modules->getModule(state, pc); 41 | if (mod) { 42 | tracedModule = m_enabledModules.find(mod->Name) != m_enabledModules.end(); 43 | } else { 44 | tracedModule = false; 45 | } 46 | } 47 | 48 | return tracedModule; 49 | } 50 | }; 51 | } 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/StateSwitchTracer.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include "StateSwitchTracer.h" 13 | 14 | namespace s2e { 15 | namespace plugins { 16 | 17 | S2E_DEFINE_PLUGIN(StateSwitchTracer, "Traces state switches", "", "ExecutionTracer"); 18 | 19 | void StateSwitchTracer::initialize() { 20 | m_tracer = s2e()->getPlugin(); 21 | 22 | s2e()->getCorePlugin()->onStateSwitch.connect(sigc::mem_fun(*this, &StateSwitchTracer::onStateSwitch)); 23 | } 24 | 25 | void StateSwitchTracer::onStateSwitch(S2EExecutionState *currentState, S2EExecutionState *nextState) { 26 | s2e_trace::PbTraceStateSwitch item; 27 | item.set_new_state(nextState->getID()); 28 | m_tracer->writeData(currentState, item, s2e_trace::TRACE_STATE_SWITCH); 29 | } 30 | 31 | } // namespace plugins 32 | } // namespace s2e 33 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/StateSwitchTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_StateSwitchTracer_H 9 | #define S2E_PLUGINS_StateSwitchTracer_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "ExecutionTracer.h" 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | class StateSwitchTracer : public Plugin { 21 | S2E_PLUGIN 22 | public: 23 | StateSwitchTracer(S2E *s2e) : Plugin(s2e) { 24 | } 25 | 26 | void initialize(); 27 | 28 | private: 29 | ExecutionTracer *m_tracer; 30 | 31 | void onStateSwitch(S2EExecutionState *currentState, S2EExecutionState *nextState); 32 | }; 33 | 34 | } // namespace plugins 35 | } // namespace s2e 36 | 37 | #endif // S2E_PLUGINS_StateSwitchTracer_H 38 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/TBCoverageTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016-2019, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | /* 9 | * S2E Selective Symbolic Execution Platform 10 | * 11 | * Copyright (c) 2014, Cisco Systems 12 | * All rights reserved. 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions are met: 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the name of Cisco Systems nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL CISCO SYSTEMS BE LIABLE FOR ANY DIRECT, 29 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef S2E__BLOCK_COVERAGE_TRACER_H 38 | #define S2E__BLOCK_COVERAGE_TRACER_H 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include "ExecutionTracer.h" 46 | 47 | namespace s2e { 48 | namespace plugins { 49 | 50 | class TBCoverageTracer : public Plugin, public IPluginInvoker { 51 | S2E_PLUGIN 52 | public: 53 | TBCoverageTracer(S2E *s2e) : Plugin(s2e) { 54 | } 55 | 56 | void initialize(void); 57 | 58 | typedef enum { Enable = 0, Disable = 1 } TraceOpcode; 59 | 60 | private: 61 | ExecutionTracer *m_tracer; 62 | ModuleExecutionDetector *m_detector; 63 | 64 | bool m_flushTbOnChange; 65 | bool m_manualTrigger; 66 | 67 | sigc::connection m_tbCompleteConnection; 68 | 69 | void onModuleTranslateBlockComplete(S2EExecutionState *state, const ModuleDescriptor &module, TranslationBlock *tb, 70 | uint64_t endPc); 71 | 72 | void trace(S2EExecutionState *state, uint64_t startPc, uint64_t endPc, TranslationBlock *tb); 73 | 74 | void enableTracing(); 75 | void disableTracing(); 76 | 77 | virtual void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 78 | }; 79 | 80 | } // namespace plugins 81 | } // namespace s2e 82 | 83 | #endif // S2E_BLOCK_COVERAGE_H 84 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/TranslationBlockTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_TBTRACER_H 10 | #define S2E_PLUGINS_TBTRACER_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include "ExecutionTracer.h" 19 | #include "ModuleTracing.h" 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | 24 | class TranslationBlockTracer : public Plugin { 25 | S2E_PLUGIN 26 | public: 27 | enum TraceType { TB_START = 0, TB_END = 1, MAX_ITEMS = 2 }; 28 | 29 | TranslationBlockTracer(S2E *s2e) : Plugin(s2e) { 30 | } 31 | 32 | void initialize(void); 33 | 34 | bool getProperty(S2EExecutionState *state, const std::string &name, std::string &value); 35 | bool setProperty(S2EExecutionState *state, const std::string &name, const std::string &value); 36 | 37 | private: 38 | ExecutionTracer *m_tracer; 39 | ProcessExecutionDetector *m_detector; 40 | 41 | bool m_traceTbStart; 42 | bool m_traceTbEnd; 43 | 44 | ModuleTracing m_modules; 45 | 46 | bool isModuleTraced(S2EExecutionState *state, uint64_t pc); 47 | 48 | void onInitializationComplete(S2EExecutionState *state); 49 | 50 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 51 | void onTranslateBlockEnd(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc, 52 | bool staticTarget, uint64_t staticTargetPc); 53 | 54 | void onBlockStartEnd(S2EExecutionState *state, uint64_t pc, bool isStart); 55 | void onBlockStart(S2EExecutionState *state, uint64_t pc); 56 | void onBlockEnd(S2EExecutionState *state, uint64_t pc); 57 | 58 | public: 59 | void enableTracing(S2EExecutionState *state, TranslationBlockTracer::TraceType type); 60 | void disableTracing(S2EExecutionState *state, TranslationBlockTracer::TraceType type); 61 | bool tracingEnabled(S2EExecutionState *state, TranslationBlockTracer::TraceType type); 62 | 63 | void trace(S2EExecutionState *state, uint64_t pc, uint32_t type /* s2e_trace::PbTraceItemHeaderType */); 64 | }; 65 | 66 | } // namespace plugins 67 | } // namespace s2e 68 | 69 | #endif // S2E_PLUGINS_TBTRACER_H 70 | -------------------------------------------------------------------------------- /src/s2e/Plugins/ExecutionTracers/UserSpaceTracer.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2014-2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_UserSpaceTracer_H 10 | #define S2E_PLUGINS_UserSpaceTracer_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace s2e { 23 | namespace plugins { 24 | 25 | class UserSpaceTracer : public Plugin { 26 | S2E_PLUGIN 27 | public: 28 | UserSpaceTracer(S2E *s2e) : Plugin(s2e) { 29 | } 30 | 31 | void initialize(); 32 | 33 | void startTracing(S2EExecutionState *state, uint64_t pid = -1); 34 | 35 | private: 36 | OSMonitor *m_monitor; 37 | WindowsMonitor *m_winmonitor; 38 | MemoryTracer *m_memoryTracer; 39 | TranslationBlockTracer *m_tbTracer; 40 | ExecutionTracer *m_tracer; 41 | 42 | // XXX: must be per-state eventually 43 | llvm::SmallVector p_pidsToTrace; 44 | bool m_tracing; 45 | 46 | sigc::connection m_privConnection; 47 | sigc::connection m_tbConnection; 48 | 49 | bool m_traceExecution; 50 | bool m_traceTranslation; 51 | 52 | void onMonitorLoad(S2EExecutionState *state); 53 | void onModuleLoad(S2EExecutionState *state, const ModuleDescriptor &module); 54 | void onProcessUnload(S2EExecutionState *state, uint64_t pageDir, uint64_t pid, uint64_t returnCode); 55 | 56 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 57 | 58 | inline uint64_t getCurrentPid(S2EExecutionState *state) { 59 | if (m_winmonitor) { 60 | return m_winmonitor->getCurrentProcessId(state); 61 | } 62 | return state->regs()->getPageDir(); 63 | } 64 | 65 | bool isTraced(uint64_t as); 66 | 67 | void trace(S2EExecutionState *state, uint64_t startPc, uint64_t endPc, 68 | uint32_t type /* s2e_trace::PbTraceItemHeaderType */, TranslationBlock *tb); 69 | 70 | void onTranslateBlockComplete(S2EExecutionState *state, TranslationBlock *tb, uint64_t endPc); 71 | 72 | void onAccessFault(S2EExecutionState *state, const S2E_WINMON2_ACCESS_FAULT &AccessFault); 73 | 74 | void onExecuteBlockStart(S2EExecutionState *state, uint64_t pc); 75 | 76 | void onPrivilegeChange(S2EExecutionState *state, unsigned previous, unsigned current); 77 | }; 78 | 79 | } // namespace plugins 80 | } // namespace s2e 81 | 82 | #endif // S2E_PLUGINS_UserSpaceTracer_H 83 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaBindings.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | #include "LuaBindings.h" 12 | #include "LuaExpression.h" 13 | #include "LuaFunctionInstrumentationState.h" 14 | #include "LuaInstructionInstrumentationState.h" 15 | #include "LuaInstrumentationState.h" 16 | #include "LuaModuleDescriptor.h" 17 | #include "LuaS2E.h" 18 | #include "LuaS2EExecutionState.h" 19 | #include "LuaS2EExecutionStateMemory.h" 20 | #include "LuaS2EExecutionStateRegisters.h" 21 | 22 | namespace s2e { 23 | namespace plugins { 24 | 25 | S2E_DEFINE_PLUGIN(LuaBindings, "S2E interface for Lua instrumentation", "LuaBindings", ); 26 | 27 | void LuaBindings::initialize() { 28 | lua_State *L = s2e()->getConfig()->getState(); 29 | Lunar::Register(L); 30 | Lunar::Register(L); 31 | 32 | m_luaS2E = new LuaS2E(L); 33 | Lunar::push(L, m_luaS2E); 34 | lua_setglobal(L, "g_s2e"); 35 | 36 | Lunar::Register(L); 37 | Lunar::Register(L); 38 | Lunar::Register(L); 39 | Lunar::Register(L); 40 | Lunar::Register(L); 41 | Lunar::Register(L); 42 | Lunar::Register(L); 43 | } 44 | 45 | } // namespace plugins 46 | } // namespace s2e 47 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaBindings.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_LUABINDINGS_H 9 | #define S2E_PLUGINS_LUABINDINGS_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "LuaS2E.h" 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | /** 21 | * This plugin acts as a centralized registry for all Lua bindings. 22 | */ 23 | class LuaBindings : public Plugin { 24 | S2E_PLUGIN 25 | 26 | private: 27 | LuaS2E *m_luaS2E; 28 | 29 | public: 30 | LuaBindings(S2E *s2e) : Plugin(s2e) { 31 | } 32 | 33 | void initialize(); 34 | }; 35 | 36 | } // namespace plugins 37 | } // namespace s2e 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaCoreEvents.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "LuaCoreEvents.h" 15 | #include "LuaInstrumentationState.h" 16 | #include "LuaS2EExecutionState.h" 17 | 18 | namespace s2e { 19 | namespace plugins { 20 | 21 | S2E_DEFINE_PLUGIN(LuaCoreEvents, "Exposes core events to lua scripts", "", "LuaBindings"); 22 | 23 | void LuaCoreEvents::initialize() { 24 | getInfoStream() << "Registering instrumentation for core signals\n"; 25 | registerCoreSignals(getConfigKey()); 26 | } 27 | 28 | std::string LuaCoreEvents::checkCoreSignal(const std::string &cfgname, const std::string &name) { 29 | ConfigFile *cfg = s2e()->getConfig(); 30 | std::stringstream ss; 31 | ss << cfgname << "." << name; 32 | std::string ret = cfg->getString(ss.str()); 33 | if (ret.length() > 0) { 34 | if (!cfg->isFunctionDefined(ret)) { 35 | getWarningsStream() << ret << " is not declared in the Lua script\n"; 36 | exit(-1); 37 | } 38 | 39 | getDebugStream() << "Registering " << name << "(" << ret << ")\n"; 40 | } 41 | return ret; 42 | } 43 | 44 | void LuaCoreEvents::registerCoreSignals(const std::string &cfgname) { 45 | m_onStateForkDecide = checkCoreSignal(cfgname, "onStateForkDecide"); 46 | if (m_onStateForkDecide.length() > 0) { 47 | s2e()->getCorePlugin()->onStateForkDecide.connect(sigc::mem_fun(*this, &LuaCoreEvents::onStateForkDecide)); 48 | } 49 | 50 | m_onStateKill = checkCoreSignal(cfgname, "onStateKill"); 51 | if (m_onStateKill.length() > 0) { 52 | s2e()->getCorePlugin()->onStateKill.connect(sigc::mem_fun(*this, &LuaCoreEvents::onStateKill)); 53 | } 54 | 55 | m_onTimer = checkCoreSignal(cfgname, "onTimer"); 56 | if (m_onTimer.length() > 0) { 57 | s2e()->getCorePlugin()->onTimer.connect(sigc::mem_fun(*this, &LuaCoreEvents::onTimer)); 58 | } 59 | } 60 | 61 | void LuaCoreEvents::onStateForkDecide(S2EExecutionState *state, bool *allowForking) { 62 | lua_State *L = s2e()->getConfig()->getState(); 63 | LuaS2EExecutionState luaS2EState(state); 64 | LuaInstrumentationState luaInstrumentation; 65 | 66 | lua_getglobal(L, m_onStateForkDecide.c_str()); 67 | Lunar::push(L, &luaS2EState); 68 | Lunar::push(L, &luaInstrumentation); 69 | 70 | lua_call(L, 2, 1); 71 | *allowForking = lua_toboolean(L, -1) != 0; 72 | lua_pop(L, 1); 73 | 74 | if (!*allowForking) { 75 | s2e()->getInfoStream() << "instrumentation prevented forking at pc=" << hexval(state->regs()->getPc()) << "\n"; 76 | } 77 | } 78 | 79 | void LuaCoreEvents::onStateKill(S2EExecutionState *state) { 80 | lua_State *L = s2e()->getConfig()->getState(); 81 | LuaS2EExecutionState luaS2EState(state); 82 | LuaInstrumentationState luaInstrumentation; 83 | 84 | lua_getglobal(L, m_onStateKill.c_str()); 85 | Lunar::push(L, &luaS2EState); 86 | Lunar::push(L, &luaInstrumentation); 87 | 88 | lua_call(L, 2, 0); 89 | 90 | if (luaInstrumentation.exitCpuLoop()) { 91 | throw CpuExitException(); 92 | } 93 | } 94 | 95 | void LuaCoreEvents::onTimer() { 96 | lua_State *L = s2e()->getConfig()->getState(); 97 | LuaInstrumentationState luaInstrumentation; 98 | 99 | lua_getglobal(L, m_onTimer.c_str()); 100 | Lunar::push(L, &luaInstrumentation); 101 | 102 | lua_call(L, 1, 0); 103 | 104 | if (luaInstrumentation.exitCpuLoop()) { 105 | throw CpuExitException(); 106 | } 107 | } 108 | 109 | } // namespace plugins 110 | } // namespace s2e 111 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaCoreEvents.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_LuaCoreEvents_H 9 | #define S2E_PLUGINS_LuaCoreEvents_H 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "Lua.h" 18 | 19 | namespace s2e { 20 | namespace plugins { 21 | 22 | class LuaCoreEvents : public Plugin { 23 | S2E_PLUGIN 24 | public: 25 | LuaCoreEvents(S2E *s2e) : Plugin(s2e) { 26 | } 27 | 28 | void initialize(); 29 | 30 | private: 31 | std::string m_onStateKill; 32 | std::string m_onTimer; 33 | std::string m_onStateForkDecide; 34 | 35 | void registerCoreSignals(const std::string &cfgname); 36 | std::string checkCoreSignal(const std::string &cfgname, const std::string &name); 37 | 38 | void onTimer(); 39 | void onStateKill(S2EExecutionState *state); 40 | void onStateForkDecide(S2EExecutionState *state, bool *allowForking); 41 | }; 42 | 43 | } // namespace plugins 44 | } // namespace s2e 45 | 46 | #endif // S2E_PLUGINS_LuaCoreEvents_H 47 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaExpression.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include "LuaExpression.h" 9 | 10 | namespace s2e { 11 | namespace plugins { 12 | 13 | const char LuaExpression::className[] = "LuaExpression"; 14 | 15 | Lunar::RegType LuaExpression::methods[] = {{0, 0}}; 16 | 17 | } // namespace plugins 18 | } // namespace s2e 19 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaExpression.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_EXPRESSION_ 9 | #define _LUA_S2E_EXPRESSION_ 10 | 11 | #include 12 | 13 | #include "Lua.h" 14 | 15 | namespace s2e { 16 | namespace plugins { 17 | 18 | class LuaExpression { 19 | private: 20 | klee::ref m_expr; 21 | 22 | public: 23 | static const char className[]; 24 | static Lunar::RegType methods[]; 25 | 26 | LuaExpression(lua_State *L) : m_expr(nullptr) { 27 | } 28 | 29 | LuaExpression(klee::ref expr) : m_expr(expr) { 30 | } 31 | 32 | klee::ref get() const { 33 | return m_expr; 34 | } 35 | }; 36 | 37 | } // namespace plugins 38 | } // namespace s2e 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaFunctionInstrumentation.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_LuaFunctionInstrumentation_H 9 | #define S2E_PLUGINS_LuaFunctionInstrumentation_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace s2e { 16 | 17 | class S2EExecutionState; 18 | 19 | namespace plugins { 20 | 21 | class FunctionMonitor; 22 | class FunctionMonitorState; 23 | class KeyValueStore; 24 | class ModuleExecutionDetector; 25 | class OSMonitor; 26 | class ModuleMap; 27 | class ProcessExecutionDetector; 28 | 29 | class LuaFunctionInstrumentation : public Plugin { 30 | S2E_PLUGIN 31 | 32 | public: 33 | LuaFunctionInstrumentation(S2E *s2e) : Plugin(s2e) { 34 | } 35 | 36 | void initialize(); 37 | 38 | private: 39 | struct Instrumentation { 40 | enum CallingConvention { STDCALL, CDECL, MAX_CONV }; 41 | 42 | const std::string moduleName; 43 | const uint64_t pc; 44 | const unsigned paramCount; 45 | const std::string instrumentationName; 46 | const CallingConvention convention; 47 | const bool fork; 48 | 49 | Instrumentation(const std::string &moduleName, uint64_t pc_, unsigned pCount, const std::string &name, 50 | CallingConvention cc, bool fork_) 51 | : moduleName(moduleName), pc(pc_), paramCount(pCount), instrumentationName(name), convention(cc), 52 | fork(fork_) { 53 | } 54 | 55 | bool operator==(const Instrumentation &a1) const { 56 | return moduleName == a1.moduleName && pc == a1.pc && paramCount == a1.paramCount && 57 | instrumentationName == a1.instrumentationName && convention == a1.convention; 58 | } 59 | }; 60 | 61 | using InstrumentationPtr = std::shared_ptr; 62 | 63 | typedef std::vector Instrumentations; 64 | Instrumentations m_instrumentations; 65 | 66 | FunctionMonitor *m_functionMonitor; 67 | KeyValueStore *m_kvs; 68 | 69 | bool registerInstrumentation(const Instrumentation &instrumentation); 70 | void invokeInstrumentation(S2EExecutionState *state, const Instrumentation &entry, bool isCall); 71 | void forkInstrumentation(S2EExecutionState *state, const Instrumentation &entry); 72 | 73 | void onCall(S2EExecutionState *state, const ModuleDescriptorConstPtr &source, const ModuleDescriptorConstPtr &dest, 74 | uint64_t callerPc, uint64_t calleePc, const FunctionMonitor::ReturnSignalPtr &returnSignal); 75 | 76 | void onRet(S2EExecutionState *state, const ModuleDescriptorConstPtr &source, const ModuleDescriptorConstPtr &dest, 77 | uint64_t returnSite, InstrumentationPtr instrumentation); 78 | }; 79 | 80 | } // namespace plugins 81 | } // namespace s2e 82 | 83 | #endif // S2E_PLUGINS_LuaFunctionInstrumentation_H 84 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaFunctionInstrumentationState.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | 10 | #include "LuaFunctionInstrumentationState.h" 11 | 12 | namespace s2e { 13 | namespace plugins { 14 | 15 | const char LuaFunctionInstrumentationState::className[] = "LuaFunctionInstrumentationState"; 16 | 17 | Lunar::RegType LuaFunctionInstrumentationState::methods[] = { 18 | LUNAR_DECLARE_METHOD(LuaFunctionInstrumentationState, skipFunction), 19 | LUNAR_DECLARE_METHOD(LuaFunctionInstrumentationState, isChild), 20 | {0, 0}}; 21 | 22 | int LuaFunctionInstrumentationState::isChild(lua_State *L) { 23 | lua_pushboolean(L, m_child); 24 | return 1; 25 | } 26 | 27 | int LuaFunctionInstrumentationState::skipFunction(lua_State *L) { 28 | if (lua_gettop(L) < 1) { 29 | m_skip = true; 30 | } else { 31 | m_skip = lua_toboolean(L, 1); 32 | } 33 | g_s2e->getDebugStream() << "skipFunction " << m_skip << '\n'; 34 | return 0; 35 | } 36 | } // namespace plugins 37 | } // namespace s2e 38 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaFunctionInstrumentationState.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_FUNCTION_ANNOTATION_STATE_ 9 | 10 | #define _LUA_S2E_FUNCTION_ANNOTATION_STATE_ 11 | 12 | #include "Lua.h" 13 | #include "LuaInstrumentationState.h" 14 | 15 | namespace s2e { 16 | namespace plugins { 17 | 18 | class LuaFunctionInstrumentationState : public LuaInstrumentationState { 19 | private: 20 | bool m_child; 21 | bool m_skip; 22 | 23 | public: 24 | static const char className[]; 25 | static Lunar::RegType methods[]; 26 | LuaFunctionInstrumentationState(lua_State *L) : LuaInstrumentationState(L) { 27 | } 28 | 29 | LuaFunctionInstrumentationState() : LuaInstrumentationState(), m_child(false), m_skip(false) { 30 | } 31 | 32 | void setChild(bool c) { 33 | m_child = c; 34 | } 35 | 36 | bool doSkip() const { 37 | return m_skip; 38 | } 39 | 40 | int skipFunction(lua_State *L); 41 | int isChild(lua_State *L); 42 | }; 43 | } // namespace plugins 44 | } // namespace s2e 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaInstructionInstrumentation.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_LuaInstructionInstrumentation_H 9 | #define S2E_PLUGINS_LuaInstructionInstrumentation_H 10 | 11 | #include 12 | #include 13 | 14 | namespace s2e { 15 | 16 | class S2EExecutionState; 17 | 18 | namespace plugins { 19 | 20 | class ModuleMap; 21 | class ProcessExecutionDetector; 22 | 23 | class LuaInstructionInstrumentation : public Plugin { 24 | S2E_PLUGIN 25 | 26 | public: 27 | LuaInstructionInstrumentation(S2E *s2e) : Plugin(s2e) { 28 | } 29 | 30 | void initialize(); 31 | 32 | private: 33 | struct Instrumentation { 34 | const std::string instrumentationName; 35 | const uint64_t pc; 36 | 37 | Instrumentation(std::string name, uint64_t pc_) : instrumentationName(name), pc(pc_) { 38 | } 39 | 40 | Instrumentation(uint64_t pc_) : Instrumentation("", pc_) { 41 | } 42 | 43 | bool operator==(const Instrumentation &a1) const { 44 | return pc == a1.pc && instrumentationName == a1.instrumentationName; 45 | } 46 | 47 | bool operator<(const Instrumentation &a1) const { 48 | return pc < a1.pc; 49 | } 50 | }; 51 | 52 | typedef std::set Moduleinstrumentation; 53 | typedef std::map InstrumentationMap; 54 | InstrumentationMap m_instrumentation; 55 | 56 | ProcessExecutionDetector *m_detector; 57 | ModuleMap *m_modules; 58 | sigc::connection m_instructionStart; 59 | 60 | bool registerInstrumentation(const std::string &moduleId, const Instrumentation &instrumentation); 61 | 62 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 63 | 64 | void onTranslateInstructionStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, 65 | uint64_t pc, const Moduleinstrumentation *instrumentation, uint64_t addend); 66 | 67 | void onTranslateBlockComplete(S2EExecutionState *state, TranslationBlock *tb, uint64_t ending_pc); 68 | 69 | void onInstruction(S2EExecutionState *state, uint64_t pc, const Moduleinstrumentation *instrumentation, 70 | uint64_t modulePc); 71 | 72 | void onMonitorLoad(S2EExecutionState *state); 73 | }; 74 | 75 | } // namespace plugins 76 | } // namespace s2e 77 | 78 | #endif // S2E_PLUGINS_LuaInstructionInstrumentation_H 79 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaInstructionInstrumentationState.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | 10 | #include "LuaInstructionInstrumentationState.h" 11 | 12 | namespace s2e { 13 | namespace plugins { 14 | 15 | const char LuaInstructionInstrumentationState::className[] = "LuaInstructionInstrumentationState"; 16 | 17 | Lunar::RegType LuaInstructionInstrumentationState::methods[] = { 18 | LUNAR_DECLARE_METHOD(LuaInstructionInstrumentationState, skipInstruction), 19 | LUNAR_DECLARE_METHOD(LuaInstructionInstrumentationState, setExitCpuLoop), 20 | {0, 0}}; 21 | 22 | int LuaInstructionInstrumentationState::skipInstruction(lua_State *L) { 23 | if (lua_gettop(L) < 1) { 24 | m_skip = true; 25 | } else { 26 | m_skip = lua_toboolean(L, 1); 27 | } 28 | g_s2e->getDebugStream() << "skipInstruction " << m_skip << '\n'; 29 | return 0; 30 | } 31 | } // namespace plugins 32 | } // namespace s2e 33 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaInstructionInstrumentationState.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_INSTRUCTION_ANNOTATION_STATE_ 9 | 10 | #define _LUA_S2E_INSTRUCTION_ANNOTATION_STATE_ 11 | 12 | #include "Lua.h" 13 | #include "LuaInstrumentationState.h" 14 | 15 | namespace s2e { 16 | namespace plugins { 17 | 18 | class LuaInstructionInstrumentationState : public LuaInstrumentationState { 19 | private: 20 | bool m_skip; 21 | 22 | public: 23 | static const char className[]; 24 | static Lunar::RegType methods[]; 25 | LuaInstructionInstrumentationState(lua_State *L) : LuaInstrumentationState(L) { 26 | } 27 | 28 | LuaInstructionInstrumentationState() : LuaInstrumentationState(), m_skip(false) { 29 | } 30 | 31 | bool doSkip() const { 32 | return m_skip; 33 | } 34 | 35 | int skipInstruction(lua_State *L); 36 | }; 37 | } // namespace plugins 38 | } // namespace s2e 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaInstrumentationState.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | #include "LuaInstrumentationState.h" 12 | 13 | namespace s2e { 14 | namespace plugins { 15 | 16 | const char LuaInstrumentationState::className[] = "LuaInstrumentationState"; 17 | 18 | Lunar::RegType LuaInstrumentationState::methods[] = { 19 | LUNAR_DECLARE_METHOD(LuaInstrumentationState, setExitCpuLoop), {0, 0}}; 20 | 21 | int LuaInstrumentationState::setExitCpuLoop(lua_State *L) { 22 | g_s2e->getDebugStream() << "requested to exit cpu loop\n"; 23 | m_exitCpuLoop = true; 24 | return 0; 25 | } 26 | } // namespace plugins 27 | } // namespace s2e 28 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaInstrumentationState.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_ANNOTATION_STATE_ 9 | 10 | #define _LUA_S2E_ANNOTATION_STATE_ 11 | 12 | #include "Lua.h" 13 | 14 | namespace s2e { 15 | namespace plugins { 16 | 17 | class LuaInstrumentationState { 18 | private: 19 | bool m_exitCpuLoop; 20 | 21 | public: 22 | static const char className[]; 23 | static Lunar::RegType methods[]; 24 | 25 | LuaInstrumentationState(lua_State *L) : LuaInstrumentationState() { 26 | } 27 | 28 | LuaInstrumentationState() : m_exitCpuLoop(false) { 29 | } 30 | 31 | bool exitCpuLoop() const { 32 | return m_exitCpuLoop; 33 | } 34 | 35 | int setExitCpuLoop(lua_State *L); 36 | }; 37 | } // namespace plugins 38 | } // namespace s2e 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaModuleDescriptor.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include "LuaModuleDescriptor.h" 9 | 10 | namespace s2e { 11 | namespace plugins { 12 | 13 | const char LuaModuleDescriptor::className[] = "LuaModuleDescriptor"; 14 | 15 | Lunar::RegType LuaModuleDescriptor::methods[] = { 16 | LUNAR_DECLARE_METHOD(LuaModuleDescriptor, getPid), 17 | LUNAR_DECLARE_METHOD(LuaModuleDescriptor, getName), 18 | LUNAR_DECLARE_METHOD(LuaModuleDescriptor, getNativeBase), 19 | LUNAR_DECLARE_METHOD(LuaModuleDescriptor, getLoadBase), 20 | LUNAR_DECLARE_METHOD(LuaModuleDescriptor, getSize), 21 | LUNAR_DECLARE_METHOD(LuaModuleDescriptor, getEntryPoint), 22 | {0, 0}}; 23 | 24 | int LuaModuleDescriptor::getPid(lua_State *L) { 25 | lua_pushinteger(L, m_desc->Pid); 26 | return 1; 27 | } 28 | 29 | int LuaModuleDescriptor::getName(lua_State *L) { 30 | lua_pushstring(L, m_desc->Name.c_str()); 31 | return 1; 32 | } 33 | 34 | int LuaModuleDescriptor::getNativeBase(lua_State *L) { 35 | lua_pushinteger(L, m_desc->NativeBase); 36 | return 1; 37 | } 38 | 39 | int LuaModuleDescriptor::getLoadBase(lua_State *L) { 40 | lua_pushinteger(L, m_desc->LoadBase); 41 | return 1; 42 | } 43 | 44 | int LuaModuleDescriptor::getSize(lua_State *L) { 45 | lua_pushinteger(L, m_desc->Size); 46 | return 1; 47 | } 48 | 49 | int LuaModuleDescriptor::getEntryPoint(lua_State *L) { 50 | lua_pushinteger(L, m_desc->EntryPoint); 51 | return 1; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaModuleDescriptor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_MODULE_DESCRIPTOR_ 9 | 10 | #define _LUA_MODULE_DESCRIPTOR_ 11 | 12 | #include 13 | #include "Lua.h" 14 | 15 | namespace s2e { 16 | namespace plugins { 17 | 18 | class LuaModuleDescriptor { 19 | private: 20 | ModuleDescriptorConstPtr m_desc; 21 | 22 | public: 23 | static const char className[]; 24 | static Lunar::RegType methods[]; 25 | 26 | LuaModuleDescriptor(lua_State *L) { 27 | } 28 | 29 | LuaModuleDescriptor(ModuleDescriptorConstPtr desc) { 30 | m_desc = desc; 31 | } 32 | 33 | int getPid(lua_State *L); 34 | int getName(lua_State *L); 35 | int getNativeBase(lua_State *L); 36 | int getLoadBase(lua_State *L); 37 | int getSize(lua_State *L); 38 | int getEntryPoint(lua_State *L); 39 | }; 40 | } 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaPlugin.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2018, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_PLUGIN_INTERFACE_ 9 | #define _LUA_S2E_PLUGIN_INTERFACE_ 10 | 11 | #include "Lua.h" 12 | 13 | namespace s2e { 14 | namespace plugins { 15 | 16 | class ILuaPlugin { 17 | public: 18 | virtual int getLuaPlugin(lua_State *L) = 0; 19 | }; 20 | 21 | } // namespace plugins 22 | } // namespace s2e 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaS2E.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2014-2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "LuaPlugin.h" 14 | #include "LuaS2E.h" 15 | 16 | namespace s2e { 17 | namespace plugins { 18 | 19 | const char LuaS2E::className[] = "LuaS2E"; 20 | 21 | // clang-format off 22 | Lunar::RegType LuaS2E::methods[] = { 23 | LUNAR_DECLARE_METHOD(LuaS2E, debug), 24 | LUNAR_DECLARE_METHOD(LuaS2E, info), 25 | LUNAR_DECLARE_METHOD(LuaS2E, warning), 26 | LUNAR_DECLARE_METHOD(LuaS2E, exit), 27 | LUNAR_DECLARE_METHOD(LuaS2E, getPlugin), 28 | {0, 0} 29 | }; 30 | // clang-format on 31 | 32 | int LuaS2E::getPlugin(lua_State *L) { 33 | const char *str = lua_tostring(L, 1); 34 | auto plugin = g_s2e->getPlugin(str); 35 | if (!plugin) { 36 | g_s2e->getWarningsStream() << "LuaS2E: could not get plugin " << str << "\n"; 37 | return 0; 38 | } 39 | 40 | ILuaPlugin *luaPlg = dynamic_cast(plugin); 41 | if (!luaPlg) { 42 | g_s2e->getWarningsStream() << "LuaS2E: plugin " << str << " does not implement ILuaPlugin\n"; 43 | return 0; 44 | } 45 | 46 | return luaPlg->getLuaPlugin(L); 47 | } 48 | 49 | int LuaS2E::debug(lua_State *L) { 50 | const char *str = lua_tostring(L, 1); 51 | g_s2e->getDebugStream(g_s2e_state) << str << "\n"; 52 | return 0; 53 | } 54 | 55 | int LuaS2E::info(lua_State *L) { 56 | const char *str = lua_tostring(L, 1); 57 | g_s2e->getInfoStream(g_s2e_state) << str << "\n"; 58 | return 0; 59 | } 60 | 61 | int LuaS2E::warning(lua_State *L) { 62 | const char *str = lua_tostring(L, 1); 63 | g_s2e->getWarningsStream(g_s2e_state) << str << "\n"; 64 | return 0; 65 | } 66 | 67 | int LuaS2E::exit(lua_State *L) { 68 | long returnCode = (long) luaL_checkinteger(L, 1); 69 | 70 | g_s2e->getInfoStream(g_s2e_state) << "Lua instrumentation requested S2E exit\n"; 71 | 72 | ::exit(returnCode); 73 | return 0; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaS2E.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_BINDINGS_ 9 | #define _LUA_S2E_BINDINGS_ 10 | 11 | #include "Lua.h" 12 | 13 | namespace s2e { 14 | namespace plugins { 15 | 16 | class LuaS2E { 17 | public: 18 | static const char className[]; 19 | static Lunar::RegType methods[]; 20 | 21 | LuaS2E(lua_State *L) { 22 | } 23 | 24 | /* Get an instance to a plugin */ 25 | int getPlugin(lua_State *L); 26 | 27 | /* Print a debug string */ 28 | int debug(lua_State *L); 29 | 30 | /* Print a message */ 31 | int info(lua_State *L); 32 | 33 | /* Print a warning */ 34 | int warning(lua_State *L); 35 | 36 | /* Exit S2E */ 37 | int exit(lua_State *L); 38 | }; 39 | 40 | } // namespace plugins 41 | } // namespace s2e 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaS2EExecutionState.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | #include "LuaExpression.h" 12 | #include "LuaS2EExecutionState.h" 13 | #include "LuaS2EExecutionStateMemory.h" 14 | #include "LuaS2EExecutionStateRegisters.h" 15 | 16 | namespace s2e { 17 | namespace plugins { 18 | 19 | const char LuaS2EExecutionState::className[] = "LuaS2EExecutionState"; 20 | 21 | Lunar::RegType LuaS2EExecutionState::methods[] = { 22 | LUNAR_DECLARE_METHOD(LuaS2EExecutionState, mem), 23 | LUNAR_DECLARE_METHOD(LuaS2EExecutionState, regs), 24 | LUNAR_DECLARE_METHOD(LuaS2EExecutionState, createSymbolicValue), 25 | LUNAR_DECLARE_METHOD(LuaS2EExecutionState, kill), 26 | LUNAR_DECLARE_METHOD(LuaS2EExecutionState, setPluginProperty), 27 | LUNAR_DECLARE_METHOD(LuaS2EExecutionState, getPluginProperty), 28 | LUNAR_DECLARE_METHOD(LuaS2EExecutionState, debug), 29 | LUNAR_DECLARE_METHOD(LuaS2EExecutionState, getPointerSize), 30 | {0, 0}}; 31 | 32 | int LuaS2EExecutionState::mem(lua_State *L) { 33 | Lunar::push(L, &m_memory); 34 | return 1; 35 | } 36 | 37 | int LuaS2EExecutionState::regs(lua_State *L) { 38 | Lunar::push(L, &m_registers); 39 | return 1; 40 | } 41 | 42 | int LuaS2EExecutionState::getPointerSize(lua_State *L) { 43 | lua_pushinteger(L, m_state->getPointerSize()); 44 | return 1; 45 | } 46 | 47 | int LuaS2EExecutionState::createSymbolicValue(lua_State *L) { 48 | std::string name = luaL_checkstring(L, 1); 49 | long size = (long) luaL_checkinteger(L, 2); 50 | 51 | assert(size <= 8); 52 | 53 | std::vector buffer(size); 54 | for (unsigned i = 0; i < size; ++i) { 55 | buffer[i] = 0; 56 | } 57 | 58 | klee::ref value = m_state->createSymbolicValue(name, size * 8, buffer); 59 | g_s2e->getDebugStream(m_state) << "LuaS2EExecutionState: " << value << "\n"; 60 | 61 | // lua will manage the LuaExpression** ptr 62 | LuaExpression **c = static_cast(lua_newuserdata(L, sizeof(LuaExpression *))); 63 | *c = new LuaExpression(value); // we manage this 64 | luaL_getmetatable(L, "LuaExpression"); 65 | lua_setmetatable(L, -2); 66 | return 1; 67 | } 68 | 69 | int LuaS2EExecutionState::kill(lua_State *L) { 70 | long status = (long) luaL_checkinteger(L, 1); 71 | std::string message = luaL_checkstring(L, 2); 72 | 73 | std::stringstream ss; 74 | ss << "LuaS2EExecutionState: killed status:" << status << " message:" << message; 75 | g_s2e->getExecutor()->terminateState(*m_state, ss.str()); 76 | 77 | return 0; 78 | } 79 | 80 | int LuaS2EExecutionState::getPluginProperty(lua_State *L) { 81 | std::string pluginName = luaL_checkstring(L, 1); 82 | std::string property = luaL_checkstring(L, 2); 83 | std::string value; 84 | 85 | Plugin *plugin = g_s2e->getPlugin(pluginName); 86 | if (!plugin) { 87 | g_s2e->getWarningsStream(m_state) << "BaseInstructions plugin not loaded\n"; 88 | goto err; 89 | } 90 | 91 | if (!plugin->getProperty(m_state, property, value)) { 92 | goto err; 93 | } 94 | 95 | lua_pushstring(L, value.c_str()); 96 | 97 | return 1; 98 | 99 | err: 100 | return 0; 101 | } 102 | 103 | int LuaS2EExecutionState::setPluginProperty(lua_State *L) { 104 | std::string pluginName = luaL_checkstring(L, 1); 105 | std::string property = luaL_checkstring(L, 2); 106 | std::string value = luaL_checkstring(L, 3); 107 | bool ret = false; 108 | Plugin *plugin = g_s2e->getPlugin(pluginName); 109 | if (!plugin) { 110 | g_s2e->getWarningsStream(m_state) << "BaseInstructions plugin not loaded\n"; 111 | goto err; 112 | } 113 | 114 | ret = plugin->setProperty(m_state, property, value); 115 | 116 | err: 117 | lua_pushboolean(L, ret); 118 | return 1; 119 | } 120 | 121 | int LuaS2EExecutionState::debug(lua_State *L) { 122 | std::string str = luaL_checkstring(L, 1); 123 | char c = 0; 124 | 125 | if (str[str.length() - 1] != '\n') { 126 | c = '\n'; 127 | } 128 | 129 | g_s2e->getDebugStream(m_state) << str << c; 130 | 131 | return 0; 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaS2EExecutionState.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_EXECUTION_STATE_ 9 | 10 | #define _LUA_S2E_EXECUTION_STATE_ 11 | 12 | #include 13 | #include "Lua.h" 14 | #include "LuaS2EExecutionStateMemory.h" 15 | #include "LuaS2EExecutionStateRegisters.h" 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | class LuaS2EExecutionState { 21 | private: 22 | S2EExecutionState *m_state; 23 | LuaS2EExecutionStateMemory m_memory; 24 | LuaS2EExecutionStateRegisters m_registers; 25 | 26 | public: 27 | static const char className[]; 28 | static Lunar::RegType methods[]; 29 | 30 | LuaS2EExecutionState(lua_State *L) 31 | : m_state(nullptr), m_memory((S2EExecutionState *) nullptr), m_registers((S2EExecutionState *) nullptr) { 32 | } 33 | 34 | LuaS2EExecutionState(S2EExecutionState *state) : m_state(state), m_memory(state), m_registers(state) { 35 | } 36 | 37 | S2EExecutionState *getState() const { 38 | return m_state; 39 | } 40 | 41 | int mem(lua_State *L); 42 | int regs(lua_State *L); 43 | int getPointerSize(lua_State *L); 44 | int createSymbolicValue(lua_State *L); 45 | int kill(lua_State *L); 46 | int setPluginProperty(lua_State *L); 47 | int getPluginProperty(lua_State *L); 48 | int debug(lua_State *L); 49 | }; 50 | } 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaS2EExecutionStateMemory.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_EXECUTION_STATE_MEMORY_ 9 | #define _LUA_S2E_EXECUTION_STATE_MEMORY_ 10 | 11 | #include "Lua.h" 12 | 13 | namespace s2e { 14 | 15 | class S2EExecutionState; 16 | 17 | namespace plugins { 18 | 19 | class LuaS2EExecutionStateMemory { 20 | private: 21 | S2EExecutionState *m_state; 22 | 23 | public: 24 | static const char className[]; 25 | static Lunar::RegType methods[]; 26 | 27 | LuaS2EExecutionStateMemory(lua_State *L) : m_state(nullptr) { 28 | } 29 | 30 | LuaS2EExecutionStateMemory(S2EExecutionState *state) : m_state(state) { 31 | } 32 | 33 | int readPointer(lua_State *L); 34 | int readBytes(lua_State *L); 35 | int write(lua_State *L); 36 | 37 | int makeSymbolic(lua_State *L); 38 | }; 39 | 40 | } // namespace plugins 41 | } // namespace s2e 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaS2EExecutionStateRegisters.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include "LuaS2EExecutionStateRegisters.h" 9 | #include 10 | #include 11 | #include "LuaExpression.h" 12 | 13 | namespace s2e { 14 | namespace plugins { 15 | 16 | const char LuaS2EExecutionStateRegisters::className[] = "LuaS2EExecutionStateRegisters"; 17 | 18 | Lunar::RegType LuaS2EExecutionStateRegisters::methods[] = { 19 | LUNAR_DECLARE_METHOD(LuaS2EExecutionStateRegisters, getPc), 20 | LUNAR_DECLARE_METHOD(LuaS2EExecutionStateRegisters, getSp), 21 | LUNAR_DECLARE_METHOD(LuaS2EExecutionStateRegisters, write), 22 | LUNAR_DECLARE_METHOD(LuaS2EExecutionStateRegisters, read), 23 | {0, 0}}; 24 | 25 | int LuaS2EExecutionStateRegisters::getPc(lua_State *L) { 26 | lua_pushinteger(L, m_state->regs()->getPc()); 27 | return 1; 28 | } 29 | 30 | int LuaS2EExecutionStateRegisters::getSp(lua_State *L) { 31 | lua_pushinteger(L, m_state->regs()->getSp()); 32 | return 1; 33 | } 34 | 35 | int LuaS2EExecutionStateRegisters::read(lua_State *L) { 36 | long offset = (long) luaL_checkinteger(L, 1); 37 | long size = (long) luaL_checkinteger(L, 2); 38 | RegReadFlags flags = CONCRETE; 39 | 40 | if (lua_gettop(L) == 3) { 41 | flags = (RegReadFlags) luaL_checkinteger(L, 3); 42 | } 43 | 44 | uint64_t value = 0; 45 | 46 | switch (flags) { 47 | case CONCRETE: 48 | switch (size) { 49 | case 1: 50 | value = m_state->regs()->read(offset); 51 | break; 52 | case 2: 53 | value = m_state->regs()->read(offset); 54 | break; 55 | case 4: 56 | value = m_state->regs()->read(offset); 57 | break; 58 | case 8: 59 | value = m_state->regs()->read(offset); 60 | break; 61 | default: { 62 | std::stringstream ss; 63 | ss << "LuaS2EExecutionStateRegisters::read: Incorrect size " << size << "\n"; 64 | g_s2e->getExecutor()->terminateState(*m_state, ss.str()); 65 | break; 66 | } 67 | } 68 | break; 69 | 70 | case CONCRETE_EXAMPLE: { 71 | auto expr = m_state->regs()->read(offset, size * 8); 72 | value = m_state->concretize(expr, "", true); 73 | } break; 74 | 75 | default: { 76 | std::stringstream ss; 77 | ss << "LuaS2EExecutionStateRegisters::read: Incorrect flags " << flags << "\n"; 78 | g_s2e->getExecutor()->terminateState(*m_state, ss.str()); 79 | } 80 | } 81 | 82 | lua_pushinteger(L, value); 83 | 84 | return 1; 85 | } 86 | 87 | int LuaS2EExecutionStateRegisters::write(lua_State *L) { 88 | long pointer = (long) luaL_checkinteger(L, 1); 89 | 90 | if (lua_isuserdata(L, 2)) { 91 | void *expr = luaL_checkudata(L, 2, "LuaExpression"); 92 | LuaExpression *value = *static_cast(expr); 93 | g_s2e->getDebugStream(m_state) << "Writing " << value->get() << "\n"; 94 | m_state->regs()->write(pointer, value->get()); 95 | } else if (lua_isnumber(L, 2)) { 96 | long value = (long) luaL_checkinteger(L, 2); 97 | long size = (long) luaL_checkinteger(L, 3); 98 | switch (size) { 99 | case 1: 100 | m_state->regs()->write(pointer, value); 101 | break; 102 | case 2: 103 | m_state->regs()->write(pointer, value); 104 | break; 105 | case 4: 106 | m_state->regs()->write(pointer, value); 107 | break; 108 | case 8: 109 | m_state->regs()->write(pointer, value); 110 | break; 111 | default: 112 | g_s2e->getDebugStream(m_state) << "LuaS2EExecutionStateRegisters::write: Incorrect size " << size 113 | << "\n"; 114 | break; 115 | } 116 | } 117 | return 0; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Lua/LuaS2EExecutionStateRegisters.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _LUA_S2E_EXECUTION_STATE_REGISTERS_ 9 | 10 | #define _LUA_S2E_EXECUTION_STATE_REGISTERS_ 11 | 12 | #include 13 | #include "Lua.h" 14 | 15 | namespace s2e { 16 | namespace plugins { 17 | 18 | class LuaS2EExecutionStateRegisters { 19 | private: 20 | S2EExecutionState *m_state; 21 | 22 | enum RegReadFlags { CONCRETE = 0, CONCRETE_EXAMPLE = 1 }; 23 | 24 | public: 25 | static const char className[]; 26 | static Lunar::RegType methods[]; 27 | 28 | LuaS2EExecutionStateRegisters(lua_State *L) : m_state(nullptr) { 29 | } 30 | 31 | LuaS2EExecutionStateRegisters(S2EExecutionState *state) : m_state(state) { 32 | } 33 | 34 | int read(lua_State *L); 35 | int write(lua_State *L); 36 | int getPc(lua_State *L); 37 | int getSp(lua_State *L); 38 | }; 39 | } 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Models/BaseFunctionModels.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2017, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015-2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_BASE_FUNCTION_MODELS_H 10 | #define S2E_PLUGINS_BASE_FUNCTION_MODELS_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace klee; 17 | 18 | namespace s2e { 19 | 20 | class S2E; 21 | class S2EExecutionState; 22 | 23 | namespace plugins { 24 | namespace models { 25 | 26 | /// 27 | /// \brief Abstract base class for modelling functions that commonly result in 28 | /// state explosion 29 | /// 30 | class BaseFunctionModels : public Plugin { 31 | public: 32 | BaseFunctionModels(S2E *s2e) : Plugin(s2e) { 33 | initCRCModels(); 34 | } 35 | 36 | virtual ~BaseFunctionModels() { 37 | } 38 | 39 | private: 40 | void initCRCModels(); 41 | 42 | protected: 43 | MemUtils *m_memutils; 44 | 45 | klee::UpdateListPtr m_crc16_ul; 46 | klee::UpdateListPtr m_crc32_ul; 47 | 48 | ref crc32(const ref &initialCrc, const std::vector> &input, bool xorResult); 49 | ref crc16(const ref &initialCrc, const std::vector> &input); 50 | 51 | bool readArgument(S2EExecutionState *state, unsigned param, uint64_t &arg); 52 | bool findNullChar(S2EExecutionState *state, uint64_t stringAddr, size_t &len); 53 | 54 | bool strlenHelper(S2EExecutionState *state, uint64_t stringAddr, size_t &len, ref &retExpr); 55 | bool strcmpHelper(S2EExecutionState *state, const uint64_t strAddrs[2], ref &retExpr); 56 | bool strncmpHelper(S2EExecutionState *state, const uint64_t strAddrs[2], size_t size, ref &retExpr); 57 | bool strcmpHelperCommon(S2EExecutionState *state, const uint64_t strAddrs[2], uint64_t memSize, ref &retExpr); 58 | bool strcpyHelper(S2EExecutionState *state, const uint64_t strAddrs[2], ref &retExpr); 59 | bool strncpyHelper(S2EExecutionState *state, const uint64_t strAddrs[2], uint64_t numBytes, ref &retExpr); 60 | bool memcmpHelper(S2EExecutionState *state, const uint64_t memAddrs[2], uint64_t numBytes, ref &retExpr); 61 | bool memcpyHelper(S2EExecutionState *state, const uint64_t memAddrs[2], uint64_t numBytes, ref &retExpr); 62 | bool strcatHelper(S2EExecutionState *state, const uint64_t strAddrs[2], ref &retExpr, uint64_t numBytes = 0, 63 | bool isNcat = false); 64 | }; 65 | 66 | } // namespace models 67 | } // namespace plugins 68 | } // namespace s2e 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Models/FunctionModels.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2017, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_FUNCTION_MODELS_H 9 | #define S2E_PLUGINS_FUNCTION_MODELS_H 10 | 11 | #include 12 | 13 | #include "BaseFunctionModels.h" 14 | 15 | struct S2E_LIBCWRAPPER_COMMAND; 16 | 17 | namespace s2e { 18 | 19 | class S2E; 20 | class S2EExecutionState; 21 | 22 | namespace plugins { 23 | namespace models { 24 | 25 | class FunctionModels : public BaseFunctionModels, public IPluginInvoker { 26 | S2E_PLUGIN 27 | 28 | public: 29 | FunctionModels(S2E *s2e) : BaseFunctionModels(s2e) { 30 | } 31 | 32 | void initialize(); 33 | 34 | private: 35 | void handleStrlen(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd, klee::ref &expr); 36 | void handleStrcmp(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd, klee::ref &expr); 37 | void handleStrncmp(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd, klee::ref &expr); 38 | void handleStrcpy(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd); 39 | void handleStrncpy(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd); 40 | void handleMemcpy(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd); 41 | void handleMemcmp(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd, klee::ref &expr); 42 | void handleStrcat(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd); 43 | void handleStrncat(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd); 44 | void handleCrc(S2EExecutionState *state, S2E_LIBCWRAPPER_COMMAND &cmd, ref &ret); 45 | void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 46 | }; 47 | 48 | } // namespace models 49 | } // namespace plugins 50 | } // namespace s2e 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Models/StaticFunctionModels.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015-2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_StaticFunctionModels_H 10 | #define S2E_PLUGINS_StaticFunctionModels_H 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include "BaseFunctionModels.h" 17 | 18 | namespace s2e { 19 | 20 | class S2E; 21 | class S2EExecutionState; 22 | 23 | namespace plugins { 24 | 25 | class ModuleExecutionDetector; 26 | 27 | namespace models { 28 | 29 | class StaticFunctionModels : public BaseFunctionModels { 30 | S2E_PLUGIN 31 | 32 | public: 33 | StaticFunctionModels(S2E *s2e) : BaseFunctionModels(s2e) { 34 | } 35 | 36 | void initialize(); 37 | 38 | /// 39 | /// \brief Returns how many function models are available. 40 | /// 41 | unsigned getFunctionModelCount() const; 42 | 43 | private: 44 | typedef bool (StaticFunctionModels::*OpHandler)(S2EExecutionState *state, uint64_t pc); 45 | typedef llvm::StringMap HandlerMap; 46 | 47 | ModuleExecutionDetector *m_detector; 48 | HandlerMap m_handlers; 49 | 50 | void onModuleTranslateBlockEnd(ExecutionSignal *signal, S2EExecutionState *state, const ModuleDescriptor &module, 51 | TranslationBlock *tb, uint64_t endPc, bool staticTarget, uint64_t targetPc); 52 | 53 | bool getBool(S2EExecutionState *state, const std::string &property); 54 | 55 | bool handleStrlen(S2EExecutionState *state, uint64_t pc); 56 | bool handleStrcmp(S2EExecutionState *state, uint64_t pc); 57 | bool handleStrncmp(S2EExecutionState *state, uint64_t pc); 58 | bool handleStrcpy(S2EExecutionState *state, uint64_t pc); 59 | bool handleStrncpy(S2EExecutionState *state, uint64_t pc); 60 | bool handleMemcpy(S2EExecutionState *state, uint64_t pc); 61 | bool handleMemcmp(S2EExecutionState *state, uint64_t pc); 62 | bool handleStrcat(S2EExecutionState *state, uint64_t pc); 63 | bool handleStrncat(S2EExecutionState *state, uint64_t pc); 64 | bool handleCrc16(S2EExecutionState *state, uint64_t pc); 65 | bool handleCrc32(S2EExecutionState *state, uint64_t pc); 66 | 67 | void onCall(S2EExecutionState *state, uint64_t pc, OpHandler handler); 68 | }; 69 | 70 | } // namespace models 71 | } // namespace plugins 72 | } // namespace s2e 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/Linux/LinuxMonitor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2017, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2014-2017, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_LINUX_MONITOR_H 10 | #define S2E_PLUGINS_LINUX_MONITOR_H 11 | 12 | #include 13 | 14 | #include "BaseLinuxMonitor.h" 15 | 16 | namespace s2e { 17 | namespace plugins { 18 | 19 | template T &operator<<(T &stream, const S2E_LINUXMON_COMMANDS &c) { 20 | switch (c) { 21 | case LINUX_SEGFAULT: 22 | stream << "SEGFAULT"; 23 | break; 24 | case LINUX_PROCESS_LOAD: 25 | stream << "PROCESS_LOAD"; 26 | break; 27 | case LINUX_TRAP: 28 | stream << "TRAP"; 29 | break; 30 | case LINUX_PROCESS_EXIT: 31 | stream << "PROCESS_EXIT"; 32 | break; 33 | default: 34 | stream << "INVALID(" << (int) c << ")"; 35 | break; 36 | } 37 | 38 | return stream; 39 | } 40 | 41 | /// 42 | /// \brief Detects the loading/unloading of modules and various errors on the 43 | /// Linux operating system. 44 | /// 45 | /// This plugin has been specifically developed for a modified version of the 46 | /// Linux 4.9.3 kernel, which can be accessed at 47 | /// https://github.com/S2E/s2e-linux-kernel.git in the linux-4.9.3 branch. 48 | /// 49 | class LinuxMonitor : public BaseLinuxMonitor { 50 | S2E_PLUGIN 51 | public: 52 | LinuxMonitor(S2E *s2e) : BaseLinuxMonitor(s2e) { 53 | } 54 | 55 | void initialize(); 56 | 57 | private: 58 | /// Address of the \c current_task object in the Linux kernel (see arch/x86/kernel/cpu/common.c) 59 | uint64_t m_currentTaskAddr; 60 | 61 | /// Offset of the thread group identifier in the \c task_struct struct (see include/linux/sched.h) 62 | uint64_t m_taskStructTgidOffset; 63 | 64 | /// Terminate if a trap (e.g. divide by zero) occurs 65 | bool m_terminateOnTrap; 66 | 67 | // 68 | // Handle the various commands emitted by the kernel 69 | // 70 | virtual void handleCommand(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize, void *cmd); 71 | 72 | void handleSegfault(S2EExecutionState *state, const S2E_LINUXMON_COMMAND &cmd); 73 | void handleProcessExit(S2EExecutionState *state, const S2E_LINUXMON_COMMAND &cmd); 74 | void handleTrap(S2EExecutionState *state, const S2E_LINUXMON_COMMAND &cmd); 75 | void handleInit(S2EExecutionState *state, const S2E_LINUXMON_COMMAND &cmd); 76 | void handleMemMap(S2EExecutionState *state, const S2E_LINUXMON_COMMAND &cmd); 77 | void handleMemUnmap(S2EExecutionState *state, const S2E_LINUXMON_COMMAND &cmd); 78 | void handleMemProtect(S2EExecutionState *state, const S2E_LINUXMON_COMMAND &cmd); 79 | 80 | public: 81 | /// Emitted when a trap occurs in the kernel (e.g. divide by zero, etc.) 82 | sigc::signal 85 | onTrap; 86 | 87 | sigc::signal 89 | onMemoryMap; 90 | 91 | sigc::signal 92 | onMemoryUnmap; 93 | 94 | sigc::signal 96 | onMemoryProtect; 97 | 98 | // Get the current process identifier 99 | virtual uint64_t getPid(S2EExecutionState *state); 100 | 101 | /// Get the current thread identifier 102 | virtual uint64_t getTid(S2EExecutionState *state); 103 | }; 104 | 105 | } // namespace plugins 106 | } // namespace s2e 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/ModuleDescriptor.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2019, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include "ModuleDescriptor.h" 9 | #include 10 | 11 | namespace s2e { 12 | 13 | ModuleDescriptor ModuleDescriptor::get(const vmi::PEFile &bin, uint64_t as, uint64_t pid, const std::string &name, 14 | const std::string &path, uint64_t loadBase) { 15 | ModuleDescriptor ret; 16 | 17 | ret.AddressSpace = as; 18 | ret.Pid = pid; 19 | ret.Name = name; 20 | ret.Path = path; 21 | ret.EntryPoint = bin.getEntryPoint(); 22 | ret.Checksum = bin.getCheckSum(); 23 | ret.Size = bin.getImageSize(); 24 | 25 | ret.LoadBase = loadBase; 26 | ret.NativeBase = bin.getImageBase(); 27 | 28 | for (auto §ion : bin.getSections()) { 29 | SectionDescriptor sd; 30 | sd.nativeLoadBase = section.start; 31 | sd.runtimeLoadBase = section.start - ret.NativeBase + ret.LoadBase; 32 | sd.size = section.virtualSize; 33 | sd.readable = section.readable; 34 | sd.writable = section.writable; 35 | sd.executable = section.executable; 36 | sd.name = section.name; 37 | 38 | if (sd.size) { 39 | ret.Sections.push_back(sd); 40 | } 41 | } 42 | 43 | return ret; 44 | } 45 | 46 | ModuleDescriptor ModuleDescriptor::get(const std::string &path, const std::string &name, uint64_t pid, uint64_t as, 47 | uint64_t entryPoint, const std::vector &mappedSections) { 48 | ModuleDescriptor ret; 49 | 50 | ret.AddressSpace = as; 51 | ret.Pid = pid; 52 | ret.Name = name; 53 | ret.Path = path; 54 | ret.EntryPoint = entryPoint; 55 | ret.Checksum = 0; 56 | ret.Size = 0; 57 | 58 | for (auto &s : mappedSections) { 59 | ret.Size += s.size; 60 | } 61 | 62 | ret.Sections = mappedSections; 63 | 64 | return ret; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/OSMonitor.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include "OSMonitor.h" 15 | 16 | using namespace klee; 17 | 18 | namespace s2e { 19 | namespace plugins { 20 | 21 | /// \brief Dump userspace memory pages 22 | /// 23 | /// This function will print contents of all userspace pages. 24 | /// Symbolic bytes will be marked as *SS* in hex output and printed separately. 25 | /// 26 | /// Output format is similar to *hexdump -C*. 27 | /// 28 | /// \param state current state 29 | /// 30 | void OSMonitor::dumpUserspaceMemory(S2EExecutionState *state, std::ostream &ss) { 31 | const int columns = 2; 32 | const int columnWidth = 8; 33 | 34 | static_assert(columns >= 1, "Invalid option"); 35 | static_assert(columnWidth >= 1, "Invalid option"); 36 | static_assert(TARGET_PAGE_SIZE % (columns * columnWidth) == 0, "Invalid option"); 37 | 38 | for (uint64_t virtAddr = 0; !isKernelAddress(virtAddr); virtAddr += TARGET_PAGE_SIZE) { 39 | s2e_assert(state, virtAddr <= UINT64_MAX - TARGET_PAGE_SIZE, "Address overflow"); 40 | 41 | // TODO: parse pagedir manually to find mapped pages faster 42 | uint64_t hostAddr = state->mem()->getHostAddress(virtAddr); 43 | if ((int) hostAddr == -1) { // page is not mapped 44 | continue; 45 | } 46 | 47 | std::ostringstream concreteBytes; 48 | std::ostringstream symbolicBytes; 49 | 50 | for (int line = 0; line < TARGET_PAGE_SIZE / (columns * columnWidth); line++) { 51 | int lineOffset = line * columns * columnWidth; 52 | 53 | std::ostringstream hex; 54 | std::ostringstream ascii; 55 | for (int col = 0; col < columns; col++) { 56 | for (int n = 0; n < columnWidth; n++) { 57 | int byteOffset = lineOffset + col * columnWidth + n; 58 | 59 | ref e = state->mem()->read(hostAddr + byteOffset, Expr::Int8, HostAddress); 60 | 61 | if (!e.isNull() && isa(e)) { 62 | uint8_t v = dyn_cast(e)->getZExtValue(); 63 | hex << " " << hexval(v, 2, false); 64 | ascii << (isprint(v) ? (char) v : '.'); 65 | } else { 66 | symbolicBytes << hexval(virtAddr + byteOffset, 8, false) << " " << e << "\n"; 67 | hex << " SS"; 68 | ascii << '.'; 69 | } 70 | } 71 | 72 | hex << " "; 73 | } 74 | 75 | concreteBytes << hexval(virtAddr + lineOffset, 8, false) << " " << hex.str() << " |" << ascii.str() 76 | << "|\n"; 77 | } 78 | 79 | ss << "Contents of page " << hexval(virtAddr) << "\n" << concreteBytes.str() << symbolicBytes.str(); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/Raw/RawMonitor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef _RAWMON_PLUGIN_H_ 10 | 11 | #define _RAWMON_PLUGIN_H_ 12 | 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | namespace s2e { 28 | namespace plugins { 29 | 30 | class RawMonitor : public OSMonitor, public IPluginInvoker { 31 | S2E_PLUGIN 32 | 33 | public: 34 | struct Cfg { 35 | std::string name; 36 | uint64_t start; 37 | uint64_t size; 38 | uint64_t nativebase; 39 | uint64_t entrypoint; 40 | bool kernelMode; 41 | }; 42 | 43 | struct OpcodeModuleConfig { 44 | uint64_t name; 45 | uint64_t nativeBase; 46 | uint64_t loadBase; 47 | uint64_t entryPoint; 48 | uint64_t size; 49 | uint32_t kernelMode; 50 | } __attribute__((packed)); 51 | 52 | typedef std::vector CfgList; 53 | 54 | private: 55 | Vmi *m_vmi; 56 | 57 | CfgList m_cfg; 58 | sigc::connection m_onTranslateInstruction; 59 | 60 | uint64_t m_kernelStart; 61 | S2E_RAWMON_COMMAND_STACK m_stack; 62 | 63 | vmi::Imports m_imports; 64 | 65 | bool initSection(const std::string &cfgKey, const std::string &svcId); 66 | void loadModule(S2EExecutionState *state, const Cfg &c); 67 | 68 | void handleModuleLoad(S2EExecutionState *state, const S2E_RAWMON_COMMAND_MODULE_LOAD &m); 69 | 70 | public: 71 | RawMonitor(S2E *s2e) : OSMonitor(s2e) { 72 | } 73 | virtual ~RawMonitor(); 74 | void initialize(); 75 | 76 | void onTranslateInstructionStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, 77 | uint64_t pc); 78 | 79 | virtual bool getImports(S2EExecutionState *s, const ModuleDescriptor &desc, vmi::Imports &I); 80 | virtual bool getExports(S2EExecutionState *s, const ModuleDescriptor &desc, vmi::Exports &E); 81 | virtual bool getRelocations(S2EExecutionState *s, const ModuleDescriptor &desc, vmi::Relocations &R); 82 | 83 | virtual uint64_t getKernelStart() const { 84 | return m_kernelStart; 85 | } 86 | 87 | virtual bool getCurrentStack(S2EExecutionState *state, uint64_t *base, uint64_t *size); 88 | 89 | void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 90 | 91 | uint64_t getPid(S2EExecutionState *state) { 92 | return state->regs()->getPageDir(); 93 | } 94 | 95 | virtual uint64_t getTid(S2EExecutionState *state) { 96 | pabort("Not implemented!"); 97 | return false; 98 | } 99 | 100 | virtual bool getProcessName(S2EExecutionState *state, uint64_t pid, std::string &name) { 101 | return false; 102 | } 103 | }; 104 | 105 | } // namespace plugins 106 | } // namespace s2e 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/Support/MemUtils.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2018, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_OSMONITOR_MEMUTILS_H 9 | #define S2E_PLUGINS_OSMONITOR_MEMUTILS_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace s2e { 23 | namespace plugins { 24 | 25 | /// 26 | /// \brief This plugin exports various memory-related APIs that provide more robust 27 | /// memory accessors. 28 | /// 29 | /// A common issue when writing a plugin is to be able to read data from executable files 30 | /// mapped to guest virtual memory. This is may be impossible to do if the guest did not 31 | /// map the memory yet (e.g., demand paging). This plugin provides a fallback mechanism in 32 | /// case of read failure by reverting to executable files stored on the host file system. 33 | /// 34 | /// This works as follows: 35 | /// 1. Try to read memory directly, if success, return immediately 36 | /// 2. Determine the module loaded at the given location. Return error in case of failure. 37 | /// 3. Load the binary from disk and attempt a read from there. 38 | /// 39 | class MemUtils : public Plugin { 40 | S2E_PLUGIN 41 | 42 | private: 43 | ModuleMap *m_map; 44 | MemoryMap *m_memmap; 45 | Vmi *m_vmi; 46 | 47 | public: 48 | struct AddrSize { 49 | uint64_t addr; 50 | size_t size; 51 | 52 | AddrSize(uint64_t addr, size_t size) : addr(addr), size(size) { 53 | } 54 | 55 | bool operator<(const AddrSize &x) const { 56 | return (size < x.size); 57 | } 58 | }; 59 | 60 | MemUtils(S2E *s2e) : Plugin(s2e) { 61 | } 62 | 63 | void initialize(); 64 | 65 | klee::ref read(S2EExecutionState *state, uint64_t addr); 66 | klee::ref read(S2EExecutionState *state, uint64_t addr, klee::Expr::Width width); 67 | bool read(S2EExecutionState *state, std::vector> &output, uint64_t address, unsigned length); 68 | 69 | /// \brief findSequencesOfSymbolicData 70 | /// Find contiguous regions of symbolic data described by an 71 | /// AddrSize structure. Walks through all bits in concreteMask to create 72 | /// a list of contiguous symbolic bytes. 73 | /// 74 | /// E.g., for bitmask 1001110000 it will find 2 sequences with sizes 2 and 4 75 | /// (0 bit means symbolic). 76 | /// 77 | /// \param sequences The resulting list of regions 78 | /// \param concreteMask Mask that specifies whether each byte of a region is symbolic or not 79 | /// \param baseAddr The virtual base address of the first bit in concreteMask 80 | /// \param prevItem Used to automatically merge sequence spanning 2 memory pages. 81 | /// If the function is called with bitmask 111000 and then 0111, it will update previously 82 | /// found sequence to have size 4. 83 | void findSequencesOfSymbolicData(const BitArrayPtr &concreteMask, uint64_t baseAddr, AddrSize *prevItem, 84 | std::vector &sequences); 85 | 86 | /// \brief Find contiguous chunks of symbolic data in selected memory pages 87 | /// 88 | /// \param state current state 89 | /// \param pages memory pages where to search for symbolic data 90 | /// \param symbolicSequences discovered sequences of symbolic data 91 | void findSequencesOfSymbolicData(S2EExecutionState *state, const std::set &sortedPages, 92 | std::vector &symbolicSequences); 93 | 94 | /// \brief Find contiguous chunks of symbolic data with given memory layout 95 | /// 96 | /// \param state current state 97 | /// \param map memory map 98 | /// \param mustBeExecutable true if symbolic data must be executable 99 | /// \param symbolicSequences discovered sequences of symbolic data 100 | void findSequencesOfSymbolicData(S2EExecutionState *state, uint64_t pid, bool mustBeExecutable, 101 | std::vector &symbolicSequences); 102 | 103 | void findMemoryPages(S2EExecutionState *state, uint64_t pid, bool mustBeWritable, bool mustBeExecutable, 104 | std::unordered_set &pages); 105 | }; 106 | } 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/Support/ModuleMap.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_ModuleMap_H 10 | #define S2E_PLUGINS_ModuleMap_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | 24 | // NOTE: these types must be in sync with those in guest-tools: 25 | // guest-tools/windows/libcommon/include/s2e/ModuleMap.h 26 | // TODO: factor these out to remove all duplication 27 | typedef enum S2E_MODULE_MAP_COMMANDS { GET_MODULE_INFO } S2E_MODULE_MAP_COMMANDS; 28 | 29 | typedef struct S2E_MODULE_MAP_MODULE_INFO { 30 | // Specified by the guest. 31 | // The plugin determines which module is located at this address/pid. 32 | uint64_t Address; 33 | uint64_t Pid; 34 | 35 | // Pointer to storage for ASCIIZ name of the module. 36 | // The guest provides the pointer, the plugin sets the name. 37 | uint64_t ModuleName; 38 | 39 | // Size of the name in bytes 40 | uint64_t ModuleNameSize; 41 | 42 | uint64_t RuntimeLoadBase; 43 | uint64_t NativeLoadBase; 44 | uint64_t Size; 45 | } S2E_MODULE_MAP_MODULE_INFO; 46 | 47 | typedef struct S2E_MODULE_MAP_COMMAND { 48 | S2E_MODULE_MAP_COMMANDS Command; 49 | union { 50 | S2E_MODULE_MAP_MODULE_INFO ModuleInfo; 51 | }; 52 | } S2E_MODULE_MAP_COMMAND; 53 | 54 | class OSMonitor; 55 | struct S2E_WINMON2_UNMAP_SECTION; 56 | 57 | class ModuleMap : public Plugin, public IPluginInvoker, public ILuaPlugin { 58 | S2E_PLUGIN 59 | 60 | public: 61 | ModuleMap(S2E *s2e) : Plugin(s2e) { 62 | } 63 | 64 | void initialize(); 65 | 66 | ModuleDescriptorConstPtr getModule(S2EExecutionState *state); 67 | ModuleDescriptorConstPtr getModule(S2EExecutionState *state, uint64_t pc); 68 | ModuleDescriptorConstPtr getModule(S2EExecutionState *state, uint64_t pid, uint64_t pc); 69 | 70 | void dump(S2EExecutionState *state); 71 | 72 | virtual void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 73 | 74 | virtual int getLuaPlugin(lua_State *L); 75 | 76 | private: 77 | OSMonitor *m_monitor; 78 | 79 | void onModuleLoad(S2EExecutionState *state, const ModuleDescriptor &module); 80 | void onModuleUnload(S2EExecutionState *state, const ModuleDescriptor &module); 81 | void onProcessUnload(S2EExecutionState *state, uint64_t addressSpace, uint64_t pid, uint64_t returnCode); 82 | void onNtUnmapViewOfSection(S2EExecutionState *state, const S2E_WINMON2_UNMAP_SECTION &s); 83 | void onMonitorLoad(S2EExecutionState *state); 84 | }; 85 | 86 | } // namespace plugins 87 | } // namespace s2e 88 | 89 | #endif // S2E_PLUGINS_ModuleMap_H 90 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/Support/ProcessExecutionDetector.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_ProcessExecutionDetector_H 9 | #define S2E_PLUGINS_ProcessExecutionDetector_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace s2e { 16 | namespace plugins { 17 | 18 | class OSMonitor; 19 | 20 | class ProcessExecutionDetector : public Plugin { 21 | S2E_PLUGIN 22 | public: 23 | ProcessExecutionDetector(S2E *s2e) : Plugin(s2e) { 24 | } 25 | 26 | void initialize(); 27 | 28 | bool isTracked(S2EExecutionState *state); 29 | bool isTracked(S2EExecutionState *state, uint64_t pid); 30 | bool isTracked(const std::string &module) const; 31 | bool isTrackedPc(S2EExecutionState *state, uint64_t pc, bool checkCpl = false); 32 | 33 | void trackPid(S2EExecutionState *state, uint64_t pid); 34 | 35 | sigc::signal onMonitorLoad; 36 | 37 | private: 38 | typedef std::unordered_set StringSet; 39 | 40 | OSMonitor *m_monitor; 41 | 42 | StringSet m_trackedModules; 43 | 44 | void onProcessLoad(S2EExecutionState *state, uint64_t pageDir, uint64_t pid, const std::string &ImageFileName); 45 | void onProcessUnload(S2EExecutionState *state, uint64_t pageDir, uint64_t pid, uint64_t returnCode); 46 | 47 | void onMonitorLoadCb(S2EExecutionState *state); 48 | }; 49 | 50 | } // namespace plugins 51 | } // namespace s2e 52 | 53 | #endif // S2E_PLUGINS_ProcessExecutionDetector_H 54 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/ThreadDescriptor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2012-2014, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef _THREAD_DESCRIPTOR_H_ 9 | 10 | #define _THREAD_DESCRIPTOR_H_ 11 | 12 | #include 13 | 14 | namespace s2e { 15 | 16 | struct ThreadDescriptor { 17 | uint64_t Pid; 18 | uint64_t Tid; 19 | uint64_t KernelStackBottom; 20 | uint64_t KernelStackSize; 21 | 22 | bool KernelMode; 23 | // TODO: add other interesting information 24 | 25 | ThreadDescriptor() { 26 | Pid = Tid = 0; 27 | KernelStackBottom = 0; 28 | KernelStackSize = 0; 29 | KernelMode = false; 30 | } 31 | }; 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/Windows/BlueScreenInterceptor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2013, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_BSOD_H 9 | #define S2E_PLUGINS_BSOD_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "WindowsMonitor.h" 17 | 18 | namespace s2e { 19 | namespace plugins { 20 | 21 | struct S2E_BSOD_COMMAND { 22 | uint64_t Code; 23 | uint64_t Parameters[4]; 24 | uint64_t Header; 25 | uint64_t HeaderSize; 26 | }; 27 | 28 | class BlueScreenInterceptor : public Plugin, public IPluginInvoker { 29 | S2E_PLUGIN 30 | public: 31 | BlueScreenInterceptor(S2E *s2e) : Plugin(s2e) { 32 | } 33 | 34 | void initialize(); 35 | 36 | /* Other plugins can react to kernel crashes via this signal */ 37 | sigc::signal 39 | onBlueScreen; 40 | 41 | virtual void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 42 | 43 | private: 44 | WindowsMonitor *m_monitor; 45 | 46 | bool invokeCrashRoutine(S2EExecutionState *state, uint64_t pc); 47 | 48 | void onTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc); 49 | 50 | void onBsod(S2EExecutionState *state, uint64_t pc); 51 | }; 52 | 53 | } // namespace plugins 54 | } // namespace s2e 55 | 56 | #endif // S2E_PLUGINS_EXAMPLE_H 57 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/Windows/WindowsCrashDumpGenerator.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2013, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_WINDOWSCRASHDUMPGENERATOR_H 10 | #define S2E_PLUGINS_WINDOWSCRASHDUMPGENERATOR_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "WindowsMonitor.h" 20 | 21 | #include 22 | 23 | namespace s2e { 24 | namespace plugins { 25 | 26 | class WindowsCrashDumpGenerator; 27 | 28 | class WindowsCrashDumpInvoker { 29 | private: 30 | WindowsCrashDumpGenerator *m_plugin; 31 | 32 | public: 33 | static const char className[]; 34 | static Lunar::RegType methods[]; 35 | 36 | WindowsCrashDumpInvoker(WindowsCrashDumpGenerator *plg); 37 | WindowsCrashDumpInvoker(lua_State *lua); 38 | ~WindowsCrashDumpInvoker(); 39 | 40 | public: 41 | int generateCrashDump(lua_State *L); 42 | }; 43 | 44 | /// 45 | /// \brief The WindowsCrashDumpGenerator plugins provides mechanisms to generate 46 | /// WinDbg-compatible crash dumps. 47 | /// 48 | /// Remarks: 49 | /// - This class has no configurable options and does not generate dumps by itself 50 | /// - Other plugins may use WindowsCrashDumpGenerator to request crash dumps 51 | /// when they detect guest bugs. BugCollector is one such plugin. 52 | /// 53 | class WindowsCrashDumpGenerator : public Plugin { 54 | S2E_PLUGIN 55 | public: 56 | WindowsCrashDumpGenerator(S2E *s2e) : Plugin(s2e) { 57 | } 58 | 59 | void initialize(); 60 | 61 | bool generateDump(S2EExecutionState *state, const std::string &filename, 62 | const vmi::windows::BugCheckDescription *info); 63 | 64 | bool generateManualDump(S2EExecutionState *state, const std::string &filename, 65 | const vmi::windows::BugCheckDescription *info); 66 | 67 | std::string getPathForDump(S2EExecutionState *state, const std::string &prefix = "dump"); 68 | 69 | private: 70 | WindowsMonitor *m_monitor; 71 | 72 | // TODO: put these somewhere else. In principe getContext functions are generic, 73 | // but for now, only WindowsCrashDumpGenerator uses them. 74 | template static void getContext(S2EExecutionState *state, T &context); 75 | static void getContext32(S2EExecutionState *state, vmi::windows::CONTEXT32 &context); 76 | static void getContext64(S2EExecutionState *state, vmi::windows::CONTEXT64 &context); 77 | 78 | bool generateCrashDump(S2EExecutionState *state, const std::string &filename, 79 | const vmi::windows::BugCheckDescription *bugDesc, const vmi::windows::CONTEXT32 &context); 80 | }; 81 | 82 | } // namespace plugins 83 | } // namespace s2e 84 | 85 | #endif // S2E_PLUGINS_EXAMPLE_H 86 | -------------------------------------------------------------------------------- /src/s2e/Plugins/OSMonitors/Windows/WindowsCrashMonitor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2017, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_WindowsCrashMonitor_H 9 | #define S2E_PLUGINS_WindowsCrashMonitor_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | 24 | struct WindowsUserModeCrash { 25 | std::string ProgramName; 26 | uint64_t Pid; 27 | uint64_t ExceptionCode; 28 | uint64_t ExceptionAddress; 29 | uint64_t ExceptionFlags; 30 | 31 | struct { 32 | uint64_t Buffer; 33 | uint64_t Size; 34 | } CrashDumpHeader; 35 | }; 36 | 37 | struct S2E_WINDOWS_USERMODE_CRASH { 38 | uint64_t ProgramName; 39 | uint64_t Pid; 40 | uint64_t ExceptionCode; 41 | uint64_t ExceptionAddress; 42 | uint64_t ExceptionFlags; 43 | }; 44 | 45 | enum S2E_WINDOWS_CRASH_COMMANDS { WINDOWS_USERMODE_CRASH }; 46 | 47 | struct S2E_CRASHDUMP_OPAQUE { 48 | uint64_t Buffer; 49 | uint64_t Size; 50 | }; 51 | 52 | struct S2E_WINDOWS_CRASH_COMMAND { 53 | S2E_WINDOWS_CRASH_COMMANDS Command; 54 | union { 55 | S2E_WINDOWS_USERMODE_CRASH UserModeCrash; 56 | }; 57 | /* Optional, used by the crash dump plugin. */ 58 | S2E_CRASHDUMP_OPAQUE Dump; 59 | }; 60 | 61 | class WindowsCrashMonitor : public Plugin, public IPluginInvoker { 62 | S2E_PLUGIN 63 | public: 64 | WindowsCrashMonitor(S2E *s2e) : Plugin(s2e) { 65 | } 66 | 67 | sigc::signal onUserModeCrash; 68 | 69 | sigc::signal onKernelModeCrash; 70 | 71 | void initialize(); 72 | virtual void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 73 | 74 | private: 75 | WindowsMonitor *m_windowsMonitor; 76 | BlueScreenInterceptor *m_bsodInterceptor; 77 | WindowsCrashDumpGenerator *m_bsodGenerator; 78 | 79 | bool m_generateDumpOnKernelCrash; 80 | bool m_generateDumpOnUserCrash; 81 | bool m_compressDumps; 82 | bool m_terminateOnCrash; 83 | int m_maxCrashDumpCount; 84 | 85 | S2ESynchronizedObject m_crashCount; 86 | 87 | void generateCrashDump(S2EExecutionState *state, const vmi::windows::BugCheckDescription *info, bool isManual); 88 | void onBlueScreen(S2EExecutionState *state, vmi::windows::BugCheckDescription *info); 89 | void opUserModeCrash(S2EExecutionState *state, uint64_t guestDataPtr, const S2E_WINDOWS_CRASH_COMMAND &command); 90 | }; 91 | 92 | } // namespace plugins 93 | } // namespace s2e 94 | 95 | #endif // S2E_PLUGINS_WindowsCrashMonitor_H 96 | -------------------------------------------------------------------------------- /src/s2e/Plugins/PathLimiters/EdgeKiller.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2011-2015, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include "EdgeKiller.h" 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | S2E_DEFINE_PLUGIN(EdgeKiller, "Kills states that encounter a given (start_pc, end_pc) edge", "", "EdgeDetector", 21 | "ModuleExecutionDetector"); 22 | 23 | void EdgeKiller::initialize() { 24 | m_detector = s2e()->getPlugin(); 25 | m_edgeDetector = s2e()->getPlugin(); 26 | m_edgeDetector->readConfig(getConfigKey(), this); 27 | m_edgeDetector->onEdge.connect(sigc::mem_fun(*this, &EdgeKiller::onEdge)); 28 | } 29 | 30 | void EdgeKiller::addEdge(const std::string &moduleName, uint64_t start, uint64_t end, EdgeType type) { 31 | getDebugStream() << "EdgeKiller: adding edge " << moduleName << " " << hexval(start) << " => " << hexval(end) 32 | << " type:" << type << "\n"; 33 | m_edgeDetector->addEdge(moduleName, start, end, type); 34 | m_edges.addEdge(moduleName, start, end, type); 35 | } 36 | 37 | void EdgeKiller::onEdge(S2EExecutionState *state, uint64_t sourcePc, EdgeType type) { 38 | auto md = m_detector->getCurrentDescriptor(state); 39 | if (!md) { 40 | return; 41 | } 42 | 43 | uint64_t relSourcePc, relPc; 44 | bool ok = true; 45 | ok &= md->ToNativeBase(sourcePc, relSourcePc); 46 | ok &= md->ToNativeBase(state->regs()->getPc(), relPc); 47 | if (!ok) { 48 | getWarningsStream(state) << "Could not get relative source/dest address\n"; 49 | return; 50 | } 51 | 52 | if (!m_edges.findEdge(md->Name, relSourcePc, relPc, &type)) { 53 | return; 54 | } 55 | 56 | std::string s; 57 | llvm::raw_string_ostream ss(s); 58 | ss << "EdgeKiller: " << hexval(sourcePc) << " => " << hexval(state->regs()->getPc()) << "\n"; 59 | ss.flush(); 60 | s2e()->getExecutor()->terminateState(*state, s); 61 | } 62 | 63 | } // namespace plugins 64 | } // namespace s2e 65 | -------------------------------------------------------------------------------- /src/s2e/Plugins/PathLimiters/EdgeKiller.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2011-2013, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_EdgeKiller_H 9 | #define S2E_PLUGINS_EdgeKiller_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | class EdgeKiller : public Plugin, public IEdgeAdder { 21 | S2E_PLUGIN 22 | public: 23 | EdgeKiller(S2E *s2e) : Plugin(s2e) { 24 | } 25 | 26 | void initialize(); 27 | void addEdge(const std::string &moduleName, uint64_t start, uint64_t end, EdgeType type); 28 | 29 | private: 30 | ModuleExecutionDetector *m_detector; 31 | EdgeDetector *m_edgeDetector; 32 | EdgeCollection m_edges; 33 | 34 | void onEdge(S2EExecutionState *state, uint64_t source, EdgeType type); 35 | }; 36 | 37 | } // namespace plugins 38 | } // namespace s2e 39 | 40 | #endif // S2E_PLUGINS_EdgeKiller_H 41 | -------------------------------------------------------------------------------- /src/s2e/Plugins/PathLimiters/ForkLimiter.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2015, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "ForkLimiter.h" 13 | 14 | namespace s2e { 15 | namespace plugins { 16 | 17 | S2E_DEFINE_PLUGIN(ForkLimiter, "Limits how many times each instruction in a module can fork", ""); 18 | 19 | void ForkLimiter::initialize() { 20 | m_detector = s2e()->getPlugin(); 21 | 22 | s2e()->getCorePlugin()->onTimer.connect(sigc::mem_fun(*this, &ForkLimiter::onTimer)); 23 | 24 | s2e()->getCorePlugin()->onProcessForkDecide.connect(sigc::mem_fun(*this, &ForkLimiter::onProcessForkDecide)); 25 | 26 | // Limit of forks per program counter, -1 means don't care 27 | bool ok; 28 | m_limit = s2e()->getConfig()->getInt(getConfigKey() + ".maxForkCount", 10, &ok); 29 | if ((int) m_limit != -1) { 30 | if (m_detector) { 31 | s2e()->getCorePlugin()->onStateForkDecide.connect(sigc::mem_fun(*this, &ForkLimiter::onStateForkDecide)); 32 | 33 | s2e()->getCorePlugin()->onStateFork.connect(sigc::mem_fun(*this, &ForkLimiter::onFork)); 34 | } else if (ok) { 35 | getWarningsStream() << "maxForkCount requires ModuleExecutionDetector\n"; 36 | exit(-1); 37 | } 38 | } 39 | 40 | // Wait 5 seconds before allowing an S2E instance to fork 41 | m_processForkDelay = s2e()->getConfig()->getInt(getConfigKey() + ".processForkDelay", 5); 42 | 43 | m_timerTicks = 0; 44 | } 45 | 46 | void ForkLimiter::onStateForkDecide(S2EExecutionState *state, bool *doFork) { 47 | auto module = m_detector->getCurrentDescriptor(state); 48 | if (!module) { 49 | return; 50 | } 51 | 52 | uint64_t curPc; 53 | if (!module->ToNativeBase(state->regs()->getPc(), curPc)) { 54 | getWarningsStream(state) << "Could not get relative pc for module " << module->Name << "\n"; 55 | return; 56 | } 57 | 58 | if (m_forkCount[module->Name][curPc] > m_limit) { 59 | *doFork = false; 60 | } 61 | } 62 | 63 | void ForkLimiter::onFork(S2EExecutionState *state, const std::vector &newStates, 64 | const std::vector> &newConditions) { 65 | auto module = m_detector->getCurrentDescriptor(state); 66 | if (!module) { 67 | return; 68 | } 69 | 70 | uint64_t curPc; 71 | if (!module->ToNativeBase(state->regs()->getPc(), curPc)) { 72 | getWarningsStream(state) << "Could not get relative pc for module " << module->Name << "\n"; 73 | return; 74 | } 75 | ++m_forkCount[module->Name][curPc]; 76 | } 77 | 78 | void ForkLimiter::onProcessForkDecide(bool *proceed) { 79 | // Rate-limit forking 80 | if (m_timerTicks < m_processForkDelay) { 81 | *proceed = false; 82 | return; 83 | } 84 | 85 | m_timerTicks = 0; 86 | } 87 | 88 | void ForkLimiter::onTimer() { 89 | ++m_timerTicks; 90 | } 91 | 92 | } // namespace plugins 93 | } // namespace s2e 94 | -------------------------------------------------------------------------------- /src/s2e/Plugins/PathLimiters/ForkLimiter.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_ForkLimiter_H 9 | #define S2E_PLUGINS_ForkLimiter_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | class ForkLimiter : public Plugin { 21 | S2E_PLUGIN 22 | public: 23 | ForkLimiter(S2E *s2e) : Plugin(s2e) { 24 | } 25 | 26 | void initialize(); 27 | 28 | private: 29 | typedef llvm::DenseMap ForkCounts; 30 | typedef std::map ModuleForkCounts; 31 | 32 | ModuleExecutionDetector *m_detector; 33 | ModuleForkCounts m_forkCount; 34 | 35 | unsigned m_limit; 36 | unsigned m_processForkDelay; 37 | 38 | unsigned m_timerTicks; 39 | 40 | void onTimer(); 41 | void onProcessForkDecide(bool *proceed); 42 | 43 | void onStateForkDecide(S2EExecutionState *state, bool *doFork); 44 | void onFork(S2EExecutionState *state, const std::vector &newStates, 45 | const std::vector> &newConditions); 46 | }; 47 | 48 | } // namespace plugins 49 | } // namespace s2e 50 | 51 | #endif // S2E_PLUGINS_ForkLimiter_H 52 | -------------------------------------------------------------------------------- /src/s2e/Plugins/PathLimiters/ResourceMonitor.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2014-2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_ResourceMonitor_H 10 | #define S2E_PLUGINS_ResourceMonitor_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace s2e { 20 | namespace plugins { 21 | 22 | class ResourceMonitor : public Plugin { 23 | S2E_PLUGIN 24 | public: 25 | ResourceMonitor(S2E *s2e) : Plugin(s2e) { 26 | } 27 | 28 | void initialize(); 29 | 30 | private: 31 | uint64_t m_timerCount; 32 | uint64_t m_rss; 33 | uint64_t m_cgroupMemLimit; 34 | std::string m_memStatFileName; 35 | S2ESynchronizedObject m_notifiedQMP; 36 | 37 | void onStateForkDecide(S2EExecutionState *state, bool *doFork); 38 | void onTimer(void); 39 | void updateMemoryUsage(); 40 | bool memoryLimitExceeded(); 41 | void dropStates(); 42 | void emitQMPNofitication(); 43 | }; 44 | 45 | } // namespace plugins 46 | } // namespace s2e 47 | 48 | #endif // S2E_PLUGINS_ResourceMonitor_H 49 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Searchers/Common.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef __S2E_SEARCHERS_COMMON__ 9 | #define __S2E_SEARCHERS_COMMON__ 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | 20 | namespace searchers { 21 | 22 | struct StatePriority { 23 | S2EExecutionState *state; 24 | int64_t priority; 25 | 26 | StatePriority() { 27 | state = nullptr; 28 | priority = 0; 29 | } 30 | 31 | StatePriority(S2EExecutionState *state, int64_t p) { 32 | this->state = state; 33 | 34 | /* State with a higher p get selected first */ 35 | this->priority = p; 36 | } 37 | }; 38 | 39 | struct state_t {}; 40 | struct priority_t {}; 41 | 42 | typedef boost::multi_index_container< 43 | StatePriority, 44 | boost::multi_index::indexed_by< 45 | boost::multi_index::ordered_unique, 46 | BOOST_MULTI_INDEX_MEMBER(StatePriority, S2EExecutionState *, state)>, 47 | boost::multi_index::ordered_non_unique, 48 | BOOST_MULTI_INDEX_MEMBER(StatePriority, int64_t, priority)>>> 49 | MultiStates; 50 | 51 | typedef MultiStates::index::type StatesByPointer; 52 | typedef MultiStates::index::type StatesByPriority; 53 | } 54 | } 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Searchers/CooperativeSearcher.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2011-2013, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_COOPSEARCHER_H 10 | #define S2E_PLUGINS_COOPSEARCHER_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | 24 | #define COOPSEARCHER_OPCODE 0xAB 25 | 26 | class CooperativeSearcher : public Plugin, public klee::Searcher { 27 | S2E_PLUGIN 28 | public: 29 | enum CoopSchedulerOpcodes { 30 | ScheduleNext = 0, 31 | Yield = 1, 32 | }; 33 | 34 | typedef std::map States; 35 | 36 | CooperativeSearcher(S2E *s2e) : Plugin(s2e) { 37 | } 38 | void initialize(); 39 | 40 | // Selects the last specified state. 41 | // If no states specified, schedules the one with the lowest ID. 42 | virtual klee::ExecutionState &selectState(); 43 | 44 | virtual void update(klee::ExecutionState *current, const klee::StateSet &addedStates, 45 | const klee::StateSet &removedStates); 46 | 47 | virtual bool empty(); 48 | 49 | private: 50 | bool m_searcherInited; 51 | States m_states; 52 | S2EExecutionState *m_currentState; 53 | 54 | void initializeSearcher(); 55 | 56 | void onCustomInstruction(S2EExecutionState *state, uint64_t opcode); 57 | }; 58 | 59 | } // namespace plugins 60 | } // namespace s2e 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Searchers/LoopExitSearcher.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2014-2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_LoopExitSearcher_H 9 | #define S2E_PLUGINS_LoopExitSearcher_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "Common.h" 29 | 30 | namespace s2e { 31 | namespace plugins { 32 | 33 | class LoopExitSearcher : public Plugin, public klee::Searcher { 34 | S2E_PLUGIN 35 | 36 | private: 37 | typedef llvm::DenseMap ForkCounts; 38 | typedef std::map ModuleForkCounts; 39 | 40 | ModuleForkCounts m_forkCount; 41 | 42 | LoopDetector *m_loopDetector; 43 | ControlFlowGraph *m_cfg; 44 | ModuleExecutionDetector *m_detector; 45 | coverage::BasicBlockCoverage *m_bbcov; 46 | EdgeCoverage *m_ecov; 47 | 48 | searchers::MultiStates m_states; 49 | searchers::MultiStates m_waitingStates; 50 | S2EExecutionState *m_currentState; 51 | 52 | unsigned m_timerTicks; 53 | 54 | void onFork(S2EExecutionState *state, const std::vector &newStates, 55 | const std::vector> &newConditions); 56 | 57 | void onTimer(); 58 | 59 | void increasePriority(S2EExecutionState *state, int64_t p); 60 | 61 | public: 62 | LoopExitSearcher(S2E *s2e) : Plugin(s2e) { 63 | } 64 | void initialize(); 65 | 66 | virtual klee::ExecutionState &selectState(); 67 | 68 | virtual void update(klee::ExecutionState *current, const klee::StateSet &addedStates, 69 | const klee::StateSet &removedStates); 70 | 71 | virtual bool empty(); 72 | 73 | private: 74 | }; 75 | 76 | } // namespace plugins 77 | } // namespace s2e 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Searchers/MergingSearcher.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2013, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_MERGINGSEARCHER_H 10 | #define S2E_PLUGINS_MERGINGSEARCHER_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include 21 | 22 | namespace s2e { 23 | namespace plugins { 24 | 25 | class IMergingSearcher { 26 | public: 27 | virtual ~IMergingSearcher() { 28 | } 29 | virtual S2EExecutionState *selectState() = 0; 30 | virtual void update(klee::ExecutionState *current, const klee::StateSet &addedStates, 31 | const klee::StateSet &removedStates) = 0; 32 | 33 | virtual void setActive(S2EExecutionState *state, bool active) = 0; 34 | }; 35 | 36 | class MergingSearcher : public Plugin, public klee::Searcher, public IPluginInvoker { 37 | S2E_PLUGIN 38 | 39 | public: 40 | typedef llvm::DenseSet States; 41 | 42 | private: 43 | /* Custom instruction command */ 44 | struct merge_desc_t { 45 | uint64_t start; 46 | }; 47 | 48 | struct merge_pool_t { 49 | /* First state that got to the merge_end instruction */ 50 | S2EExecutionState *firstState; 51 | 52 | /* All the states that belong to the pool */ 53 | States states; 54 | 55 | merge_pool_t() { 56 | firstState = nullptr; 57 | } 58 | }; 59 | 60 | /* maps a group id to the first state */ 61 | typedef std::map MergePools; 62 | 63 | MergePools m_mergePools; 64 | States m_activeStates; 65 | S2EExecutionState *m_currentState; 66 | uint64_t m_nextMergeGroupId; 67 | 68 | IMergingSearcher *m_selector; 69 | 70 | bool m_debug; 71 | 72 | public: 73 | MergingSearcher(S2E *s2e) : Plugin(s2e) { 74 | } 75 | void initialize(); 76 | 77 | void setCustomSelector(IMergingSearcher *selector) { 78 | m_selector = selector; 79 | } 80 | 81 | States &getActiveStates() { 82 | return m_activeStates; 83 | } 84 | 85 | virtual klee::ExecutionState &selectState(); 86 | 87 | virtual void update(klee::ExecutionState *current, const klee::StateSet &addedStates, 88 | const klee::StateSet &removedStates); 89 | 90 | virtual bool empty(); 91 | 92 | bool mergeStart(S2EExecutionState *state); 93 | bool mergeEnd(S2EExecutionState *state, bool skipOpcode, bool clearTmpFlags); 94 | 95 | private: 96 | void suspend(S2EExecutionState *state); 97 | void resume(S2EExecutionState *state); 98 | 99 | virtual void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 100 | }; 101 | 102 | class MergingSearcherState : public PluginState { 103 | private: 104 | uint64_t m_groupId; 105 | 106 | public: 107 | MergingSearcherState(); 108 | virtual ~MergingSearcherState(); 109 | virtual MergingSearcherState *clone() const; 110 | static PluginState *factory(Plugin *p, S2EExecutionState *s); 111 | 112 | void setGroupId(uint64_t groupId) { 113 | m_groupId = groupId; 114 | } 115 | 116 | uint64_t getGroupId() const { 117 | return m_groupId; 118 | } 119 | }; 120 | 121 | } // namespace plugins 122 | } // namespace s2e 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Searchers/MultiSearcher.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "MultiSearcher.h" 13 | 14 | namespace s2e { 15 | namespace plugins { 16 | 17 | S2E_DEFINE_PLUGIN(MultiSearcher, "MultiSearcher S2E plugin", "", ); 18 | 19 | void MultiSearcher::initialize() { 20 | s2e()->getCorePlugin()->onInitializationComplete.connect(sigc::mem_fun(*this, &MultiSearcher::onInitComplete)); 21 | 22 | s2e()->getExecutor()->setSearcher(this); 23 | } 24 | 25 | void MultiSearcher::onInitComplete(S2EExecutionState *state) { 26 | if (m_searchers.empty()) { 27 | getWarningsStream() << "No searchers have been registered.\n"; 28 | exit(-1); 29 | } 30 | } 31 | 32 | bool MultiSearcher::registerSearcher(const std::string &name, klee::Searcher *searcher) { 33 | if (m_searchers[name] == nullptr) { 34 | getDebugStream() << "Registering " << name << "\n"; 35 | m_searchers[name] = searcher; 36 | 37 | if (m_searchers.size() == 1) { 38 | selectSearcher(name); 39 | } 40 | 41 | return true; 42 | } 43 | 44 | return false; 45 | } 46 | 47 | bool MultiSearcher::selectSearcher(const std::string &name) { 48 | Searchers::iterator it = m_searchers.find(name); 49 | if (it == m_searchers.end()) { 50 | return false; 51 | } 52 | 53 | if (m_currentSearcher != (*it).second) { 54 | getDebugStream() << "Switching to " << (*it).first << "\n"; 55 | } 56 | 57 | m_currentSearcher = (*it).second; 58 | return true; 59 | } 60 | 61 | klee::ExecutionState &MultiSearcher::selectState() { 62 | assert(m_currentSearcher); 63 | return m_currentSearcher->selectState(); 64 | } 65 | 66 | void MultiSearcher::update(klee::ExecutionState *current, const klee::StateSet &addedStates, 67 | const klee::StateSet &removedStates) { 68 | foreach2 (it, m_searchers.begin(), m_searchers.end()) { (*it).second->update(current, addedStates, removedStates); } 69 | } 70 | 71 | bool MultiSearcher::empty() { 72 | assert(m_currentSearcher); 73 | return m_currentSearcher->empty(); 74 | } 75 | 76 | } // namespace plugins 77 | } // namespace s2e 78 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Searchers/MultiSearcher.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_MultiSearcher_H 9 | #define S2E_PLUGINS_MultiSearcher_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace s2e { 20 | namespace plugins { 21 | 22 | class MultiSearcher : public Plugin, public klee::Searcher { 23 | S2E_PLUGIN 24 | 25 | private: 26 | typedef std::map Searchers; 27 | 28 | Searchers m_searchers; 29 | klee::Searcher *m_currentSearcher; 30 | 31 | void onInitComplete(S2EExecutionState *state); 32 | 33 | public: 34 | MultiSearcher(S2E *s2e) : Plugin(s2e) { 35 | } 36 | 37 | void initialize(); 38 | 39 | bool registerSearcher(const std::string &name, klee::Searcher *searcher); 40 | bool selectSearcher(const std::string &name); 41 | 42 | virtual klee::ExecutionState &selectState(); 43 | 44 | virtual void update(klee::ExecutionState *current, const klee::StateSet &addedStates, 45 | const klee::StateSet &removedStates); 46 | 47 | virtual bool empty(); 48 | 49 | private: 50 | }; 51 | 52 | } // namespace plugins 53 | } // namespace s2e 54 | 55 | #endif // S2E_PLUGINS_MultiSearcher_H 56 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Searchers/SeedScheduler.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2010-2013, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_SeedScheduler_H 9 | #define S2E_PLUGINS_SeedScheduler_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "SeedSearcher.h" 17 | 18 | namespace s2e { 19 | namespace plugins { 20 | namespace seeds { 21 | 22 | enum ExplorationState { 23 | /* 24 | * Let S2E find crashes in the first seconds before trying 25 | * to use any seeds. 26 | */ 27 | WARM_UP, 28 | 29 | /* Wait for new seeds to become available */ 30 | WAIT_FOR_NEW_SEEDS, 31 | 32 | /* Wait for the guest to actually fetch the seed */ 33 | WAIT_SEED_SCHEDULING, 34 | 35 | /* Wait for a while that the seeds executes */ 36 | WAIT_SEED_EXECUTION 37 | }; 38 | 39 | class SeedScheduler : public Plugin { 40 | S2E_PLUGIN 41 | public: 42 | SeedScheduler(S2E *s2e) : Plugin(s2e) { 43 | } 44 | 45 | void initialize(); 46 | 47 | private: 48 | SeedSearcher *m_seeds; 49 | 50 | uint64_t m_stateMachineTimeout; 51 | unsigned m_lowPrioritySeedThreshold; 52 | bool m_stateKilled; 53 | 54 | ExplorationState m_explorationState; 55 | uint64_t m_timeOfLastCoveredBlock; 56 | uint64_t m_timeOfLastCrash; 57 | uint64_t m_timeOfLastHighPrioritySeed; 58 | uint64_t m_timeOfLastFetchedSeed; 59 | 60 | void onSeed(const Seed &seed, SeedEvent event); 61 | void onNewBlockCovered(S2EExecutionState *state); 62 | void onSegFault(S2EExecutionState *state, uint64_t pid, uint64_t address); 63 | void onWindowsUserCrash(S2EExecutionState *state, const WindowsUserModeCrash &desc); 64 | void onWindowsKernelCrash(S2EExecutionState *state, const vmi::windows::BugCheckDescription &desc); 65 | 66 | void onProcessForkDecide(bool *proceed); 67 | void onTimer(); 68 | void onStateKill(S2EExecutionState *state); 69 | 70 | void processSeedStateMachine(uint64_t currentTime); 71 | 72 | /// 73 | /// \brief Terminates an idle S2E instance 74 | /// 75 | /// An idle S2E instance is an instance that only has one state running, 76 | /// and that state waits for new seeds. It may happen that the system 77 | /// is filled with idle instances. This situation prevents busy instances 78 | /// to offload some of their states by forking new S2E instances because 79 | /// all the slots are taken by idle instances. Killing the idle instances 80 | /// frees up instance slots so that the busy S2E process can fork a child again. 81 | /// 82 | /// NOTE: this is required only because S2E has no mechanism to migrate 83 | /// states between already running instances. 84 | /// 85 | void terminateIdleInstance(); 86 | }; 87 | 88 | } // namespace seeds 89 | } // namespace plugins 90 | } // namespace s2e 91 | 92 | #endif // S2E_PLUGINS_SeedScheduler_H 93 | -------------------------------------------------------------------------------- /src/s2e/Plugins/StaticAnalysis/ControlFlowGraph.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2013-2015, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_ControlFlowGraph_H 10 | #define S2E_PLUGINS_ControlFlowGraph_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace s2e { 21 | namespace plugins { 22 | 23 | /// 24 | /// \brief The ControlFlowGraph class represents a CFG 25 | /// 26 | class ControlFlowGraph : public Plugin, public IPluginInvoker { 27 | S2E_PLUGIN 28 | public: 29 | ControlFlowGraph(S2E *s2e) : Plugin(s2e) { 30 | } 31 | 32 | void initialize(); 33 | 34 | typedef llvm::SmallVector ProgramCounters; 35 | 36 | // Maps a function entry block to a function name 37 | typedef llvm::DenseMap FunctionEntryPoints; 38 | 39 | struct BasicBlock { 40 | uint64_t start_pc; 41 | uint64_t end_pc; 42 | unsigned size; 43 | uint64_t call_target; 44 | ProgramCounters successors; 45 | ProgramCounters predecessors; 46 | 47 | BasicBlock() { 48 | start_pc = end_pc = 0; 49 | size = 0; 50 | } 51 | 52 | // TODO: take into account the size 53 | bool operator<(const BasicBlock &bb) const { 54 | return start_pc + size <= bb.start_pc; 55 | } 56 | }; 57 | 58 | typedef std::set BasicBlocks; 59 | typedef std::map ModuleBasicBlocks; 60 | 61 | typedef std::map ModuleFunctions; 62 | 63 | sigc::signal onReload; 64 | 65 | const BasicBlock *findBasicBlock(const std::string &module, uint64_t pc) const; 66 | 67 | bool getBasicBlockRange(const std::string &module, uint64_t start, uint64_t end, 68 | std::vector &blocks); 69 | 70 | uint64_t getBasicBlockCount(const std::string &module) const; 71 | uint64_t getBasicBlockCount() const { 72 | return m_basicBlockCount; 73 | } 74 | 75 | /** 76 | * Follows a chain of basic blocks linked together by direct jumps. 77 | * Return the pc of the first basic block that has multiple targets. 78 | */ 79 | bool getFinalSuccessor(const std::string &module, uint64_t start, uint64_t *end) const; 80 | 81 | bool getFunctionName(const std::string &module, uint64_t entry_point, std::string &name) const; 82 | 83 | bool isReachable(const std::string &module, uint64_t source, uint64_t dest, bool &result) const; 84 | bool isReachable(const BasicBlocks &bbs, uint64_t source, uint64_t dest, bool &result) const; 85 | 86 | private: 87 | ModuleExecutionDetector *m_detector; 88 | ModuleFunctions m_entryPoints; 89 | ModuleBasicBlocks m_basicBlocks; 90 | 91 | uint64_t m_basicBlockCount; 92 | 93 | void loadConfiguration(); 94 | const BasicBlock *findBasicBlock(const BasicBlocks &bbs, uint64_t pc) const; 95 | 96 | void onTimer(); 97 | 98 | /* Guest config interface */ 99 | virtual void handleOpcodeInvocation(S2EExecutionState *state, uint64_t guestDataPtr, uint64_t guestDataSize); 100 | }; 101 | 102 | } // namespace plugins 103 | } // namespace s2e 104 | 105 | #endif // S2E_PLUGINS_ControlFlowGraph_H 106 | -------------------------------------------------------------------------------- /src/s2e/Plugins/StaticAnalysis/EdgeDetector.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2013, Dependable Systems Laboratory, EPFL 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_EDGEDETECTOR_H 9 | #define S2E_PLUGINS_EDGEDETECTOR_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace s2e { 17 | namespace plugins { 18 | 19 | enum EdgeType { EDGE_NONE, EDGE_LOOP_ENTRY, EDGE_LOOP_BACKEDGE, EDGE_LOOP_EXIT }; 20 | 21 | class IEdgeAdder { 22 | public: 23 | virtual ~IEdgeAdder() { 24 | } 25 | virtual void addEdge(const std::string &moduleName, uint64_t start, uint64_t end, EdgeType type) = 0; 26 | }; 27 | 28 | class EdgeCollection { 29 | public: 30 | typedef std::pair EdgeTargetType; 31 | 32 | typedef llvm::SmallVector EdgeTargets; 33 | 34 | /* Maps a source program counter to a set of destinations */ 35 | typedef llvm::DenseMap Edges; 36 | 37 | /* Maps a module name to its set of edges */ 38 | typedef std::map ModuleEdges; 39 | 40 | typedef ModuleEdges::const_iterator const_iterator; 41 | 42 | private: 43 | ModuleEdges m_edges; 44 | 45 | public: 46 | bool findEdge(const std::string &moduleName, uint64_t start, uint64_t end, EdgeType *result); 47 | void addEdge(const std::string &moduleName, uint64_t start, uint64_t end, EdgeType type); 48 | 49 | const_iterator end() const { 50 | return m_edges.end(); 51 | } 52 | const_iterator find(const ModuleEdges::key_type &key) const { 53 | return m_edges.find(key); 54 | } 55 | }; 56 | 57 | class EdgeDetector : public Plugin, public IEdgeAdder { 58 | S2E_PLUGIN 59 | public: 60 | EdgeDetector(S2E *s2e) : Plugin(s2e) { 61 | } 62 | 63 | void initialize(); 64 | 65 | /** 66 | * Other plugins can use this only during their configuration phase. 67 | */ 68 | void addEdge(const std::string &moduleName, uint64_t start, uint64_t end, EdgeType type); 69 | 70 | /** 71 | * Signal that is emitted when an edge is detected. 72 | * Only transmit the source instruction. The destination can 73 | * be read with state->regs()->getPc(). 74 | */ 75 | sigc::signal onEdge; 76 | 77 | bool findEdge(const std::string &moduleName, uint64_t start, uint64_t end, EdgeType *result); 78 | 79 | void readConfig(const std::string &configKey, IEdgeAdder *adder); 80 | 81 | private: 82 | sigc::connection m_ins_connection; 83 | sigc::connection m_mod_connection; 84 | 85 | EdgeCollection m_edges; 86 | ModuleExecutionDetector *m_detector; 87 | 88 | void onModuleLoad(S2EExecutionState *state, const ModuleDescriptor &module); 89 | 90 | void onModuleTranslateBlockStart(ExecutionSignal *signal, S2EExecutionState *state, const ModuleDescriptor &module, 91 | TranslationBlock *tb, uint64_t pc); 92 | 93 | void onTranslateInstructionEnd(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, uint64_t pc, 94 | uint64_t addend, const EdgeCollection::Edges *edges); 95 | 96 | void onModuleTranslateBlockComplete(S2EExecutionState *state, const ModuleDescriptor &module, TranslationBlock *tb, 97 | uint64_t endPc); 98 | 99 | void onModuleTransition(S2EExecutionState *state, ModuleDescriptorConstPtr prevModule, 100 | ModuleDescriptorConstPtr nextModule); 101 | 102 | void onEdgeInternal(S2EExecutionState *state, uint64_t sourcePc, uint64_t addend, 103 | const EdgeCollection::EdgeTargets *target); 104 | }; 105 | 106 | } // namespace plugins 107 | } // namespace s2e 108 | 109 | #endif // S2E_PLUGINS_EXAMPLE_H 110 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Support/Database.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015-2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #include "Database.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | extern "C" { 21 | void register_factory_postgresql(); 22 | } 23 | 24 | namespace s2e { 25 | namespace plugins { 26 | 27 | S2E_DEFINE_PLUGIN(Database, "Databse support plugin", ""); 28 | 29 | void Database::initialize() { 30 | // Register soci backends that we want to support 31 | register_factory_postgresql(); 32 | 33 | ConfigFile *cfg = s2e()->getConfig(); 34 | ConfigFile::string_list databases = cfg->getListKeys(getConfigKey()); 35 | 36 | if (databases.empty()) { 37 | getWarningsStream() << "no databases configured!\n"; 38 | } 39 | 40 | for (auto &database : databases) { 41 | std::string connection_string = cfg->getString(getConfigKey() + '.' + database); 42 | 43 | soci::session &db = m_sessions 44 | .emplace(std::piecewise_construct, std::forward_as_tuple(database), 45 | std::forward_as_tuple(connection_string)) 46 | .first->second; 47 | db << "SET AUTOCOMMIT TO ON"; // FIXME: make this configurable 48 | } 49 | 50 | s2e()->getCorePlugin()->onProcessFork.connect(sigc::mem_fun(*this, &Database::onProcessFork)); 51 | } 52 | 53 | void Database::onProcessFork(bool prefork, bool, unsigned) { 54 | if (prefork) { 55 | for (auto &it : m_sessions) 56 | it.second.close(); 57 | } else { 58 | for (auto &it : m_sessions) 59 | it.second.reconnect(); 60 | } 61 | } 62 | 63 | std::string Database::escapeBytea(soci::session &session, const std::vector &data) { 64 | if (session.get_backend_name() == "postgresql") { 65 | PGconn *conn = static_cast(session.get_backend())->conn_; 66 | 67 | size_t out_length = 0; 68 | unsigned char *out_bytes = PQescapeByteaConn(conn, data.data(), data.size(), &out_length); 69 | 70 | std::string out((const char *) out_bytes); 71 | PQfreemem(out_bytes); 72 | 73 | return out; 74 | } else { 75 | llvm::errs() << "Database::escapeBytea() is not supported on " << session.get_backend_name() << " yet\n"; 76 | abort(); 77 | } 78 | } 79 | 80 | } // namespace plugins 81 | } // namespace s2e 82 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Support/Database.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_DATABASE_H 10 | #define S2E_PLUGINS_DATABASE_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace soci { 18 | class session; 19 | } 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | 24 | class Database : public Plugin { 25 | S2E_PLUGIN 26 | 27 | public: 28 | Database(S2E *s2e) : Plugin(s2e) { 29 | } 30 | void initialize(); 31 | 32 | soci::session &session() { 33 | return session("default"); 34 | } 35 | 36 | soci::session &session(const std::string &name) { 37 | try { 38 | return m_sessions.at(name); 39 | } catch (std::out_of_range &) { 40 | getWarningsStream() << "Database " << name << " is not configured!\n"; 41 | exit(-1); 42 | } 43 | } 44 | 45 | static std::string escapeBytea(soci::session &session, const std::vector &data); 46 | 47 | private: 48 | std::map m_sessions; 49 | 50 | void onProcessFork(bool prefork, bool, unsigned); 51 | 52 | }; // class Database 53 | 54 | } // namespace plugins 55 | } // namespace s2e 56 | 57 | #endif // S2E_PLUGINS_DATABASE_H 58 | -------------------------------------------------------------------------------- /src/s2e/Plugins/Support/WebServiceInterface.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2017, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_WEBSVC_H 9 | #define S2E_PLUGINS_WEBSVC_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace s2e { 21 | namespace plugins { 22 | 23 | class WebServiceInterface : public Plugin { 24 | S2E_PLUGIN 25 | public: 26 | WebServiceInterface(S2E *s2e) : Plugin(s2e) { 27 | } 28 | 29 | void initialize(); 30 | 31 | private: 32 | uint64_t m_statsLastSent; 33 | uint64_t m_statsUpdateInterval; 34 | 35 | uint32_t m_maxCompletedPathDepth; 36 | uint32_t m_maxPathDepth; 37 | 38 | uint32_t m_completedPaths; 39 | uint32_t m_completedSeeds; 40 | 41 | uint32_t m_segFaults; 42 | 43 | seeds::SeedSearcher *m_seedSearcher; 44 | recipe::Recipe *m_recipe; 45 | 46 | void sendStats(); 47 | 48 | void onEngineShutdown(); 49 | void onTimer(); 50 | void onProcessForkComplete(bool isChild); 51 | void onStateKill(S2EExecutionState *state); 52 | void onSeed(const seeds::Seed &seed, seeds::SeedEvent event); 53 | void onSegFault(S2EExecutionState *state, uint64_t pid, uint64_t pc); 54 | 55 | void onWindowsUserCrash(S2EExecutionState *state, const WindowsUserModeCrash &desc); 56 | void onWindowsKernelCrash(S2EExecutionState *state, const vmi::windows::BugCheckDescription &desc); 57 | 58 | QDict *getGlobalStats(); 59 | }; 60 | 61 | } // namespace plugins 62 | } // namespace s2e 63 | 64 | #endif // S2E_PLUGINS_WEBSVC_H 65 | -------------------------------------------------------------------------------- /src/s2e/Plugins/SymbolicHardware/SymbolicHardware.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2017, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_SymbolicHardware_H 9 | #define S2E_PLUGINS_SymbolicHardware_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | namespace hw { 24 | 25 | typedef std::vector ConcreteArray; 26 | typedef std::pair SymbolicPortRange; 27 | typedef std::pair SymbolicMmioRange; 28 | 29 | typedef llvm::SmallVector SymbolicPortRanges; 30 | typedef llvm::SmallVector SymbolicMmioRanges; 31 | 32 | class SymbolicHardware : public Plugin { 33 | S2E_PLUGIN 34 | 35 | private: 36 | // TODO: make this per-state and per-device 37 | SymbolicPortRanges m_ports; 38 | SymbolicMmioRanges m_mmio; 39 | 40 | template bool parseRangeList(ConfigFile *cfg, const std::string &key, T &result); 41 | 42 | bool parseConfig(); 43 | 44 | template inline bool isSymbolic(T ports, U port); 45 | 46 | public: 47 | /// 48 | /// \brief onSymbolicRegisterRead control whether 49 | /// a symbolic value should be created upon a read from a symbolic 50 | /// hardware region. 51 | /// 52 | sigc::signal 54 | onSymbolicRegisterRead; 55 | 56 | SymbolicHardware(S2E *s2e) : Plugin(s2e) { 57 | } 58 | 59 | void initialize(); 60 | 61 | bool isPortSymbolic(uint16_t port); 62 | bool isMmioSymbolic(uint64_t physAddr); 63 | 64 | klee::ref createExpression(S2EExecutionState *state, SymbolicHardwareAccessType type, uint64_t address, 65 | unsigned size, uint64_t concreteValue); 66 | }; 67 | 68 | } // namespace hw 69 | } // namespace plugins 70 | } // namespace s2e 71 | 72 | #endif // S2E_PLUGINS_SymbolicHardware_H 73 | -------------------------------------------------------------------------------- /src/s2e/Plugins/VulnerabilityAnalysis/CGCInterface.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015-2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015-2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_CGC_INTERFACE_H 10 | #define S2E_PLUGINS_CGC_INTERFACE_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "PovGenerationPolicy.h" 23 | 24 | #include 25 | #include 26 | 27 | namespace s2e { 28 | namespace plugins { 29 | 30 | enum TC_TYPES { TC_EXP1, TC_EXP2, TC_TEST, TC_CRASH, TC_TIMEOUT }; 31 | enum BB_TYPES { FUNC_ENTRY = 1, ICALL_TGT = 1 << 1, IJMP_TGT = 1 << 2, JIT_ENTRY = 1 << 3 }; 32 | 33 | namespace pov { 34 | class PovGenerator; 35 | } 36 | 37 | class DecreeMonitor; 38 | class ModuleExecutionDetector; 39 | 40 | struct CBStats { 41 | /* Whether the CB called the random() syscall at some point */ 42 | bool calledRandom; 43 | 44 | /* Stores program counters of branches that depend on a random value */ 45 | llvm::DenseSet randomBranchesPc; 46 | }; 47 | 48 | class CGCInterface : public Plugin { 49 | S2E_PLUGIN 50 | 51 | typedef PovGenerationPolicy::TestCaseType TestCaseType; 52 | 53 | private: 54 | friend class CGCInterfaceState; 55 | DecreeMonitor *m_monitor; 56 | ModuleExecutionDetector *m_detector; 57 | ProcessExecutionDetector *m_procDetector; 58 | pov::DecreePovGenerator *m_povGenerator; 59 | PovGenerationPolicy *m_exploitGenerator; 60 | coverage::BasicBlockCoverage *m_coverage; 61 | coverage::TranslationBlockCoverage *m_tbcoverage; 62 | ControlFlowGraph *m_cfg; 63 | CallSiteMonitor *m_csTracker; 64 | seeds::SeedSearcher *m_seedSearcher; 65 | models::StaticFunctionModels *m_models; 66 | 67 | typedef std::set AddressSet; 68 | typedef std::unordered_map BBFlags; 69 | BBFlags m_bbFlags; 70 | 71 | uint64_t m_maxPovCount; 72 | bool m_recordAllPaths; 73 | bool m_recordConstraints; 74 | bool m_disableSendingExtraDataToDB; // data is used by fuzzer 75 | 76 | std::unordered_map m_cbStats; 77 | uint64_t m_cbStatsLastSent; 78 | unsigned m_cbStatsUpdateInterval; 79 | bool m_cbStatsChanged; 80 | 81 | uint64_t m_timeOfLastCoverageReport; 82 | uint64_t m_coverageTimeout; 83 | 84 | coverage::GlobalCoverage m_coveredTbs; 85 | coverage::ModuleTBs m_localCoveredTbs; 86 | 87 | typedef pov::PovOptions PovOptions; 88 | typedef pov::PovType PovType; 89 | 90 | bool sendCoveragePov(S2EExecutionState *state, TestCaseType tctype); 91 | 92 | void onStateKill(S2EExecutionState *state); 93 | 94 | void onRandom(S2EExecutionState *state, uint64_t pid, const std::vector> &); 95 | 96 | void onRandomInputFork(S2EExecutionState *state, const ModuleDescriptor &module); 97 | 98 | void onTimer(); 99 | 100 | void onPovReady(S2EExecutionState *state, const PovOptions &opt, const std::string &recipeName, 101 | const std::vector &filePaths, TestCaseType tcType); 102 | 103 | void sendTestcase(S2EExecutionState *state, const std::string &xmlPovPath, const std::string &cPovPath, 104 | TestCaseType tcType, const PovOptions &opt, const std::string &recipeName = ""); 105 | 106 | void constraintsToJson(S2EExecutionState *state, std::stringstream &output); 107 | std::string constraintsToJsonFile(S2EExecutionState *state); 108 | 109 | void processIntermediateCoverage(uint64_t currentTime); 110 | 111 | bool updateCoverage(S2EExecutionState *state); 112 | 113 | public: 114 | CGCInterface(S2E *s2e) : Plugin(s2e) { 115 | } 116 | void initialize(); 117 | }; // class CGCInterface 118 | 119 | } // namespace plugins 120 | } // namespace s2e 121 | 122 | #endif // S2E_PLUGINS_CGC_INTERFACE_H 123 | -------------------------------------------------------------------------------- /src/s2e/Plugins/VulnerabilityAnalysis/DecreePovGenerator.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2015-2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2014-2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_POVGEN_H 10 | #define S2E_PLUGINS_POVGEN_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "PovGenerator.h" 22 | 23 | namespace s2e { 24 | namespace plugins { 25 | namespace pov { 26 | 27 | class DecreePovGeneratorState; 28 | 29 | /** Handler required for KLEE interpreter */ 30 | class DecreePovGenerator : public PovGenerator { 31 | S2E_PLUGIN 32 | 33 | private: 34 | typedef std::pair> VarValuePair; 35 | typedef std::vector ConcreteInputs; 36 | 37 | typedef std::set AddressSet; 38 | AddressSet m_povAddresses; // addresses at which POVs were generated 39 | unsigned m_numPOVs; // number of POVs generated so far 40 | 41 | static const std::string XML_HEADER, XML_FOOTER; 42 | static const std::string C_HEADER, C_FOOTER; 43 | DecreeMonitor *m_monitor; 44 | ProcessExecutionDetector *m_detector; 45 | ModuleExecutionDetector *m_modules; 46 | seeds::SeedSearcher *m_seedSearcher; 47 | 48 | std::string generatePoV(bool xmlFormat, uint64_t seedIndex, const DecreePovGeneratorState *plgState, 49 | const PovOptions &opt, const VariableRemapping &remapping, const klee::Assignment &solution, 50 | const klee::ConstraintManager &constraints); 51 | 52 | void generatePoV(S2EExecutionState *state, const PovOptions &opt, std::string &xmlPov, std::string &cPov); 53 | 54 | public: 55 | DecreePovGenerator(S2E *s2e); 56 | 57 | void initialize(); 58 | 59 | bool generatePoV(S2EExecutionState *state, const PovOptions &opt, const std::string &filePrefix, 60 | std::vector &filePaths); 61 | 62 | static bool isReceive(const klee::Array *array); 63 | static bool isRandom(const klee::Array *array); 64 | static bool isRandomRead(const klee::ref &e); 65 | static bool isReceiveRead(const klee::ref &e); 66 | 67 | sigc::signal onRandomInputFork; 68 | 69 | private: 70 | void unmergeSelects(S2EExecutionState *state, const klee::Assignment &assignment); 71 | 72 | void onStateFork(S2EExecutionState *state, const std::vector &newStates, 73 | const std::vector> &newConditions); 74 | 75 | void onRandom(S2EExecutionState *state, uint64_t pid, const std::vector> &data); 76 | 77 | void onWrite(S2EExecutionState *state, uint64_t pid, uint64_t fd, const std::vector> &data, 78 | klee::ref sizeExpr); 79 | 80 | void onSymbolicRead(S2EExecutionState *state, uint64_t pid, uint64_t fd, uint64_t size, 81 | const std::vector>, std::string>> &data, 82 | klee::ref sizeExpr); 83 | 84 | void onConcreteRead(S2EExecutionState *state, uint64_t pid, uint64_t fd, const std::vector &data); 85 | 86 | void generateNegotiate(std::stringstream &ss, bool xmlFormat, const PovOptions &opt); 87 | void generateReadSecret(std::stringstream &ss, bool xmlFormat, const PovOptions &opt); 88 | }; 89 | } 90 | } 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/s2e/Plugins/VulnerabilityAnalysis/FilePovGenerator.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2018, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_FilePovGenerator_H 9 | #define S2E_PLUGINS_FilePovGenerator_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include "PovGenerator.h" 18 | 19 | namespace s2e { 20 | namespace plugins { 21 | namespace pov { 22 | 23 | class FilePovGenerator : public PovGenerator { 24 | S2E_PLUGIN 25 | public: 26 | FilePovGenerator(S2E *s2e) : PovGenerator(s2e) { 27 | } 28 | 29 | void initialize(); 30 | 31 | virtual bool generatePoV(S2EExecutionState *state, const PovOptions &opt, const std::string &filePrefix, 32 | std::vector &filePaths); 33 | 34 | private: 35 | testcases::TestCaseGenerator *m_tc; 36 | 37 | uint64_t m_gp; 38 | uint64_t m_pc; 39 | 40 | void assignNegotiatedVariables(std::unordered_map &varAssignment, const PovOptions &opt); 41 | 42 | void constrainNegotiatedVariables(S2EExecutionState *state, std::unordered_map &varAssignment, 43 | PovOptions &opt); 44 | }; 45 | 46 | } // namespace pov 47 | } // namespace plugins 48 | } // namespace s2e 49 | 50 | #endif // S2E_PLUGINS_FilePovGenerator_H 51 | -------------------------------------------------------------------------------- /src/s2e/Plugins/VulnerabilityAnalysis/PovGenerationPolicy.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2015-2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_PovGenerationPolicy_H 10 | #define S2E_PLUGINS_PovGenerationPolicy_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace s2e { 22 | namespace plugins { 23 | 24 | namespace recipe { 25 | class Recipe; 26 | } 27 | 28 | class DecreeMonitor; 29 | 30 | class PovGenerationPolicy : public Plugin { 31 | S2E_PLUGIN 32 | 33 | private: 34 | DecreeMonitor *m_decreeMonitor; 35 | LinuxMonitor *m_linuxMonitor; 36 | WindowsCrashMonitor *m_windowsCrashMonitor; 37 | 38 | recipe::Recipe *m_recipe; 39 | pov::PovGenerator *m_povGenerator; 40 | ProcessExecutionDetector *m_process; 41 | 42 | uint64_t m_maxCrashCount; 43 | uint64_t m_crashCount; 44 | 45 | typedef pov::PovOptions PovOptions; 46 | typedef pov::PovType PovType; 47 | 48 | typedef std::tuple UniquePovKey; 49 | typedef std::map UniquePovMap; 50 | 51 | // TODO: implement proper sharing between multiple s2e processes (e.g., through KeyValueStore plugin) 52 | UniquePovMap m_uniquePovMap; 53 | unsigned m_maxPovCount; 54 | 55 | void onPovReadyHandler(S2EExecutionState *state, const PovOptions &opt, const std::string &recipeName, 56 | bool isCrash); 57 | void onSegFault(S2EExecutionState *state, uint64_t pid, uint64_t pc); 58 | 59 | void onSegFaultWinUser(S2EExecutionState *state, const WindowsUserModeCrash &crash); 60 | 61 | void onSegFaultWinKernel(S2EExecutionState *state, const vmi::windows::BugCheckDescription &crash); 62 | 63 | void onSymbolicAddress(S2EExecutionState *state, ref virtualAddress, uint64_t concreteAddress, 64 | bool &concretize, CorePlugin::symbolicAddressReason reason); 65 | 66 | public: 67 | enum TestCaseType { POV, CRASH, END_OF_PATH, PARTIAL_PATH }; 68 | 69 | void initialize(); 70 | PovGenerationPolicy(S2E *s2e) : Plugin(s2e) { 71 | } 72 | 73 | sigc::signal & /* filePaths */, TestCaseType /* tcType */> 75 | onPovReady; 76 | }; 77 | 78 | } // namespace plugins 79 | } // namespace s2e 80 | 81 | #endif // S2E_PLUGINS_PovGenerationPolicy_H 82 | -------------------------------------------------------------------------------- /src/s2e/Plugins/VulnerabilityAnalysis/PovGenerator.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2018, Cyberhaven 3 | /// All rights reserved. 4 | /// 5 | /// Licensed under the Cyberhaven Research License Agreement. 6 | /// 7 | 8 | #ifndef S2E_PLUGINS_PovGenerator_H 9 | #define S2E_PLUGINS_PovGenerator_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace s2e { 17 | namespace plugins { 18 | namespace pov { 19 | 20 | const std::string VARNAME_PC = "$pc"; 21 | const std::string VARNAME_GP = "$gp"; 22 | const std::string VARNAME_ADDR = "$addr"; 23 | const std::string VARNAME_SIZE = "$size"; 24 | 25 | enum PovType { POV_GENERAL, POV_TYPE1, POV_TYPE2 }; 26 | 27 | typedef std::vector> ExprList; 28 | typedef std::map VariableRemapping; 29 | 30 | struct PovOptions { 31 | PovType m_type; 32 | uint64_t m_faultAddress; 33 | uint64_t m_ipMask; 34 | uint64_t m_regMask; 35 | uint64_t m_regNum; 36 | size_t m_bytesBeforeSecret; 37 | ExprList m_extraConstraints; 38 | VariableRemapping m_remapping; 39 | PovOptions() { 40 | m_type = POV_GENERAL; 41 | m_faultAddress = 0; 42 | m_ipMask = 0; 43 | m_regMask = 0; 44 | m_regNum = 0; 45 | m_bytesBeforeSecret = 0; 46 | } 47 | }; 48 | 49 | class PovGenerator : public Plugin { 50 | protected: 51 | bool m_compress; 52 | 53 | PovGenerator(S2E *s2e) : Plugin(s2e) { 54 | m_compress = false; 55 | } 56 | 57 | static std::string getFileName(S2EExecutionState *state, const PovOptions &opt, const std::string &filePrefix, 58 | const std::string &fileExtWithoutDot); 59 | 60 | static bool writeToFile(const std::string &fileName, const void *data, unsigned size, bool compress); 61 | 62 | std::string writeToFile(S2EExecutionState *state, const PovOptions &opt, const std::string &filePrefix, 63 | const std::string &fileExtWithoutDot, const void *data, unsigned data_size); 64 | 65 | bool solveConstraints(S2EExecutionState *state, const PovOptions &opt, klee::Assignment &assignment); 66 | 67 | public: 68 | /** TODO: move this to some common plugin */ 69 | static void compress(const void *in_data, size_t in_data_size, std::vector &out_data); 70 | static std::vector compress(const std::string &s); 71 | static std::vector compress(const void *data, unsigned size); 72 | 73 | virtual bool generatePoV(S2EExecutionState *state, const PovOptions &opt, const std::string &filePrefix, 74 | std::vector &filePaths) = 0; 75 | }; 76 | 77 | } // namespace pov 78 | } // namespace plugins 79 | } // namespace s2e 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/s2e/Plugins/VulnerabilityAnalysis/Recipe/Register.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #include "Register.h" 10 | 11 | namespace s2e { 12 | namespace plugins { 13 | namespace recipe { 14 | 15 | const char *Register::s_regs32[10] = {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "EIP", nullptr}; 16 | const char *Register::s_regs64[18] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", 17 | "R9", "R10", "R11", "R12", "R13", "R14", "R15", "RIP", nullptr}; 18 | 19 | std::string Register::name() const { 20 | if (m_bits == 32) { 21 | return s_regs32[m_reg]; 22 | } else { 23 | return s_regs64[m_reg]; 24 | } 25 | } 26 | 27 | klee::ref Register::fromName(const std::string &name, unsigned byteIdx) { 28 | 29 | for (unsigned i = 0; s_regs32[i]; ++i) { 30 | if (s_regs32[i] == name) { 31 | return klee::ref(new Register(i, 32, byteIdx)); 32 | } 33 | } 34 | 35 | for (unsigned i = 0; s_regs64[i]; ++i) { 36 | if (s_regs64[i] == name) { 37 | return klee::ref(new Register(i, 64, byteIdx)); 38 | } 39 | } 40 | 41 | return nullptr; 42 | } 43 | 44 | klee::ref Register::fromIndex(Reg reg, uint8_t bits) { 45 | return new Register(reg, bits, 0); 46 | } 47 | 48 | bool Register::isPc() const { 49 | if (m_bits == 32) { 50 | return m_reg == 8; 51 | } else if (m_bits == 64) { 52 | return m_reg == 16; 53 | } 54 | return false; 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/s2e/Plugins/VulnerabilityAnalysis/Recipe/Register.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Copyright (C) 2016, Dependable Systems Laboratory, EPFL 3 | /// Copyright (C) 2016, Cyberhaven 4 | /// All rights reserved. 5 | /// 6 | /// Licensed under the Cyberhaven Research License Agreement. 7 | /// 8 | 9 | #ifndef S2E_PLUGINS_RecipeRegister_H_ 10 | #define S2E_PLUGINS_RecipeRegister_H_ 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace s2e { 18 | namespace plugins { 19 | namespace recipe { 20 | 21 | class Register { 22 | public: 23 | typedef uint8_t Reg; 24 | 25 | private: 26 | static const char *s_regs32[]; 27 | static const char *s_regs64[]; 28 | 29 | Reg m_reg = -1; 30 | uint8_t m_bits = 0; 31 | uint8_t m_idx = 0; 32 | 33 | Register() { 34 | } 35 | 36 | Register(Reg regIdx, uint8_t bits, uint8_t idx) : m_reg(regIdx), m_bits(bits), m_idx(idx) { 37 | assert(bits == 32 || bits == 64); 38 | assert(!(bits == 32) || ((regIdx < 9) && (idx < 4))); 39 | assert(!(bits == 64) || ((regIdx < 17) && (idx < 8))); 40 | } 41 | 42 | public: 43 | // These are required for klee::ref<> 44 | unsigned refCount = 0; 45 | bool permanent = false; 46 | bool temporary = false; 47 | 48 | static klee::ref fromName(const std::string &name, unsigned byteIdx); 49 | static klee::ref fromIndex(Reg reg, uint8_t bits); 50 | std::string name() const; 51 | 52 | bool operator==(const Register &rhs) const { 53 | return compare(rhs) == 0; 54 | } 55 | 56 | uint8_t reg() const { 57 | return m_reg; 58 | } 59 | uint8_t bits() const { 60 | return m_bits; 61 | } 62 | uint8_t idx() const { 63 | return m_idx; 64 | } 65 | 66 | bool isPc() const; 67 | 68 | int compare(const Register &b) const { 69 | return m_reg - b.m_reg; 70 | } 71 | }; 72 | } 73 | } 74 | } 75 | 76 | #endif 77 | --------------------------------------------------------------------------------