diff options
Diffstat (limited to 'plugins/pychrysalide')
| -rw-r--r-- | plugins/pychrysalide/Makefile.am | 1 | ||||
| -rw-r--r-- | plugins/pychrysalide/constval.c | 300 | ||||
| -rw-r--r-- | plugins/pychrysalide/constval.h | 45 | ||||
| -rw-r--r-- | plugins/pychrysalide/helpers.c | 3 | ||||
| -rw-r--r-- | plugins/pychrysalide/pychrysa.c | 2 | 
5 files changed, 350 insertions, 1 deletions
| diff --git a/plugins/pychrysalide/Makefile.am b/plugins/pychrysalide/Makefile.am index 8051bb9..3fe13af 100644 --- a/plugins/pychrysalide/Makefile.am +++ b/plugins/pychrysalide/Makefile.am @@ -6,6 +6,7 @@ libdir = $(pluginslibdir)  pychrysalide_la_SOURCES =				\  	access.h access.c					\ +	constval.h constval.c				\  	dt.h dt.c							\  	helpers.h helpers.c					\  	plugin.h plugin.c					\ diff --git a/plugins/pychrysalide/constval.c b/plugins/pychrysalide/constval.c new file mode 100644 index 0000000..b6d20aa --- /dev/null +++ b/plugins/pychrysalide/constval.c @@ -0,0 +1,300 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constval.c - conversion de constantes C en équivalent Python + * + * Copyright (C) 2018 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 "constval.h" + + +#include <longintrepr.h> + + +#include <i18n.h> + + +#include "access.h" +#include "helpers.h" + + + +/* Objet à vocation interne */ +typedef struct _PyConstvalObject +{ +    PyLongObject base;                      /* A laisser en premier        */ + +    /** +     * Le champ suivant est rajouté à la fin de l'allocation +     * de l'objet PyLongObject, dont la taille est dynamique. +     */ + +    /*const char *name;*/                   /* Désignation de la valeur    */ + +} PyConstvalObject; + + + +/* Interdit la création d'une instance depuis Python. */ +static PyObject *py_constval_new(PyTypeObject *, PyObject *, PyObject *); + +/* Calcule l'emplacement reservé pour une désignation de valeur. */ +static const char **py_constval_compute_name_ptr(PyConstvalObject *); + +/* Construit une représentation textuelle de l'objet. */ +static PyObject *py_constval_str(PyObject *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type du nouvel objet à mettre en place.               * +*                args = éventuelle liste d'arguments.                         * +*                kwds = éventuel dictionnaire de valeurs mises à disposition. * +*                                                                             * +*  Description : Interdit la création d'une instance depuis Python.           * +*                                                                             * +*  Retour      : NULL.                                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_constval_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ +    PyErr_Format(PyExc_RuntimeError, _("%s is meant to be only used from C code"), type->tp_name); + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = valeur constante C convertie en Python.               * +*                                                                             * +*  Description : Calcule l'emplacement reservé pour une désignation de valeur.* +*                                                                             * +*  Retour      : Pointeur vers l'adresse de désignation.                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static const char **py_constval_compute_name_ptr(PyConstvalObject *self) +{ +    digit *result;                          /* Adresse mémoire à retourner */ +    Py_ssize_t size;                        /* Taille supplémentaire       */ + +    size = Py_SIZE(&self->base); + +    if (size < 0) +        size = -size; + +    result = &self->base.ob_digit[size]; + +    return (const char **)result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = valeur constante C convertie en Python.               * +*                                                                             * +*  Description : Construit une représentation textuelle de l'objet.           * +*                                                                             * +*  Retour      : Chaîne de caractère Unicode.                                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_constval_str(PyObject *self) +{ +    PyObject *result;                       /* Elément à retourner         */ +    PyConstvalObject *constval;             /* Autre version de l'objet    */ +    const char **ptr;                       /* Désignation à convertir     */ + +    constval = (PyConstvalObject *)self; + +    ptr = py_constval_compute_name_ptr(constval); + +    result = PyUnicode_FromString(*ptr); + +    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_py_constval_type(void) +{ +    static PyMethodDef py_constval_methods[] = { +        { NULL } +    }; + +    static PyGetSetDef py_constval_getseters[] = { +        { NULL } +    }; + +    static PyTypeObject py_constval_type = { + +        PyVarObject_HEAD_INIT(NULL, 0) + +        .tp_name        = "pychrysalide.PyConstvalObject", +        .tp_basicsize   = offsetof(PyLongObject, ob_digit), +        .tp_itemsize    = sizeof(digit), + +        .tp_str         = py_constval_str, + +        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + +        .tp_doc         = "PyChrysalide object for C constant values", + +        .tp_methods     = py_constval_methods, +        .tp_getset      = py_constval_getseters, +        .tp_base        = &PyLong_Type, + +        .tp_new         = py_constval_new, + +    }; + +    return &py_constval_type; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Prend en charge l'objet 'pychrysalide.PyConstvalObject'.     * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool ensure_python_py_constval_is_registered(void) +{ +    PyTypeObject *type;                     /* Type Python 'PyConstval...' */ +    PyObject *module;                       /* Module à recompléter        */ + +    type = get_python_py_constval_type(); + +    if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) +    { +        module = get_access_to_python_module("pychrysalide"); + +        if (PyType_Ready(type) != 0) +            return false; + +        if (!register_python_module_object(module, type)) +            return false; + +    } + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : name  = désignation de la constante à représenter.           * +*                value = valeur de la constante à représenter.                * +*                                                                             * +*  Description : Construit un objet pour valeur constante en C.               * +*                                                                             * +*  Retour      : Object Python résultant de la construction opérée.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PyObject *build_constval_from_c_code(const char *name, unsigned long value) +{ +    PyObject *result;                       /* Instance à retourner        */ +    PyLongObject *tmp;                      /* Construction temporaire     */ +    Py_ssize_t size;                        /* Taille supplémentaire       */ +    PyTypeObject *type;                     /* Type Python 'PyConstval...' */ +    PyConstvalObject *constval;             /* Autre version de l'objet    */ +    const char **ptr;                       /* Désignation à convertir     */ + +    /* Création d'une base de travail */ + +    tmp = (PyLongObject *)PyLong_FromUnsignedLong(value); + +    size = Py_SIZE(tmp); + +    if (size < 0) +        size = -size; + +    /** +     * En allouant 2 éléments "digit" supplémentaires, on est assuré +     * de disposer de l'espace nécessaire pour la conservation +     * d'un pointeur. +     */ + +    result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + (size + 2) * sizeof(digit)); + +    if (!result) +    { +        PyErr_NoMemory(); +        return NULL; +    } + +    type = get_python_py_constval_type(); + +    result = PyObject_INIT_VAR(result, type, size); + +    /* Copie de la valeur */ + +    Py_SIZE(result) = Py_SIZE(tmp); + +    constval = (PyConstvalObject *)result; + +    while (--size >= 0) +        constval->base.ob_digit[size] = tmp->ob_digit[size]; + +    Py_DECREF(tmp); + +    /* Copie de la désignation */ + +    ptr = py_constval_compute_name_ptr(constval); + +    *ptr = name; + +    return result; + +} diff --git a/plugins/pychrysalide/constval.h b/plugins/pychrysalide/constval.h new file mode 100644 index 0000000..1099ee5 --- /dev/null +++ b/plugins/pychrysalide/constval.h @@ -0,0 +1,45 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constval.h - prototypes pour la conversion de constantes C en équivalent Python + * + * Copyright (C) 2018 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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_PYCHRYSALIDE_CONSTVAL_H +#define _PLUGINS_PYCHRYSALIDE_CONSTVAL_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_py_constval_type(void); + +/* Prend en charge l'objet 'pychrysalide.PyConstvalObject'. */ +bool ensure_python_py_constval_is_registered(void); + +/* Construit un objet pour valeur constante en C. */ +PyObject *build_constval_from_c_code(const char *, unsigned long); + + + +#endif  /* _PLUGINS_PYCHRYSALIDE_CONSTVAL_H */ diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c index be580a4..dae2aea 100644 --- a/plugins/pychrysalide/helpers.c +++ b/plugins/pychrysalide/helpers.c @@ -32,6 +32,7 @@  #include "access.h" +#include "constval.h" @@ -222,7 +223,7 @@ bool PyDict_AddIntConstant(PyTypeObject *obj_type, const char *key, long value)      PyObject *item;                         /* Nouvel élément à insérer    */      int ret;                                /* Bilan d'un ajout            */ -    item = PyLong_FromLong(value); +    item = build_constval_from_c_code(key, value);      ret = PyDict_SetItemString(obj_type->tp_dict, key, item);      result = (ret != -1); diff --git a/plugins/pychrysalide/pychrysa.c b/plugins/pychrysalide/pychrysa.c index 514442a..7772592 100644 --- a/plugins/pychrysalide/pychrysa.c +++ b/plugins/pychrysalide/pychrysa.c @@ -44,6 +44,7 @@  #include "access.h" +#include "constval.h"  #include "dt.h"  #include "helpers.h"  #include "plugin.h" @@ -386,6 +387,7 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)      if (status) status = add_mangling_module(result);      if (status) status = ensure_python_plugin_module_is_registered(); +    if (status) status = ensure_python_py_constval_is_registered();      if (status) status = ensure_python_py_struct_is_registered();      if (status) status = populate_analysis_module(); | 
