def test(): from manticore.native import Manticore m = Manticore("test_ais3_crackme/ais3_crackme", ["a" * 30]) buffer_addr = 0 num_bytes = 24 with m.locked_context() as w: w[1] = False @m.hook(0x4005CD) def hook(state): print("fake 2 args EDI=2") state.cpu.EDI = 0x2 @m.hook(0x4005F3) def hook(state): print("retreive buffer from rax") global buffer_addr # print state.cpu.read_int(state.cpu.RAX), 'yoo' # assert 0 solution = state.new_symbolic_buffer(num_bytes) state.constrain(solution[0] == ord("a")) state.constrain(solution[1] == ord("i")) state.constrain(solution[2] == ord("s")) state.constrain(solution[3] == ord("3")) state.constrain(solution[4] == ord("{")) buffer_addr = state.cpu.read_int(state.cpu.RAX) with m.locked_context() as w: w[1] = buffer_addr print("buffer addr : %08x " % (buffer_addr)) state.cpu.write_bytes(buffer_addr, solution) @m.hook(0x40060E) def hook(state): state.abandon() print("failure path") @m.hook(0x400602) def hook(state): print("win path: attemping to solve") with m.locked_context() as w: buffer_addr = w[1] res = "".join(map(chr, state.solve_buffer(buffer_addr, num_bytes))) print("flag: %s" % res) if res == "ais3{I_tak3_g00d_n0t3s}": with m.locked_context() as w: w[1] = True m.kill() m.verbosity = 1 m.run() with m.locked_context() as w: assert w[1]
class StateMergeTest(unittest.TestCase): # Need to add a plugin that counts the number of states in did_fork_state, and records the max # Then, when we hit class StateCounter(Plugin): def did_fork_state_callback(self, *_args, **_kwargs): self.max_states = max( self.max_states, self.manticore.count_busy_states() + self.manticore.count_ready_states() + self.manticore.count_killed_states() + self.manticore.count_terminated_states(), ) @property def max_states(self): with self.manticore.locked_context() as ctx: return ctx.setdefault("max_states", 0) @max_states.setter def max_states(self, new_val): with self.manticore.locked_context() as ctx: ctx["max_states"] = new_val def setUp(self): core = config.get_group("core") core.seed = 61 core.mprocessing = core.mprocessing.single dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "basic_state_merging"), policy="random" ) self.plugin = self.StateCounter() self.m.register_plugin(Merger()) self.m.register_plugin(self.plugin) def test_state_merging(self): @self.m.hook(0x40065D) def hook_post_merge(*_args, **_kwargs): with self.m.locked_context() as ctx: ctx["state_count"] = ( self.m.count_busy_states() + self.m.count_ready_states() + self.m.count_killed_states() + self.m.count_terminated_states() ) self.m.run() s = config.get_group("core").seed self.assertLess( self.m.context["state_count"], self.plugin.max_states, f"State merging failed with seed: {s}", )
def executeDirected(program, pathsObject, args=[]): workplace_url = "/tmp/mcore_tmp" m = Manticore(program, argv=args, workspace_url=workplace_url, pure_symbolic=False) consts = config.get_group("core") consts.__setattr__("procs", 1) #Store variables in global context to ensure that we can communicate them to the callback function with m.locked_context() as context: context['paths'] = pathsObject context['targets'] = dict() #Register hook to have each executed instruction's RIP logged m.add_hook(None, log_rip) m.register_plugin(DirectedExtractorPlugin()) #Output the set of paths for i in pathsObject.paths: l = [hex(j) for j in i.path] logger.debug(",".join(l)) #Execute the directed symbolic execution m.run() #Obtain the dictionary of control flow edges from Manticore with m.locked_context() as context: targets = context['targets'] #Output results logger.debug("--Results Sorted by Pathlen--") sortedPaths = sorted(pathsObject.paths, key=lambda x: x.pathLen, reverse=False) for i in range(pathsObject.pathsLen): pathID = sortedPaths[i].pathID if pathID in targets.keys(): logger.debug("Path " + str(pathID) + "[len=" + str(sortedPaths[i].pathLen) + "] ending with " + hex( pathsObject.lastAddresses[pathID]) + " has the following successors " + ",".join([str(i) for i in targets[pathID]])) else: logger.debug("Path " + str(pathID) + "[len=" + str(sortedPaths[i].pathLen) + "]" + " is infeasible") return targets
def concrete_run(prog, params): print "Starting concrete execution" m = Manticore(prog, params) # 'trace' will contain the executed instructions m.context['trace'] = [] # None: The hook will be applied to all the instructions @m.hook(None) def record_trace(state): pc = state.cpu.PC # Store the instruction with m.locked_context() as c: c['trace'] += [pc] m.run() # Print number of instructions recorded with m.locked_context() as c: print "%d instructions are recorded" % len(c['trace']) return c
class ManticoreTest(unittest.TestCase): _multiprocess_can_split_ = True def setUp(self): dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "arguments_linux_amd64")) def test_profiling_data(self): p = Profiler() self.m.verbosity(0) self.m.register_plugin(p) self.m.run() profile_path = os.path.join(self.m.workspace, "profiling.bin") with open(profile_path, "wb") as f: p.save_profiling_data(f) self.assertTrue(os.path.exists(profile_path)) self.assertTrue(os.path.getsize(profile_path) > 0) def test_add_hook(self): def tmp(state): pass entry = 0x00400E40 self.m.add_hook(entry, tmp) self.assertTrue(tmp in self.m._hooks[entry]) def test_hook_dec(self): entry = 0x00400E40 @self.m.hook(entry) def tmp(state): pass self.assertTrue(tmp in self.m._hooks[entry]) def test_hook(self): self.m.context["x"] = 0 @self.m.hook(None) def tmp(state): with self.m.locked_context() as ctx: ctx["x"] = 1 self.m.kill() self.m.run() self.assertEqual(self.m.context["x"], 1) def test_init_hook(self): self.m.context["x"] = 0 @self.m.init def tmp(m, _ready_states): m.context["x"] = 1 m.kill() self.m.run() self.assertEqual(self.m.context["x"], 1) def test_hook_dec_err(self): with self.assertRaises(TypeError): @self.m.hook("0x00400e40") def tmp(state): pass def test_symbol_resolution(self): dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "basic_linux_amd64")) self.assertTrue(self.m.resolve("sbrk"), 0x449EE0) def test_symbol_resolution_fail(self): with self.assertRaises(ValueError): self.m.resolve("does_not_exist") def test_integration_basic_stdin(self): import struct dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "basic_linux_amd64")) self.m.run() self.m.finalize() workspace = self.m._output.store.uri with open(os.path.join(workspace, "test_00000000.stdin"), "rb") as f: a = struct.unpack("<I", f.read())[0] with open(os.path.join(workspace, "test_00000001.stdin"), "rb") as f: b = struct.unpack("<I", f.read())[0] if a > 0x41: self.assertTrue(a > 0x41) self.assertTrue(b <= 0x41) else: self.assertTrue(a <= 0x41) self.assertTrue(b > 0x41)
#!/usr/bin/env python import sys from manticore.native import Manticore """ Count the number of emulated instructions. This example uses the context property of the Manticore object to store data that's updated by the hook function. Manticore.context is needed to properly share data when running with multiple worker processes. """ if __name__ == "__main__": if len(sys.argv) < 2: sys.stderr.write(f"Usage: {sys.argv[0]} [binary]\n") sys.exit(2) m = Manticore(sys.argv[1]) with m.locked_context() as context: context["count"] = 0 @m.hook(None) def explore(state): with m.locked_context() as context: context["count"] += 1 m.run() print(f"Executed {m.context['count']} instructions.")
def test_resume(self): m = Manticore(ms_file, stdin_size=17) with m.locked_context() as ctx: self.assertNotIn("unlocked", str(m._lock))
class ManticoreTest(unittest.TestCase): _multiprocess_can_split_ = True def setUp(self): dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "arguments_linux_amd64")) def test_profiling_data(self): p = Profiler() set_verbosity(0) self.m.register_plugin(p) self.m.run() self.m.finalize() profile_path = os.path.join(self.m.workspace, "profiling.bin") self.assertTrue(os.path.exists(profile_path)) self.assertTrue(os.path.getsize(profile_path) > 0) profile_path_2 = os.path.join(self.m.workspace, "profiling_2.bin") with open(profile_path_2, "wb") as f: p.save_profiling_data(f) self.assertTrue(os.path.exists(profile_path_2)) self.assertTrue(os.path.getsize(profile_path_2) > 0) self.assertTrue(filecmp.cmp(profile_path, profile_path_2)) def test_add_hook(self): def tmp(state): pass entry = 0x00400E40 self.m.add_hook(entry, tmp) self.assertTrue(tmp in self.m._hooks[entry]) def test_hook_dec(self): entry = 0x00400E40 @self.m.hook(entry) def tmp(state): pass self.assertTrue(tmp in self.m._hooks[entry]) def test_hook(self): self.m.context["x"] = 0 @self.m.hook(None) def tmp(state): with self.m.locked_context() as ctx: ctx["x"] = 1 self.m.kill() self.m.run() self.assertEqual(self.m.context["x"], 1) def test_add_hook_after(self): def tmp(state): pass entry = 0x00400E40 self.m.add_hook(entry, tmp, after=True) assert tmp in self.m._after_hooks[entry] def test_hook_after_dec(self): entry = 0x00400E40 @self.m.hook(entry, after=True) def tmp(state): # Make sure we've executed the instruction at entry and we're at # the next one (but before it executes). assert state.cpu.PC == 0x00400E42 self.m.kill() self.m.run() assert tmp in self.m._after_hooks[entry] def test_add_sys_hook(self): name = "sys_brk" index = 12 def tmp(state): assert state._platformn._syscall_abi.syscall_number() == index self.m.kill() self.m.add_hook(name, tmp, syscall=True) self.assertTrue(tmp in self.m._sys_hooks[index]) def test_sys_hook_dec(self): index = 12 @self.m.hook(index, syscall=True) def tmp(state): assert state._platformn._syscall_abi.syscall_number() == index self.m.kill() self.assertTrue(tmp in self.m._sys_hooks[index]) def test_sys_hook(self): self.m.context["x"] = 0 @self.m.hook(None, syscall=True) def tmp(state): with self.m.locked_context() as ctx: ctx["x"] = 1 self.m.kill() self.m.run() self.assertEqual(self.m.context["x"], 1) def test_add_sys_hook_after(self): def tmp(state): pass index = 12 self.m.add_hook(index, tmp, after=True, syscall=True) assert tmp in self.m._sys_after_hooks[index] def test_sys_hook_after_dec(self): name = "sys_mmap" index = 9 @self.m.hook(name, after=True, syscall=True) def tmp(state): pass self.m.run() assert tmp in self.m._sys_after_hooks[index] def test_init_hook(self): self.m.context["x"] = 0 @self.m.init def tmp(_state): self.m.context["x"] = 1 self.m.kill() self.m.run() self.assertEqual(self.m.context["x"], 1) def test_hook_dec_err(self): with self.assertRaises(TypeError): @self.m.hook("0x00400e40") def tmp(state): pass def test_symbol_resolution(self): dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "basic_linux_amd64")) self.assertTrue(self.m.resolve("sbrk"), 0x449EE0) def test_symbol_resolution_fail(self): with self.assertRaises(ValueError): self.m.resolve("does_not_exist") def test_integration_basic_stdin(self): import struct dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "basic_linux_amd64")) self.m.run() self.m.finalize() workspace = self.m._output.store.uri with open(os.path.join(workspace, "test_00000000.stdin"), "rb") as f: a = struct.unpack("<I", f.read())[0] with open(os.path.join(workspace, "test_00000001.stdin"), "rb") as f: b = struct.unpack("<I", f.read())[0] if a > 0x41: self.assertTrue(a > 0x41) self.assertTrue(b <= 0x41) else: self.assertTrue(a <= 0x41) self.assertTrue(b > 0x41)