about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/jitter/x86_64.py94
-rw-r--r--miasm/arch/x86/sem.py5
-rw-r--r--miasm/jitter/csts.py1
-rw-r--r--miasm/os_dep/linux/syscall.py11
4 files changed, 103 insertions, 8 deletions
diff --git a/example/jitter/x86_64.py b/example/jitter/x86_64.py
new file mode 100644
index 00000000..78d88c18
--- /dev/null
+++ b/example/jitter/x86_64.py
@@ -0,0 +1,94 @@
+from argparse import ArgumentParser
+from pdb import pm
+from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_SYSCALL
+from miasm.analysis.machine import Machine
+
+
+# Some syscalls often used by shellcodes
+# See https://filippo.io/linux-syscall-table/
+SYSCALL = {
+        0: "read",
+        1: "write",
+        2: "open",
+        0x9: "mmap",
+        0x27: "getpid",
+        0x29: "socket",
+        0x2a: "connect",
+        0x2b: "accept",
+        0x2c: "sendto",
+        0x2d: "recvfrom",
+        0x31: "bind",
+        0x32: "listen",
+        0x33: "getsockname",
+        0x34: "getpeername",
+        0x3b: "execve",
+        0x3c: "exit",
+        0x3d: "wait4",
+        0x3e: "kill",
+        0x57: "unlink",
+        0x5a: "chmod",
+        0x5b: "fchmod",
+        0x5c: "chown"
+}
+
+
+def code_sentinelle(jitter):
+    jitter.run = False
+    jitter.pc = 0
+    return True
+
+
+def log_syscalls(jitter):
+    # For parameters, see
+    # https://en.wikibooks.org/wiki/X86_Assembly/Interfacing_with_Linux
+    # Example of how to implement some syscalls
+    if jitter.cpu.EAX == 1:
+        # Write
+        size_t = jitter.cpu.RDX
+        print("write(fd: {}, buf: {}, size_t: {})".format(
+            jitter.cpu.RDI,
+            jitter.vm.get_mem(jitter.cpu.RSI, size_t),
+            size_t
+        ))
+        # Return value is the size written
+        jitter.cpu.EAX = size_t
+    elif jitter.cpu.EAX == 0x3c:
+        # exit
+        print("Exit syscall - stopping the machine")
+        return False
+    else:
+        # Most syscalls are not implemented, it may create issues
+        if jitter.cpu.EAX in SYSCALL:
+            print("syscall {} - {} : Not Implemented".format(jitter.cpu.EAX, SYSCALL[jitter.cpu.EAX]))
+        else:
+            print("Unknown syscall {} : NotImplemented".format(jitter.cpu.EAX))
+    jitter.cpu.set_exception(0)
+    jitter.cpu.EAX = 0
+    return True
+
+
+if __name__ == "__main__":
+    parser = ArgumentParser(description="x86 64 basic Jitter")
+    parser.add_argument("filename", help="x86 64 shellcode filename")
+    parser.add_argument("-j", "--jitter",
+                        help="Jitter engine (default is 'gcc')",
+                        default="gcc")
+    parser.add_argument("--verbose", "-v", action="store_true",
+                        help="Verbose mode")
+    args = parser.parse_args()
+
+    myjit = Machine("x86_64").jitter(args.jitter)
+    myjit.init_stack()
+
+    with open(args.filename, 'rb') as f:
+        data = f.read()
+    run_addr = 0x40000000
+    myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data)
+
+    if args.verbose:
+        myjit.set_trace_log()
+    myjit.push_uint64_t(0x1337beef)
+    myjit.add_breakpoint(0x1337beef, code_sentinelle)
+    # Add routine catching syscalls
+    myjit.add_exception_handler(EXCEPT_SYSCALL, log_syscalls)
+    myjit.run(run_addr)
diff --git a/miasm/arch/x86/sem.py b/miasm/arch/x86/sem.py
index cf3539e2..fdb4efd6 100644
--- a/miasm/arch/x86/sem.py
+++ b/miasm/arch/x86/sem.py
@@ -28,7 +28,8 @@ from miasm.arch.x86.arch import mn_x86, repeat_mn, replace_regs
 from miasm.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm.core.sembuilder import SemBuilder
 from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_ILLEGAL_INSN, \
