about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <serpilliere@users.noreply.github.com>2022-01-15 14:46:19 +0100
committerGitHub <noreply@github.com>2022-01-15 14:46:19 +0100
commit3f3385ef21df3d108d573bcf8d299b645eff8c91 (patch)
treed03017ff4b5b044a6384f3245019e98077a5175a
parent09376c524aedc7920a7eda304d6095e12f6958f4 (diff)
parent245dc7f32fd6be33fb4fdc57276425210d947fe9 (diff)
downloadfocaccia-miasm-3f3385ef21df3d108d573bcf8d299b645eff8c91.tar.gz
focaccia-miasm-3f3385ef21df3d108d573bcf8d299b645eff8c91.zip
Merge pull request #1409 from icecr4ck/add_syscall_sem_mips32
Implement syscall handler for mips32b + minimal Linux environment
-rw-r--r--miasm/arch/mips32/jit.py11
-rw-r--r--miasm/arch/mips32/sem.py8
-rw-r--r--miasm/os_dep/linux/environment.py5
-rw-r--r--miasm/os_dep/linux/syscall.py43
4 files changed, 66 insertions, 1 deletions
diff --git a/miasm/arch/mips32/jit.py b/miasm/arch/mips32/jit.py
index 53f48303..a4d8a193 100644
--- a/miasm/arch/mips32/jit.py
+++ b/miasm/arch/mips32/jit.py
@@ -135,6 +135,17 @@ class jitter_mips32l(Jitter):
             arg = self.get_stack_arg(index-4)
         return arg
 
+    def syscall_args_systemv(self, n_args):
+        # Documentation: http://man7.org/linux/man-pages/man2/syscall.2.html
+        # mips/o32      a0    a1    a2    a3    stack
+        args = [self.get_arg_n_stdcall(i) for i in range(n_args)]
+        return args
+
+    def syscall_ret_systemv(self, value1, value2, error):
+        # Documentation: http://man7.org/linux/man-pages/man2/syscall.2.html
+        self.cpu.V0 = value1
+        self.cpu.V1 = value2
+        self.cpu.A3 = error  # 0 -> no error, -1 -> error
 
     func_args_systemv = func_args_stdcall
     func_ret_systemv = func_ret_stdcall
diff --git a/miasm/arch/mips32/sem.py b/miasm/arch/mips32/sem.py
index 0e2fca71..649adcaa 100644
--- a/miasm/arch/mips32/sem.py
+++ b/miasm/arch/mips32/sem.py
@@ -3,7 +3,7 @@ from miasm.ir.ir import Lifter, IRBlock, AssignBlock
 from miasm.arch.mips32.arch import mn_mips32
 from miasm.arch.mips32.regs import R_LO, R_HI, PC, RA, ZERO, exception_flags
 from miasm.core.sembuilder import SemBuilder
-from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_SOFT_BP
+from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_SOFT_BP, EXCEPT_SYSCALL
 
 
 # SemBuilder context
@@ -400,6 +400,11 @@ def break_(ir, instr):
     e.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprInt(EXCEPT_SOFT_BP, 32)))
     return e, []
 
+def syscall(ir, instr, code):
+    e = []
+    e.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprInt(EXCEPT_SYSCALL, 32)))
+    return e, []
+
 def ins(ir, instr, a, b, c, d):
     e = []
     pos = int(c)
@@ -611,6 +616,7 @@ mnemo_func.update(
         'break': break_,
         'sb': sb,
         'sh': sh,
+        'syscall': syscall,
     }
 )
 
diff --git a/miasm/os_dep/linux/environment.py b/miasm/os_dep/linux/environment.py
index 53a97ce8..808fc847 100644
--- a/miasm/os_dep/linux/environment.py
+++ b/miasm/os_dep/linux/environment.py
@@ -710,6 +710,11 @@ class LinuxEnvironment_arml(LinuxEnvironment):
     kuser_helper_version = 3
 
 
+class LinuxEnvironment_mips32b(LinuxEnvironment):
+    platform_arch = b"mips32b"
+    sys_machine = b"mips32b"
+
+
 class AuxVec(object):
     """Auxiliary vector abstraction, filled with default values
     (mainly based on https://lwn.net/Articles/519085)
diff --git a/miasm/os_dep/linux/syscall.py b/miasm/os_dep/linux/syscall.py
index 32aaea83..bbaae1bc 100644
--- a/miasm/os_dep/linux/syscall.py
+++ b/miasm/os_dep/linux/syscall.py
@@ -898,6 +898,15 @@ def sys_arml_gettimeofday(jitter, linux_env):
     jitter.cpu.R0 = 0
 
 
+def sys_mips32b_socket(jitter, linux_env):
+    # Parse arguments
+    family, type_, protocol = jitter.syscall_args_systemv(3)
+    log.debug("sys_socket(%x, %x, %x)", family, type_, protocol)
+
+    ret1 = linux_env.socket(family, type_, protocol)
+    jitter.syscall_ret_systemv(ret1, 0, 0)
+
+
 syscall_callbacks_x86_32 = {
     0x7A: sys_x86_32_newuname,
 }
@@ -978,6 +987,11 @@ syscall_callbacks_arml = {
     0xf0005: sys_arml_set_tls,
 }
 
+
+syscall_callbacks_mips32b = {
+    0x1057: sys_mips32b_socket,
+}
+
 def syscall_x86_64_exception_handler(linux_env, syscall_callbacks, jitter):
     """Call to actually handle an EXCEPT_SYSCALL exception
     In the case of an error raised by a SYSCALL, call the corresponding
@@ -1059,6 +1073,31 @@ def syscall_arml_exception_handler(linux_env, syscall_callbacks, jitter):
 
 
 
+def syscall_mips32b_exception_handler(linux_env, syscall_callbacks, jitter):
+    """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_mips32b instance
+    @syscall_callbacks: syscall number -> func(jitter, linux_env)
+    """
+
+    # Dispatch to SYSCALL stub
+    syscall_number = jitter.cpu.V0
+    callback = syscall_callbacks.get(syscall_number)
+    if callback is None:
+        raise KeyError(
+            "No callback found for syscall number 0x%x" % syscall_number
+        )
+    callback(jitter, linux_env)
+    log.debug("-> %x", jitter.cpu.V0)
+
+    # Clean exception and move pc to the next instruction, to let the jitter
+    # continue
+    jitter.cpu.set_exception(jitter.cpu.get_exception() ^ EXCEPT_SYSCALL)
+    return True
+
+
+
 def enable_syscall_handling(jitter, linux_env, syscall_callbacks):
     """Activate handling of syscall for the current jitter instance.
     Syscall handlers are provided by @syscall_callbacks
@@ -1082,5 +1121,9 @@ def enable_syscall_handling(jitter, linux_env, syscall_callbacks):
         handler = syscall_arml_exception_handler
         handler = functools.partial(handler, linux_env, syscall_callbacks)
         jitter.add_exception_handler(EXCEPT_INT_XX, handler)
+    elif arch_name == "mips32b":
+        handler = syscall_mips32b_exception_handler
+        handler = functools.partial(handler, linux_env, syscall_callbacks)
+        jitter.add_exception_handler(EXCEPT_SYSCALL, handler)
     else:
         raise ValueError("No syscall handler implemented for %s" % arch_name)