def test_trace(self): """ This checks the sequence of pushes and pops that take place during an example execution. That sequence isn't meant to be invariant, so if you change the implementation and break this test, by all means, replace it with the new sequence. :return: """ def arg_gen(_state): return [I32(1337)] m = ManticoreWASM(wasm_file) tracker_plugin = StackTrackerPlugin() m.register_plugin(tracker_plugin) m.invoke("collatz", arg_gen) m.run() results = [] for idx, val_list in enumerate(m.collect_returns()): results.append(val_list[0][0]) self.assertEqual(sorted(results), [44]) push_pop_seq = "".join(tracker_plugin.context.get("push_pop_seq")) self.assertEqual(push_pop_seq, "+-" * 892)
def test_getchar(self): m = ManticoreWASM(wasm_file, env={"getchar": getchar}) m.invoke("main") m.run() results = [] for idx, val_list in enumerate(m.collect_returns()): results.append(val_list[0][0]) self.assertEqual(sorted(results), [0, 1, 2, 5, 7, 8, 16])
def test_symbolic_args(self): m = ManticoreWASM(wasm_file, env={}) m.invoke("collatz", arg_gen) m.run() results = [] for idx, val_list in enumerate(m.collect_returns()): results.append(val_list[0][0]) self.assertEqual(sorted(results), [2, 3, 8]) m.finalize() inputs = [] for fn in glob.glob(m.workspace + "/*.input"): with open(fn, "r") as f: raw = f.read().strip() inputs.append(int(raw.replace("collatz_arg: ", ""))) self.assertEqual(sorted(inputs), [4, 6, 8])
def test_plugin(self): def arg_gen(_state): return [I32(1337)] m = ManticoreWASM(wasm_file) counter_plugin = CallCounterPlugin() m.register_plugin(counter_plugin) m.invoke("collatz", arg_gen) m.run() # counts = m.context.get("<class 'test_examples.CallCounterPlugin'>").get("counter") counts = counter_plugin.context.get("counter") self.assertEqual(counts["br_if"], 45) self.assertEqual(counts["loop"], 44) self.assertEqual(counts["i32.add"], 88) results = [] for idx, val_list in enumerate(m.collect_returns()): results.append(val_list[0][0]) self.assertEqual(sorted(results), [44])
def arg_gen(state): # Generate a symbolic argument to pass to the collatz function. # Possible values: 4, 6, 8 arg = state.new_symbolic_value(32, "collatz_arg") state.constrain(arg > 3) state.constrain(arg < 9) state.constrain(arg % 2 == 0) return [arg] # Set up Manticore to run the collatz function with the given argument generator. # We use an argument generator function instead of a list of arguments because Manticore # might have multiple states waiting to begin execution, and we can conveniently map a # generator function over all the ready states and get access to their respective # constraint sets. m.invoke("collatz", arg_gen) # Run the collatz function m.run() # Manually collect return values for idx, val_list in enumerate(m.collect_returns()): print("State", idx, "::", val_list[0]) # Finalize the run (dump testcases) m.finalize() print( """