-    EXCEPT_PRIV_INSN, EXCEPT_SOFT_BP, EXCEPT_INT_XX, EXCEPT_INT_1
+    EXCEPT_PRIV_INSN, EXCEPT_SOFT_BP, EXCEPT_INT_XX, EXCEPT_INT_1, \
+    EXCEPT_SYSCALL
 import math
 import struct
 
@@ -3408,7 +3409,7 @@ def l_sysenter(_, instr):
 def l_syscall(_, instr):
     e = []
     e.append(m2_expr.ExprAssign(exception_flags,
-                             m2_expr.ExprInt(EXCEPT_PRIV_INSN, 32)))
+                             m2_expr.ExprInt(EXCEPT_SYSCALL, 32)))
     return e, []
 
 # XXX
diff --git a/miasm/jitter/csts.py b/miasm/jitter/csts.py
index 6d40fe0d..3829ed98 100644
--- a/miasm/jitter/csts.py
+++ b/miasm/jitter/csts.py
@@ -9,6 +9,7 @@ EXCEPT_CODE_AUTOMOD = (1 << 0)
 EXCEPT_SOFT_BP = (1 << 1)
 EXCEPT_INT_XX = (1 << 2)
 EXCEPT_SPR_ACCESS = (1 << 3)
+EXCEPT_SYSCALL = (1 << 4)
 EXCEPT_BREAKPOINT_MEMORY = (1 << 10)
 # Deprecated
 EXCEPT_BREAKPOINT_INTERN = EXCEPT_BREAKPOINT_MEMORY
diff --git a/miasm/os_dep/linux/syscall.py b/miasm/os_dep/linux/syscall.py
index fc6bbd8a..3b612f74 100644
--- a/miasm/os_dep/linux/syscall.py
+++ b/miasm/os_dep/linux/syscall.py
@@ -5,7 +5,7 @@ import logging
 import struct
 import termios
 
-from miasm.jitter.csts import EXCEPT_PRIV_INSN, EXCEPT_INT_XX
+from miasm.jitter.csts import EXCEPT_INT_XX, EXCEPT_SYSCALL
 from miasm.core.utils import pck64
 
 log = logging.getLogger('syscalls')
@@ -979,7 +979,7 @@ syscall_callbacks_arml = {
 }
 
 def syscall_x86_64_exception_handler(linux_env, syscall_callbacks, jitter):
-    """Call to actually handle an EXCEPT_PRIV_INSN exception
+    """Call to actually handle an EXCEPT_SYSCALL exception
     In the case of an error raised by a SYSCALL, call the corresponding
     syscall_callbacks
     @linux_env: LinuxEnvironment_x86_64 instance
@@ -1002,14 +1002,14 @@ def syscall_x86_64_exception_handler(linux_env, syscall_callbacks, jitter):
 
     # Clean exception and move pc to the next instruction, to let the jitter
     # continue
-    jitter.cpu.set_exception(jitter.cpu.get_exception() ^ EXCEPT_PRIV_INSN)
+    jitter.cpu.set_exception(jitter.cpu.get_exception() ^ EXCEPT_SYSCALL)
     jitter.pc += cur_instr.l
     return True
 
 
 
 def syscall_x86_32_exception_handler(linux_env, syscall_callbacks, jitter):
-    """Call to actually handle an EXCEPT_PRIV_INSN exception
+    """Call to actually handle an EXCEPT_INT_XX exception
     In the case of an error raised by a SYSCALL, call the corresponding
     syscall_callbacks
     @linux_env: LinuxEnvironment_x86_32 instance
@@ -1078,7 +1078,7 @@ def enable_syscall_handling(jitter, linux_env, syscall_callbacks):
     if arch_name == "x8664":
         handler = syscall_x86_64_exception_handler
         handler = functools.partial(handler, linux_env, syscall_callbacks)
-        jitter.add_exception_handler(EXCEPT_PRIV_INSN, handler)
+        jitter.add_exception_handler(EXCEPT_SYSCALL, handler)
     elif arch_name == "x8632":
         handler = syscall_x86_32_exception_handler
         handler = functools.partial(handler, linux_env, syscall_callbacks)
@@ -1089,4 +1089,3 @@ def enable_syscall_handling(jitter, linux_env, syscall_callbacks):
         jitter.add_exception_handler(EXCEPT_INT_XX, handler)
     else:
         raise ValueError("No syscall handler implemented for %s" % arch_name)
-