diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2022-02-22 12:57:05 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2022-02-22 12:57:05 (GMT) |
commit | fbde6e0ebfc5b0203eda1c5fe3c6ba72d1427896 (patch) | |
tree | f825dde8617b9efa0e77124785e8afa3f9d1a031 /plugins/pychrysalide | |
parent | 8bf77ba6e5ef40d8bb936dc952ac2c8cc30aab3e (diff) |
Introduce a generic way to subclass Python analysis clients.
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r-- | plugins/pychrysalide/analysis/db/analyst.c | 48 | ||||
-rw-r--r-- | plugins/pychrysalide/helpers.c | 58 | ||||
-rw-r--r-- | plugins/pychrysalide/helpers.h | 16 |
3 files changed, 102 insertions, 20 deletions
diff --git a/plugins/pychrysalide/analysis/db/analyst.c b/plugins/pychrysalide/analysis/db/analyst.c index c55f34a..3cb77d1 100644 --- a/plugins/pychrysalide/analysis/db/analyst.c +++ b/plugins/pychrysalide/analysis/db/analyst.c @@ -30,7 +30,7 @@ #include <i18n.h> -#include <analysis/db/analyst.h> +#include <analysis/db/analyst-int.h> #include <core/collections.h> @@ -45,8 +45,8 @@ -/* Crée un nouvel objet Python de type 'AnalystClient'. */ -static PyObject *py_analyst_client_new(PyTypeObject *, PyObject *, PyObject *); +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_analyst_client_init(PyObject *, PyObject *, PyObject *); /* Envoie un contenu binaire pour conservation côté serveur. */ static PyObject *py_analyst_client_send_content(PyObject *, PyObject *); @@ -80,23 +80,26 @@ static PyObject *py_analyst_client_get_current_snapshot(PyObject *, void *); +CREATE_DYN_CONSTRUCTOR(analyst_client, G_TYPE_ANALYST_CLIENT); + + /****************************************************************************** * * -* Paramètres : type = type de l'objet à instancier. * +* Paramètres : self = objet à initialiser (théoriquement). * * args = arguments fournis à l'appel. * * kwds = arguments de type key=val fournis. * * * -* Description : Crée un nouvel objet Python de type 'AnalystClient'. * +* Description : Initialise une instance sur la base du dérivé de GObject. * * * -* Retour : Instance Python mise en place. * +* Retour : 0. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static int py_analyst_client_init(PyObject *self, PyObject *args, PyObject *kwds) { - PyObject *result; /* Instance à retourner */ + int result; /* Bilan à retourner */ GLoadedContent *loaded; /* Contenu local déjà chargé */ const char *hash; /* Empreinte du binaire visé */ const char *class; /* Nature du contenu analysé */ @@ -107,7 +110,8 @@ static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObj Py_ssize_t i; /* Boucle de parcours */ PyObject *item; /* Elément de la liste Python */ GDbCollection *collec; /* Version équivalente native */ - GAnalystClient *client; /* Serveur mis en place */ + GAnalystClient *client; /* Client mis en place */ + bool status; /* Bilan d'initialisation */ #define ANALYST_CLIENT_DOC \ "AnalystClient provides and receives binary updates to and from a connected" \ @@ -142,12 +146,17 @@ static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObj loaded = NULL; ret = PyArg_ParseTuple(args, "ssO|O&", &hash, &class, &list, convert_to_loaded_content, &loaded); - if (!ret) return NULL; + if (!ret) return -1; + + /* Initialisation d'un objet GLib */ + + ret = forward_pygobjet_init(self); + if (ret == -1) return -1; if (!PySequence_Check(list)) { PyErr_SetString(PyExc_TypeError, _("The second argument must be a collection list")); - return NULL; + return -1; } length = PySequence_Length(list); @@ -165,7 +174,7 @@ static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObj if (ret != 1) { delete_collections_list(&collections); - result = NULL; + result = -1; goto exit; } @@ -174,14 +183,11 @@ static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObj } - client = g_analyst_client_new(hash, class, collections, loaded); + client = G_ANALYST_CLIENT(pygobject_get(self)); - if (client != NULL) - { - result = pygobject_new(G_OBJECT(client)); - g_object_unref(client); - } - else result = NULL; + status = g_analyst_client_setup(client, hash, class, collections, loaded); + + result = status ? 0 : -1; exit: @@ -861,7 +867,9 @@ PyTypeObject *get_python_analyst_client_type(void) .tp_methods = py_analyst_client_methods, .tp_getset = py_analyst_client_getseters, - .tp_new = py_analyst_client_new, + + .tp_init = py_analyst_client_init, + .tp_new = py_analyst_client_new }; diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c index 320e40a..b04c801 100644 --- a/plugins/pychrysalide/helpers.c +++ b/plugins/pychrysalide/helpers.c @@ -37,6 +37,7 @@ #include <i18n.h> #include <common/extstr.h> +#include <plugins/dt.h> #include "access.h" @@ -509,6 +510,63 @@ bool register_python_module_object(PyObject *module, PyTypeObject *type) * args = éventuelle liste d'arguments. * * kwds = éventuel dictionnaire de valeurs mises à disposition. * * * +* Description : Accompagne la création d'une instance dérivée en Python. * +* * +* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *python_constructor_with_dynamic_gtype(PyTypeObject *type, PyObject *args, PyObject *kwds, PyTypeObject *base, GType base_gtype) +{ + PyObject *result; /* Objet à retourner */ + bool first_time; /* Evite les multiples passages*/ + GType gtype; /* Nouveau type de processeur */ + bool status; /* Bilan d'un enregistrement */ + + /* Validations diverses */ + + if (type == base) + goto simple_way; + + /* Mise en place d'un type dédié */ + + first_time = (g_type_from_name(type->tp_name) == 0); + + gtype = build_dynamic_type(base_gtype, type->tp_name, NULL, NULL, NULL); + + if (first_time) + { + status = register_class_for_dynamic_pygobject(gtype, type, base); + + if (!status) + { + result = NULL; + goto exit; + } + + } + + /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ + + simple_way: + + result = PyType_GenericNew(type, args, kwds); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type du nouvel objet à mettre en place. * +* args = éventuelle liste d'arguments. * +* kwds = éventuel dictionnaire de valeurs mises à disposition. * +* * * Description : Marque l'interdiction d'une instanciation depuis Python. * * * * Retour : NULL pour la levée d'exception. * diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h index 0ef8adc..32851c0 100644 --- a/plugins/pychrysalide/helpers.h +++ b/plugins/pychrysalide/helpers.h @@ -158,6 +158,22 @@ bool register_python_module_object(PyObject *, PyTypeObject *); #define APPLY_ABSTRACT_FLAG(tp) tp->tp_new = PyBaseObject_Type.tp_new +/* Accompagne la création d'une instance dérivée en Python. */ +PyObject *python_constructor_with_dynamic_gtype(PyTypeObject *, PyObject *, PyObject *, PyTypeObject *, GType); + + +#define CREATE_DYN_CONSTRUCTOR(pyname, gbase) \ +static PyObject *py_ ## pyname ## _new(PyTypeObject *, PyObject *, PyObject *); \ +static PyObject *py_ ## pyname ## _new(PyTypeObject *type, PyObject *args, PyObject *kwds) \ +{ \ + PyObject *result; /* Objet à retourner */ \ + PyTypeObject *base; /* Type de base à dériver */ \ + base = get_python_ ## pyname ## _type(); \ + result = python_constructor_with_dynamic_gtype(type, args, kwds, base, gbase); \ + return result; \ +} + + /* Marque l'interdiction d'une instanciation depuis Python. */ PyObject *no_python_constructor_allowed(PyTypeObject *, PyObject *, PyObject *); |