about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/jitter/trace.py58
-rw-r--r--miasm2/jitter/jitcore_python.py6
-rwxr-xr-xtest/test_all.py2
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__":