summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2023-07-07 06:32:43 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2023-07-07 06:32:43 (GMT)
commit4c10dfa2a95cea6fc704d68066d0c284cfd79342 (patch)
tree5827bbc411459800747e21929daecdf99fde7dfd /plugins/pychrysalide/analysis
parent3f996be1e5858b54740bf92515795982a16b169a (diff)
Rewrite core parts of the ROST API.
Diffstat (limited to 'plugins/pychrysalide/analysis')
-rw-r--r--plugins/pychrysalide/analysis/scan/Makefile.am1
-rw-r--r--plugins/pychrysalide/analysis/scan/func.c213
-rw-r--r--plugins/pychrysalide/analysis/scan/func.h45
-rw-r--r--plugins/pychrysalide/analysis/scan/item.c136
-rw-r--r--plugins/pychrysalide/analysis/scan/module.c2
-rw-r--r--plugins/pychrysalide/analysis/scan/space.c114
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 }
};