diff options
Diffstat (limited to 'plugins')
-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 | ||||
-rw-r--r-- | plugins/pychrysalide/core/global.c | 47 |
7 files changed, 233 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 } }; diff --git a/plugins/pychrysalide/core/global.c b/plugins/pychrysalide/core/global.c index ecaf2c6..9632e75 100644 --- a/plugins/pychrysalide/core/global.c +++ b/plugins/pychrysalide/core/global.c @@ -187,6 +187,52 @@ static PyObject *py_global_get_content_resolver(PyObject *self, PyObject *args) * Paramètres : self = objet Python concerné par l'appel. * * args = non utilisé ici. * * * +* Description : Fournit l'adresse de l'espace de noms principal pour ROST. * +* * +* Retour : Espace de noms racine de ROST ou NULL si aucun (!). * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_global_get_rost_root_namespace(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance Python à retourner */ + GScanNamespace *root_ns; /* Espace de noms ROST racine */ + +#define GLOBAL_GET_ROST_ROOT_NAMESPACE_METHOD PYTHON_METHOD_DEF \ +( \ + get_rost_root_namespace, "", \ + METH_NOARGS, py_global, \ + "Get the root namespace for ROST." \ + "\n" \ + "The returned object is a pychrysalide.analysis.scan.ScanNamespace" \ + " instance used as singleton; it should not be *None*." \ +) + + root_ns = get_rost_root_namespace(); + + if (root_ns != NULL) + { + result = pygobject_new(G_OBJECT(root_ns)); + g_object_unref(G_OBJECT(root_ns)); + } + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* args = non utilisé ici. * +* * * Description : Fournit l'adresse du projet courant. * * * * Retour : Adresse du résolveur global ou None si aucun. * @@ -289,6 +335,7 @@ bool populate_core_module_with_global(void) GLOBAL_IS_BATCH_MODE_METHOD, GLOBAL_GET_CONTENT_EXPLORER_METHOD, GLOBAL_GET_CONTENT_RESOLVER_METHOD, + GLOBAL_GET_ROST_ROOT_NAMESPACE_METHOD, GLOBAL_GET_CURRENT_PROJECT_METHOD, GLOBAL_SET_CURRENT_PROJECT_METHOD, { NULL } |