From 6b4e291cacb988376573b64914e37c671693abdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Sat, 30 May 2015 09:29:20 +0200 Subject: [PATCH] Add `enumerate_applications()` to Device --- src/_frida.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++ src/frida/core.py | 3 + 2 files changed, 164 insertions(+) diff --git a/src/_frida.c b/src/_frida.c index 0fd963a..db7ea47 100644 --- a/src/_frida.c +++ b/src/_frida.c @@ -53,6 +53,7 @@ static GHashTable * exception_by_error_code; typedef struct _PyDeviceManager PyDeviceManager; typedef struct _PyDevice PyDevice; +typedef struct _PyApplication PyApplication; typedef struct _PyProcess PyProcess; typedef struct _PyIcon PyIcon; typedef struct _PySession PySession; @@ -80,6 +81,16 @@ struct _PyDevice GList * on_lost; }; +struct _PyApplication +{ + PyObject_HEAD + + FridaApplication * handle; + + const gchar * identifier; + const gchar * name; +}; + struct _PyProcess { PyObject_HEAD @@ -128,6 +139,7 @@ static PyObject * PyDevice_from_handle (FridaDevice * handle); static int PyDevice_init (PyDevice * self); static void PyDevice_dealloc (PyDevice * self); static PyObject * PyDevice_repr (PyDevice * self); +static PyObject * PyDevice_enumerate_applications (PyDevice * self); static PyObject * PyDevice_enumerate_processes (PyDevice * self); static PyObject * PyDevice_spawn (PyDevice * self, PyObject * args); static PyObject * PyDevice_resume (PyDevice * self, PyObject * args); @@ -137,6 +149,13 @@ static PyObject * PyDevice_on (PyDevice * self, PyObject * args); static PyObject * PyDevice_off (PyDevice * self, PyObject * args); static void PyDevice_on_lost (PyDevice * self, FridaDevice * handle); +static PyObject * PyApplication_from_handle (FridaApplication * handle); +static int PyApplication_init (PyApplication * self); +static void PyApplication_dealloc (PyApplication * self); +static PyObject * PyApplication_repr (PyApplication * self); +static PyObject * PyApplication_get_small_icon (PyApplication * self); +static PyObject * PyApplication_get_large_icon (PyApplication * self); + static PyObject * PyProcess_from_handle (FridaProcess * handle); static int PyProcess_init (PyProcess * self); static void PyProcess_dealloc (PyProcess * self); @@ -185,6 +204,7 @@ static PyMethodDef PyDeviceManager_methods[] = static PyMethodDef PyDevice_methods[] = { + { "enumerate_applications", (PyCFunction) PyDevice_enumerate_applications, METH_NOARGS, "Enumerate applications." }, { "enumerate_processes", (PyCFunction) PyDevice_enumerate_processes, METH_NOARGS, "Enumerate processes." }, { "spawn", (PyCFunction) PyDevice_spawn, METH_VARARGS, "Spawn a process into an attachable state." }, { "resume", (PyCFunction) PyDevice_resume, METH_VARARGS, "Resume a process from the attachable state." }, @@ -204,6 +224,20 @@ static PyMemberDef PyDevice_members[] = { NULL } }; +static PyMethodDef PyApplication_methods[] = +{ + { "get_small_icon", (PyCFunction) PyApplication_get_small_icon, METH_NOARGS, "Small icon." }, + { "get_large_icon", (PyCFunction) PyApplication_get_large_icon, METH_NOARGS, "Large icon." }, + { NULL } +}; + +static PyMemberDef PyApplication_members[] = +{ + { "identifier", T_STRING, G_STRUCT_OFFSET (PyApplication, identifier), READONLY, "Application identifier."}, + { "name", T_STRING, G_STRUCT_OFFSET (PyApplication, name), READONLY, "Human-readable process name."}, + { NULL } +}; + static PyMethodDef PyProcess_methods[] = { { "get_small_icon", (PyCFunction) PyProcess_get_small_icon, METH_NOARGS, "Small icon." }, @@ -328,6 +362,46 @@ static PyTypeObject PyDeviceType = (initproc) PyDevice_init, /* tp_init */ }; +static PyTypeObject PyApplicationType = +{ + PyVarObject_HEAD_INIT (NULL, 0) + "_frida.Application", /* tp_name */ + sizeof (PyApplication), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) PyApplication_dealloc, /* tp_dealloc */ + NULL, /* tp_print */ + NULL, /* tp_getattr */ + NULL, /* tp_setattr */ + NULL, /* tp_compare */ + (reprfunc) PyApplication_repr, /* tp_repr */ + NULL, /* tp_as_number */ + NULL, /* tp_as_sequence */ + NULL, /* tp_as_mapping */ + NULL, /* tp_hash */ + NULL, /* tp_call */ + NULL, /* tp_str */ + NULL, /* tp_getattro */ + NULL, /* tp_setattro */ + NULL, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "Frida Application", /* tp_doc */ + NULL, /* tp_traverse */ + NULL, /* tp_clear */ + NULL, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + NULL, /* tp_iter */ + NULL, /* tp_iternext */ + PyApplication_methods, /* tp_methods */ + PyApplication_members, /* tp_members */ + NULL, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + NULL, /* tp_descr_get */ + NULL, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) PyApplication_init, /* tp_init */ +}; + static PyTypeObject PyProcessType = { PyVarObject_HEAD_INIT (NULL, 0) @@ -726,6 +800,31 @@ PyDevice_repr (PyDevice * self) return PyRepr_FromFormat ("Device(id=%u, name=\"%s\", type='%s')", self->id, self->name, self->type); } +static PyObject * +PyDevice_enumerate_applications (PyDevice * self) +{ + GError * error = NULL; + FridaApplicationList * result; + gint result_length, i; + PyObject * applications; + + Py_BEGIN_ALLOW_THREADS + result = frida_device_enumerate_applications_sync (self->handle, &error); + Py_END_ALLOW_THREADS + if (error != NULL) + return PyFrida_raise (error); + + result_length = frida_application_list_size (result); + applications = PyList_New (result_length); + for (i = 0; i != result_length; i++) + { + PyList_SET_ITEM (applications, i, PyApplication_from_handle (frida_application_list_get (result, i))); + } + g_object_unref (result); + + return applications; +} + static PyObject * PyDevice_enumerate_processes (PyDevice * self) { @@ -962,6 +1061,61 @@ PyDevice_on_lost (PyDevice * self, FridaDevice * handle) } +static PyObject * +PyApplication_from_handle (FridaApplication * handle) +{ + PyObject * result; + PyApplication * application; + + result = PyObject_CallFunction ((PyObject *) &PyApplicationType, NULL); + + application = (PyApplication *) result; + application->handle = handle; + application->identifier = frida_application_get_identifier (handle); + application->name = frida_application_get_name (handle); + + return result; +} + +static int +PyApplication_init (PyApplication * self) +{ + self->handle = NULL; + + self->identifier = NULL; + self->name = NULL; + + return 0; +} + +static void +PyApplication_dealloc (PyApplication * self) +{ + if (self->handle != NULL) + g_object_unref (self->handle); + + Py_TYPE (self)->tp_free ((PyObject *) self); +} + +static PyObject * +PyApplication_repr (PyApplication * self) +{ + return PyRepr_FromFormat ("Application(identifier=\"%s\", name=\"%s\")", self->identifier, self->name); +} + +static PyObject * +PyApplication_get_small_icon (PyApplication * self) +{ + return PyIcon_from_handle (frida_application_get_small_icon (self->handle)); +} + +static PyObject * +PyApplication_get_large_icon (PyApplication * self) +{ + return PyIcon_from_handle (frida_application_get_large_icon (self->handle)); +} + + static PyObject * PyProcess_from_handle (FridaProcess * handle) { @@ -1612,6 +1766,10 @@ MOD_INIT (_frida) if (PyType_Ready (&PyDeviceType) < 0) return MOD_ERROR_VAL; + PyApplicationType.tp_new = PyType_GenericNew; + if (PyType_Ready (&PyApplicationType) < 0) + return MOD_ERROR_VAL; + PyProcessType.tp_new = PyType_GenericNew; if (PyType_Ready (&PyProcessType) < 0) return MOD_ERROR_VAL; @@ -1638,6 +1796,9 @@ MOD_INIT (_frida) Py_INCREF (&PyDeviceType); PyModule_AddObject (module, "Device", (PyObject *) &PyDeviceType); + Py_INCREF (&PyApplicationType); + PyModule_AddObject (module, "Application", (PyObject *) &PyApplicationType); + Py_INCREF (&PyProcessType); PyModule_AddObject (module, "Process", (PyObject *) &PyProcessType); diff --git a/src/frida/core.py b/src/frida/core.py index b3b41a0..270066e 100644 --- a/src/frida/core.py +++ b/src/frida/core.py @@ -44,6 +44,9 @@ class Device(object): def __repr__(self): return repr(self._impl) + def enumerate_applications(self): + return self._impl.enumerate_applications() + def enumerate_processes(self): return self._impl.enumerate_processes()