Add support for the new crash reporting APIs

This commit is contained in:
Ole André Vadla Ravnås
2018-12-14 02:34:58 +01:00
committed by Ole André Vadla Ravnås
parent 5c2dc4da55
commit 5e8cd65665
+183
View File
@@ -106,6 +106,7 @@ typedef struct _PyApplication PyApplication;
typedef struct _PyProcess PyProcess;
typedef struct _PySpawn PySpawn;
typedef struct _PyChild PyChild;
typedef struct _PyCrash PyCrash;
typedef struct _PyIcon PyIcon;
typedef struct _PySession PySession;
typedef struct _PyScript PyScript;
@@ -185,6 +186,15 @@ struct _PyChild
PyObject * envp;
};
struct _PyCrash
{
PyGObject parent;
guint pid;
PyObject * process_name;
PyObject * report;
PyObject * parameters;
};
struct _PyIcon
{
PyGObject parent;
@@ -239,6 +249,7 @@ static gboolean PyGObject_unmarshal_envp (PyObject * value, gchar *** envp, gint
static PyObject * PyGObject_marshal_enum (gint value, GType type);
static gboolean PyGObject_unmarshal_enum (const gchar * str, GType type, gpointer value);
static PyObject * PyGObject_marshal_bytes (GBytes * bytes);
static PyObject * PyGObject_marshal_variant_dict (GVariant * dict);
static PyObject * PyGObject_marshal_object (gpointer handle, GType type);
static int PyDeviceManager_init (PyDeviceManager * self, PyObject * args, PyObject * kwds);
@@ -296,6 +307,11 @@ static void PyChild_init_from_handle (PyChild * self, FridaChild * handle);
static void PyChild_dealloc (PyChild * self);
static PyObject * PyChild_repr (PyChild * self);
static int PyCrash_init (PyCrash * self, PyObject * args, PyObject * kw);
static void PyCrash_init_from_handle (PyCrash * self, FridaCrash * handle);
static void PyCrash_dealloc (PyCrash * self);
static PyObject * PyCrash_repr (PyCrash * self);
static PyObject * PyIcon_new_from_handle (FridaIcon * handle);
static int PyIcon_init (PyIcon * self, PyObject * args, PyObject * kw);
static void PyIcon_init_from_handle (PyIcon * self, FridaIcon * handle);
@@ -423,6 +439,15 @@ static PyMemberDef PyChild_members[] =
{ NULL }
};
static PyMemberDef PyCrash_members[] =
{
{ "pid", T_UINT, G_STRUCT_OFFSET (PyCrash, pid), READONLY, "Process ID." },
{ "process_name", T_OBJECT_EX, G_STRUCT_OFFSET (PyCrash, process_name), READONLY, "Process name." },
{ "report", T_OBJECT_EX, G_STRUCT_OFFSET (PyCrash, report), READONLY, "Human-readable crash report." },
{ "parameters", T_OBJECT_EX, G_STRUCT_OFFSET (PyCrash, parameters), READONLY, "Parameters." },
{ NULL }
};
static PyMemberDef PyIcon_members[] =
{
{ "width", T_INT, G_STRUCT_OFFSET (PyIcon, width), READONLY, "Width in pixels." },
@@ -762,6 +787,48 @@ static PyTypeObject PyChildType =
PYFRIDA_DEFINE_TYPE (Child, PyChild_init_from_handle, g_object_unref);
static PyTypeObject PyCrashType =
{
PyVarObject_HEAD_INIT (NULL, 0)
"_frida.Crash", /* tp_name */
sizeof (PyCrash), /* tp_basicsize */
0, /* tp_itemsize */
(destructor) PyCrash_dealloc, /* tp_dealloc */
NULL, /* tp_print */
NULL, /* tp_getattr */
NULL, /* tp_setattr */
NULL, /* tp_compare */
(reprfunc) PyCrash_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 Crash Details", /* tp_doc */
NULL, /* tp_traverse */
NULL, /* tp_clear */
NULL, /* tp_richcompare */
0, /* tp_weaklistoffset */
NULL, /* tp_iter */
NULL, /* tp_iternext */
NULL, /* tp_methods */
PyCrash_members, /* tp_members */
NULL, /* tp_getset */
&PyGObjectType, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
NULL, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc) PyCrash_init, /* tp_init */
};
PYFRIDA_DEFINE_TYPE (Crash, PyCrash_init_from_handle, g_object_unref);
static PyTypeObject PyIconType =
{
PyVarObject_HEAD_INIT (NULL, 0)
@@ -1587,6 +1654,48 @@ PyGObject_marshal_bytes (GBytes * bytes)
return PyBytes_FromStringAndSize (data, size);
}
static PyObject *
PyGObject_marshal_variant_dict (GVariant * dict)
{
PyObject * result;
GVariantIter iter;
gchar * key;
GVariant * raw_value;
result = PyDict_New ();
g_variant_iter_init (&iter, dict);
while (g_variant_iter_next (&iter, "{sv}", &key, &raw_value))
{
PyObject * value = NULL;
if (g_variant_is_of_type (raw_value, G_VARIANT_TYPE_STRING))
{
value = PyGObject_marshal_string (g_variant_get_string (raw_value, NULL));
}
else if (g_variant_is_of_type (raw_value, G_VARIANT_TYPE_INT64))
{
value = PyLong_FromLongLong (g_variant_get_int64 (raw_value));
}
else if (g_variant_is_of_type (raw_value, G_VARIANT_TYPE_BOOLEAN))
{
value = PyBool_FromLong (g_variant_get_boolean (raw_value));
}
else
{
g_assert_not_reached ();
}
PyDict_SetItemString (result, key, value);
Py_DECREF (value);
g_variant_unref (raw_value);
g_free (key);
}
return result;
}
static PyObject *
PyGObject_marshal_object (gpointer handle, GType type)
{
@@ -2544,6 +2653,79 @@ PyChild_repr (PyChild * self)
}
static int
PyCrash_init (PyCrash * self, PyObject * args, PyObject * kw)
{
if (PyGObjectType.tp_init ((PyObject *) self, args, kw) < 0)
return -1;
self->pid = 0;
self->process_name = NULL;
self->report = NULL;
self->parameters = NULL;
return 0;
}
static void
PyCrash_init_from_handle (PyCrash * self, FridaCrash * handle)
{
GVariantDict * parameters_dict;
GVariant * parameters;
self->pid = frida_crash_get_pid (handle);
self->process_name = PyGObject_marshal_string (frida_crash_get_process_name (handle));
self->report = PyGObject_marshal_string (frida_crash_get_report (handle));
parameters_dict = frida_crash_load_parameters (handle);
parameters = g_variant_dict_end (parameters_dict);
self->parameters = PyGObject_marshal_variant_dict (parameters);
g_variant_unref (parameters);
g_variant_dict_unref (parameters_dict);
}
static void
PyCrash_dealloc (PyCrash * self)
{
Py_XDECREF (self->process_name);
Py_XDECREF (self->report);
Py_XDECREF (self->parameters);
PyGObjectType.tp_dealloc ((PyObject *) self);
}
static PyObject *
PyCrash_repr (PyCrash * self)
{
PyObject * result;
FridaCrash * handle;
GString * repr;
gchar * str;
handle = PY_GOBJECT_HANDLE (self);
repr = g_string_new ("Crash(");
g_string_append_printf (repr, "pid=%u, process_name=\"%s\"", self->pid, frida_crash_get_process_name (handle));
str = PyFrida_repr (self->report);
g_string_append_printf (repr, ", report=%s", str);
g_free (str);
str = PyFrida_repr (self->parameters);
g_string_append_printf (repr, ", parameters=%s", str);
g_free (str);
g_string_append (repr, ")");
result = PyRepr_FromString (repr->str);
g_string_free (repr, TRUE);
return result;
}
static PyObject *
PyIcon_new_from_handle (FridaIcon * handle)
{
@@ -3037,6 +3219,7 @@ MOD_INIT (_frida)
PYFRIDA_REGISTER_TYPE (Process, FRIDA_TYPE_PROCESS);
PYFRIDA_REGISTER_TYPE (Spawn, FRIDA_TYPE_SPAWN);
PYFRIDA_REGISTER_TYPE (Child, FRIDA_TYPE_CHILD);
PYFRIDA_REGISTER_TYPE (Crash, FRIDA_TYPE_CRASH);
PYFRIDA_REGISTER_TYPE (Icon, FRIDA_TYPE_ICON);
PYFRIDA_REGISTER_TYPE (Session, FRIDA_TYPE_SESSION);
PYFRIDA_REGISTER_TYPE (Script, FRIDA_TYPE_SCRIPT);