summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-07-12 13:52:22 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-07-12 13:52:22 (GMT)
commit2bd3ea7249d1234204c1b70abac8bc46e221fb95 (patch)
treef6b0f71d430bda2e8d762afbf5d084ac58cee640 /plugins/pychrysalide/analysis
parent6ea1b9a8550adf84cde510c2d4446c5120c4d065 (diff)
Improved the API for loaded contents.
Diffstat (limited to 'plugins/pychrysalide/analysis')
-rw-r--r--plugins/pychrysalide/analysis/loaded.c791
-rw-r--r--plugins/pychrysalide/analysis/storage/serialize.c2
2 files changed, 760 insertions, 33 deletions
diff --git a/plugins/pychrysalide/analysis/loaded.c b/plugins/pychrysalide/analysis/loaded.c
index 768b11c..e3b2625 100644
--- a/plugins/pychrysalide/analysis/loaded.c
+++ b/plugins/pychrysalide/analysis/loaded.c
@@ -33,22 +33,52 @@
#include <i18n.h>
-#include <analysis/loaded.h>
+#include <analysis/loaded-int.h>
#include <core/global.h>
+#include "content.h"
#include "../access.h"
#include "../helpers.h"
-#define LOADED_CONTENT_DOC \
- "The LoadedContent interface is an intermediary level of abstraction" \
- " for all loaded binary contents to analyze." \
- "\n" \
- "No matter if the loaded content comes from an ELF file or XML data," \
- " some basic features are available here."
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void py_loaded_content_interface_init(GLoadedContentIface *, gpointer *);
+
+/* Fournit le contenu représenté de l'élément chargé. */
+static GBinContent *py_loaded_content_get_content_wrapper(const GLoadedContent *);
+
+/* Fournit le format associé à l'élément chargé. */
+static char *py_loaded_content_get_format_name_wrapper(const GLoadedContent *);
+
+/* Lance l'analyse propre à l'élément chargé. */
+static bool py_loaded_content_analyze_wrapper(GLoadedContent *, bool, bool, wgroup_id_t, GtkStatusStack *);
+/* Fournit le désignation associée à l'élément chargé. */
+static char *py_loaded_content_describe_wrapper(const GLoadedContent *, bool);
+
+/* Détermine le nombre de vues disponibles pour un contenu. */
+static unsigned int py_loaded_content_count_views_wrapper(const GLoadedContent *);
+
+/* Fournit le nom d'une vue donnée d'un contenu chargé. */
+static char *py_loaded_content_get_view_name_wrapper(const GLoadedContent *, unsigned int);
+
+/* Met en place la vue initiale pour un contenu chargé. */
+static GtkWidget *py_loaded_content_build_default_view_wrapper(GLoadedContent *);
+
+/* Met en place la vue demandée pour un contenu chargé. */
+static GtkWidget *py_loaded_content_build_view_wrapper(GLoadedContent *, unsigned int);
+
+/* Retrouve l'indice correspondant à la vue donnée d'un contenu. */
+static unsigned int py_loaded_content_get_view_index_wrapper(GLoadedContent *, GtkWidget *);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
/* Lance l'analyse propre à l'élément chargé. */
@@ -83,6 +113,690 @@ static PyObject *py_loaded_content_get_format_name(PyObject *, void *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* unused = adresse non utilisée ici. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_loaded_content_interface_init(GLoadedContentIface *iface, gpointer *unused)
+{
+#define LOADED_CONTENT_DOC \
+ "The LoadedContent interface is an intermediary level of abstraction" \
+ " for all loaded binary contents to analyze." \
+ "\n" \
+ "No matter if the loaded content comes from an ELF file or XML data," \
+ " some basic features are available here." \
+ "\n" \
+ "A typical class declaration for a new implementation looks like:\n" \
+ "\n" \
+ " class NewImplem(GObject.Object, LoadedContent):\n" \
+ " ...\n" \
+ "\n" \
+ "The following methods have to be defined for new implementations:\n" \
+ "* pychrysalide.analysis.storage.LoadedContent._get_content();\n" \
+ "* pychrysalide.analysis.storage.LoadedContent._get_format_name();\n" \
+ "* pychrysalide.analysis.storage.LoadedContent._analyze();\n" \
+ "* pychrysalide.analysis.storage.LoadedContent._describe();\n" \
+ "* pychrysalide.analysis.storage.LoadedContent._count_views();\n" \
+ "* pychrysalide.analysis.storage.LoadedContent._get_view_name();\n" \
+ "* pychrysalide.analysis.storage.LoadedContent._build_default_view();\n"\
+ "* pychrysalide.analysis.storage.LoadedContent._build_view();\n" \
+ "* pychrysalide.analysis.storage.LoadedContent._get_view_index();\n"
+
+ iface->get_content = py_loaded_content_get_content_wrapper;
+ iface->get_format_name = py_loaded_content_get_format_name_wrapper;
+
+ iface->analyze = py_loaded_content_analyze_wrapper;
+
+ iface->describe = py_loaded_content_describe_wrapper;
+
+ iface->count_views = py_loaded_content_count_views_wrapper;
+ iface->get_view_name = py_loaded_content_get_view_name_wrapper;
+ iface->build_def_view = py_loaded_content_build_default_view_wrapper;
+ iface->build_view = py_loaded_content_build_view_wrapper;
+ iface->get_view_index = py_loaded_content_get_view_index_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = élément chargé à manipuler. *
+* *
+* Description : Fournit le contenu représenté de l'élément chargé. *
+* *
+* Retour : Contenu représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBinContent *py_loaded_content_get_content_wrapper(const GLoadedContent *content)
+{
+ GBinContent *result; /* Contenu interne à renvoyer */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define LOADED_CONTENT_GET_CONTENT_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_content, "$self", \
+ METH_VARARGS, \
+ "Abstract method used to get the binary content linked to the" \
+ " loaded content. The result is provided as a" \
+ " pychrysalide.analysis.BinContent instance." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_get_content"))
+ {
+ pyret = run_python_method(pyobj, "_get_content", NULL);
+
+ if (pyret != NULL)
+ {
+ if (convert_to_binary_content(pyret, &result) != 1)
+ PyErr_Clear();
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = élément chargé à manipuler. *
+* *
+* Description : Fournit le format associé à l'élément chargé. *
+* *
+* Retour : Format associé à l'élément chargé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_loaded_content_get_format_name_wrapper(const GLoadedContent *content)
+{
+ char *result; /* Contenu interne à renvoyer */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define LOADED_CONTENT_GET_FORMAT_NAME_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_format_name, "$self", \
+ METH_VARARGS, \
+ "Abstract method used to provide the aw name of the format connected" \
+ " to the loaded content.\n" \
+ "\n" \
+ "The name associated to a loaded Elf binary is for instance 'elf'." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_get_format_name"))
+ {
+ pyret = run_python_method(pyobj, "_get_format_name", NULL);
+
+ if (pyret != NULL)
+ {
+ ret = PyUnicode_Check(pyret);
+
+ if (ret)
+ result = strdup(PyUnicode_AsUTF8(pyret));
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = élément chargé à manipuler. *
+* connect = organise le lancement des connexions aux serveurs. *
+* cache = précise si la préparation d'un rendu est demandée. *
+* gid = groupe de travail dédié. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Lance l'analyse propre à l'élément chargé. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_loaded_content_analyze_wrapper(GLoadedContent *content, bool connect, bool cache, wgroup_id_t gid, GtkStatusStack *status)
+{
+ bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *connect_obj; /* Ordre de connexion */
+ PyObject *cache_obj; /* Usage du cache */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define LOADED_CONTENT_ANALYZE_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _analyze, "$self, connect, cache, gid, status", \
+ METH_VARARGS, \
+ "Abstract method used to start the analysis of the loaded binary." \
+ "\n" \
+ "The *connect* parameter defines if connections to database servers" \
+ " (internal and/or remote) will be established. The default value" \
+ " depends on the running mode: if the analysis is run from the GUI," \
+ " the binary will get connected to servers; in batch mode, no" \
+ " connection will be made." \
+ "\n" \
+ "The *cache* parameter rules the build of the cache for rendering" \
+ " lines. The same behavior relative to the running mode applies." \
+ "\n" \
+ "The identifier refers to the working queue used to process the" \
+ " analysis. A reference to the main status bar may also be provided," \
+ " as a pychrysalide.gtkext.StatusStack instance if running in" \
+ " graphical mode or None otherwise." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_analyze"))
+ {
+ connect_obj = connect ? Py_True : Py_False;
+ Py_INCREF(connect_obj);
+
+ cache_obj = cache ? Py_True : Py_False;
+ Py_INCREF(cache_obj);
+
+ args = PyTuple_New(4);
+ PyTuple_SetItem(args, 0, connect_obj);
+ PyTuple_SetItem(args, 1, cache_obj);
+ PyTuple_SetItem(args, 2, PyLong_FromUnsignedLong(gid));
+ PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(status)));
+
+ pyret = run_python_method(pyobj, "_analyze", args);
+
+ if (pyret != NULL)
+ {
+ result = (pyret == Py_True);
+ Py_DECREF(pyret);
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = élément chargé à consulter. *
+* full = précise s'il s'agit d'une version longue ou non. *
+* *
+* Description : Fournit le désignation associée à l'élément chargé. *
+* *
+* Retour : Description courante. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_loaded_content_describe_wrapper(const GLoadedContent *content, bool full)
+{
+ char *result; /* Description à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *full_obj; /* Précision sur la longueur */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define LOADED_CONTENT_DESCRIBE_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _describe, "$self, full", \
+ METH_VARARGS, \
+ "Abstract method used to describe the loaded content.\n" \
+ "\n" \
+ "The boolean *full* parameter shapes the size of the returned string.\n" \
+ "\n" \
+ "This method is mainly used to provide a label (or a tooltip text)" \
+ " for tabs in the graphical main window." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_describe"))
+ {
+ full_obj = full ? Py_True : Py_False;
+ Py_INCREF(full_obj);
+
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, full_obj);
+
+ pyret = run_python_method(pyobj, "_describe", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyUnicode_Check(pyret);
+
+ if (ret)
+ result = strdup(PyUnicode_AsUTF8(pyret));
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu chargé à consulter. *
+* *
+* Description : Détermine le nombre de vues disponibles pour un contenu. *
+* *
+* Retour : Quantité strictement positive. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static unsigned int py_loaded_content_count_views_wrapper(const GLoadedContent *content)
+{
+ unsigned int result; /* Quantité de vues à renvoyer */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define LOADED_CONTENT_COUNT_VIEWS_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _count_views, "$self", \
+ METH_VARARGS, \
+ "Abstract method used to compute the quantity of available" \
+ " views for the loaded binary." \
+)
+
+ result = 0;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_count_views"))
+ {
+ pyret = run_python_method(pyobj, "_count_views", NULL);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ result = PyLong_AsUnsignedLong(pyret);
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu chargé à consulter. *
+* index = indice de la vue ciblée. *
+* *
+* Description : Fournit le nom d'une vue donnée d'un contenu chargé. *
+* *
+* Retour : Désignation humainement lisible. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_loaded_content_get_view_name_wrapper(const GLoadedContent *content, unsigned int index)
+{
+ char *result; /* Désignation à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define LOADED_CONTENT_GET_VIEW_NAME_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_view_name, "$self, index", \
+ METH_VARARGS, \
+ "Abstract method used to provide the human readable name for" \
+ " a given view of a loaded binary.\n" \
+ "\n" \
+ "Such a method is used in the graphical main window for" \
+ " building menu labels." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_get_view_name"))
+ {
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(index));
+
+ pyret = run_python_method(pyobj, "_get_view_name", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyUnicode_Check(pyret);
+
+ if (ret)
+ result = strdup(PyUnicode_AsUTF8(pyret));
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu chargé à consulter. *
+* *
+* Description : Met en place la vue initiale pour un contenu chargé. *
+* *
+* Retour : Composant graphique nouveau. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkWidget *py_loaded_content_build_default_view_wrapper(GLoadedContent *content)
+{
+ GtkWidget *result; /* Support à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define LOADED_CONTENT_BUILD_DEFAULT_VIEW_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _build_default_view, "$self", \
+ METH_VARARGS, \
+ "Abstract method used to build a new widget for the default graphical" \
+ " view of the loaded content." \
+ "\n" \
+ "This method is aimed to only be called from the GUI internals." \
+ " It provides the first view displayed in the main Chrysalide window" \
+ " after a binary loading." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_build_default_view"))
+ {
+ pyret = run_python_method(pyobj, "_build_default_view", NULL);
+
+ if (pyret != NULL)
+ {
+ ret = convert_to_gtk_widget(pyret, &result);
+
+ if (ret == 1)
+ g_object_ref(G_OBJECT(result));
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu chargé à consulter. *
+* index = indice de la vue ciblée. *
+* *
+* Description : Met en place la vue demandée pour un contenu chargé. *
+* *
+* Retour : Composant graphique nouveau. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkWidget *py_loaded_content_build_view_wrapper(GLoadedContent *content, unsigned int index)
+{
+ GtkWidget *result; /* Support à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define LOADED_CONTENT_BUILD_VIEW_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _build_view, "$self, index", \
+ METH_VARARGS, \
+ "Abstract method used to build a new widget for a given graphical view" \
+ " of the loaded content.\n" \
+ "\n" \
+ "This method is aimed to only be called from the GUI internals." \
+ " It provides a view displayed in the main Chrysalide window" \
+ " once the binary is loaded." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_build_view"))
+ {
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(index));
+
+ pyret = run_python_method(pyobj, "_build_view", args);
+
+ if (pyret != NULL)
+ {
+ ret = convert_to_gtk_widget(pyret, &result);
+
+ if (ret == 1)
+ g_object_ref(G_OBJECT(result));
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu chargé à consulter. *
+* index = composant graphique en place. *
+* *
+* Description : Retrouve l'indice correspondant à la vue donnée d'un contenu.*
+* *
+* Retour : Indice de la vue représentée, ou -1 en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static unsigned int py_loaded_content_get_view_index_wrapper(GLoadedContent *content, GtkWidget *view)
+{
+ unsigned int result; /* Indice à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define LOADED_CONTENT_GET_VIEW_INDEX_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_view_index, "$self, view", \
+ METH_VARARGS, \
+ "Abstract method used to define the index of a given view for the" \
+ " loaded binary.\n" \
+ "\n" \
+ "The view is provided as a GTK *widget*.\n" \
+ "\n" \
+ "The result is the index of the type of view, or -1 in case of error." \
+)
+
+ result = 0;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_get_view_index"))
+ {
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(view)));
+
+ pyret = run_python_method(pyobj, "_get_view_index", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ result = PyLong_AsUnsignedLong(pyret);
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONNEXION AVEC L'API DE PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = contenu binaire à manipuler. *
@@ -416,15 +1130,16 @@ static PyObject *py_loaded_content_build_default_view(PyObject *self, PyObject *
GLoadedContent *content; /* Version GLib de l'élément */
GtkWidget *view; /* Composant GTK à transposer */
-#define LOADED_CONTENT_BUILD_DEFAULT_VIEW_METHOD PYTHON_METHOD_DEF \
-( \
- build_default_view, "$self", \
- METH_NOARGS, py_loaded_content, \
- "Build a new widget for the default graphical view of the loaded content." \
- "\n" \
- "This method is aimed to only be called from the GUI internals." \
- " It provides the first view displayed in the main Chrysalide window" \
- " after a binary loading." \
+#define LOADED_CONTENT_BUILD_DEFAULT_VIEW_METHOD PYTHON_METHOD_DEF \
+( \
+ build_default_view, "$self", \
+ METH_NOARGS, py_loaded_content, \
+ "Build a new widget for the default graphical view of the loaded" \
+ " content.\n" \
+ "\n" \
+ "This method is aimed to only be called from the GUI internals." \
+ " It provides the first view displayed in the main Chrysalide window" \
+ " after a binary loading." \
)
content = G_LOADED_CONTENT(pygobject_get(self));
@@ -461,15 +1176,16 @@ static PyObject *py_loaded_content_build_view(PyObject *self, PyObject *args)
GLoadedContent *content; /* Version GLib de l'élément */
GtkWidget *view; /* Composant GTK à transposer */
-#define LOADED_CONTENT_BUILD_VIEW_METHOD PYTHON_METHOD_DEF \
-( \
- build_view, "$self, index", \
- METH_VARARGS, py_loaded_content, \
- "Build a new widget for a given graphical view of the loaded content." \
- "\n" \
- "This method is aimed to only be called from the GUI internals." \
- " It provides a view displayed in the main Chrysalide window" \
- " once the binary is loaded." \
+#define LOADED_CONTENT_BUILD_VIEW_METHOD PYTHON_METHOD_DEF \
+( \
+ build_view, "$self, index", \
+ METH_VARARGS, py_loaded_content, \
+ "Build a new widget for a given graphical view of the loaded" \
+ " content.\n" \
+ "\n" \
+ "This method is aimed to only be called from the GUI internals." \
+ " It provides a view displayed in the main Chrysalide window" \
+ " once the binary is loaded." \
)
ret = PyArg_ParseTuple(args, "I", &index);
@@ -541,12 +1257,6 @@ static PyObject *py_loaded_content_get_view_index(PyObject *self, PyObject *args
if (!ret) return NULL;
- if (!GTK_IS_WIDGET(pygobject_get(widget_obj)))
- {
- PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to GTK widget");
- return NULL;
- }
-
content = G_LOADED_CONTENT(pygobject_get(self));
widget = GTK_WIDGET(pygobject_get(widget_obj));
@@ -653,6 +1363,15 @@ static PyObject *py_loaded_content_get_format_name(PyObject *self, void *closure
PyTypeObject *get_python_loaded_content_type(void)
{
static PyMethodDef py_loaded_content_methods[] = {
+ LOADED_CONTENT_GET_CONTENT_WRAPPER,
+ LOADED_CONTENT_GET_FORMAT_NAME_WRAPPER,
+ LOADED_CONTENT_ANALYZE_WRAPPER,
+ LOADED_CONTENT_DESCRIBE_WRAPPER,
+ LOADED_CONTENT_COUNT_VIEWS_WRAPPER,
+ LOADED_CONTENT_GET_VIEW_NAME_WRAPPER,
+ LOADED_CONTENT_BUILD_DEFAULT_VIEW_WRAPPER,
+ LOADED_CONTENT_BUILD_VIEW_WRAPPER,
+ LOADED_CONTENT_GET_VIEW_INDEX_WRAPPER,
LOADED_CONTENT_ANALYZE_METHOD,
LOADED_CONTENT_ANALYZE_AND_WAIT_METHOD,
LOADED_CONTENT_DESCRIBE_METHOD,
@@ -710,6 +1429,14 @@ bool ensure_python_loaded_content_is_registered(void)
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
+ static GInterfaceInfo info = { /* Paramètres d'inscription */
+
+ .interface_init = (GInterfaceInitFunc)py_loaded_content_interface_init,
+ .interface_finalize = NULL,
+ .interface_data = NULL,
+
+ };
+
type = get_python_loaded_content_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
@@ -718,7 +1445,7 @@ bool ensure_python_loaded_content_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_LOADED_CONTENT, type))
+ if (!register_interface_for_pygobject_2(dict, G_TYPE_LOADED_CONTENT, type, &info))
return false;
}
diff --git a/plugins/pychrysalide/analysis/storage/serialize.c b/plugins/pychrysalide/analysis/storage/serialize.c
index 67e1256..3e94271 100644
--- a/plugins/pychrysalide/analysis/storage/serialize.c
+++ b/plugins/pychrysalide/analysis/storage/serialize.c
@@ -97,7 +97,7 @@ static void py_serializable_object_interface_init(GSerializableObjectIface *ifac
"\n" \
"The following methods have to be defined for new implementations:\n" \
"* pychrysalide.analysis.storage.SerializableObject._load();\n" \
- "* pychrysalide.analysis.storage.SerializableObject._store();\n" \
+ "* pychrysalide.analysis.storage.SerializableObject._store();\n"
iface->load = py_serializable_object_load_wrapper;
iface->store = py_serializable_object_store_wrapper;