From 5108aad8eb7b20a14c1e7d9e084af2272035192d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 15 Feb 2020 18:22:18 +0100 Subject: Improved the documentation for the loaded content Python bindings. --- plugins/pychrysalide/analysis/loaded.c | 315 +++++++++++++++++++++++++++++++-- 1 file changed, 302 insertions(+), 13 deletions(-) diff --git a/plugins/pychrysalide/analysis/loaded.c b/plugins/pychrysalide/analysis/loaded.c index 4a762ef..768b11c 100644 --- a/plugins/pychrysalide/analysis/loaded.c +++ b/plugins/pychrysalide/analysis/loaded.c @@ -42,24 +42,45 @@ +#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." + + + /* Lance l'analyse propre à l'élément chargé. */ static PyObject *py_loaded_content_analyze(PyObject *, PyObject *, PyObject *); /* Lance l'analyse de l'élément chargé et attend sa conclusion. */ static PyObject *py_loaded_content_analyze_and_wait(PyObject *, PyObject *, PyObject *); +/* Fournit le désignation associée à l'élément chargé. */ +static PyObject *py_loaded_content_describe(PyObject *, PyObject *); + /* Etablit une liste d'obscurcissements présents. */ static PyObject *py_loaded_content_detect_obfuscators(PyObject *, PyObject *); /* Détermine le nombre de vues disponibles pour un contenu. */ static PyObject *py_loaded_content_count_views(PyObject *, PyObject *); +/* Fournit le nom d'une vue donnée d'un contenu chargé. */ +static PyObject *py_loaded_content_get_view_name(PyObject *, PyObject *); + /* Met en place la vue initiale pour un contenu chargé. */ static PyObject *py_loaded_content_build_default_view(PyObject *, PyObject *); +/* Met en place la vue initiale pour un contenu chargé. */ +static PyObject *py_loaded_content_build_view(PyObject *, PyObject *); + /* Fournit le contenu représenté de l'élément chargé. */ static PyObject *py_loaded_content_get_content(PyObject *, void *); +/* Fournit le format associé à l'élément chargé. */ +static PyObject *py_loaded_content_get_format_name(PyObject *, void *); + /****************************************************************************** @@ -192,7 +213,54 @@ static PyObject *py_loaded_content_analyze_and_wait(PyObject *self, PyObject *ar /****************************************************************************** * * * Paramètres : self = contenu binaire à manipuler. * -* args = non utilisé ici. * +* args = arguments associés à l'appel. * +* * +* Description : Fournit le désignation associée à l'élément chargé. * +* * +* Retour : Description courante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_loaded_content_describe(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + int full; /* Précision quant aux attentes*/ + int ret; /* Bilan de lecture des args. */ + GLoadedContent *content; /* Version GLib de l'élément */ + const char *desc; /* Description associée */ + +#define LOADED_CONTENT_DESCRIBE_METHOD PYTHON_METHOD_DEF \ +( \ + describe, "$self, full", \ + METH_VARARGS, py_loaded_content, \ + "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." \ +) + + ret = PyArg_ParseTuple(args, "p", &full); + if (!ret) return NULL; + + content = G_LOADED_CONTENT(pygobject_get(self)); + + desc = g_loaded_content_describe(content, full); + + result = PyUnicode_FromString(desc); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = contenu binaire à manipuler. * +* args = arguments associés à l'appel. * * * * Description : Etablit une liste d'obscurcissements présents. * * * @@ -212,6 +280,18 @@ static PyObject *py_loaded_content_detect_obfuscators(PyObject *self, PyObject * char **detections; /* Liste d'obscurcissements */ size_t i; /* Boucle de parcours */ +#define LOADED_CONTENT_DETECT_OBFUSCATORS_METHOD PYTHON_METHOD_DEF \ +( \ + detect_obfuscators, "$self, version", \ + METH_VARARGS, py_loaded_content, \ + "List all detected obfuscators.\n" \ + "\n" \ + "If the *version* parameter is equal to True, the operation tries to" \ + " resolve obfuscators versions too.\n" \ + "\n" \ + "The result is a tuple of strings or an empty tuple." \ +) + ret = PyArg_ParseTuple(args, "p", &version); if (!ret) return NULL; @@ -238,7 +318,7 @@ static PyObject *py_loaded_content_detect_obfuscators(PyObject *self, PyObject * /****************************************************************************** * * * Paramètres : self = contenu chargé à manipuler. * -* args = non utilisé ici. * +* args = arguments associés à l'appel. * * * * Description : Détermine le nombre de vues disponibles pour un contenu. * * * @@ -254,6 +334,13 @@ static PyObject *py_loaded_content_count_views(PyObject *self, PyObject *args) GLoadedContent *content; /* Version GLib de l'élément */ size_t count; /* Quantité à retourner */ +#define LOADED_CONTENT_COUNT_VIEWS_METHOD PYTHON_METHOD_DEF \ +( \ + count_views, "$self", \ + METH_NOARGS, py_loaded_content, \ + "Compute the quantity of available views for the loaded binary." \ +) + content = G_LOADED_CONTENT(pygobject_get(self)); count = g_loaded_content_count_views(content); @@ -268,6 +355,51 @@ static PyObject *py_loaded_content_count_views(PyObject *self, PyObject *args) /****************************************************************************** * * * Paramètres : self = contenu chargé à manipuler. * +* args = arguments associés à l'appel. * +* * +* Description : Fournit le nom d'une vue donnée d'un contenu chargé. * +* * +* Retour : Désignation humainement lisible. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_loaded_content_get_view_name(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + unsigned int index; /* Indice de la vue ciblée */ + int ret; /* Bilan de lecture des args. */ + GLoadedContent *content; /* Version GLib de l'élément */ + const char *name; /* Dénomination récupérée */ + +#define LOADED_CONTENT_GET_VIEW_NAME_METHOD PYTHON_METHOD_DEF \ +( \ + get_view_name, "$self, index", \ + METH_VARARGS, py_loaded_content, \ + "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." \ +) + + ret = PyArg_ParseTuple(args, "I", &index); + if (!ret) return NULL; + + content = G_LOADED_CONTENT(pygobject_get(self)); + + name = g_loaded_content_get_view_name(content, index); + + result = PyUnicode_FromString(name); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = contenu chargé à manipuler. * * args = non utilisé ici. * * * * Description : Met en place la vue initiale pour un contenu chargé. * @@ -310,6 +442,126 @@ static PyObject *py_loaded_content_build_default_view(PyObject *self, PyObject * /****************************************************************************** * * +* Paramètres : self = contenu chargé à manipuler. * +* args = arguments associés à l'appel. * +* * +* Description : Met en place la vue initiale pour un contenu chargé. * +* * +* Retour : Composant graphique nouveau. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_loaded_content_build_view(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + unsigned int index; /* Indice de la vue ciblée */ + int ret; /* Bilan de lecture des 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." \ +) + + ret = PyArg_ParseTuple(args, "I", &index); + if (!ret) return NULL; + + content = G_LOADED_CONTENT(pygobject_get(self)); + + view = g_loaded_content_build_default_view(content); + + result = new_pygobject_widget(view); + + g_object_unref(G_OBJECT(view)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = contenu chargé à manipuler. * +* args = arguments associés à l'appel. * +* * +* 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 PyObject *py_loaded_content_get_view_index(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + PyObject *gtk_mod; /* Module Python Gtk */ + PyObject *type; /* Module "GtkWidget" */ + PyObject *widget_obj; /* Composant GTK en Python */ + int ret; /* Bilan de lecture des args. */ + GLoadedContent *content; /* Version GLib de l'élément */ + GtkWidget *widget; /* Composant GTK à retrouver */ + unsigned int index; /* Indice de la vue fournie */ + +#define LOADED_CONTENT_GET_VIEW_INDEX_METHOD PYTHON_METHOD_DEF \ +( \ + get_view_index, "$self, widget", \ + METH_VARARGS, py_loaded_content, \ + "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." \ +) + + gtk_mod = PyImport_ImportModule("gi.repository.Gtk"); + + if (gtk_mod == NULL) + { + PyErr_SetString(PyExc_TypeError, "unable to find the Gtk Python module"); + return NULL; + } + + type = PyObject_GetAttrString(gtk_mod, "Widget"); + + Py_DECREF(gtk_mod); + + ret = PyArg_ParseTuple(args, "O!", type, &widget_obj); + + Py_DECREF(type); + + 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)); + + index = g_loaded_content_get_view_index(content, widget); + + result = PyLong_FromUnsignedLong(index); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * @@ -348,6 +600,46 @@ static PyObject *py_loaded_content_get_content(PyObject *self, void *closure) /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le format associé à l'élément chargé. * +* * +* Retour : Format associé à l'élément chargé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_loaded_content_get_format_name(PyObject *self, void *closure) +{ + PyObject *result; /* Instance Python à retourner */ + GLoadedContent *content; /* Version GLib de l'élément */ + GBinContent *bincnt; /* Contenu binaire associé */ + +#define LOADED_CONTENT_FORMAT_NAME_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + format_name, py_loaded_content, \ + "Raw name of the format connected to the loaded content.\n" \ + "\n" \ + "The name associated to a loaded Elf binary is for instance 'elf'." \ +) + + content = G_LOADED_CONTENT(pygobject_get(self)); + + bincnt = g_loaded_content_get_content(content); + + result = pygobject_new(G_OBJECT(bincnt)); + + g_object_unref(G_OBJECT(bincnt)); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -363,22 +655,19 @@ PyTypeObject *get_python_loaded_content_type(void) static PyMethodDef py_loaded_content_methods[] = { LOADED_CONTENT_ANALYZE_METHOD, LOADED_CONTENT_ANALYZE_AND_WAIT_METHOD, - { - "detect_obfuscators", py_loaded_content_detect_obfuscators, - METH_VARARGS, - "detect_obfuscators($self, version, /)\n--\n\nList all detected obfuscators." - }, - { - "count_views", py_loaded_content_count_views, - METH_NOARGS, - "count_views($self, /)\n--\n\nCompute the quantity of available views." - }, + LOADED_CONTENT_DESCRIBE_METHOD, + LOADED_CONTENT_DETECT_OBFUSCATORS_METHOD, + LOADED_CONTENT_COUNT_VIEWS_METHOD, + LOADED_CONTENT_GET_VIEW_NAME_METHOD, LOADED_CONTENT_BUILD_DEFAULT_VIEW_METHOD, + LOADED_CONTENT_BUILD_VIEW_METHOD, + LOADED_CONTENT_GET_VIEW_INDEX_METHOD, { NULL } }; static PyGetSetDef py_loaded_content_getseters[] = { LOADED_CONTENT_CONTENT_ATTRIB, + LOADED_CONTENT_FORMAT_NAME_ATTRIB, { NULL } }; @@ -391,7 +680,7 @@ PyTypeObject *get_python_loaded_content_type(void) .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_doc = "PyChrysalide loaded content", + .tp_doc = LOADED_CONTENT_DOC, .tp_methods = py_loaded_content_methods, .tp_getset = py_loaded_content_getseters -- cgit v0.11.2-87-g4458