diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/pyoida/Makefile.am | 3 | ||||
-rw-r--r-- | plugins/pyoida/debug/debugger.c | 87 | ||||
-rw-r--r-- | plugins/pyoida/debug/module.c | 6 | ||||
-rw-r--r-- | plugins/pyoida/pyoida.c | 2 | ||||
-rw-r--r-- | plugins/pyoida/quirks.c | 148 | ||||
-rw-r--r-- | plugins/pyoida/quirks.h | 42 | ||||
-rw-r--r-- | plugins/python/exectracer/exectracer.py | 4 |
7 files changed, 280 insertions, 12 deletions
diff --git a/plugins/pyoida/Makefile.am b/plugins/pyoida/Makefile.am index a343e6f..42a2fc2 100644 --- a/plugins/pyoida/Makefile.am +++ b/plugins/pyoida/Makefile.am @@ -4,7 +4,8 @@ pkglib_LTLIBRARIES = pyoida.la pyoida_la_SOURCES = \ plugin.h plugin.c \ py_log.h py_log.c \ - pyoida.h pyoida.c + pyoida.h pyoida.c \ + quirks.h quirks.c pyoida_la_LIBADD = \ analysis/libpyoidaanalysis.la \ diff --git a/plugins/pyoida/debug/debugger.c b/plugins/pyoida/debug/debugger.c index 380f579..75de6d8 100644 --- a/plugins/pyoida/debug/debugger.c +++ b/plugins/pyoida/debug/debugger.c @@ -28,9 +28,12 @@ #include <pygobject.h> +#include "../quirks.h" +/* Fournit les identifiants de tous les threads actifs. */ +static PyObject *py_binary_debugger_list_all_threads(PyObject *, PyObject *); /* Fournit la pile d'exécution courante via un débogueur. */ static PyObject *py_binary_debugger_get_current_stack(PyObject *, PyObject *); @@ -38,9 +41,6 @@ static PyObject *py_binary_debugger_get_current_stack(PyObject *, PyObject *); - - - /****************************************************************************** * * * Paramètres : type = type de l'objet à instancier. * @@ -89,6 +89,15 @@ static PyObject *py_binary_debugger_new(PyTypeObject *type, PyObject *args, PyOb PyObject *py_binary_debugger_from_c(GBinaryDebugger *debugger) { + PyObject *module; /* Module d'appartenance */ + PyTypeObject *type; /* Type Python correspondant */ + + module = PyImport_ImportModule("pyoida.debug"); + type = (PyTypeObject*)PyObject_GetAttrString(module, "BinaryDebugger"); + Py_DECREF(module); + + pychrysalide_set_instance_data(G_OBJECT(debugger), type); + return pygobject_new(G_OBJECT(debugger)); } @@ -96,25 +105,75 @@ PyObject *py_binary_debugger_from_c(GBinaryDebugger *debugger) + /****************************************************************************** * * * Paramètres : self = classe représentant un débogueur. * * args = arguments fournis à l'appel. * * * -* Description : Fournit la pile d'exécution courante via un débogueur. * +* Description : Fournit les identifiants de tous les threads actifs. * * * -* Retour : Valeur booléenne indiquant le statut d'une option. * +* Retour : Object Python représentant le résultat de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_binary_debugger_get_current_stack(PyObject *self, PyObject *args) +static PyObject *py_binary_debugger_list_all_threads(PyObject *self, PyObject *args) { + PyObject *result; /* Trouvailles à retourner */ + GBinaryDebugger *debugger; /* Version native */ + char **names; /* Noms associés aux threads */ + size_t count; /* Taille de cette liste */ + pid_t *threads; /* Liste des threads actifs */ + size_t i; /* Boucle de parcours */ + PyObject *thread; /* Détails sur un thread donné */ + + debugger = G_BINARY_DEBUGGER(pygobject_get(self)); + + threads = g_binary_debugger_list_all_threads(debugger, &names, &count); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + thread = PyTuple_New(2); + PyTuple_SetItem(result, i, thread); + + PyTuple_SetItem(thread, 0, PyLong_FromLong(threads[i])); + PyTuple_SetItem(thread, 1, PyString_FromString(names[i])); + + free(names[i]); + + } + + if (names != NULL) + free(names); + + if (threads != NULL) + free(threads); + + return result; + +} + - printf(" -->> get stack\n"); +/****************************************************************************** +* * +* Paramètres : self = classe représentant un débogueur. * +* args = arguments fournis à l'appel. * +* * +* Description : Fournit la pile d'exécution courante via un débogueur. * +* * +* Retour : Object Python représentant le résultat de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ - return Py_BuildValue("i", true); +static PyObject *py_binary_debugger_get_current_stack(PyObject *self, PyObject *args) +{ + return PyLong_FromLong(23); } @@ -136,10 +195,16 @@ static PyObject *py_binary_debugger_get_current_stack(PyObject *self, PyObject * bool register_python_binary_debugger(PyObject *module) { + PyObject *pygobj_mod; /* Module Python-GObject */ int ret; /* Bilan d'un appel */ static PyMethodDef py_binary_debugger_methods[] = { { + "list_all_threads", (PyCFunction)py_binary_debugger_list_all_threads, + METH_NOARGS, + "List all current active threads." + }, + { "get_current_stack", (PyCFunction)py_binary_debugger_get_current_stack, METH_NOARGS, "Provide the current callstack using a debugger." @@ -163,6 +228,12 @@ bool register_python_binary_debugger(PyObject *module) }; + pygobj_mod = PyImport_ImportModule("gobject"); + if (pygobj_mod == NULL) return false; + + py_binary_debugger_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); + Py_DECREF(pygobj_mod); + if (PyType_Ready(&py_binary_debugger_type) < 0) return false; diff --git a/plugins/pyoida/debug/module.c b/plugins/pyoida/debug/module.c index fe59595..7537dc7 100644 --- a/plugins/pyoida/debug/module.c +++ b/plugins/pyoida/debug/module.c @@ -47,15 +47,15 @@ bool add_debug_module_to_python_module(PyObject *super) PyObject *module; int ret; /* Bilan d'un appel */ - static PyMethodDef py_analysis_methods[] = { + static PyMethodDef py_debug_methods[] = { { NULL } }; - module = Py_InitModule("pychrysalide.debug", py_analysis_methods); + module = Py_InitModule("pyoida.debug", py_debug_methods); if (module == NULL) return false; Py_INCREF(module); - ret = PyModule_AddObject(super, "pychrysalide.debug", module); + ret = PyModule_AddObject(super, "pyoida.debug", module); result = (ret != 0); diff --git a/plugins/pyoida/pyoida.c b/plugins/pyoida/pyoida.c index d3b37e5..f3051cc 100644 --- a/plugins/pyoida/pyoida.c +++ b/plugins/pyoida/pyoida.c @@ -32,6 +32,7 @@ #include <pygobject.h> +#include "quirks.h" #include "analysis/module.h" #include "arch/module.h" #include "debug/module.h" @@ -253,6 +254,7 @@ initpyoida(void) PyObject *module; pygobject_init(-1, -1, -1); + pychrysalide_init_quirks(); printf("Passage 2\n"); module = Py_InitModule("pyoida", SpamMethods); diff --git a/plugins/pyoida/quirks.c b/plugins/pyoida/quirks.c new file mode 100644 index 0000000..4dcae2c --- /dev/null +++ b/plugins/pyoida/quirks.c @@ -0,0 +1,148 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * quirks.c - transmission du type Python exact aux instances de PyObject + * + * Copyright (C) 2012 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "quirks.h" + + + +#include <pyglib.h> +#include <pygobject.h> + + + + + + +/* Coordonnées insérées manuellement */ +typedef struct _PyGObjectData_fake +{ + PyTypeObject *type; /* Type précis pour Python */ + GSList *closures; /* Supports d'appel */ + +} PyGObjectData_fake; + + +/* Clef d'accès réservée */ +static GQuark pygobject_instance_data_key_fake = 0; + + + + + +static void pygobject_data_free_fake(PyGObjectData_fake *data) +{ + PyGILState_STATE state; /* Etat interne de Python */ + GSList *iter; /* Boucle de parcours */ + + state = pyglib_gil_state_ensure(); + + Py_DECREF(data->type); + + pyg_begin_allow_threads; + + for (iter = data->closures; iter; ) + { + /** + * On obtient le lien avant la libération via + * pygobject_unwatch_closure()... + */ + iter = iter->next; + + g_closure_invalidate((GClosure *)iter->data); + + } + + pyg_end_allow_threads; + + g_free(data); + + pyglib_gil_state_release(state); + +} + + + +static PyGObjectData_fake *pygobject_data_new_fake(void) +{ + PyGObjectData_fake *result; /* Instance à retourner */ + + result = g_new0(PyGObjectData_fake, 1); + + return result; + +} + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Définit les éléments immuables pour toute association. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void pychrysalide_init_quirks(void) +{ + pygobject_instance_data_key_fake = g_quark_from_static_string("PyGObject::instance-data"); + +} + + +/****************************************************************************** +* * +* Paramètres : obj = instance GLib crée en C. * +* type = type de l'objet Python correspond. * +* * +* Description : Crée l'association précise attendue par Python-GObject. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void pychrysalide_set_instance_data(GObject *obj, PyTypeObject *type) +{ + PyGObjectData_fake *data; + + data = g_object_get_qdata(obj, pygobject_instance_data_key_fake); + + if (data == NULL) + { + data = pygobject_data_new_fake(); + + data->type = type; + Py_INCREF(type); + + g_object_set_qdata_full(obj, pygobject_instance_data_key_fake, + data, (GDestroyNotify)pygobject_data_free_fake); + + } + +} diff --git a/plugins/pyoida/quirks.h b/plugins/pyoida/quirks.h new file mode 100644 index 0000000..70e036e --- /dev/null +++ b/plugins/pyoida/quirks.h @@ -0,0 +1,42 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * quirks.h - prototypes pour la transmission du type Python exact aux instances de PyObject + * + * Copyright (C) 2012 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYOIDA_QUIRKS_H +#define _PLUGINS_PYOIDA_QUIRKS_H + + +#include <Python.h> +#include <glib-object.h> + + + +/* Définit les éléments immuables pour toute association. */ +void pychrysalide_init_quirks(void); + +/* Crée l'association précise attendue par Python-GObject. */ +void pychrysalide_set_instance_data(GObject *, PyTypeObject *); + + + +#endif /* _PLUGINS_PYOIDA_QUIRKS_H */ diff --git a/plugins/python/exectracer/exectracer.py b/plugins/python/exectracer/exectracer.py index ddeff75..898f0be 100644 --- a/plugins/python/exectracer/exectracer.py +++ b/plugins/python/exectracer/exectracer.py @@ -17,3 +17,7 @@ class ExecTracer(Plugin): print "Python Hello !" print debugger + + for i in debugger.list_all_threads(): + + print "Thread %d '%s'" % (i[0], i[1]) |