diff options
Diffstat (limited to 'plugins/pychrysa/glibext')
| -rw-r--r-- | plugins/pychrysa/glibext/Makefile.am | 8 | ||||
| -rw-r--r-- | plugins/pychrysa/glibext/configuration.c | 1214 | ||||
| -rw-r--r-- | plugins/pychrysa/glibext/configuration.h | 66 | ||||
| -rw-r--r-- | plugins/pychrysa/glibext/module.c | 49 | ||||
| -rw-r--r-- | plugins/pychrysa/glibext/module.h | 6 | 
5 files changed, 1326 insertions, 17 deletions
diff --git a/plugins/pychrysa/glibext/Makefile.am b/plugins/pychrysa/glibext/Makefile.am index 14ab026..8383434 100644 --- a/plugins/pychrysa/glibext/Makefile.am +++ b/plugins/pychrysa/glibext/Makefile.am @@ -1,9 +1,13 @@  noinst_LTLIBRARIES = libpychrysaglibext.la +# libpychrysaglibext_la_SOURCES =			\ +# 	bufferline.h bufferline.c			\ +# 	codebuffer.h codebuffer.c			\ +# 	module.h module.c +  libpychrysaglibext_la_SOURCES =			\ -	bufferline.h bufferline.c			\ -	codebuffer.h codebuffer.c			\ +	configuration.h configuration.c		\  	module.h module.c diff --git a/plugins/pychrysa/glibext/configuration.c b/plugins/pychrysa/glibext/configuration.c new file mode 100644 index 0000000..9820af3 --- /dev/null +++ b/plugins/pychrysa/glibext/configuration.c @@ -0,0 +1,1214 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * configuration.c - prototypes pour l'équivalent Python du fichier "glibext/configuration.c" + * + * Copyright (C) 2012 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  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 "configuration.h" + + +#include <pygobject.h> + + +#include <glibext/configuration.h> + + + +/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */ + + +/* Crée un nouvel objet Python de type 'ConfigParam'. */ +static PyObject *py_config_param_new(PyTypeObject *, PyObject *, PyObject *); + +/* Efface toute valeur courante d'un paramètre de configuration. */ +static PyObject *py_config_param_make_empty(PyObject *, PyObject *); + +/* Réinitialise la valeur d'un paramètre de configuration. */ +static PyObject *py_config_param_reset(PyObject *, PyObject *); + +/* Indique le chemin d'accès utilisé pour un paramètre. */ +static PyObject *py_config_param_get_path(PyObject *, void *); + +/* Indique le type de valeur utilisée par un paramètre. */ +static PyObject *py_config_param_get_type(PyObject *, void *); + +/* Indique le statut d'une valeur utilisée par un paramètre. */ +static PyObject *py_config_param_get_state(PyObject *, void *); + +/* Indique la valeur courante d'un paramètre de configuration. */ +static PyObject *py_config_param_get_value(PyObject *, void *); + +/* Modifie la valeur courante d'un paramètre de configuration. */ +static int py_config_param_set_value(PyObject *, PyObject *, void *); + +/* Définit les constantes pour les paramètres. */ +static bool py_config_param_define_constants(PyObject *); + + + +/* ----------------------------- PARCOURS DE PARAMETRES ----------------------------- */ + + + +typedef struct _pyConfigParamIterator +{ + +  PyObject_HEAD +  long int m; +  long int i; + + + +    GGenConfig *config;                     /* Configuration à parcourir   */ +    GList *params;                          /* Liste de paramètres         */ + +    GList *last;                            /* Dernier élément retourné    */ + +} pyConfigParamIterator; + + + + +/* Prend acte d'un compteur de référence à 0. */ +static void py_config_param_iterator_dealloc(PyObject *); + +/* Fournit un itérateur pour paramètres de configuration. */ +static PyObject *py_config_param_iterator_iter(PyObject *); + +/* Fournit un itérateur pour paramètres de configuration. */ +static PyObject *py_config_param_iterator_next(PyObject *); + +/* Initialise un objet Python de type 'ConfigParamIterator'. */ +static int py_config_param_iterator_init(PyObject *, PyObject *, PyObject *); + + + +/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */ + + +/* Crée un nouvel objet Python de type 'GenConfig'. */ +static PyObject *py_generic_config_new(PyTypeObject *, PyObject *, PyObject *); + +/* Lit la configuration depuis un fichier. */ +static PyObject *py_generic_config_read(PyObject *, PyObject *); + +/* Ecrit la configuration dans un fichier. */ +static PyObject *py_generic_config_write(PyObject *, PyObject *); + +/* Retrouve un élément de configuration par son chemin. */ +static PyObject *py_generic_config_search(PyObject *, PyObject *); + +/* Ajoute un paramètre à une configuration. */ +static PyObject *py_generic_config_add(PyObject *, PyObject *); + +/* Retire un paramètre d'une configuration. */ +static PyObject *py_generic_config_delete(PyObject *, PyObject *); + +/* Fournit le chemin d'accès au binaire représenté. */ +static PyObject *py_generic_config_get_filename(PyObject *, void *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                              ELEMENT DE CONFIGURATION                              */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  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 'ConfigParam'.           * +*                                                                             * +*  Retour      : Instance Python mise en place.                               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ +    PyObject *result;                       /* Instance à retourner        */ +    char *path;                             /* Accès au paramètre          */ +    unsigned int ptype;                     /* Type de paramètre           */ +    PyObject *value;                        /* Valeur par défaut éventuelle*/ +    int ret;                                /* Bilan de lecture des args.  */ +    GCfgParam *param;                       /* Paramètre mis en place      */ + +    value = NULL; + +    ret = PyArg_ParseTuple(args, "sI|O", &path, &ptype, &value); +    if (!ret) Py_RETURN_NONE; + +    if (value == NULL || value == Py_None) +        param = g_config_param_new_empty(path, ptype); + +    else +        switch (ptype) +        { +            case CPT_BOOLEAN: +                if (PyBool_Check(value)) +                    param = g_config_param_new(path, CPT_BOOLEAN, (bool)(value == Py_True)); +                else +                    param = NULL; +                break; + +            case CPT_INTEGER: +                if (PyLong_Check(value)) +                    param = g_config_param_new(path, CPT_INTEGER, (int)PyLong_AsLong(value)); +                else +                    param = NULL; +                break; + +            case CPT_STRING: +                if (PyUnicode_Check(value)) +                    param = g_config_param_new(path, CPT_STRING, PyUnicode_DATA(value)); +                else +                    param = NULL; +                break; + +            default: +                param = NULL; +                break; + +        } + +    if (param != NULL) +    { +        result = pygobject_new(G_OBJECT(param)); +        g_object_unref(param); +    } +    else result = NULL; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = paramètre de configuration à manipuler.               * +*                args = non utilisé ici.                                      * +*                                                                             * +*  Description : Efface toute valeur courante d'un paramètre de configuration.* +*                                                                             * +*  Retour      : None.                                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_make_empty(PyObject *self, PyObject *args) +{ +    GCfgParam *param;                       /* Paramètre visé par l'opérat°*/ + +    param = G_CFG_PARAM(pygobject_get(self)); + +    g_config_param_make_empty(param); + +    Py_RETURN_NONE; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = paramètre de configuration à manipuler.               * +*                args = non utilisé ici.                                      * +*                                                                             * +*  Description : Réinitialise la valeur d'un paramètre de configuration.      * +*                                                                             * +*  Retour      : None.                                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_reset(PyObject *self, PyObject *args) +{ +    GCfgParam *param;                       /* Paramètre visé par l'opérat°*/ + +    param = G_CFG_PARAM(pygobject_get(self)); + +    g_config_param_reset(param); + +    Py_RETURN_NONE; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = paramètre de configuration à manipuler.               * +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Indique le chemin d'accès utilisé pour un paramètre.         * +*                                                                             * +*  Retour      : Chemin d'accès en Python.                                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_get_path(PyObject *self, void *closure) +{ +    GCfgParam *param;                       /* Paramètre visé par l'opérat°*/ +    const char *path;                       /* Chemin d'accès à diffuser   */ + +    param = G_CFG_PARAM(pygobject_get(self)); +    path = g_config_param_get_path(param); + +    return PyUnicode_FromString(path); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = paramètre de configuration à manipuler.               * +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Indique le type de valeur utilisée par un paramètre.         * +*                                                                             * +*  Retour      : Type en Python.                                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_get_type(PyObject *self, void *closure) +{ +    GCfgParam *param;                       /* Paramètre visé par l'opérat°*/ +    ConfigParamType type;                   /* Type de paramètre           */ + +    param = G_CFG_PARAM(pygobject_get(self)); +    type = g_config_param_get_ptype(param); + +    return PyLong_FromLong(type); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = paramètre de configuration à manipuler.               * +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Indique le statut d'une valeur utilisée par un paramètre.    * +*                                                                             * +*  Retour      : Etat en Python.                                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_get_state(PyObject *self, void *closure) +{ +    GCfgParam *param;                       /* Paramètre visé par l'opérat°*/ +    ConfigParamState state;                 /* Statut de paramètre         */ + +    param = G_CFG_PARAM(pygobject_get(self)); +    state = g_config_param_get_state(param); + +    return PyLong_FromLong(state); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = paramètre de configuration à manipuler.               * +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Indique la valeur courante d'un paramètre de configuration.  * +*                                                                             * +*  Retour      : Etat en Python.                                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_get_value(PyObject *self, void *closure) +{ +    PyObject *result;                       /* Valeur à retourner          */ +    GCfgParam *param;                       /* Paramètre visé par l'opérat°*/ +    ConfigParamType type;                   /* Type de paramètre manipulé  */ +    bool boolean;                           /* Valeur booléenne            */ +    int integer;                            /* Valeur entière              */ +    char *string;                           /* Chaîne de caractères        */ + +    param = G_CFG_PARAM(pygobject_get(self)); +    type = g_config_param_get_ptype(param); + +    switch (type) +    { +        case CPT_BOOLEAN: +            g_config_param_get_value(param, &boolean); +            result = (boolean ? Py_True : Py_False); +            Py_INCREF(result); +            break; + +        case CPT_INTEGER: +            g_config_param_get_value(param, &integer); +            result = PyLong_FromLong(integer); +            break; + +        case CPT_STRING: +            g_config_param_get_value(param, &string); +            if (string != NULL) +                result = PyUnicode_FromString(string); +            else +            { +                result = Py_None; +                Py_INCREF(result); +            } +            break; + +        default: +            result = NULL; +            break; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self    = paramètre de configuration à manipuler.            * +*                value   = nouvelle valeur à convertir et définir.            * +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Modifie la valeur courante d'un paramètre de configuration.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static int py_config_param_set_value(PyObject *self, PyObject *value, void *closure) +{ +    int result;                             /* Conclusion à remonter       */ +    GCfgParam *param;                       /* Paramètre visé par l'opérat°*/ +    ConfigParamType type;                   /* Type de paramètre manipulé  */ + +    result = -1; + +    param = G_CFG_PARAM(pygobject_get(self)); + +    if (value == Py_None) +    { +        g_config_param_make_empty(param); +        result = 0; +    } + +    else +    { +        type = g_config_param_get_ptype(param); + +        switch (type) +        { +            case CPT_BOOLEAN: +                if (PyBool_Check(value)) +                { +                    g_config_param_set_value(param, (bool)(value == Py_True)); +                    result = 0; +                } +                break; + +            case CPT_INTEGER: +                if (PyLong_Check(value)) +                { +                    g_config_param_set_value(param, (int)PyLong_AsLong(value)); +                    result = 0; +                } +                break; + +            case CPT_STRING: +                if (PyUnicode_Check(value)) +                { +                    g_config_param_set_value(param, PyUnicode_DATA(value)); +                    result = 0; +                } +                break; + +            default: +                break; + +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Fournit un accès à une définition de type à diffuser.        * +*                                                                             * +*  Retour      : Définition d'objet pour Python.                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PyTypeObject *get_python_config_param_type(void) +{ +    static PyMethodDef py_config_param_methods[] = { +        { "make_empty", py_config_param_make_empty, +          METH_NOARGS, +          "Unset the value of the current parameter." +        }, +        { "reset", py_config_param_reset, +          METH_NOARGS, +          "Reset the content of the current parameter." +        }, +        { NULL } +    }; + +    static PyGetSetDef py_config_param_getseters[] = { +        { +            "path", py_config_param_get_path, NULL, +            "Show the path used as key for a configuration parameter.", NULL +        }, +        { +            "type", py_config_param_get_type, NULL, +            "Show the type of value provided by a configuration parameter.", NULL +        }, +        { +            "state", py_config_param_get_state, NULL, +            "Show the state of a configuration parameter.", NULL +        }, +        { +            "value", py_config_param_get_value, py_config_param_set_value, +            "Handle the value of a configuration parameter.", NULL +        }, +        { NULL } +    }; + +    static PyTypeObject py_config_param_type = { + +        PyVarObject_HEAD_INIT(NULL, 0) + +        .tp_name        = "pychrysalide.glibext.ConfigParam", +        .tp_basicsize   = sizeof(PyGObject), + +        .tp_flags       = Py_TPFLAGS_DEFAULT, + +        .tp_doc         = "PyChrysalide generic configuration", + +        .tp_methods     = py_config_param_methods, +        .tp_getset      = py_config_param_getseters, +        .tp_new         = (newfunc)py_config_param_new + +    }; + +    return &py_config_param_type; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : dict = dictionnaire à compléter.                             * +*                                                                             * +*  Description : Définit les constantes pour les paramètres.                  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool py_config_param_define_constants(PyObject *dict) +{ +    int ret;                                /* Bilan d'un ajout            */ + +#define DEF_ULONG_CONST(name)                                               \ +    ret = PyDict_SetItemString(dict, #name, PyLong_FromUnsignedLong(name)); \ +    if (ret == -1) return false; + +    DEF_ULONG_CONST(CPT_BOOLEAN); +    DEF_ULONG_CONST(CPT_INTEGER); +    DEF_ULONG_CONST(CPT_STRING); +    DEF_ULONG_CONST(CPT_COUNT); + +    DEF_ULONG_CONST(CPS_UNDEFINED); +    DEF_ULONG_CONST(CPS_CHANGED); +    DEF_ULONG_CONST(CPS_DEFAULT); +    DEF_ULONG_CONST(CPS_EMPTY); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Prend en charge l'objet 'pychrysalide.glibext.ConfigParam'.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool register_python_config_param(PyObject *module) +{ +    PyTypeObject *py_config_param_type;     /* Type Python 'ConfigParam'     */ +    int ret;                                /* Bilan d'un appel            */ +    PyObject *dict;                         /* Dictionnaire du module      */ + +    py_config_param_type = get_python_config_param_type(); + +    py_config_param_type->tp_base = &PyGObject_Type; +    py_config_param_type->tp_basicsize = py_config_param_type->tp_base->tp_basicsize; + +    if (PyType_Ready(py_config_param_type) != 0) +        return false; + +    if (!py_config_param_define_constants(py_config_param_type->tp_dict)) +        return false; + +    Py_INCREF(py_config_param_type); +    ret = PyModule_AddObject(module, "ConfigParam", (PyObject *)py_config_param_type); +    if (ret != 0) return false; + +    dict = PyModule_GetDict(module); +    pygobject_register_class(dict, "ConfigParam", G_TYPE_CFG_PARAM, py_config_param_type, +                             Py_BuildValue("(O)", py_config_param_type->tp_base)); + +    return true; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                               PARCOURS DE PARAMETRES                               */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = instance Python à libérer de la mémoire.              * +*                                                                             * +*  Description : Prend acte d'un compteur de référence à 0.                   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void py_config_param_iterator_dealloc(PyObject *self) +{ +    pyConfigParamIterator *iterator;        /* Références pour le parcours */ + +    /** +     * Il aurait été sans doute mieux de reposer ici sur .tp_finalize, +     * mais cela semble impliquer de mettre en place tous les mécanismes de GC... +     * +     * cf. https://docs.python.org/3/extending/newtypes.html#finalization-and-de-allocation +     */ + +    iterator = (pyConfigParamIterator *)self; + +    g_generic_config_runlock(iterator->config); +    g_object_unref(G_OBJECT(iterator->config)); + +    Py_TYPE(self)->tp_free((PyObject*)self); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = itérateur à manipuler.                                * +*                                                                             * +*  Description : Fournit un itérateur pour paramètres de configuration.       * +*                                                                             * +*  Retour      : Instance Python prête à emploi.                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_iterator_iter(PyObject *self) +{ +    Py_INCREF(self); + +    return self; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = itérateur à manipuler.                                * +*                                                                             * +*  Description : Fournit un itérateur pour paramètres de configuration.       * +*                                                                             * +*  Retour      : Instance Python prête à emploi.                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_config_param_iterator_next(PyObject *self) +{ +    PyObject *result;                       /* Instance à retourner        */ +    pyConfigParamIterator *iterator;        /* Références pour le parcours */ +    GList *item;                            /* Nouvel élément courant      */ + +    iterator = (pyConfigParamIterator *)self; + +    if (iterator->last == NULL) item = iterator->params; +    else item = g_list_next(iterator->last); + +    iterator->last = item; + +    if (item != NULL) +    { +        result = pygobject_new(G_OBJECT(item->data)); +        Py_XINCREF(result); +    } +    else +    { +        PyErr_SetNone(PyExc_StopIteration); +        result = NULL; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = objet instancié à initialiser.                        * +*                args = arguments fournis à l'appel.                          * +*                kwds = arguments de type key=val fournis.                    * +*                                                                             * +*  Description : Initialise un objet Python de type 'ConfigParamIterator'.    * +*                                                                             * +*  Retour      : Instance Python mise en place.                               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static int py_config_param_iterator_init(PyObject *self, PyObject *args, PyObject *kwds) +{ +    pyConfigParamIterator *iterator;        /* Références pour le parcours */ +    PyObject *config;                       /* Configuration format Python */ +    int ret;                                /* Bilan de lecture des args.  */ + +    ret = PyArg_ParseTuple(args, "O", &config); +    if (!ret) return -1; + +    ret = PyObject_IsInstance(config, (PyObject *)get_python_generic_config_type()); +    if (!ret) return -1; + +    iterator = (pyConfigParamIterator *)self; + +    iterator->config = G_GEN_CONFIG(pygobject_get(config)); +    g_object_ref(G_OBJECT(iterator->config)); + +    g_generic_config_rlock(iterator->config); + +    iterator->params = g_generic_config_list_params(iterator->config); + +    iterator->last = NULL; + +    return 0; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Fournit un accès à une définition de type à diffuser.        * +*                                                                             * +*  Retour      : Définition d'objet pour Python.                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PyTypeObject *get_python_config_param_iterator_type(void) +{ +    static PyTypeObject py_config_param_iterator_type = { + +        PyVarObject_HEAD_INIT(NULL, 0) + +        .tp_name        = "pychrysalide.glibext.ConfigParamIterator", +        .tp_basicsize   = sizeof(pyConfigParamIterator), + +        .tp_dealloc     = py_config_param_iterator_dealloc, + +        .tp_flags       = Py_TPFLAGS_DEFAULT, + +        .tp_doc         = "Iterator for configuration parameters", + +        .tp_iter        = py_config_param_iterator_iter, +        .tp_iternext    = py_config_param_iterator_next, + +        .tp_init        = py_config_param_iterator_init, + +        .tp_new         = PyType_GenericNew, + +    }; + +    return &py_config_param_iterator_type; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Prend en charge l'objet 'pychrysalide...ConfigParamIterator'.* +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool register_python_config_param_iterator(PyObject *module) +{ +    PyTypeObject *py_config_param_iterator_type;    /* Type Python 'ConfigParamIterator' */ +    int ret;                                /* Bilan d'un appel            */ + +    py_config_param_iterator_type = get_python_config_param_iterator_type(); + +    py_config_param_iterator_type->tp_base = &PyBaseObject_Type; +    py_config_param_iterator_type->tp_basicsize = py_config_param_iterator_type->tp_base->tp_basicsize; + +    if (PyType_Ready(py_config_param_iterator_type) != 0) +        return false; + +    Py_INCREF(py_config_param_iterator_type); +    ret = PyModule_AddObject(module, "ConfigParamIterator", (PyObject *)py_config_param_iterator_type); +    if (ret != 0) return false; + +    return true; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                         GESTION GENERIQUE DE CONFIGURATION                         */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  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 'GenConfig'.             * +*                                                                             * +*  Retour      : Instance Python mise en place.                               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_generic_config_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ +    PyObject *result;                       /* Instance à retourner        */ +    char *name;                             /* Nom du fichier à charger    */ +    int ret;                                /* Bilan de lecture des args.  */ +    GGenConfig *config;                     /* Version GLib du format      */ + +    ret = PyArg_ParseTuple(args, "s", &name); +    if (!ret) Py_RETURN_NONE; + +    config = g_generic_config_new(name); + +    result = pygobject_new(G_OBJECT(config)); +    g_object_unref(config); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = configuration à manipuler.                            * +*                args = non utilisé ici.                                      * +*                                                                             * +*  Description : Lit la configuration depuis un fichier.                      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_generic_config_read(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Instance à retourner        */ +    GGenConfig *config;                     /* Version GLib du format      */ +    bool status;                            /* Bilan de l'opération        */ + +    config = G_GEN_CONFIG(pygobject_get(self)); + +    status = g_generic_config_read(config); + +    result = status ? Py_True : Py_False; +    Py_INCREF(result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = configuration à manipuler.                            * +*                args = non utilisé ici.                                      * +*                                                                             * +*  Description : Ecrit la configuration dans un fichier.                      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_generic_config_write(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Instance à retourner        */ +    GGenConfig *config;                     /* Version GLib du format      */ +    bool status;                            /* Bilan de l'opération        */ + +    config = G_GEN_CONFIG(pygobject_get(self)); + +    status = g_generic_config_write(config); + +    result = status ? Py_True : Py_False; +    Py_INCREF(result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = configuration à manipuler.                            * +*                args = indication sur l'élément à retrouver.                 * +*                                                                             * +*  Description : Retrouve un élément de configuration par son chemin.         * +*                                                                             * +*  Retour      : Elément trouvé ou NULL en cas d'échec.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_generic_config_search(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Instance à retourner        */ +    GGenConfig *config;                     /* Version GLib du format      */ +    char *path;                             /* Chemin d'accès du paramètre */ +    int ret;                                /* Bilan de lecture des args.  */ +    GCfgParam *param;                       /* Paramètre trouvé ou NULL    */ + +    config = G_GEN_CONFIG(pygobject_get(self)); + +    ret = PyArg_ParseTuple(args, "s", &path); +    if (!ret) Py_RETURN_NONE; + +    param = g_generic_config_search(config, path); + +    result = pygobject_new(G_OBJECT(param)); +    Py_XINCREF(result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = configuration à manipuler.                            * +*                args = indication sur l'élément à retrouver.                 * +*                                                                             * +*  Description : Ajoute un paramètre à une configuration.                     * +*                                                                             * +*  Retour      : Elément ajouté ou NULL en cas d'échec.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_generic_config_add(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Instance à retourner        */ +    GGenConfig *config;                     /* Version GLib du format      */ +    PyObject *param;                        /* Paramètre transmis          */ +    int ret;                                /* Bilan de lecture des args.  */ +    GCfgParam *added;                       /* Elément ajouté ou NULL      */ + +    config = G_GEN_CONFIG(pygobject_get(self)); + +    ret = PyArg_ParseTuple(args, "O", ¶m); +    if (!ret) Py_RETURN_NONE; + +    ret = PyObject_IsInstance(param, (PyObject *)get_python_config_param_type()); +    if (!ret) Py_RETURN_NONE; + +    added = g_generic_config_add_param(config, G_CFG_PARAM(pygobject_get(param))); + +    if (added != NULL) +    { +        result = pygobject_new(G_OBJECT(added)); +        Py_XINCREF(result); +    } +    else +        result = NULL; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = configuration à manipuler.                            * +*                args = indication sur l'élément à retrouver.                 * +*                                                                             * +*  Description : Retire un paramètre d'une configuration.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_generic_config_delete(PyObject *self, PyObject *args) +{ +    GGenConfig *config;                     /* Version GLib du format      */ +    char *path;                             /* Chemin d'accès du paramètre */ +    int ret;                                /* Bilan de lecture des args.  */ + +    config = G_GEN_CONFIG(pygobject_get(self)); + +    ret = PyArg_ParseTuple(args, "s", &path); +    if (!ret) Py_RETURN_NONE; + +    g_generic_config_delete_param(config, path); + +    Py_RETURN_NONE; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = configuration à manipuler.                            * +*                args = non utilisé ici.                                      * +*                                                                             * +*  Description : Renvoie la liste des paramètres de configuration.            * +*                                                                             * +*  Retour      : Itérateur pour la liste des paramètres.                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_generic_config_list_params(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Instance à retourner        */ +    PyTypeObject *iterator_type;            /* Type Python de l'itérateur  */ +    PyObject *args_list;                    /* Arguments de mise en place  */ + +    iterator_type = get_python_config_param_iterator_type(); +     +    Py_INCREF(self); + +    args_list = Py_BuildValue("(O)", self); +    result = PyObject_CallObject((PyObject *)iterator_type, args_list); + +    Py_DECREF(args_list); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self    = NULL car méthode statique.                         * +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Fournit le chemin d'accès au binaire représenté.             * +*                                                                             * +*  Retour      : Chemin d'accès en Python.                                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_generic_config_get_filename(PyObject *self, void *closure) +{ +    GGenConfig *config;                     /* Version GLib du format      */ +    const char *filename;                   /* Chemin d'accès au fichier   */ + +    config = G_GEN_CONFIG(pygobject_get(self)); + +    filename = g_generic_config_get_filename(config); + +    return PyUnicode_FromString(filename); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Fournit un accès à une définition de type à diffuser.        * +*                                                                             * +*  Retour      : Définition d'objet pour Python.                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PyTypeObject *get_python_generic_config_type(void) +{ +    static PyMethodDef py_generic_config_methods[] = { +        { "read", py_generic_config_read, +          METH_NOARGS, +          "Read the configuration from its relative XML file." +        }, +        { "write", py_generic_config_write, +          METH_NOARGS, +          "Write the configuration to its relative XML file." +        }, +        { "search", py_generic_config_search, +          METH_VARARGS, +          "Look for a given configuration parameter." +        }, +        { "add", py_generic_config_add, +          METH_VARARGS, +          "Add an existing parameter to a configuration." +        }, +        { "delete", py_generic_config_delete, +          METH_VARARGS, +          "Delete an existing parameter from a configuration." +        }, +        { "params", py_generic_config_list_params, +          METH_NOARGS, +          "List all registered configuration parameters." +        }, +        { NULL } +    }; + +    static PyGetSetDef py_generic_config_getseters[] = { +        { +            "filename", py_generic_config_get_filename, NULL, +            "Show the filename of the loaded binary file.", NULL +        }, +        { NULL } +    }; + +    static PyTypeObject py_generic_config_type = { + +        PyVarObject_HEAD_INIT(NULL, 0) + +        .tp_name        = "pychrysalide.glibext.GenConfig", +        .tp_basicsize   = sizeof(PyGObject), + +        .tp_flags       = Py_TPFLAGS_DEFAULT, + +        .tp_doc         = "PyChrysalide generic configuration", + +        .tp_methods     = py_generic_config_methods, +        .tp_getset      = py_generic_config_getseters, +        .tp_new         = (newfunc)py_generic_config_new + +    }; + +    return &py_generic_config_type; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Prend en charge l'objet 'pychrysalide.glibext.GenConfig'.    * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool register_python_generic_config(PyObject *module) +{ +    PyTypeObject *py_generic_config_type;   /* Type Python 'GenConfig'     */ +    int ret;                                /* Bilan d'un appel            */ +    PyObject *dict;                         /* Dictionnaire du module      */ + +    py_generic_config_type = get_python_generic_config_type(); + +    py_generic_config_type->tp_base = &PyGObject_Type; +    py_generic_config_type->tp_basicsize = py_generic_config_type->tp_base->tp_basicsize; + +    if (PyType_Ready(py_generic_config_type) != 0) +        return false; + +    Py_INCREF(py_generic_config_type); +    ret = PyModule_AddObject(module, "GenConfig", (PyObject *)py_generic_config_type); +    if (ret != 0) return false; + +    dict = PyModule_GetDict(module); +    pygobject_register_class(dict, "GenConfig", G_TYPE_GEN_CONFIG, py_generic_config_type, +                             Py_BuildValue("(O)", py_generic_config_type->tp_base)); + +    return true; + +} diff --git a/plugins/pychrysa/glibext/configuration.h b/plugins/pychrysa/glibext/configuration.h new file mode 100644 index 0000000..e55b3e1 --- /dev/null +++ b/plugins/pychrysa/glibext/configuration.h @@ -0,0 +1,66 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * configuration.h - prototypes pour l'équivalent Python du fichier "glibext/configuration.h" + * + * Copyright (C) 2014 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  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_GLIBEXT_CONFIGURATION_H +#define _PLUGINS_PYCHRYSA_GLIBEXT_CONFIGURATION_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_config_param_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.ConfigParam'. */ +bool register_python_config_param(PyObject *); + + + +/* ----------------------------- PARCOURS DE PARAMETRES ----------------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_config_param_iterator_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.ConfigParamIterator'. */ +bool register_python_config_param_iterator(PyObject *); + + +/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_generic_config_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.GenConfig'. */ +bool register_python_generic_config(PyObject *); + + + +#endif  /* _PLUGINS_PYCHRYSA_GLIBEXT_CONFIGURATION_H */ diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c index b62ae7b..9f3d3a8 100644 --- a/plugins/pychrysa/glibext/module.c +++ b/plugins/pychrysa/glibext/module.c @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * module.c - intégration du répertoire glibext en tant que module   * - * Copyright (C) 2012 Cyrille Bagard + * Copyright (C) 2012-2014 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -25,8 +25,7 @@  #include "module.h" -#include "bufferline.h" -#include "codebuffer.h" +#include "configuration.h" @@ -44,24 +43,50 @@  bool add_glibext_module_to_python_module(PyObject *super)  { -    bool result; -    PyObject *module; +    bool result;                            /* Bilan à retourner           */ +    PyObject *module;                       /* Sous-module mis en place    */      int ret;                                /* Bilan d'un appel            */ -    static PyMethodDef py_glibext_methods[] = { -        { NULL } +    static PyModuleDef py_chrysalide_glibext_module = { + +        .m_base = PyModuleDef_HEAD_INIT, + +        .m_name = "pychrysalide.glibext", +        .m_doc = "Python module for Chrysalide.glibext", + +        .m_size = -1, +      }; -    module = Py_InitModule("pychrysalide.glibext", py_glibext_methods); +    result = false; + +    module = PyModule_Create(&py_chrysalide_glibext_module);      if (module == NULL) return false; +    ret = PyState_AddModule(super, &py_chrysalide_glibext_module); +    if (ret != 0) goto agmtpm_exit; + +    ret = _PyImport_FixupBuiltin(module, "pychrysalide.glibext"); +    if (ret != 0) goto agmtpm_exit; +      Py_INCREF(module); -    ret = PyModule_AddObject(super, "pychrysalide.glibext", module); +    ret = PyModule_AddObject(super, "glibext", module); +    if (ret != 0) goto agmtpm_exit; + +    result = true; + +    result &= register_python_config_param(module); +    result &= register_python_config_param_iterator(module); +    result &= register_python_generic_config(module); + + agmtpm_exit: -    result = (ret == 0); +    if (!result) +    { +        printf("something went wrong in %s...\n", __FUNCTION__); +        /* ... */ -    result &= register_python_buffer_line(module); -    result &= register_python_code_buffer(module); +    }      return result; diff --git a/plugins/pychrysa/glibext/module.h b/plugins/pychrysa/glibext/module.h index fe13d4c..ddcab15 100644 --- a/plugins/pychrysa/glibext/module.h +++ b/plugins/pychrysa/glibext/module.h @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * module.h - prototypes pour l'intégration du répertoire glibext en tant que module   * - * Copyright (C) 2012 Cyrille Bagard + * Copyright (C) 2012-2014 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -22,8 +22,8 @@   */ -#ifndef _PLUGINS_PYOIDA_GLIBEXT_MODULE_H -#define _PLUGINS_PYOIDA_GLIBEXT_MODULE_H +#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_H  #include <Python.h>  | 
