summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-01-13 22:37:31 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-01-13 22:37:31 (GMT)
commit23b9c6e68bbe5f0531f9a9408c2deb9f897701dc (patch)
tree3804d6c21c9cd5e291cb8c7853607cdda992d125 /plugins
parenta6975c1d754a1ba5bfb9e23f0b26692c746e6f9c (diff)
Created a real iterator for symbols.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/pychrysa/format/Makefile.am3
-rw-r--r--plugins/pychrysa/format/format.c228
-rw-r--r--plugins/pychrysa/format/module.c3
-rw-r--r--plugins/pychrysa/format/symiter.c276
-rw-r--r--plugins/pychrysa/format/symiter.h42
5 files changed, 329 insertions, 223 deletions
diff --git a/plugins/pychrysa/format/Makefile.am b/plugins/pychrysa/format/Makefile.am
index e59cf8a..325206c 100644
--- a/plugins/pychrysa/format/Makefile.am
+++ b/plugins/pychrysa/format/Makefile.am
@@ -5,7 +5,8 @@ libpychrysaformat_la_SOURCES = \
executable.h executable.c \
format.h format.c \
module.h module.c \
- symbol.h symbol.c
+ symbol.h symbol.c \
+ symiter.h symiter.c
libpychrysaformat_la_LIBADD =
diff --git a/plugins/pychrysa/format/format.c b/plugins/pychrysa/format/format.c
index aed9664..5920b27 100644
--- a/plugins/pychrysa/format/format.c
+++ b/plugins/pychrysa/format/format.c
@@ -31,36 +31,12 @@
#include <format/format.h>
+#include "symiter.h"
#include "../helpers.h"
#include "../arch/vmpa.h"
-/* ------------------------ PARCOURS DE SYMBOLES DE BINAIRES ------------------------ */
-
-
-/* Parcours des symboles présents dans un binaire */
-typedef struct _pyBinSymbolIterator
-{
- PyObject_HEAD /* A laisser en premier */
-
- GBinFormat *format; /* Format binaire à consulter */
- size_t next; /* Symbole binaire à présenter */
-
-} pyBinSymbolIterator;
-
-
-/* Prend acte d'un compteur de référence à 0. */
-static void py_binary_symbol_iterator_dealloc(PyObject *);
-
-/* Fournit un itérateur pour symboles de format binaire. */
-static PyObject *py_binary_symbol_iterator_next(PyObject *);
-
-/* Initialise un objet Python de type 'BinSymbolIterator'. */
-static int py_binary_symbol_iterator_init(PyObject *, PyObject *, PyObject *);
-
-
-
/* ---------------------------- FORMAT BINAIRE GENERIQUE ---------------------------- */
@@ -104,195 +80,6 @@ static bool define_python_binary_format_constants(PyTypeObject *);
/* ---------------------------------------------------------------------------------- */
-/* PARCOURS DE SYMBOLES DE BINAIRES */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* 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_binary_symbol_iterator_dealloc(PyObject *self)
-{
- pyBinSymbolIterator *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 = (pyBinSymbolIterator *)self;
-
- g_object_unref(G_OBJECT(iterator->format));
-
- Py_TYPE(self)->tp_free((PyObject *)self);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = itérateur à manipuler. *
-* *
-* Description : Fournit un itérateur pour symboles de format binaire. *
-* *
-* Retour : Instance Python prête à emploi. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_binary_symbol_iterator_next(PyObject *self)
-{
- PyObject *result; /* Instance à retourner */
- pyBinSymbolIterator *iterator; /* Références pour le parcours */
- size_t count; /* Nombre de symboles présents */
- GBinSymbol **symbols; /* Liste de ces mêmes symboles */
-
- iterator = (pyBinSymbolIterator *)self;
-
- symbols = g_binary_format_get_symbols(iterator->format, &count);
-
- if (iterator->next < count)
- {
- result = pygobject_new(G_OBJECT(symbols[iterator->next]));
- iterator->next++;
- }
- 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 'BinSymbolIterator'. *
-* *
-* Retour : Instance Python mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static int py_binary_symbol_iterator_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
- pyBinSymbolIterator *iterator; /* Références pour le parcours */
- PyObject *format; /* Format binaire en Python */
- int ret; /* Bilan de lecture des args. */
-
- ret = PyArg_ParseTuple(args, "O", &format);
- if (!ret) return -1;
-
- ret = PyObject_IsInstance(format, (PyObject *)get_python_binary_format_type());
- if (!ret) return -1;
-
- iterator = (pyBinSymbolIterator *)self;
-
- iterator->format = G_BIN_FORMAT(pygobject_get(format));
- g_object_ref(G_OBJECT(iterator->format));
-
- iterator->next = 0;
-
- 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_binary_symbol_iterator_type(void)
-{
- static PyTypeObject py_binary_symbol_iterator_type = {
-
- PyVarObject_HEAD_INIT(NULL, 0)
-
- .tp_name = "pychrysalide.format.BinSymbolIterator",
- .tp_basicsize = sizeof(pyBinSymbolIterator),
-
- .tp_dealloc = py_binary_symbol_iterator_dealloc,
-
- .tp_flags = Py_TPFLAGS_DEFAULT,
-
- .tp_doc = "Iterator for binary symbols",
-
- .tp_iter = PyObject_SelfIter,
- .tp_iternext = py_binary_symbol_iterator_next,
-
- .tp_init = py_binary_symbol_iterator_init,
-
- .tp_new = PyType_GenericNew,
-
- };
-
- return &py_binary_symbol_iterator_type;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : module = module dont la définition est à compléter. *
-* *
-* Description : Prend en charge l'objet 'pychrysalide...BinSymbolIterator'. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool register_python_binary_symbol_iterator(PyObject *module)
-{
- PyTypeObject *py_binary_symbol_iterator_type; /* Type Python 'BinSymbolIterator' */
- int ret; /* Bilan d'un appel */
-
- py_binary_symbol_iterator_type = get_python_binary_symbol_iterator_type();
-
- py_binary_symbol_iterator_type->tp_base = &PyBaseObject_Type;
-
- if (PyType_Ready(py_binary_symbol_iterator_type) != 0)
- return false;
-
- Py_INCREF(py_binary_symbol_iterator_type);
- ret = PyModule_AddObject(module, "BinSymbolIterator", (PyObject *)py_binary_symbol_iterator_type);
- if (ret != 0) return false;
-
- return true;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
/* FORMAT BINAIRE GENERIQUE */
/* ---------------------------------------------------------------------------------- */
@@ -539,18 +326,17 @@ static PyObject *py_binary_format_get_content(PyObject *self, void *closure)
static PyObject *py_binary_format_get_symbols(PyObject *self, void *closure)
{
- PyObject *result; /* Instance à retourner */
+ PyObject *result; /* Instance Python à retourner */
PyTypeObject *iterator_type; /* Type Python de l'itérateur */
- PyObject *args_list; /* Arguments de mise en place */
+ PyObject *args; /* Liste des arguments d'appel */
- iterator_type = get_python_binary_symbol_iterator_type();
+ iterator_type = get_python_sym_iterator_type();
- Py_INCREF(self);
+ args = Py_BuildValue("On", self, 0);
- args_list = Py_BuildValue("(O)", self);
- result = PyObject_CallObject((PyObject *)iterator_type, args_list);
+ result = PyObject_CallObject((PyObject *)iterator_type, args);
- Py_DECREF(args_list);
+ Py_DECREF(args);
return result;
diff --git a/plugins/pychrysa/format/module.c b/plugins/pychrysa/format/module.c
index 642b1dc..1daeb3f 100644
--- a/plugins/pychrysa/format/module.c
+++ b/plugins/pychrysa/format/module.c
@@ -31,6 +31,7 @@
#include "executable.h"
#include "format.h"
#include "symbol.h"
+#include "symiter.h"
#include "../access.h"
@@ -81,10 +82,10 @@ bool add_format_module_to_python_module(PyObject *super)
result = true;
- result &= register_python_binary_symbol_iterator(module);
result &= register_python_binary_format(module);
result &= register_python_executable_format(module);
result &= register_python_binary_symbol(module);
+ result &= register_python_sym_iterator(module);
if (result)
register_access_to_python_module("pychrysalide.format", module);
diff --git a/plugins/pychrysa/format/symiter.c b/plugins/pychrysa/format/symiter.c
new file mode 100644
index 0000000..db0b744
--- /dev/null
+++ b/plugins/pychrysa/format/symiter.c
@@ -0,0 +1,276 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * symiter.c - équivalent Python du fichier "format/symiter.c"
+ *
+ * Copyright (C) 2017 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 "symiter.h"
+
+
+#include <pygobject.h>
+
+
+#include <format/symiter.h>
+
+
+#include "format.h"
+
+
+
+/* Transcription d'un itérateur en Python */
+typedef struct _PySymIterator
+{
+ PyObject_HEAD; /* A laisser en premier */
+
+ sym_iter_t *native; /* Version native de l'objet */
+ bool first_time; /* Premier élément retourné ? */
+
+} PySymIterator;
+
+
+/* Libère de la mémoire un itérateur sur des symboles. */
+static void py_sym_iterator_dealloc(PySymIterator *);
+
+/* Fournit le symbole qui en suit un autr. */
+static PyObject *py_sym_iterator_next(PySymIterator *);
+
+/* Initialise un nouvel itérateur. */
+static int py_sym_iterator_init(PySymIterator *, PyObject *, PyObject *);
+
+/* Construit un nouvel itérateur. */
+static PyObject *py_sym_iterator_new(PyTypeObject *, PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = itérateur à supprimer. *
+* *
+* Description : Libère de la mémoire un itérateur sur des symboles. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_sym_iterator_dealloc(PySymIterator *self)
+{
+ delete_symbol_iterator(self->native);
+
+ Py_TYPE(self)->tp_free((PyObject *)self);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = itérateur à manipuler. *
+* *
+* Description : Fournit le symbole qui en suit un autre. *
+* *
+* Retour : Symbole suivant trouvé, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_sym_iterator_next(PySymIterator *self)
+{
+ PyObject *result; /* Résultat à retourner */
+ GBinSymbol *next; /* Symbole suivant */
+
+ if (self->first_time)
+ {
+ next = get_symbol_iterator_current(self->native);
+ self->first_time = false;
+ }
+
+ else
+ next = get_symbol_iterator_next(self->native);
+
+ if (next != NULL)
+ {
+ result = pygobject_new(G_OBJECT(next));
+ g_object_unref(G_OBJECT(next));
+ }
+
+ else
+ {
+ PyErr_SetNone(PyExc_StopIteration);
+ result = NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = instance d'objet à initialiser. *
+* args = arguments passés pour l'appel. *
+* kwds = mots clefs éventuellement fournis en complément. *
+* *
+* Description : Initialise un nouvel itérateur. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_sym_iterator_init(PySymIterator *self, PyObject *args, PyObject *kwds)
+{
+ int result; /* Bilan à retourner */
+ PyObject *fmt_obj; /* Format version Python */
+ unsigned long index; /* Indice de premier symbole */
+ int ret; /* Bilan de lecture des args. */
+ GBinFormat *format; /* Version native du format */
+
+ result = -1;
+
+ ret = PyArg_ParseTuple(args, "Ok", &fmt_obj, &index);
+ if (ret == 0) goto psii_exit;
+
+ ret = PyObject_IsInstance(fmt_obj, (PyObject *)get_python_binary_format_type());
+ if (!ret) goto psii_exit;
+
+ format = G_BIN_FORMAT(pygobject_get(fmt_obj));
+
+ self->native = create_symbol_iterator(format, index);
+ self->first_time = true;
+
+ result = 0;
+
+ psii_exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'objet à mettre en place. *
+* args = arguments passés pour l'appel. *
+* kwds = mots clefs éventuellement fournis en complément. *
+* *
+* Description : Construit un nouvel itérateur. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_sym_iterator_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PySymIterator *result; /* Nouvelle instance à renvoyer*/
+ int ret; /* Bilan de l'initialisation */
+
+ result = (PySymIterator *)type->tp_alloc(type, 0);
+
+ if (result != NULL)
+ {
+ ret = py_sym_iterator_init(result, args, kwds);
+
+ if (ret != 0)
+ {
+ Py_DECREF(result);
+ result = NULL;
+ }
+
+ }
+
+ return (PyObject *)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_sym_iterator_type(void)
+{
+ static PyTypeObject py_sym_iterator_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.format.SymIterator",
+ .tp_basicsize = sizeof(PySymIterator),
+
+ .tp_dealloc = (destructor)py_sym_iterator_dealloc,
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "Iterator for Chrysalide symbols registered in a given format.",
+
+ .tp_iter = PyObject_SelfIter,
+ .tp_iternext = (iternextfunc)py_sym_iterator_next,
+
+ .tp_init = (initproc)py_sym_iterator_init,
+ .tp_new = py_sym_iterator_new,
+
+ };
+
+ return &py_sym_iterator_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.format.SymIterator'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_sym_iterator(PyObject *module)
+{
+ PyTypeObject *py_sym_iterator_type; /* Type Python 'BinContent' */
+ int ret; /* Bilan d'un appel */
+
+ py_sym_iterator_type = get_python_sym_iterator_type();
+
+ if (PyType_Ready(py_sym_iterator_type) < 0)
+ return false;
+
+ Py_INCREF(py_sym_iterator_type);
+ ret = PyModule_AddObject(module, "SymIterator", (PyObject *)py_sym_iterator_type);
+
+ return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/format/symiter.h b/plugins/pychrysa/format/symiter.h
new file mode 100644
index 0000000..6cc1d29
--- /dev/null
+++ b/plugins/pychrysa/format/symiter.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * symiter.h - prototypes pour l'équivalent Python du fichier "format/symiter.h"
+ *
+ * Copyright (C) 2017 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_FORMAT_SYMITER_H
+#define _PLUGINS_PYCHRYSALIDE_FORMAT_SYMITER_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_sym_iterator_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.format.SymIterator'. */
+bool register_python_sym_iterator(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_FORMAT_SYMITER_H */