From 490fbf20b8f2d549a70bd314421ce0c70df107a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Sat, 5 May 2018 03:25:14 +0200 Subject: [PATCH] Update to the new core API --- examples/child_gating.py | 4 ++ src/_frida.c | 90 ++++++++++++++++++++++++++++++++++------ src/frida/core.py | 15 ++++--- 3 files changed, 92 insertions(+), 17 deletions(-) diff --git a/examples/child_gating.py b/examples/child_gating.py index c827e9d..5f7640b 100644 --- a/examples/child_gating.py +++ b/examples/child_gating.py @@ -14,6 +14,7 @@ class Application(object): self._device.on("child-added", lambda child: self._reactor.schedule(lambda: self._on_child_added(child))) self._device.on("child-removed", lambda child: self._reactor.schedule(lambda: self._on_child_removed(child))) + self._device.on("output", lambda pid, fd, data: self._reactor.schedule(lambda: self._on_output(pid, fd, data))) def run(self): self._reactor.schedule(lambda: self._start()) @@ -61,6 +62,9 @@ Interceptor.attach(Module.findExportByName(null, 'open'), { def _on_child_removed(self, child): print("⚡ child_removed: {}".format(child)) + def _on_output(self, pid, fd, data): + print("⚡ output: pid={}, fd={}, data={}".format(pid, fd, repr(data))) + def _on_detached(self, pid, session, reason): print("⚡ detached: pid={}, reason='{}'".format(pid, reason)) self._sessions.remove(session) diff --git a/src/_frida.c b/src/_frida.c index b713c3f..5f2f2af 100644 --- a/src/_frida.c +++ b/src/_frida.c @@ -1802,24 +1802,26 @@ PyDevice_enumerate_pending_children (PyDevice * self) static PyObject * PyDevice_spawn (PyDevice * self, PyObject * args, PyObject * kw) { - static char * keywords[] = { "path", "argv", "envp", "cwd", "stdio", "aslr", NULL }; - const char * path; + static char * keywords[] = { "program", "argv", "envp", "env", "cwd", "stdio", "aux", NULL }; + const char * program; PyObject * argv_value = Py_None; PyObject * envp_value = Py_None; + PyObject * env_value = Py_None; const char * cwd = NULL; const char * stdio_value = NULL; - const char * aslr_value = NULL; + PyObject * aux_value = Py_None; FridaSpawnOptions * options; GError * error = NULL; guint pid; - if (!PyArg_ParseTupleAndKeywords (args, kw, "s|OOzzz", keywords, - &path, + if (!PyArg_ParseTupleAndKeywords (args, kw, "s|OOOzzO", keywords, + &program, &argv_value, &envp_value, + &env_value, &cwd, &stdio_value, - &aslr_value)) + &aux_value)) return NULL; options = frida_spawn_options_new (); @@ -1850,6 +1852,19 @@ PyDevice_spawn (PyDevice * self, PyObject * args, PyObject * kw) g_strfreev (envp); } + if (env_value != Py_None) + { + gchar ** env; + gint env_length; + + if (!PyGObject_unmarshal_strv (env_value, &env, &env_length)) + goto invalid_argument; + + frida_spawn_options_set_env (options, env, env_length); + + g_strfreev (env); + } + if (cwd != NULL) frida_spawn_options_set_cwd (options, cwd); @@ -1863,18 +1878,60 @@ PyDevice_spawn (PyDevice * self, PyObject * args, PyObject * kw) frida_spawn_options_set_stdio (options, stdio); } - if (aslr_value != NULL) + if (aux_value != Py_None) { - FridaAslr aslr; + GVariantDict * aux; + Py_ssize_t pos; + PyObject * key, * value; - if (!PyGObject_unmarshal_enum (aslr_value, FRIDA_TYPE_ASLR, &aslr)) - goto invalid_argument; + aux = frida_spawn_options_get_aux (options); - frida_spawn_options_set_aslr (options, aslr); + if (!PyDict_Check (aux_value)) + goto invalid_aux_dict; + + pos = 0; + while (PyDict_Next (aux_value, &pos, &key, &value)) + { + char * raw_key; + GVariant * raw_value; + + if (!PyString_Check (key)) + goto invalid_aux_dict; + raw_key = PyString_AsString (key); + + if (PyString_Check (value)) + { + raw_value = g_variant_new_string (PyString_AsString (value)); + } + else if (PyBool_Check (value)) + { + raw_value = g_variant_new_boolean (value == Py_True); + } + else if (PyInt_Check (value)) + { + raw_value = g_variant_new_int64 (PyInt_AS_LONG (value)); + } + else if (PyLong_Check (value)) + { + PY_LONG_LONG val; + + val = PyLong_AsLongLong (value); + if (val == -1 && PyErr_Occurred ()) + goto invalid_long_value; + + raw_value = g_variant_new_int64 (val); + } + else + { + goto invalid_aux_dict; + } + + g_variant_dict_insert_value (aux, raw_key, raw_value); + } } Py_BEGIN_ALLOW_THREADS - pid = frida_device_spawn_sync (PY_GOBJECT_HANDLE (self), path, options, &error); + pid = frida_device_spawn_sync (PY_GOBJECT_HANDLE (self), program, options, &error); Py_END_ALLOW_THREADS g_object_unref (options); @@ -1885,9 +1942,18 @@ PyDevice_spawn (PyDevice * self, PyObject * args, PyObject * kw) return PyLong_FromUnsignedLong (pid); invalid_argument: +invalid_long_value: { g_object_unref (options); + return NULL; + } +invalid_aux_dict: + { + g_object_unref (options); + + PyErr_SetString (PyExc_TypeError, "unsupported parameter"); + return NULL; } } diff --git a/src/frida/core.py b/src/frida/core.py index e697323..824a9a0 100644 --- a/src/frida/core.py +++ b/src/frida/core.py @@ -84,11 +84,16 @@ class Device(object): def enumerate_pending_children(self): return self._impl.enumerate_pending_children() - def spawn(self, path, argv=None, envp=None, cwd=None, stdio=None, aslr=None): - if not isinstance(path, string_types): - argv = path - path = argv[0] - return self._impl.spawn(path, argv, envp, cwd, stdio, aslr) + def spawn(self, program, argv=None, envp=None, env=None, cwd=None, stdio=None, **kwargs): + if not isinstance(program, string_types): + argv = program + if len(argv) == 1: + argv = None + program = argv[0] + + aux_options = kwargs + + return self._impl.spawn(program, argv, envp, env, cwd, stdio, aux_options) def input(self, target, data): self._impl.input(self._pid_of(target), data)