diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2012-12-18 22:44:24 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2012-12-18 22:44:24 (GMT) |
commit | f4dbbab3190d13e61f125eea51a0ecec2ab9e897 (patch) | |
tree | 2362579b428c363e2cca94e0fa89b1e39b7a50e7 /plugins/pychrysa | |
parent | 64e09a6c3e39785975b5322973ed83734cedb82e (diff) |
Created a proper panel for the Android permissions in the editor.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@305 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins/pychrysa')
-rw-r--r-- | plugins/pychrysa/Makefile.am | 4 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/module.c | 2 | ||||
-rw-r--r-- | plugins/pychrysa/gtkext/Makefile.am | 17 | ||||
-rw-r--r-- | plugins/pychrysa/gtkext/module.c | 66 | ||||
-rw-r--r-- | plugins/pychrysa/gtkext/module.h | 39 | ||||
-rw-r--r-- | plugins/pychrysa/gtkext/viewpanel.c | 214 | ||||
-rw-r--r-- | plugins/pychrysa/gtkext/viewpanel.h | 44 | ||||
-rw-r--r-- | plugins/pychrysa/gui/Makefile.am | 1 | ||||
-rw-r--r-- | plugins/pychrysa/gui/editem.c | 441 | ||||
-rw-r--r-- | plugins/pychrysa/gui/editem.h | 39 | ||||
-rw-r--r-- | plugins/pychrysa/gui/module.c | 2 | ||||
-rw-r--r-- | plugins/pychrysa/gui/panels/panel.c | 33 | ||||
-rw-r--r-- | plugins/pychrysa/gui/panels/panel.h | 4 | ||||
-rw-r--r-- | plugins/pychrysa/helpers.c | 63 | ||||
-rw-r--r-- | plugins/pychrysa/helpers.h | 37 | ||||
-rw-r--r-- | plugins/pychrysa/plugin.c | 129 | ||||
-rw-r--r-- | plugins/pychrysa/pychrysa.c | 2 | ||||
-rw-r--r-- | plugins/pychrysa/quirks.c | 29 | ||||
-rw-r--r-- | plugins/pychrysa/quirks.h | 3 |
19 files changed, 1117 insertions, 52 deletions
diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am index e027c91..25074cb 100644 --- a/plugins/pychrysa/Makefile.am +++ b/plugins/pychrysa/Makefile.am @@ -2,6 +2,7 @@ pkglib_LTLIBRARIES = pychrysa.la pychrysa_la_SOURCES = \ + helpers.h helpers.c \ plugin.h plugin.c \ py_log.h py_log.c \ pychrysa.h pychrysa.c \ @@ -13,6 +14,7 @@ pychrysa_la_LIBADD = \ debug/libpychrysadebug.la \ format/libpychrysaformat.la \ glibext/libpychrysaglibext.la \ + gtkext/libpychrysagtkext.la \ gui/libpychrysagui.la pychrysa_la_LDFLAGS = -module -avoid-version $(LIBGTK_LIBS) $(LIBXML_LIBS) $(LIBPYTHON_LIBS) \ @@ -27,4 +29,4 @@ AM_CPPFLAGS = AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = analysis arch debug format glibext gui +SUBDIRS = analysis arch debug format glibext gtkext gui diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c index b2ba4ab..2212c32 100644 --- a/plugins/pychrysa/glibext/module.c +++ b/plugins/pychrysa/glibext/module.c @@ -34,7 +34,7 @@ * * * Paramètres : module = module dont la définition est à compléter. * * * -* Description : Ajoute le module 'glibext' au module Python. * +* Description : Ajoute le module 'glibext' au module Python. * * * * Retour : - * * * diff --git a/plugins/pychrysa/gtkext/Makefile.am b/plugins/pychrysa/gtkext/Makefile.am new file mode 100644 index 0000000..79cece8 --- /dev/null +++ b/plugins/pychrysa/gtkext/Makefile.am @@ -0,0 +1,17 @@ + +noinst_LTLIBRARIES = libpychrysagtkext.la + +libpychrysagtkext_la_SOURCES = \ + viewpanel.h viewpanel.c \ + module.h module.c + + +libpychrysagtkext_la_LDFLAGS = + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I../../../src + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/pychrysa/gtkext/module.c b/plugins/pychrysa/gtkext/module.c new file mode 100644 index 0000000..fb17633 --- /dev/null +++ b/plugins/pychrysa/gtkext/module.c @@ -0,0 +1,66 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire gtkext en tant que module + * + * 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 "module.h" + + +#include "viewpanel.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'gtkext' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_gtkext_module_to_python_module(PyObject *super) +{ + bool result; + PyObject *module; + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_gtkext_methods[] = { + { NULL } + }; + + module = Py_InitModule("pychrysalide.gtkext", py_gtkext_methods); + if (module == NULL) return false; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "pychrysalide.gtkext", module); + + result = (ret != 0); + + result &= register_python_view_panel(module); + + return result; + +} diff --git a/plugins/pychrysa/gtkext/module.h b/plugins/pychrysa/gtkext/module.h new file mode 100644 index 0000000..94d1eeb --- /dev/null +++ b/plugins/pychrysa/gtkext/module.h @@ -0,0 +1,39 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire gtkext en tant que module + * + * 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_GTKEXT_MODULE_H +#define _PLUGINS_PYOIDA_GTKEXT_MODULE_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Ajoute le module 'gtkext' au module Python. */ +bool add_gtkext_module_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYOIDA_GTKEXT_MODULE_H */ diff --git a/plugins/pychrysa/gtkext/viewpanel.c b/plugins/pychrysa/gtkext/viewpanel.c new file mode 100644 index 0000000..c1108c2 --- /dev/null +++ b/plugins/pychrysa/gtkext/viewpanel.c @@ -0,0 +1,214 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * viewpanel.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkviewpanel.c" + * + * 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 "viewpanel.h" + + +#include <pygobject.h> + + +#include "../quirks.h" + + + +/* Crée un nouvel objet Python de type 'ViewPanel'. */ +static PyObject *py_view_panel_new(PyTypeObject *, PyObject *, PyObject *); + +/* S'assure qu'une adresse donnée est visible à l'écran. */ +static PyObject *py_view_panel_scroll_to_address(PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'ViewPanel'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_view_panel_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ +#if 0 + PyObject *result; /* Instance à retourner */ + const char *name; /* Désignation humaine */ + const char *lname; /* Nom version longue */ + PyGObject *widget; /* Composant visuel du panneau */ + const char *path; /* Placement à l'affichage */ + int ret; /* Bilan de lecture des args. */ + GEditorItem *item; /* Version GLib du format */ + + ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path); + if (!ret) return Py_None; + + item = g_view_panel_new(get_internal_ref(), name, lname, + GTK_WIDGET(pygobject_get(widget)), path); + + result = py_view_panel_from_c(G_VIEW_PANEL(item)); + g_object_unref(item); + + return (PyObject *)result; +#endif + + /* FIXME */ + return Py_None; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance existante GLib. * +* * +* Description : Crée un nouvel objet Python de type 'ViewPanel'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *py_view_panel_from_c(GtkViewPanel *item) +{ + PyObject *module; /* Module d'appartenance */ + PyTypeObject *type; /* Type Python correspondant */ + + module = PyImport_ImportModule("pychrysalide.gtkext"); + type = (PyTypeObject *)PyObject_GetAttrString(module, "ViewPanel"); + Py_DECREF(module); + + pychrysalide_set_instance_data(G_OBJECT(item), type); + + return pygobject_new(G_OBJECT(item)); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : S'assure qu'une adresse donnée est visible à l'écran. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_view_panel_scroll_to_address(PyObject *self, PyObject *args) +{ + GtkViewPanel *panel; /* Panneau à manipuler */ + vmpa_t addr; /* Adresse demandée en visuel */ + int ret; /* Bilan de lecture des args. */ + + panel = GTK_VIEW_PANEL(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "K", &addr); + if (!ret) return Py_None; + + gtk_view_panel_scroll_to_address(panel, addr); + + Py_RETURN_NONE; + +} + + + + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.gtkext.ViewPanel'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_view_panel(PyObject *module) +{ + PyObject *parent_mod; /* Module Python-EditorItem */ + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_view_panel_methods[] = { + { + "scroll_to_address", (PyCFunction)py_view_panel_scroll_to_address, + METH_VARARGS, + "Ensure a given address is displayed in the view panel." + }, + { NULL } + }; + + static PyGetSetDef py_view_panel_getseters[] = { + { NULL } + }; + + static PyTypeObject py_view_panel_type = { + + PyObject_HEAD_INIT(NULL) + + .tp_name = "pychrysalide.gtkext.ViewPanel", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide view panel", + + .tp_methods = py_view_panel_methods, + .tp_getset = py_view_panel_getseters, + .tp_new = (newfunc)py_view_panel_new, + .tp_init = (initproc)pychrysalide_allow_args_for_gobjects + + }; + + parent_mod = PyImport_ImportModule("gtk"); + if (parent_mod == NULL) return false; + + py_view_panel_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "Fixed"); + Py_DECREF(parent_mod); + + if (PyType_Ready(&py_view_panel_type) < 0) + return false; + + Py_INCREF(&py_view_panel_type); + ret = PyModule_AddObject(module, "ViewPanel", (PyObject *)&py_view_panel_type); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/gtkext/viewpanel.h b/plugins/pychrysa/gtkext/viewpanel.h new file mode 100644 index 0000000..98b1150 --- /dev/null +++ b/plugins/pychrysa/gtkext/viewpanel.h @@ -0,0 +1,44 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * viewpanel.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkviewpanel.h" + * + * 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_PYCHRYSA_GTKEXT_MODULE_VIEW_PANEL_H +#define _PLUGINS_PYCHRYSA_GTKEXT_MODULE_VIEW_PANEL_H + + +#include <Python.h> +#include <stdbool.h> + +#include <gtkext/gtkviewpanel.h> + + + +/* Crée un nouvel objet Python de type 'ViewPanel'. */ +PyObject *py_view_panel_from_c(GtkViewPanel *); + +/* Prend en charge l'objet 'pychrysalide.gtkext.ViewPanel'. */ +bool register_python_view_panel(PyObject *module); + + + +#endif /* _PLUGINS_PYCHRYSA_GTKEXT_MODULE_VIEW_PANEL_H */ diff --git a/plugins/pychrysa/gui/Makefile.am b/plugins/pychrysa/gui/Makefile.am index 48fde30..97c2d46 100644 --- a/plugins/pychrysa/gui/Makefile.am +++ b/plugins/pychrysa/gui/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libpychrysagui.la libpychrysagui_la_SOURCES = \ + editem.h editem.c \ module.h module.c libpychrysagui_la_LIBADD = \ diff --git a/plugins/pychrysa/gui/editem.c b/plugins/pychrysa/gui/editem.c new file mode 100644 index 0000000..3b7a8b8 --- /dev/null +++ b/plugins/pychrysa/gui/editem.c @@ -0,0 +1,441 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * editem.c - prototypes pour l'équivalent Python du fichier "gui/editem.c" + * + * 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 "editem.h" + + +#include <pygobject.h> + + +#include <gui/editem-int.h> + + +#include "../helpers.h" +#include "../quirks.h" + + +#include "../analysis/binary.h" +#include "../gtkext/viewpanel.h" + + + +/* Réagit à un changement du binaire courant. */ +static void _update_editor_item_for_binary_python_wrapper(GEditorItem *, GLoadedBinary *); + +/* Réagit à un changement de vue. */ +static void _update_editor_item_for_view_python_wrapper(GEditorItem *, GtkViewPanel *); + +/* Réagit à un changement de contenu. */ +static void _update_editor_item_for_view_content_python_wrapper(GEditorItem *, GtkViewPanel *); + +/* Réagit à un changement du binaire courant. */ +static PyObject *py_editor_item_update_for_binary(PyObject *, PyObject *); + +/* Réagit à un changement d'affichage principal de contenu. */ +static PyObject *py_editor_item_update_for_view(PyObject *, PyObject *); + +/* Réagit à un changement d'affichage principal de contenu. */ +static PyObject *py_editor_item_update_for_content(PyObject *, PyObject *); + +/* Fournit l'affichage de binaire courant. */ +static PyObject *py_editor_item_get_current_view(PyObject *, PyObject *); + +/* Procède à l'enregistrement d'un élément reactif de l'éditeur. */ +static PyObject *py_editor_item_register(PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : item = élément à actualiser. * +* binary = nouvelle instance de binaire analysé. * +* * +* Description : Réagit à un changement du binaire courant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _update_editor_item_for_binary_python_wrapper(GEditorItem *item, GLoadedBinary *binary) +{ + PyObject *target; /* Version Python de l'élément */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Retour obtenu */ + + /** + * Normalement, l'objet Python est enregistré dans la liste de Chrysalide + * des éléments d'éditeur, via py_editor_item_register(), donc son compteur + * de références doit le maintenir en vie. + * + * On peut donc le récupérer directement depuis l'instane GLib, sans passer + * par la procédure de pygobject, qui obligerait à connaître le type précis + * de l'instance GLib manipulée. + */ + target = pychrysalide_get_pygobject(G_OBJECT(item)); + + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, py_loaded_binary_from_c(binary)); + + value = run_python_method(target, "update_for_binary", args); + + Py_XDECREF(value); + Py_DECREF(args); + Py_DECREF(target); + +} + + +/****************************************************************************** +* * +* Paramètres : item = élément à actualiser. * +* view = nouveau panneau d'affichage actif. * +* * +* Description : Réagit à un changement de vue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _update_editor_item_for_view_python_wrapper(GEditorItem *item, GtkViewPanel *view) +{ + PyObject *target; /* Version Python de l'élément */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Retour obtenu */ + + /** + * Normalement, l'objet Python est enregistré dans la liste de Chrysalide + * des éléments d'éditeur, via py_editor_item_register(), donc son compteur + * de références doit le maintenir en vie. + * + * On peut donc le récupérer directement depuis l'instane GLib, sans passer + * par la procédure de pygobject, qui obligerait à connaître le type précis + * de l'instance GLib manipulée. + */ + target = pychrysalide_get_pygobject(G_OBJECT(item)); + + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, py_view_panel_from_c(view)); + + value = run_python_method(target, "update_for_view", args); + + Py_XDECREF(value); + Py_DECREF(args); + Py_DECREF(target); + +} + + +/****************************************************************************** +* * +* Paramètres : item = élément à actualiser. * +* view = nouveau panneau d'affichage actif. * +* * +* Description : Réagit à un changement de contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _update_editor_item_for_view_content_python_wrapper(GEditorItem *item, GtkViewPanel *view) +{ + PyObject *target; /* Version Python de l'élément */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Retour obtenu */ + + /** + * Normalement, l'objet Python est enregistré dans la liste de Chrysalide + * des éléments d'éditeur, via py_editor_item_register(), donc son compteur + * de références doit le maintenir en vie. + * + * On peut donc le récupérer directement depuis l'instane GLib, sans passer + * par la procédure de pygobject, qui obligerait à connaître le type précis + * de l'instance GLib manipulée. + */ + target = pychrysalide_get_pygobject(G_OBJECT(item)); + + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, py_view_panel_from_c(view)); + + value = run_python_method(target, "update_for_content", args); + + Py_XDECREF(value); + Py_DECREF(args); + Py_DECREF(target); + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Réagit à un changement du binaire courant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_update_for_binary(PyObject *self, PyObject *args) +{ + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Réagit à un changement d'affichage principal de contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_update_for_view(PyObject *self, PyObject *args) +{ + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Réagit à un changement d'affichage principal de contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_update_for_content(PyObject *self, PyObject *args) +{ + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Fournit le gestionnaire du binaire courant. * +* * +* Retour : Instance en place ou Py_None si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_get_current_binary(PyObject *self, PyObject *args) +{ + PyObject *result; /* Résultat à retourner */ + GEditorItem *item; /* Elément à manipuler */ + GLoadedBinary *binary; /* Instance à convertir */ + + item = G_EDITOR_ITEM(pygobject_get(self)); + binary = g_editor_item_get_current_binary(item); + + if (binary == NULL) + { + Py_INCREF(Py_None); + result = Py_None; + } + else + result = py_loaded_binary_from_c(binary); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Fournit l'affichage de binaire courant. * +* * +* Retour : Instance en place ou Py_None si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_get_current_view(PyObject *self, PyObject *args) +{ + PyObject *result; /* Résultat à retourner */ + GEditorItem *item; /* Elément à manipuler */ + GtkViewPanel *panel; /* Instance à convertir */ + + item = G_EDITOR_ITEM(pygobject_get(self)); + panel = g_editor_item_get_current_view(item); + + if (panel == NULL) + { + Py_INCREF(Py_None); + result = Py_None; + } + else + result = py_view_panel_from_c(panel); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Procède à l'enregistrement d'un élément reactif de l'éditeur.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_register(PyObject *self, PyObject *args) +{ + GEditorItem *item; /* Version GLib de l'élément */ + + item = G_EDITOR_ITEM(pygobject_get(self)); + + item->update_binary = _update_editor_item_for_binary_python_wrapper; + item->update_view = _update_editor_item_for_view_python_wrapper; + item->update_content = _update_editor_item_for_view_content_python_wrapper; + + Py_INCREF(self); + register_editor_item(item); + + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.gui.EditorItem'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_editor_item(PyObject *module) +{ + PyObject *parent_mod; /* Module Python-GObject */ + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_editor_item_methods[] = { + { + "update_for_binary", (PyCFunction)py_editor_item_update_for_binary, + METH_VARARGS, + "Called by Chrysalide on each binary change, if the item is registered." + }, + { + "update_for_view", (PyCFunction)py_editor_item_update_for_view, + METH_VARARGS, + "Called by Chrysalide on each view change, if the item is registered." + }, + { + "update_for_content", (PyCFunction)py_editor_item_update_for_content, + METH_VARARGS, + "Called by Chrysalide on each view content change, if the item is registered." + }, + { + "get_current_binary", (PyCFunction)py_editor_item_get_current_binary, + METH_NOARGS, + "Provide the current binary." + }, + { + "get_current_view", (PyCFunction)py_editor_item_get_current_view, + METH_NOARGS, + "Provide the current binary view." + }, + { + "register", (PyCFunction)py_editor_item_register, + METH_NOARGS, + "Register the item as editor item." + }, + { NULL } + }; + + static PyGetSetDef py_editor_item_getseters[] = { + { NULL } + }; + + static PyTypeObject py_editor_item_type = { + + PyObject_HEAD_INIT(NULL) + + .tp_name = "pychrysalide.gui.EditorItem", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide editor item", + + .tp_methods = py_editor_item_methods, + .tp_getset = py_editor_item_getseters + + }; + + parent_mod = PyImport_ImportModule("gobject"); + if (parent_mod == NULL) return false; + + py_editor_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "GObject"); + Py_DECREF(parent_mod); + + if (PyType_Ready(&py_editor_item_type) < 0) + return false; + + Py_INCREF(&py_editor_item_type); + ret = PyModule_AddObject(module, "EditorItem", (PyObject *)&py_editor_item_type); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/gui/editem.h b/plugins/pychrysa/gui/editem.h new file mode 100644 index 0000000..cea5118 --- /dev/null +++ b/plugins/pychrysa/gui/editem.h @@ -0,0 +1,39 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * editem.h - prototypes pour l'équivalent Python du fichier "gui/editem.h" + * + * 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_PYCHRYSA_GUI_EDITEM_H +#define _PLUGINS_PYCHRYSA_GUI_EDITEM_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Prend en charge l'objet 'pychrysalide.gui.EditorItem'. */ +bool register_python_editor_item(PyObject *module); + + + +#endif /* _PLUGINS_PYCHRYSA_GUI_EDITEM_H */ diff --git a/plugins/pychrysa/gui/module.c b/plugins/pychrysa/gui/module.c index bee46df..cf09c44 100644 --- a/plugins/pychrysa/gui/module.c +++ b/plugins/pychrysa/gui/module.c @@ -25,6 +25,7 @@ #include "module.h" +#include "editem.h" #include "panels/module.h" @@ -61,6 +62,7 @@ bool add_gui_module_to_python_module(PyObject *super) if (ret != 0) /* ... */; + result &= register_python_editor_item(module); result &= add_gui_panels_module_to_python_module(module); return true; diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c index b1bcc61..4b982d0 100644 --- a/plugins/pychrysa/gui/panels/panel.c +++ b/plugins/pychrysa/gui/panels/panel.c @@ -40,7 +40,6 @@ static PyObject *py_panel_item_dock(PyObject *, PyObject *); - /****************************************************************************** * * * Paramètres : type = type de l'objet à instancier. * @@ -71,7 +70,7 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject item = g_panel_item_new(get_internal_ref(), name, lname, GTK_WIDGET(pygobject_get(widget)), path); - result = py_panel_item_from_c(G_PANEL_ITEM(item)); + result = _py_panel_item_from_c(G_PANEL_ITEM(item), type); g_object_unref(item); return (PyObject *)result; @@ -79,9 +78,11 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject } + /****************************************************************************** * * * Paramètres : item = instance existante GLib. * +* type = éventuel type final de l'instance Python imposé. * * * * Description : Crée un nouvel objet Python de type 'PanelItem'. * * * @@ -91,14 +92,16 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject * * ******************************************************************************/ -PyObject *py_panel_item_from_c(GPanelItem *item) +PyObject *_py_panel_item_from_c(GPanelItem *item, PyTypeObject *type) { PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - module = PyImport_ImportModule("pychrysalide.gui.panels"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "PanelItem"); - Py_DECREF(module); + if (type == NULL) + { + module = PyImport_ImportModule("pychrysalide.gui.panels"); + type = (PyTypeObject *)PyObject_GetAttrString(module, "PanelItem"); + Py_DECREF(module); + } pychrysalide_set_instance_data(G_OBJECT(item), type); @@ -128,7 +131,7 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) g_panel_item_dock(item); - return Py_None; + Py_RETURN_NONE; } @@ -145,8 +148,6 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) - - /****************************************************************************** * * * Paramètres : module = module dont la définition est à compléter. * @@ -161,14 +162,14 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) bool register_python_panel_item(PyObject *module) { - PyObject *pygobj_mod; /* Module Python-GObject */ + PyObject *parent_mod; /* Module Python-EditorItem */ int ret; /* Bilan d'un appel */ static PyMethodDef py_panel_item_methods[] = { { "dock", (PyCFunction)py_panel_item_dock, METH_NOARGS, - "DIsplay the panel item in the right place." + "Display the panel item in the right place." }, { NULL } }; @@ -195,11 +196,11 @@ bool register_python_panel_item(PyObject *module) }; - pygobj_mod = PyImport_ImportModule("gobject"); - if (pygobj_mod == NULL) return false; + parent_mod = PyImport_ImportModule("pychrysalide.gui"); + if (parent_mod == NULL) return false; - py_panel_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); - Py_DECREF(pygobj_mod); + py_panel_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "EditorItem"); + Py_DECREF(parent_mod); if (PyType_Ready(&py_panel_item_type) < 0) return false; diff --git a/plugins/pychrysa/gui/panels/panel.h b/plugins/pychrysa/gui/panels/panel.h index 8d06094..a7b6e0c 100644 --- a/plugins/pychrysa/gui/panels/panel.h +++ b/plugins/pychrysa/gui/panels/panel.h @@ -34,7 +34,9 @@ /* Crée un nouvel objet Python de type 'PanelItem'. */ -PyObject *py_panel_item_from_c(GPanelItem *); +PyObject *_py_panel_item_from_c(GPanelItem *, PyTypeObject *); + +#define py_panel_item_from_c(item) _py_panel_item_from_c(item, NULL) /* Prend en charge l'objet 'pychrysalide.gui.panels.PanelItem'. */ bool register_python_panel_item(PyObject *module); diff --git a/plugins/pychrysa/helpers.c b/plugins/pychrysa/helpers.c new file mode 100644 index 0000000..bc420c0 --- /dev/null +++ b/plugins/pychrysa/helpers.c @@ -0,0 +1,63 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * helpers.c - simplification des interactions de base avec Python + * + * 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "helpers.h" + + + +/****************************************************************************** +* * +* Paramètres : target = propriétaire de la routine visée. * +* method = désignation de la fonction à appeler. * +* args = arguments à associer à l'opération. * +* * +* Description : Appelle une routine Python. * +* * +* Retour : Retour obtenu ou NULL si erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *run_python_method(PyObject *module, const char *method, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + PyObject *func; /* Fonction visée */ + + result = NULL; + + func = PyObject_GetAttrString(module, method); + if (func == NULL) return NULL; + + if (PyCallable_Check(func)) + { + result = PyObject_CallObject(func, args); + if (result == NULL) PyErr_Print(); + } + else if (PyErr_Occurred()) PyErr_Print(); + + Py_DECREF(func); + + return result; + +} diff --git a/plugins/pychrysa/helpers.h b/plugins/pychrysa/helpers.h new file mode 100644 index 0000000..474978b --- /dev/null +++ b/plugins/pychrysa/helpers.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * helpers.h - prototypes pour la simplification des interactions de base avec Python + * + * 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_HELPERS_H +#define _PLUGINS_HELPERS_H + + +#include <Python.h> + + + +/* Appelle une routine Python. */ +PyObject *run_python_method(PyObject *, const char *, PyObject *); + + + +#endif /* _PLUGINS_HELPERS_H */ diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c index 9601432..1bda007 100644 --- a/plugins/pychrysa/plugin.c +++ b/plugins/pychrysa/plugin.c @@ -25,10 +25,14 @@ #include "plugin.h" +#include <pygobject.h> + + #include "../../src/analysis/binary.h" #include "../../src/plugins/plugin-int.h" +#include "helpers.h" #include "analysis/binary.h" #include "debug/debugger.h" @@ -65,6 +69,9 @@ static void g_python_plugin_class_init(GPythonPluginClass *); /* Initialise l'instance d'un greffon Python. */ static void g_python_plugin_init(GPythonPlugin *); +/* Procède à l'initialisation du greffon. */ +static bool g_python_plugin_do_init(GPythonPlugin *, GObject *); + /* Indique l'utilité pratique du greffon. */ static PluginAction g_python_plugin_get_action(const GPythonPlugin *); @@ -106,6 +113,9 @@ static PyObject *pychrysa_plugin_run(PyObject *, PyObject *); /* Définit les constantes pour les greffons en Python. */ static bool pychrysa_plugin_define_constants(PyObject *); +/* Procède à l'initialisation du greffon. */ +static PyObject *pychrysa_plugin_init(PyObject *, PyObject *); + /* Définit le comportement par défaut d'un greffon Python. */ static PyObject *pychrysa_plugin_get_action(PyObject *, PyObject *); @@ -255,29 +265,6 @@ static void g_python_plugin_init(GPythonPlugin *plugin) -PyObject *run_python_method(PyObject *module, const char *method, PyObject *args) -{ - PyObject *result; /* Bilan à retourner */ - PyObject *func; /* Fonction visée */ - - result = NULL; - - func = PyObject_GetAttrString(module, method); - if (func == NULL) return NULL; - - if (PyCallable_Check(func)) - { - result = PyObject_CallObject(func, args); - if (result == NULL) PyErr_Print(); - } - else if (PyErr_Occurred()) PyErr_Print(); - - Py_DECREF(func); - - return result; - -} - /****************************************************************************** * * @@ -333,7 +320,9 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) G_PLUGIN_MODULE(result)->name = strdup(modname); G_PLUGIN_MODULE(result)->name = stradd(G_PLUGIN_MODULE(result)->name, ".py"); + G_PLUGIN_MODULE(result)->filename = strdup(G_PLUGIN_MODULE(result)->name); + G_PLUGIN_MODULE(result)->init = g_python_plugin_do_init; G_PLUGIN_MODULE(result)->get_action = g_python_plugin_get_action; G_PLUGIN_MODULE(result)->is_matching = g_python_plugin_is_matching; @@ -360,6 +349,44 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) /****************************************************************************** * * +* Paramètres : plugin = greffon à initialiser. * +* ref = espace de référencement global. * +* * +* Description : Procède à l'initialisation du greffon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_python_plugin_do_init(GPythonPlugin *plugin, GObject *ref) +{ + bool result; /* Bilan à retourner */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Valeur obtenue */ + int cmp; /* Bilan de la comparaison */ + + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pygobject_new(ref)); + + value = run_python_method(plugin->instance, "init", args); + + if (PyObject_Cmp(value, Py_True, &cmp) == -1) + result = false; + else + result = (cmp == 0); + + Py_XDECREF(value); + Py_DECREF(args); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : plugin = greffon de prise en charge à utiliser. * * * * Description : Indique l'utilité pratique du greffon. * @@ -669,6 +696,27 @@ static bool pychrysa_plugin_define_constants(PyObject *dict) * Paramètres : self = classe assurant le lien avec l'éditeur de messages. * * args = arguments fournis à l'appel. * * * +* Description : Procède à l'initialisation du greffon. * +* * +* Retour : Rien en équivalent Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *pychrysa_plugin_init(PyObject *self, PyObject *args) +{ + Py_INCREF(Py_True); + return Py_True; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe assurant le lien avec l'éditeur de messages. * +* args = arguments fournis à l'appel. * +* * * Description : Définit le comportement par défaut d'un greffon Python. * * * * Retour : Rien en équivalent Python. * @@ -820,20 +868,35 @@ bool add_plugin_to_python_module(PyObject *module) static PyMethodDef pychrysa_plugin_methods[] = { - { "get_action", (PyCFunction)pychrysa_plugin_get_action, METH_NOARGS, - "Register the plugin for given actions." + { + "init", (PyCFunction)pychrysa_plugin_init, + METH_VARARGS, + "Initialize the plugin." + }, + { + "get_action", (PyCFunction)pychrysa_plugin_get_action, + METH_NOARGS, + "Register the plugin for given actions." }, - { "is_matching", (PyCFunction)pychrysa_plugin_is_matching, METH_VARARGS, - "Define if the given file can be handled." + { + "is_matching", (PyCFunction)pychrysa_plugin_is_matching, + METH_VARARGS, + "Define if the given file can be handled." }, - { "handle_debugger", (PyCFunction)pychrysa_plugin_handle_debugger, METH_VARARGS, - "Be notify about debugger attaching or detaching." + { + "handle_debugger", (PyCFunction)pychrysa_plugin_handle_debugger, + METH_VARARGS, + "Be notify about debugger attaching or detaching." }, - { "run", (PyCFunction)pychrysa_plugin_run, METH_VARARGS, - "Run the plugin for a specific action." + { + "run", (PyCFunction)pychrysa_plugin_run, + METH_VARARGS, + "Run the plugin for a specific action." }, - { "add_wgt", (PyCFunction)add_wgt, METH_VARARGS, - "Run the plugin for a specific action." + { + "add_wgt", (PyCFunction)add_wgt, + METH_VARARGS, + "Run the plugin for a specific action." }, NULL }; diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c index 0aa6175..d7cdfe4 100644 --- a/plugins/pychrysa/pychrysa.c +++ b/plugins/pychrysa/pychrysa.c @@ -38,6 +38,7 @@ #include "debug/module.h" #include "format/module.h" #include "glibext/module.h" +#include "gtkext/module.h" #include "gui/module.h" /* @@ -269,6 +270,7 @@ PyMODINIT_FUNC initpychrysa(void) add_debug_module_to_python_module(module); add_format_module_to_python_module(module); add_glibext_module_to_python_module(module); + add_gtkext_module_to_python_module(module); add_gui_module_to_python_module(module); add_log_to_python_module(module); diff --git a/plugins/pychrysa/quirks.c b/plugins/pychrysa/quirks.c index bd60925..68f0a2e 100644 --- a/plugins/pychrysa/quirks.c +++ b/plugins/pychrysa/quirks.c @@ -46,6 +46,8 @@ typedef struct _PyGObjectData_fake /* Clef d'accès réservée */ static GQuark pygobject_instance_data_key_fake = 0; +/* Clef pour l'enregistrement de l'objet Python dans l'objet GLib */ +static GQuark pygobject_wrapper_key_fake = 0; @@ -113,6 +115,7 @@ static GObject *_ref = NULL; void pychrysalide_init_quirks(void) { pygobject_instance_data_key_fake = g_quark_from_static_string("PyGObject::instance-data"); + pygobject_wrapper_key_fake = g_quark_from_static_string("PyGObject::wrapper"); } @@ -153,6 +156,32 @@ void pychrysalide_set_instance_data(GObject *obj, PyTypeObject *type) /****************************************************************************** * * +* Paramètres : obj = instance existante GLib. * +* * +* Description : Fournit l'instance Python d'une instance GLib, si existante. * +* * +* Retour : Instance Python mise en place ou NULL. * +* * +* Remarques : Les retours non nuls voient leur compteur incrémenté. * +* * +******************************************************************************/ + +PyObject *pychrysalide_get_pygobject(GObject *obj) +{ + PyObject *result; /* Objet en place à renvoyer */ + + result = (PyObject *)g_object_get_qdata(obj, pygobject_wrapper_key_fake); + + if (result != NULL) + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = objet à initialiser (théoriquement). * * args = arguments fournis à l'appel. * * kwds = arguments de type key=val fournis. * diff --git a/plugins/pychrysa/quirks.h b/plugins/pychrysa/quirks.h index 84a778f..ca198f3 100644 --- a/plugins/pychrysa/quirks.h +++ b/plugins/pychrysa/quirks.h @@ -37,6 +37,9 @@ void pychrysalide_init_quirks(void); /* Crée l'association précise attendue par Python-GObject. */ void pychrysalide_set_instance_data(GObject *, PyTypeObject *); +/* Fournit l'instance Python d'une instance GLib, si existante. */ +PyObject *pychrysalide_get_pygobject(GObject *); + /* Initialise un objet dérivé de GObject en Python. */ int pychrysalide_allow_args_for_gobjects(PyObject *, PyObject *, PyObject *); |