diff options
| -rw-r--r-- | example/jitter/trace.py | 58 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore_python.py | 6 | ||||
| -rwxr-xr-x | test/test_all.py | 2 |
3 files changed, 64 insertions, 2 deletions
diff --git a/example/jitter/trace.py b/example/jitter/trace.py new file mode 100644 index 00000000..aeb4c775 --- /dev/null +++ b/example/jitter/trace.py @@ -0,0 +1,58 @@ +""" +This example demonstrates two instrumentation possibility: + - instrumentation executed at each instruction + - instrumentation on jitter behavior (here, memory tracking) + +Note: for better performance, one can also extend Codegen to produce +instrumentation at the C / LLVM level +""" +import os +import time +from pdb import pm +from miasm2.analysis.sandbox import Sandbox_Linux_arml +from miasm2.jitter.emulatedsymbexec import EmulatedSymbExec +from miasm2.jitter.jitcore_python import JitCore_Python + +# Function called at each instruction +instr_count = 0 +def instr_hook(jitter): + global instr_count + instr_count += 1 + return True + +# Extension of the Python jitter to track memory accesses +class ESETrackMemory(EmulatedSymbExec): + """Emulated symb exec with memory access tracking""" + + def _func_read(self, expr_mem): + value = super(ESETrackMemory, self)._func_read(expr_mem) + print "Read %s: %s" % (expr_mem, value) + return value + + def _func_write(self, symb_exec, dest, data): + print "Write %s: %s" % (dest, data) + return super(ESETrackMemory, self)._func_write(symb_exec, dest, data) + +# Parse arguments +parser = Sandbox_Linux_arml.parser(description="Tracer") +parser.add_argument("filename", help="ELF Filename") +options = parser.parse_args() + +# Use our memory tracker +JitCore_Python.SymbExecClass = ESETrackMemory + +# Create sandbox, forcing Python jitter +options.jitter = "python" +sb = Sandbox_Linux_arml(options.filename, options, globals()) + +# Force jit one instr per call, and register our callback +sb.jitter.jit.set_options(jit_maxline=1, max_exec_per_call=1) +sb.jitter.exec_cb = instr_hook + +# Run +start_time = time.time() +sb.run() +stop_time = time.time() + +assert sb.jitter.run is False +print "Instr speed: %02.f / sec" % (instr_count / (stop_time - start_time)) diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py index 27666ab4..a8ecc3d6 100644 --- a/miasm2/jitter/jitcore_python.py +++ b/miasm2/jitter/jitcore_python.py @@ -13,6 +13,8 @@ from miasm2.jitter.emulatedsymbexec import EmulatedSymbExec class JitCore_Python(jitcore.JitCore): "JiT management, using Miasm2 Symbol Execution engine as backend" + SymbExecClass = EmulatedSymbExec + def __init__(self, ir_arch, bs=None): super(JitCore_Python, self).__init__(ir_arch, bs) self.ir_arch = ir_arch @@ -20,8 +22,8 @@ class JitCore_Python(jitcore.JitCore): # CPU & VM (None for now) will be set later expr_simp = ExpressionSimplifier() expr_simp.enable_passes(ExpressionSimplifier.PASS_COMMONS) - self.symbexec = EmulatedSymbExec(None, None, self.ir_arch, {}, - sb_expr_simp=expr_simp) + self.symbexec = self.SymbExecClass(None, None, self.ir_arch, {}, + sb_expr_simp=expr_simp) self.symbexec.enable_emulated_simplifications() def set_cpu_vm(self, cpu, vm): diff --git a/test/test_all.py b/test/test_all.py index ab9e4b9b..2f8c6421 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -617,6 +617,8 @@ for jitter in ExampleJitterNoPython.jitter_engines: tags=tags) testset += ExampleJitter(["example_types.py"]) +testset += ExampleJitter(["trace.py", Example.get_sample("md5_arm"), "-a", + "0xA684"]) if __name__ == "__main__": |