diff options
Diffstat (limited to 'plugins/pychrysalide/analysis')
| -rw-r--r-- | plugins/pychrysalide/analysis/scan/Makefile.am | 1 | ||||
| -rw-r--r-- | plugins/pychrysalide/analysis/scan/func.c | 213 | ||||
| -rw-r--r-- | plugins/pychrysalide/analysis/scan/func.h | 45 | ||||
| -rw-r--r-- | plugins/pychrysalide/analysis/scan/item.c | 136 | ||||
| -rw-r--r-- | plugins/pychrysalide/analysis/scan/module.c | 2 | ||||
| -rw-r--r-- | plugins/pychrysalide/analysis/scan/space.c | 114 | 
6 files changed, 186 insertions, 325 deletions
| diff --git a/plugins/pychrysalide/analysis/scan/Makefile.am b/plugins/pychrysalide/analysis/scan/Makefile.am index b07154a..565ce82 100644 --- a/plugins/pychrysalide/analysis/scan/Makefile.am +++ b/plugins/pychrysalide/analysis/scan/Makefile.am @@ -5,7 +5,6 @@ libpychrysaanalysisscan_la_SOURCES =		\  	constants.h constants.c					\  	context.h context.c						\  	expr.h expr.c							\ -	func.h func.c							\  	item.h item.c							\  	module.h module.c						\  	options.h options.c						\ diff --git a/plugins/pychrysalide/analysis/scan/func.c b/plugins/pychrysalide/analysis/scan/func.c deleted file mode 100644 index 0bff6e8..0000000 --- a/plugins/pychrysalide/analysis/scan/func.c +++ /dev/null @@ -1,213 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * func.c - équivalent Python du fichier "analysis/scan/func.c" - * - * Copyright (C) 2022 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 "func.h" - - -#include <pygobject.h> - - -#include <i18n.h> -#include <analysis/content.h> -#include <analysis/scan/func-int.h> -#include <plugins/pychrysalide/access.h> -#include <plugins/pychrysalide/helpers.h> -#include <plugins/pychrysalide/analysis/content.h> - - -#include "item.h" - - - -CREATE_DYN_ABSTRACT_CONSTRUCTOR(scan_function, G_TYPE_SCAN_FUNCTION, NULL); - -/* Initialise une instance sur la base du dérivé de GObject. */ -static int py_scan_function_init(PyObject *, PyObject *, PyObject *); - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : self = objet à initialiser (théoriquement).                  * -*                args = arguments fournis à l'appel.                          * -*                kwds = arguments de type key=val fournis.                    * -*                                                                             * -*  Description : Initialise une instance sur la base du dérivé de GObject.    * -*                                                                             * -*  Retour      : 0.                                                           * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static int py_scan_function_init(PyObject *self, PyObject *args, PyObject *kwds) -{ -    int ret;                                /* Bilan de lecture des args.  */ - -#define SCAN_FUNCTION_DOC                                               \ -    "A ScanFunction instance introduces a new method to analyze data"   \ -    " while scanning binary content.\n"                                 \ -    "\n"                                                                \ -    "Instances can be created using the following constructor:\n"       \ -    "\n"                                                                \ -    "    ScanFunction()" - -    /* Initialisation d'un objet GLib */ - -    ret = forward_pygobjet_init(self); -    if (ret == -1) return -1; - -    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_scan_function_type(void) -{ -    static PyMethodDef py_scan_function_methods[] = { -        { NULL } -    }; - -    static PyGetSetDef py_scan_function_getseters[] = { -        { NULL } -    }; - -    static PyTypeObject py_scan_function_type = { - -        PyVarObject_HEAD_INIT(NULL, 0) - -        .tp_name        = "pychrysalide.analysis.scan.ScanFunction", -        .tp_basicsize   = sizeof(PyGObject), - -        .tp_flags       = Py_TPFLAGS_DEFAULT, - -        .tp_doc         = SCAN_FUNCTION_DOC, - -        .tp_methods     = py_scan_function_methods, -        .tp_getset      = py_scan_function_getseters, - -        .tp_init        = py_scan_function_init, -        .tp_new         = py_scan_function_new, - -    }; - -    return &py_scan_function_type; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : -                                                            * -*                                                                             * -*  Description : Prend en charge l'objet 'pychrysalide....scan.ScanFunction'. * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool ensure_python_scan_function_is_registered(void) -{ -    PyTypeObject *type;                     /* Type Python 'ScanFunction'  */ -    PyObject *module;                       /* Module à recompléter        */ -    PyObject *dict;                         /* Dictionnaire du module      */ - -    type = get_python_scan_function_type(); - -    if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) -    { -        module = get_access_to_python_module("pychrysalide.analysis.scan"); - -        dict = PyModule_GetDict(module); - -        if (!ensure_python_registered_item_is_registered()) -            return false; - -        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_FUNCTION, type)) -            return false; - -    } - -    return true; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : arg = argument quelconque à tenter de convertir.             * -*                dst = destination des valeurs récupérées en cas de succès.   * -*                                                                             * -*  Description : Tente de convertir en fonction d'analyse pour scan.          * -*                                                                             * -*  Retour      : Bilan de l'opération, voire indications supplémentaires.     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -int convert_to_scan_function(PyObject *arg, void *dst) -{ -    int result;                             /* Bilan à retourner           */ - -    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_function_type()); - -    switch (result) -    { -        case -1: -            /* L'exception est déjà fixée par Python */ -            result = 0; -            break; - -        case 0: -            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to scan function"); -            break; - -        case 1: -            *((GScanFunction **)dst) = G_SCAN_FUNCTION(pygobject_get(arg)); -            break; - -        default: -            assert(false); -            break; - -    } - -    return result; - -} diff --git a/plugins/pychrysalide/analysis/scan/func.h b/plugins/pychrysalide/analysis/scan/func.h deleted file mode 100644 index d5d59f0..0000000 --- a/plugins/pychrysalide/analysis/scan/func.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * func.h - prototypes pour l'équivalent Python du fichier "analysis/scan/func.h" - * - * Copyright (C) 2022 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_ANALYSIS_SCAN_FUNC_H -#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_FUNC_H - - -#include <Python.h> -#include <stdbool.h> - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_scan_function_type(void); - -/* Prend en charge l'objet 'pychrysalide.analysis.scan.ScanFunction'. */ -bool ensure_python_scan_function_is_registered(void); - -/* Tente de convertir en fonction d'analyse pour scan. */ -int convert_to_scan_function(PyObject *, void *); - - - -#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_FUNC_H */ diff --git a/plugins/pychrysalide/analysis/scan/item.c b/plugins/pychrysalide/analysis/scan/item.c index aae5b73..2379632 100644 --- a/plugins/pychrysalide/analysis/scan/item.c +++ b/plugins/pychrysalide/analysis/scan/item.c @@ -34,12 +34,18 @@  #include <plugins/pychrysalide/helpers.h> +#include "context.h" + +  CREATE_DYN_CONSTRUCTOR(registered_item, G_TYPE_REGISTERED_ITEM);  /* Initialise une instance sur la base du dérivé de GObject. */  static int py_registered_item_init(PyObject *, PyObject *, PyObject *); +/* Lance une résolution d'élément à appeler. */ +static PyObject *py_registered_item_resolve(PyObject *, PyObject *); +  /****************************************************************************** @@ -80,6 +86,134 @@ static int py_registered_item_init(PyObject *self, PyObject *args, PyObject *kwd  /******************************************************************************  *                                                                             * +*  Paramètres  : self = élément d'appel à consulter.                          * +*                args = arguments fournis pour l'opération.                   * +*                                                                             * +*  Description : Lance une résolution d'élément à appeler.                    * +*                                                                             * +*  Retour      : Nouvel élément d'appel identifié ou None.                    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_registered_item_resolve(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Bilan à retourner           */ +    const char *target;                     /* Désignation de la cible     */ +    GScanContext *ctx;                      /* Contexte d'analyse          */ +    GScanScope *scope;                      /* Portée de variables locales */ +    int ret;                                /* Bilan de lecture des args.  */ +    GRegisteredItem *item;                  /* Version native              */ +    bool status;                            /* Bilan d'exécution           */ +    GRegisteredItem *resolved;              /* Elément trouvé              */ + +#define REGISTERED_ITEM_RESOLVE_METHOD PYTHON_METHOD_DEF                \ +(                                                                       \ +    resolve, "$self, target, /, ctx=None, scope=None)", \ +    METH_VARARGS, py_registered_item,                                   \ +    "Resolve a name into a scan item."                                  \ +    "\n"                                                                \ +    "The *target* name is the only mandatory parameter and has to point"\ +    " to only one item. The *ctx* argument points to an optional useful"\ +    " storage for resolution lookup, as a"                              \ +    " pychrysalide.analysis.scan.ScanContext instance. The *args* list" \ +    " defines an optional list of arguments, as"                        \ +    " pychrysalide.analysis.scan.ScanExpression instances, to use for"  \ +    " building the resolved item. The *final* flag states if the"       \ +    " scanning process is about to conclude or not."                    \ +    "\n"                                                                \ +    "The result is an object inheriting from"                           \ +    " pychrysalide.analysis.scan.RegisteredItem or *None* if the"       \ +    " resolution operation failed."                                     \ +) + +    ctx = NULL; +    scope = NULL; + +    ret = PyArg_ParseTuple(args, "s|O&", &target, +                           convert_to_scan_context, &ctx); +    if (!ret) return NULL; + +    item = G_REGISTERED_ITEM(pygobject_get(self)); + +    status = g_registered_item_resolve(item, target, ctx, scope, &resolved); + +    if (!status) +    { +        result = NULL; +        PyErr_Format(PyExc_RuntimeError, _("Unable to resolve any target from the item")); +    } +    else +    { +        if (resolved != NULL) +        { +            result = pygobject_new(G_OBJECT(resolved)); +            g_object_unref(G_OBJECT(resolved)); +        } +        else +        { +            result = Py_None; +            Py_INCREF(result); +        } +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self    = classe représentant un composant nommé à manipuler.* +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Fournit le désignation associée à un composant nommé.        * +*                                                                             * +*  Retour      : Description courante.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_registered_item_get_name(PyObject *self, void *closure) +{ +    PyObject *result;                       /* Décompte à retourner        */ +    GRegisteredItem *item;                  /* Version native              */ +    char *name;                             /* Désignation à convertir     */ + +#define REGISTERED_ITEM_NAME_ATTRIB PYTHON_GET_DEF_FULL                 \ +(                                                                       \ +    name, py_registered_item,                                           \ +    "Name linked to the registered item.\n"                             \ +    "\n"                                                                \ +    "The result should be a string, or *None* for the root namespace."  \ +) + +    item = G_REGISTERED_ITEM(pygobject_get(self)); + +    name = g_registered_item_get_name(item); + +    if (name == NULL) +    { +        result = Py_None; +        Py_INCREF(result); +    } +    else +    { +        result = PyUnicode_FromString(name); +        free(name); +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : -                                                            *  *                                                                             *  *  Description : Fournit un accès à une définition de type à diffuser.        * @@ -93,10 +227,12 @@ static int py_registered_item_init(PyObject *self, PyObject *args, PyObject *kwd  PyTypeObject *get_python_registered_item_type(void)  {      static PyMethodDef py_registered_item_methods[] = { +        REGISTERED_ITEM_RESOLVE_METHOD,          { NULL }      };      static PyGetSetDef py_registered_item_getseters[] = { +        REGISTERED_ITEM_NAME_ATTRIB,          { NULL }      }; diff --git a/plugins/pychrysalide/analysis/scan/module.c b/plugins/pychrysalide/analysis/scan/module.c index 3af4af2..d56e44a 100644 --- a/plugins/pychrysalide/analysis/scan/module.c +++ b/plugins/pychrysalide/analysis/scan/module.c @@ -30,7 +30,6 @@  #include "context.h"  #include "expr.h" -#include "func.h"  #include "item.h"  #include "options.h"  #include "scanner.h" @@ -107,7 +106,6 @@ bool populate_analysis_scan_module(void)      if (result) result = ensure_python_content_scanner_is_registered();      if (result) result = ensure_python_scan_context_is_registered();      if (result) result = ensure_python_scan_expression_is_registered(); -    if (result) result = ensure_python_scan_function_is_registered();      if (result) result = ensure_python_registered_item_is_registered();      if (result) result = ensure_python_scan_options_is_registered();      if (result) result = ensure_python_scan_namespace_is_registered(); diff --git a/plugins/pychrysalide/analysis/scan/space.c b/plugins/pychrysalide/analysis/scan/space.c index 7d85fca..79e0c28 100644 --- a/plugins/pychrysalide/analysis/scan/space.c +++ b/plugins/pychrysalide/analysis/scan/space.c @@ -30,20 +30,24 @@  #include <i18n.h>  #include <analysis/content.h> +#include <analysis/scan/item.h>  #include <analysis/scan/space-int.h>  #include <plugins/pychrysalide/access.h>  #include <plugins/pychrysalide/helpers.h>  #include <plugins/pychrysalide/analysis/content.h> +#include "item.h" + +  CREATE_DYN_CONSTRUCTOR(scan_namespace, G_TYPE_SCAN_NAMESPACE);  /* Initialise une instance sur la base du dérivé de GObject. */  static int py_scan_namespace_init(PyObject *, PyObject *, PyObject *); -/* Indique le nom attribué à un espace de noms. */ -static PyObject *py_scan_namespace_get_name(PyObject *, void *); +/* Intègre un nouvel élément dans l'esapce de noms. */ +static PyObject *py_scan_namespace_register_item(PyObject *, PyObject *); @@ -63,7 +67,9 @@ static PyObject *py_scan_namespace_get_name(PyObject *, void *);  static int py_scan_namespace_init(PyObject *self, PyObject *args, PyObject *kwds)  { +    const char *name;                       /* Désignation de l'espace     */      int ret;                                /* Bilan de lecture des args.  */ +    GScanNamespace *space;                  /* Création GLib à transmettre */  #define SCAN_NAMESPACE_DOC                                              \      "ScanNamespace defines a group of properties and functions for a"   \ @@ -71,101 +77,82 @@ static int py_scan_namespace_init(PyObject *self, PyObject *args, PyObject *kwds      "\n"                                                                \      "Instances can be created using the following constructor:\n"       \      "\n"                                                                \ -    "    ScanNamespace()" +    "    ScanNamespace(name)"                                           \ +    "\n"                                                                \ +    "Where *name* is a string providing the name of the new namespace." + +    /* Récupération des paramètres */ + +    ret = PyArg_ParseTuple(args, "s", &name); +    if (!ret) return -1;      /* Initialisation d'un objet GLib */      ret = forward_pygobjet_init(self);      if (ret == -1) return -1; +    /* Elément de base */ + +    space = G_SCAN_NAMESPACE(pygobject_get(self)); + +    if (!g_scan_namespace_create(space, name)) +    { +        PyErr_SetString(PyExc_ValueError, _("Unable to create scan namespace.")); +        return -1; +    } +      return 0;  } -#if 0 +  /******************************************************************************  *                                                                             *  *  Paramètres  : self = objet représentant une table de chaînes.              *  *                args = arguments fournis pour l'opération.                   *  *                                                                             * -*  Description : Remplace les propriétés renvoyant à des ressources.          * +*  Description : Intègre un nouvel élément dans l'esapce de noms.             *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static PyObject *py_scan_namespace_resolve(PyObject *self, PyObject *args) +static PyObject *py_scan_namespace_register_item(PyObject *self, PyObject *args)  {      PyObject *result;                       /* Bilan à retourner           */ -    GResourceTable *table;                  /* Table de ressources         */ +    GRegisteredItem *item;                  /* Elément d'évaluation à lier */      int ret;                                /* Bilan de lecture des args.  */ -    GScanNamespace *format;                    /* Version native              */ - -#define SCAN_NAMESPACE_RESOLVE_METHOD PYTHON_METHOD_DEF    \ -(                                                       \ -    resolve, "$self, table, /",                         \ -    METH_VARARGS, py_scan_namespace,                       \ -    "Resolve all XML node attribute values pointing to" \ -    " resource entries. Such values are identifiers"    \ -    " of the forme '@0x...'.\n"                         \ -    "\n"                                                \ -    "The *table* argument has to be a loaded"           \ -     " pychrysalide.format.androidfw.ResourceTable"     \ -    " instance.\n"                                      \ +    GScanNamespace *space;                  /* Version native              */ +    bool status;                            /* Bilan de l'opération        */ + +#define SCAN_NAMESPACE_REGISTER_ITEM_METHOD PYTHON_METHOD_DEF                   \ +(                                                                               \ +    register_item, "$self, item, /",                                            \ +    METH_VARARGS, py_scan_namespace,                                            \ +    "Include an item into a namespace.\n"                                       \ +    "\n"                                                                        \ +    "The *item* argument has to be a pychrysalide.analysis.scan.RegisteredItem" \ +    " instance.\n"                                                              \ +    "\n"                                                                        \ +    "The function returns a boolean value translating the operation status:"    \ +    " *True* in case of success, *False* for a failure.\n"                      \  ) -    ret = PyArg_ParseTuple(args, "O&", convert_to_resource_table, &table); +    ret = PyArg_ParseTuple(args, "O&", convert_to_registered_item, &item);      if (!ret) return NULL; -    format = G_SCAN_NAMESPACE(pygobject_get(self)); - -    g_scan_namespace_resvolve(format, table); - -    result = Py_None; -    Py_INCREF(result); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : self    = classe représentant un format Axml.                * -*                closure = adresse non utilisée ici.                          * -*                                                                             * -*  Description : Indique le nom attribué à un espace de noms.                 * -*                                                                             * -*  Retour      : Désignation associée.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static PyObject *py_scan_namespace_get_name(PyObject *self, void *closure) -{ -    PyObject *result;                       /* Liste éventuelle à renvoyer */ -    GScanNamespace *space;                  /* Version native              */ -    const char *name;                       /* Désignation à exporter      */ - -#define SCAN_NAMESPACE_NAME_ATTRIB PYTHON_GET_DEF_FULL  \ -(                                                       \ -    name, py_scan_namespace,                            \ -    "Name provided for the namespace."                  \ -) -      space = G_SCAN_NAMESPACE(pygobject_get(self)); -    name = g_scan_namespace_get_name(space); +    status = g_scan_namespace_register_item(space, item); -    result = PyUnicode_FromString(name); +    result = status ? Py_True : Py_False; +    Py_INCREF(result);      return result;  } -#endif  /****************************************************************************** @@ -183,12 +170,11 @@ static PyObject *py_scan_namespace_get_name(PyObject *self, void *closure)  PyTypeObject *get_python_scan_namespace_type(void)  {      static PyMethodDef py_scan_namespace_methods[] = { -        //SCAN_NAMESPACE_RESOLVE_METHOD, +        SCAN_NAMESPACE_REGISTER_ITEM_METHOD,          { NULL }      };      static PyGetSetDef py_scan_namespace_getseters[] = { -        //SCAN_NAMESPACE_NAME_ATTRIB,          { NULL }      }; | 
