From 4afd9debd489e3920b85cb6c542de10aabb0dcce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Thu, 2 Jun 2016 23:00:18 +0200 Subject: [PATCH] Add support for the new bytecode APIs --- examples/bytecode.py | 22 +++++++++++++++ src/_frida.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ src/frida/core.py | 6 ++++ 3 files changed, 95 insertions(+) create mode 100644 examples/bytecode.py diff --git a/examples/bytecode.py b/examples/bytecode.py new file mode 100644 index 0000000..a26ca10 --- /dev/null +++ b/examples/bytecode.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function +import frida + +system_session = frida.attach(0) +system_session.disable_jit() +bytecode = system_session.compile_script("""\ +'use strict'; + +rpc.exports = { + listThreads: function () { + return Process.enumerateThreadsSync(); + } +}; +""") + +session = frida.attach("Twitter") +session.disable_jit() +script = session.create_script_from_bytes(bytecode) +script.load() +api = script.exports +print("api.list_threads() =>", api.list_threads()) diff --git a/src/_frida.c b/src/_frida.c index 637c030..c773819 100644 --- a/src/_frida.c +++ b/src/_frida.c @@ -226,6 +226,8 @@ static int PySession_init (PySession * self); static void PySession_dealloc (PySession * self); static PyObject * PySession_detach (PySession * self); static PyObject * PySession_create_script (PySession * self, PyObject * args, PyObject * kw); +static PyObject * PySession_create_script_from_bytes (PySession * self, PyObject * args, PyObject * kw); +static PyObject * PySession_compile_script (PySession * self, PyObject * args, PyObject * kw); static PyObject * PySession_enable_debugger (PySession * self, PyObject * args, PyObject * kw); static PyObject * PySession_disable_debugger (PySession * self); static PyObject * PySession_disable_jit (PySession * self); @@ -346,6 +348,8 @@ static PyMethodDef PySession_methods[] = { { "detach", (PyCFunction) PySession_detach, METH_NOARGS, "Detach session from the process." }, { "create_script", (PyCFunction) PySession_create_script, METH_VARARGS | METH_KEYWORDS, "Create a new script." }, + { "create_script_from_bytes", (PyCFunction) PySession_create_script_from_bytes, METH_VARARGS | METH_KEYWORDS, "Create a new script from bytecode." }, + { "compile_script", (PyCFunction) PySession_compile_script, METH_VARARGS | METH_KEYWORDS, "Compile script source code to bytecode." }, { "enable_debugger", (PyCFunction) PySession_enable_debugger, METH_VARARGS | METH_KEYWORDS, "Enable the Node.js compatible script debugger." }, { "disable_debugger", (PyCFunction) PySession_disable_debugger, METH_NOARGS, "Disable the Node.js compatible script debugger." }, { "disable_jit", (PyCFunction) PySession_disable_jit, METH_NOARGS, "Disable JIT." }, @@ -1892,6 +1896,69 @@ PySession_create_script (PySession * self, PyObject * args, PyObject * kw) return PyScript_from_handle (handle); } +static PyObject * +PySession_create_script_from_bytes (PySession * self, PyObject * args, PyObject * kw) +{ + static char * keywords[] = { "data", "name", NULL }; + guint8 * data; + int size; + char * name = NULL; + GBytes * bytes; + GError * error = NULL; + FridaScript * handle; + +#if PY_MAJOR_VERSION >= 3 + if (!PyArg_ParseTupleAndKeywords (args, kw, "y#|es", keywords, &data, &size, "utf-8", &name)) +#else + if (!PyArg_ParseTupleAndKeywords (args, kw, "s#|es", keywords, &data, &size, "utf-8", &name)) +#endif + return NULL; + + bytes = g_bytes_new (data, size); + + Py_BEGIN_ALLOW_THREADS + handle = frida_session_create_script_from_bytes_sync (self->handle, name, bytes, &error); + Py_END_ALLOW_THREADS + + g_bytes_unref (bytes); + PyMem_Free (name); + + if (error != NULL) + return PyFrida_raise (error); + + return PyScript_from_handle (handle); +} + +static PyObject * +PySession_compile_script (PySession * self, PyObject * args, PyObject * kw) +{ + static char * keywords[] = { "source", NULL }; + char * source; + GError * error = NULL; + GBytes * bytes; + gconstpointer data; + gsize size; + PyObject * result; + + if (!PyArg_ParseTupleAndKeywords (args, kw, "es", keywords, "utf-8", &source)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + bytes = frida_session_compile_script_sync (self->handle, source, &error); + Py_END_ALLOW_THREADS + + PyMem_Free (source); + + if (error != NULL) + return PyFrida_raise (error); + + data = g_bytes_get_data (bytes, &size); + result = PyBytes_FromStringAndSize (data, size); + g_bytes_unref (bytes); + + return result; +} + static PyObject * PySession_enable_debugger (PySession * self, PyObject * args, PyObject * kw) { diff --git a/src/frida/core.py b/src/frida/core.py index 641266c..17699c1 100644 --- a/src/frida/core.py +++ b/src/frida/core.py @@ -174,6 +174,12 @@ class Session(FunctionContainer): def create_script(self, *args, **kwargs): return Script(self._impl.create_script(*args, **kwargs)) + def create_script_from_bytes(self, *args, **kwargs): + return Script(self._impl.create_script_from_bytes(*args, **kwargs)) + + def compile_script(self, *args, **kwargs): + return self._impl.compile_script(*args, **kwargs) + def enable_debugger(self, *args, **kwargs): return self._impl.enable_debugger(*args, **kwargs)