From 5288d5da3d81e578faa00ffb6bd2d40ea98bb205 Mon Sep 17 00:00:00 2001 From: Peter Goodman Date: Wed, 5 Dec 2018 13:55:57 -0500 Subject: [PATCH 1/3] Saturating version of InRange, new variable UsingSymExec --- bin/deepstate/common.py | 3 +++ bin/deepstate/main_angr.py | 7 ++++++ bin/deepstate/main_manticore.py | 8 +++++++ src/include/deepstate/DeepState.h | 38 +++++++++++++++++++++++++------ src/include/deepstate/Log.h | 1 + src/lib/DeepState.c | 9 ++++++++ src/lib/Log.c | 2 +- 7 files changed, 60 insertions(+), 8 deletions(-) diff --git a/bin/deepstate/common.py b/bin/deepstate/common.py index 8ca19ee..59828aa 100644 --- a/bin/deepstate/common.py +++ b/bin/deepstate/common.py @@ -87,6 +87,9 @@ class DeepState(object): def write_uint8_t(self, ea, val): raise NotImplementedError("Must be implemented by engine.") + def write_uint32_t(self, ea, val): + raise NotImplementedError("Must be implemented by engine.") + def concretize(self, val, constrain=False): raise NotImplementedError("Must be implemented by engine.") diff --git a/bin/deepstate/main_angr.py b/bin/deepstate/main_angr.py index 5478c94..b122d49 100644 --- a/bin/deepstate/main_angr.py +++ b/bin/deepstate/main_angr.py @@ -84,6 +84,10 @@ class DeepAngr(DeepState): self.state.memory.store(ea, val, size=1) return ea + 1 + def write_uint32_t(self, ea, val): + self.state.memory.store(ea, val, size=4) + return ea + 4 + def concretize(self, val, constrain=False): if isinstance(val, (int, long)): return val @@ -336,6 +340,9 @@ def hook_apis(args, project, run_state): mc = DeepAngr(state=run_state) apis = mc.read_api_table(ea_of_api_table) + # Tell the system that we're using symbolic execution. + mc.write_uint32_t(apis["UsingSymExec"], 1) + # Hook various functions. hook_function(project, apis['IsSymbolicUInt'], IsSymbolicUInt) hook_function(project, apis['ConcretizeData'], ConcretizeData) diff --git a/bin/deepstate/main_manticore.py b/bin/deepstate/main_manticore.py index 8f0a356..c467f97 100644 --- a/bin/deepstate/main_manticore.py +++ b/bin/deepstate/main_manticore.py @@ -87,6 +87,10 @@ class DeepManticore(DeepState): self.state.cpu.write_int(ea, val, size=8) return ea + 1 + def write_uint32_t(self, ea, val): + self.state.cpu.write_int(ea, val, size=32) + return ea + 1 + def concretize(self, val, constrain=False): if isinstance(val, (int, long)): return val @@ -418,6 +422,10 @@ def main_takeover(m, args, takeover_symbol): base = get_base(m) apis = mc.read_api_table(ea_of_api_table, base) + + # Tell the system that we're using symbolic execution. + mc.write_uint32_t(apis["UsingSymExec"], 1) + del mc fake_test = TestInfo(takeover_ea, '_takeover_test', '_takeover_file', 0) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index 1020910..613a732 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -230,17 +230,41 @@ DEEPSTATE_INLINE static void DeepState_Check(int expr) { } } -/* Return a symbolic value in a the range `[low_inc, high_inc]`. */ +/* Return a symbolic value in a the range `[low_inc, high_inc]`. + * + * Current implementation saturates values. An alternative implementation + * worth exploring, and perhaps supporting in addition to saturation, is + * something like: + * + * x = symbolic_value; + * size = (high - low) + 1 + * if (symbolic mode) { + * assume 0 <= x and x < size + * return x + * } else { + * return low + (x % size) + * } + * + * This type of version lets a reducer drive toward zero. + */ #define DEEPSTATE_MAKE_SYMBOLIC_RANGE(Tname, tname) \ DEEPSTATE_INLINE static tname DeepState_ ## Tname ## InRange( \ tname low, tname high) { \ - tname x = DeepState_ ## Tname(); \ - if (!(DeepState_UsingLibFuzzer || HAS_FLAG_input_test_file \ - || HAS_FLAG_input_test_dir || HAS_FLAG_input_test_files_dir)) \ + if (low > high) { \ + return DeepState_ ## Tname ## InRange(high, low); \ + } \ + const tname x = DeepState_ ## Tname(); \ + if (DeepState_UsingSymExec) { \ (void) DeepState_Assume(low <= x && x <= high); \ - else \ - x = low + (x%((high+1)-low)); \ - return x; \ + return x; \ + } \ + if (x < low) { \ + return low; \ + } else if (x > high) { \ + return high; \ + } else { \ + return x; \ + } \ } DEEPSTATE_MAKE_SYMBOLIC_RANGE(Size, size_t) diff --git a/src/include/deepstate/Log.h b/src/include/deepstate/Log.h index 8cb2767..7763c5d 100644 --- a/src/include/deepstate/Log.h +++ b/src/include/deepstate/Log.h @@ -24,6 +24,7 @@ DEEPSTATE_BEGIN_EXTERN_C extern int DeepState_UsingLibFuzzer; +extern int DeepState_UsingSymExec; struct DeepState_Stream; diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 91bbfc4..ad4a61a 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -38,6 +38,12 @@ DEFINE_bool(take_over, false, "Replay test cases in take-over mode."); DEFINE_bool(abort_on_fail, false, "Abort on file replay failure (useful in file fuzzing)."); DEFINE_bool(verbose_reads, false, "Report on bytes being read during execution of test."); +/* Set to 1 by Manticore/Angr/etc. when we're running symbolically. */ +int DeepState_UsingSymExec = 0; + +/* Set to 1 when we're using libFuzzer. */ +int DeepState_UsingLibFuzzer = 0; + /* Pointer to the last registers DeepState_TestInfo data structure */ struct DeepState_TestInfo *DeepState_LastTestInfo = NULL; @@ -366,6 +372,9 @@ const struct DeepState_IndexEntry DeepState_API[] = { {"StreamFloat", (void *) _DeepState_StreamFloat}, {"StreamString", (void *) _DeepState_StreamString}, + {"UsingLibFuzzer", (void *) &DeepState_UsingLibFuzzer}, + {"UsingSymExec", (void *) &DeepState_UsingSymExec}, + {NULL, NULL}, }; diff --git a/src/lib/Log.c b/src/lib/Log.c index e09eab3..63d67e4 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -66,7 +66,7 @@ enum { DeepState_LogBufSize = 4096 }; -int DeepState_UsingLibFuzzer = 0; +extern int DeepState_UsingLibFuzzer; char DeepState_LogBuf[DeepState_LogBufSize + 1] = {}; From 48092c7b4b7560ffaadb91272856e5eac707ca87 Mon Sep 17 00:00:00 2001 From: Peter Goodman Date: Wed, 5 Dec 2018 13:57:07 -0500 Subject: [PATCH 2/3] Update main_manticore.py --- bin/deepstate/main_manticore.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/deepstate/main_manticore.py b/bin/deepstate/main_manticore.py index c467f97..b7de01d 100644 --- a/bin/deepstate/main_manticore.py +++ b/bin/deepstate/main_manticore.py @@ -89,7 +89,7 @@ class DeepManticore(DeepState): def write_uint32_t(self, ea, val): self.state.cpu.write_int(ea, val, size=32) - return ea + 1 + return ea + 4 def concretize(self, val, constrain=False): if isinstance(val, (int, long)): From fa2cc6ab382b79f1ff3825a8890988db7cfd62a0 Mon Sep 17 00:00:00 2001 From: Peter Goodman Date: Wed, 5 Dec 2018 13:58:03 -0500 Subject: [PATCH 3/3] Update DeepState.h --- src/include/deepstate/DeepState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index 613a732..bc0661b 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -240,7 +240,7 @@ DEEPSTATE_INLINE static void DeepState_Check(int expr) { * size = (high - low) + 1 * if (symbolic mode) { * assume 0 <= x and x < size - * return x + * return low + x * } else { * return low + (x % size) * }