summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-03-26 10:53:53 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-03-26 10:53:53 (GMT)
commit4319c0ae542b60f225d0f6ce373fe8d2e5f1475d (patch)
tree2fb50b16c5a3d0120ffba1ab6270dcd603797e94
parenta2f149e5d151dcd937351f6e54229e508123c3ad (diff)
Extended the Python bindings to immediate operands.
-rw-r--r--ChangeLog24
-rw-r--r--plugins/pychrysa/arch/Makefile.am8
-rw-r--r--plugins/pychrysa/arch/immediate.c621
-rw-r--r--plugins/pychrysa/arch/immediate.h (renamed from plugins/pychrysa/arch/archbase.h)30
-rw-r--r--plugins/pychrysa/arch/module.c63
-rw-r--r--plugins/pychrysa/arch/operand.c (renamed from plugins/pychrysa/arch/archbase.c)86
-rw-r--r--plugins/pychrysa/arch/operand.h42
-rw-r--r--plugins/pychrysa/debug/gdbrsp/gdb.c1
8 files changed, 799 insertions, 76 deletions
diff --git a/ChangeLog b/ChangeLog
index af5e121..841c7e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+17-03-26 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/pychrysa/arch/Makefile.am:
+ Add the 'immediate.[ch]' and 'operand.[ch]' files to
+ libpychrysaarch_la_SOURCES.
+
+ * plugins/pychrysa/arch/archbase.c:
+ * plugins/pychrysa/arch/archbase.h:
+ Deleted entries.
+
+ * plugins/pychrysa/arch/immediate.c:
+ * plugins/pychrysa/arch/immediate.h:
+ New entries: extend the Python bindings to immediate operands.
+
+ * plugins/pychrysa/arch/module.c:
+ Update code.
+
+ * plugins/pychrysa/arch/operand.c:
+ * plugins/pychrysa/arch/operand.h:
+ New entries: extend the Python bindings to architecture operands.
+
+ * plugins/pychrysa/debug/gdbrsp/gdb.c:
+ Typo.
+
17-03-24 Cyrille Bagard <nocbos@gmail.com>
* src/analysis/routine.c:
diff --git a/plugins/pychrysa/arch/Makefile.am b/plugins/pychrysa/arch/Makefile.am
index 5d631bb..21e3856 100644
--- a/plugins/pychrysa/arch/Makefile.am
+++ b/plugins/pychrysa/arch/Makefile.am
@@ -2,21 +2,17 @@
noinst_LTLIBRARIES = libpychrysaarch.la
libpychrysaarch_la_SOURCES = \
+ immediate.h immediate.c \
instriter.h instriter.c \
instruction.h instruction.c \
module.h module.c \
+ operand.h operand.c \
processor.h processor.c \
vmpa.h vmpa.c
libpychrysaarch_la_LIBADD = \
arm/libpychrysaarcharm.la
-# libpychrysaarch_la_SOURCES = \
-# archbase.h archbase.c \
-# instruction.h instruction.c \
-# module.h module.c \
-# processor.h processor.c
-
libpychrysaarch_la_LDFLAGS =
diff --git a/plugins/pychrysa/arch/immediate.c b/plugins/pychrysa/arch/immediate.c
new file mode 100644
index 0000000..e600a9a
--- /dev/null
+++ b/plugins/pychrysa/arch/immediate.c
@@ -0,0 +1,621 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * immediate.c - équivalent Python du fichier "arch/immediate.h"
+ *
+ * Copyright (C) 2012-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 "immediate.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+
+
+#include <arch/immediate.h>
+
+
+#include "operand.h"
+#include "../helpers.h"
+
+
+
+/* Fournit la valeur portée par une opérande numérique. */
+static PyObject *py_imm_operand_get_value(PyObject *, void *);
+
+/* Indique si l'affichage est complété avec des zéros. */
+static PyObject *py_imm_operand_get_padding(PyObject *self, void *);
+
+/* Précise si des zéro doivent compléter l'affichage ou non. */
+static int py_imm_operand_set_padding(PyObject *, PyObject *, void *);
+
+/* Indique le format textuel par défaut de la valeur. */
+static PyObject *py_imm_operand_get_default_display(PyObject *, void *);
+
+/* Définit le format textuel par défaut de la valeur. */
+static int py_imm_operand_set_default_display(PyObject *, PyObject *, void *);
+
+/* Indique la grande ligne du format textuel de la valeur. */
+static PyObject *py_imm_operand_get_display(PyObject *, void *);
+
+/* Définit la grande ligne du format textuel de la valeur. */
+static int py_imm_operand_set_display(PyObject *, PyObject *, void *);
+
+/* Construit la chaîne de caractères correspondant à l'opérande. */
+static PyObject *py_imm_operand_to_string(PyObject *, PyObject *);
+
+/* Crée un nouvel objet Python de type 'ImmOperand'. */
+static PyObject *py_imm_operand_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Définit les constantes pour les opérandes d'immédiats. */
+static bool py_imm_operand_define_constants(PyTypeObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Renseigne la taille de la valeur indiquée à la construction. *
+* *
+* Retour : Taille de la valeur représentée en mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_imm_operand_get_size(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+ MemoryDataSize size; /* Type de donnée représentée */
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ size = g_imm_operand_get_size(operand);
+
+ result = Py_BuildValue("I", size);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la valeur portée par une opérande numérique. *
+* *
+* Retour : Valeur contenue dans l'opérande, ou None en cas de soucis. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_imm_operand_get_value(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+ MemoryDataSize size; /* Type de donnée représentée */
+ uint8_t uval8; /* Valeur sur 8 bits */
+ uint16_t uval16; /* Valeur sur 16 bits */
+ uint32_t uval32; /* Valeur sur 32 bits */
+ uint64_t uval64; /* Valeur sur 64 bits */
+ int8_t sval8; /* Valeur sur 8 bits */
+ int16_t sval16; /* Valeur sur 16 bits */
+ int32_t sval32; /* Valeur sur 32 bits */
+ int64_t sval64; /* Valeur sur 64 bits */
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ size = g_imm_operand_get_size(operand);
+
+ switch (size)
+ {
+ /* Pour GCC... */
+ case MDS_UNDEFINED:
+ result = Py_None;
+ Py_INCREF(result);
+ break;
+ case MDS_4_BITS_UNSIGNED:
+ case MDS_8_BITS_UNSIGNED:
+ g_imm_operand_get_value(operand, size, &uval8);
+ result = PyLong_FromUnsignedLong(uval8);
+ break;
+ case MDS_16_BITS_UNSIGNED:
+ g_imm_operand_get_value(operand, size, &uval16);
+ result = PyLong_FromUnsignedLong(uval16);
+ break;
+ case MDS_32_BITS_UNSIGNED:
+ g_imm_operand_get_value(operand, size, &uval32);
+ result = PyLong_FromUnsignedLong(uval32);
+ break;
+ case MDS_64_BITS_UNSIGNED:
+ g_imm_operand_get_value(operand, size, &uval64);
+ result = PyLong_FromUnsignedLongLong(uval64);
+ break;
+ case MDS_4_BITS_SIGNED:
+ case MDS_8_BITS_SIGNED:
+ g_imm_operand_get_value(operand, size, &sval8);
+ result = PyLong_FromLong(sval8);
+ break;
+ case MDS_16_BITS_SIGNED:
+ g_imm_operand_get_value(operand, size, &sval16);
+ result = PyLong_FromLong(sval16);
+ break;
+ case MDS_32_BITS_SIGNED:
+ g_imm_operand_get_value(operand, size, &sval32);
+ result = PyLong_FromLong(sval32);
+ break;
+ case MDS_64_BITS_SIGNED:
+ g_imm_operand_get_value(operand, size, &sval64);
+ result = PyLong_FromLongLong(sval64);
+ break;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique si l'affichage est complété avec des zéros. *
+* *
+* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_imm_operand_get_padding(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+ bool padding; /* Bourrage en préfixe ? */
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ padding = g_imm_operand_does_padding(operand);
+
+ result = Py_BuildValue("p", padding);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* value = valeur fournie à intégrer ou prendre en compte. *
+* closure = non utilisé ici. *
+* *
+* Description : Précise si des zéro doivent compléter l'affichage ou non. *
+* *
+* Retour : Bilan de l'opération pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_imm_operand_set_padding(PyObject *self, PyObject *value, void *closure)
+{
+ bool padding; /* Bourrage en préfixe ? */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+
+ if (!PyBool_Check(value))
+ {
+ PyErr_SetString(PyExc_TypeError, _("Invalid padding state"));
+ return -1;
+ }
+
+ padding = (value == Py_True);
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ g_imm_operand_pad(operand, padding);
+
+ return 0;
+
+}
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique le format textuel par défaut de la valeur. *
+* *
+* Retour : Format global d'un affichage de valeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_imm_operand_get_default_display(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+ ImmOperandDisplay display; /* Type d'affichage courant */
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ display = g_imm_operand_get_default_display(operand);
+
+ result = Py_BuildValue("I", display);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* value = valeur fournie à intégrer ou prendre en compte. *
+* closure = non utilisé ici. *
+* *
+* Description : Définit le format textuel par défaut de la valeur. *
+* *
+* Retour : Bilan de l'opération pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_imm_operand_set_default_display(PyObject *self, PyObject *value, void *closure)
+{
+ ImmOperandDisplay display; /* Type d'affichage demandé */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+
+ if (!PyLong_Check(value))
+ {
+ PyErr_SetString(PyExc_TypeError, _("Invalid display type"));
+ return -1;
+ }
+
+ display = PyLong_AsUnsignedLong(value);
+
+ if (!(IOD_BIN <= display && display <= IOD_CHAR))
+ {
+ PyErr_SetString(PyExc_TypeError, _("Invalid display type"));
+ return -1;
+ }
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ g_imm_operand_set_default_display(operand, display);
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique la grande ligne du format textuel de la valeur. *
+* *
+* Retour : Format global d'un affichage de valeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_imm_operand_get_display(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+ ImmOperandDisplay display; /* Type d'affichage courant */
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ display = g_imm_operand_get_display(operand);
+
+ result = Py_BuildValue("I", display);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* value = valeur fournie à intégrer ou prendre en compte. *
+* closure = non utilisé ici. *
+* *
+* Description : Définit la grande ligne du format textuel de la valeur. *
+* *
+* Retour : Bilan de l'opération pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_imm_operand_set_display(PyObject *self, PyObject *value, void *closure)
+{
+ ImmOperandDisplay display; /* Type d'affichage demandé */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+
+ if (!PyLong_Check(value))
+ {
+ PyErr_SetString(PyExc_TypeError, _("Invalid display type"));
+ return -1;
+ }
+
+ display = PyLong_AsUnsignedLong(value);
+
+ if (!(IOD_BIN <= display && display <= IOD_CHAR))
+ {
+ PyErr_SetString(PyExc_TypeError, _("Invalid display type"));
+ return -1;
+ }
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ g_imm_operand_set_display(operand, display);
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = operande à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Construit la chaîne de caractères correspondant à l'opérande.*
+* *
+* Retour : Chaîne de caractères mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_imm_operand_to_string(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+ unsigned int raw_syntax; /* Affichage brut à utiliser */
+ int ret; /* Bilan de lecture des args. */
+ AsmSyntax syntax; /* Affichage final à utiliser */
+ char value[IMM_MAX_SIZE]; /* Valeur humainement lisible */
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ assert(operand != NULL);
+
+ ret = PyArg_ParseTuple(args, "I", &raw_syntax);
+ if (!ret) return NULL;
+
+ syntax = raw_syntax;
+
+ if (syntax != ASX_INTEL && syntax != ASX_ATT)
+ {
+ PyErr_SetString(PyExc_ValueError, _("Invalid syntax type"));
+ return NULL;
+ }
+
+ g_imm_operand_to_string(operand, syntax, value);
+
+ result = PyUnicode_FromString(value);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de l'objet à instancier. *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Crée un nouvel objet Python de type 'ImmOperand'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_imm_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Instance à retourner */
+ unsigned int raw_size; /* Taille obtenue de Python */
+ unsigned long long value; /* Valeur brute à représenter */
+ int ret; /* Bilan de lecture des args. */
+ MemoryDataSize size; /* Taille des données finale */
+ GArchOperand *operand; /* Création GLib à transmettre */
+
+ ret = PyArg_ParseTuple(args, "IK", &raw_size, &value);
+ if (!ret) return NULL;
+
+ size = raw_size;
+
+ if (size != MDS_UNDEFINED
+ && !(MDS_4_BITS_UNSIGNED <= size && size <= MDS_64_BITS_UNSIGNED)
+ && !(MDS_4_BITS_SIGNED <= size && size <= MDS_64_BITS_SIGNED))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Invalid size to build an immediate operand"));
+ return NULL;
+ }
+
+ operand = g_imm_operand_new_from_value(size, value);
+
+ result = pygobject_new(G_OBJECT(operand));
+
+ g_object_unref(operand);
+
+ return (PyObject *)result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes pour les opérandes d'immédiats. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_imm_operand_define_constants(PyTypeObject *obj_type)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ result &= PyDict_AddIntMacro(obj_type, IOD_BIN);
+ result &= PyDict_AddIntMacro(obj_type, IOD_OCT);
+ result &= PyDict_AddIntMacro(obj_type, IOD_DEC);
+ result &= PyDict_AddIntMacro(obj_type, IOD_HEX);
+ result &= PyDict_AddIntMacro(obj_type, IOD_CHAR);
+ result &= PyDict_AddIntMacro(obj_type, IOD_COUNT);
+
+ 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_imm_operand_type(void)
+{
+ static PyMethodDef py_imm_operand_methods[] = {
+ {
+ "to_string", py_imm_operand_to_string,
+ METH_VARARGS,
+ "to_string($self, syntax, /)\n--\n\nConvert the immediate operand to a string."
+ },
+ { NULL }
+ };
+
+ static PyGetSetDef py_imm_operand_getseters[] = {
+ {
+ "size", py_imm_operand_get_size, NULL,
+ "Size of the value contained in the operand.", NULL
+ },
+ {
+ "value", py_imm_operand_get_value, NULL,
+ "Value of the immediate operand.", NULL
+ },
+ {
+ "padding", py_imm_operand_get_padding, py_imm_operand_set_padding,
+ "Status of padding with zeros in front of the textual representation.", NULL
+ },
+ {
+ "default_display", py_imm_operand_get_default_display, py_imm_operand_set_default_display,
+ "Definition of the immediate operand default textual representation.", NULL
+ },
+ {
+ "display", py_imm_operand_get_display, py_imm_operand_set_display,
+ "Definition of the immediate operand current textual representation.", NULL
+ },
+ { NULL }
+ };
+
+ static PyTypeObject py_imm_operand_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.arch.ImmOperand",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = "PyChrysalide immediate operand.",
+
+ .tp_methods = py_imm_operand_methods,
+ .tp_getset = py_imm_operand_getseters,
+ .tp_new = py_imm_operand_new
+
+ };
+
+ return &py_imm_operand_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.arch.ImmOperand'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_imm_operand(PyObject *module)
+{
+ PyTypeObject *py_imm_operand_type; /* Type Python 'BinContent' */
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_imm_operand_type = get_python_imm_operand_type();
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_class_for_pygobject(dict, G_TYPE_IMM_OPERAND,
+ py_imm_operand_type, get_python_arch_operand_type()))
+ return false;
+
+ if (!py_imm_operand_define_constants(py_imm_operand_type))
+ return false;
+
+ return true;
+
+}
diff --git a/plugins/pychrysa/arch/archbase.h b/plugins/pychrysa/arch/immediate.h
index 30f0432..d6e5eba 100644
--- a/plugins/pychrysa/arch/archbase.h
+++ b/plugins/pychrysa/arch/immediate.h
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * vmpa.h - prototypes pour l'équivalent Python du fichier "arch/vmpa.h"
+ * immediate.h - prototypes pour l'équivalent Python du fichier "arch/immediate.h"
*
- * Copyright (C) 2012-2017 Cyrille Bagard
+ * Copyright (C) 2017 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,33 +22,21 @@
*/
-#ifndef _PLUGINS_PYCHRYSA_ARCH_VMPA_H
-#define _PLUGINS_PYCHRYSA_ARCH_VMPA_H
-
+#ifndef _PLUGINS_PYOIDA_ARCH_IMMEDIATE_H
+#define _PLUGINS_PYOIDA_ARCH_IMMEDIATE_H
#include <Python.h>
-
-
-
-
-
-
-#if 0
#include <stdbool.h>
-#include <arch/archbase.h>
-
-
-/* Crée un nouvel objet Python de type 'py_vmpa'. */
-PyObject *py_vmpa_new_from_existing(vmpa_t);
-/* Ajoute l'objet 'arch.vmpa' au module Python. */
-bool add_arch_vmpa_to_python_module(PyObject *);
-#endif
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_imm_operand_type(void);
+/* Prend en charge l'objet 'pychrysalide.arch.ImmOperand'. */
+bool register_python_imm_operand(PyObject *);
-#endif /* _PLUGINS_PYCHRYSA_ARCH_VMPA_H */
+#endif /* _PLUGINS_PYOIDA_ARCH_IMMEDIATE_H */
diff --git a/plugins/pychrysa/arch/module.c b/plugins/pychrysa/arch/module.c
index 8ef9590..68f702d 100644
--- a/plugins/pychrysa/arch/module.c
+++ b/plugins/pychrysa/arch/module.c
@@ -28,16 +28,74 @@
#include <assert.h>
+#include <arch/archbase.h>
+
+
+#include "immediate.h"
#include "instriter.h"
#include "instruction.h"
+#include "operand.h"
#include "processor.h"
#include "vmpa.h"
#include "arm/module.h"
+#include "../helpers.h"
+
+
+
+/* Définit les constantes de base pour une architecture. */
+static bool py_base_define_constants(PyTypeObject *);
/******************************************************************************
* *
+* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes de base pour une architecture. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_base_define_constants(PyTypeObject *obj_type)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ result &= PyDict_AddIntMacro(obj_type, MDS_UNDEFINED);
+
+ result &= PyDict_AddIntMacro(obj_type, MDS_4_BITS_UNSIGNED);
+ result &= PyDict_AddIntMacro(obj_type, MDS_8_BITS_UNSIGNED);
+ result &= PyDict_AddIntMacro(obj_type, MDS_16_BITS_UNSIGNED);
+ result &= PyDict_AddIntMacro(obj_type, MDS_32_BITS_UNSIGNED);
+ result &= PyDict_AddIntMacro(obj_type, MDS_64_BITS_UNSIGNED);
+
+ result &= PyDict_AddIntMacro(obj_type, MDS_4_BITS_SIGNED);
+ result &= PyDict_AddIntMacro(obj_type, MDS_8_BITS_SIGNED);
+ result &= PyDict_AddIntMacro(obj_type, MDS_16_BITS_SIGNED);
+ result &= PyDict_AddIntMacro(obj_type, MDS_32_BITS_SIGNED);
+ result &= PyDict_AddIntMacro(obj_type, MDS_64_BITS_SIGNED);
+
+ result &= PyDict_AddIntMacro(obj_type, MDS_4_BITS);
+ result &= PyDict_AddIntMacro(obj_type, MDS_8_BITS);
+ result &= PyDict_AddIntMacro(obj_type, MDS_16_BITS);
+ result &= PyDict_AddIntMacro(obj_type, MDS_32_BITS);
+ result &= PyDict_AddIntMacro(obj_type, MDS_64_BITS);
+
+ result &= PyDict_AddIntMacro(obj_type, ASX_INTEL);
+ result &= PyDict_AddIntMacro(obj_type, ASX_ATT);
+ result &= PyDict_AddIntMacro(obj_type, ASX_COUNT);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : module = module dont la définition est à compléter. *
* *
* Description : Ajoute le module 'arch' au module Python. *
@@ -82,12 +140,17 @@ bool add_arch_module_to_python_module(PyObject *super)
result = true;
+ result &= py_base_define_constants(Py_TYPE(module));
+
result &= register_python_arch_instruction(module);
+ result &= register_python_arch_operand(module);
result &= register_python_arch_processor(module);
result &= register_python_instr_iterator(module);
result &= register_python_vmpa(module);
result &= register_python_mrange(module);
+ result &= register_python_imm_operand(module);
+
result &= add_arch_arm_module_to_python_module(module);
loading_failed:
diff --git a/plugins/pychrysa/arch/archbase.c b/plugins/pychrysa/arch/operand.c
index 146b4dd..427f92b 100644
--- a/plugins/pychrysa/arch/archbase.c
+++ b/plugins/pychrysa/arch/operand.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * archbase.c - équivalent Python du fichier "arch/archbase.h"
+ * operand.c - équivalent Python du fichier "arch/operand.h"
*
* Copyright (C) 2012-2017 Cyrille Bagard
*
@@ -22,71 +22,58 @@
*/
-#include "archbase.h"
+#include "operand.h"
+#include <pygobject.h>
-
-/* Classe 'arch.vmpa' pour Python */
-typedef PyLongObject py_vmpa;
-
-
-
-/* Fournit le type d'objet 'arch.vmpa' pour Python. */
-static PyTypeObject *get_arch_vmpa_type(void);
-
+#include <arch/operand.h>
+#include "../helpers.h"
/******************************************************************************
* *
-* Paramètres : value = adresse à convertir en objet Python. *
+* Paramètres : - *
* *
-* Description : Crée un nouvel objet Python de type 'py_vmpa'. *
+* Description : Fournit un accès à une définition de type à diffuser. *
* *
-* Retour : - *
+* Retour : Définition d'objet pour Python. *
* *
* Remarques : - *
* *
******************************************************************************/
-PyObject *py_vmpa_new_from_existing(vmpa_t value)
+PyTypeObject *get_python_arch_operand_type(void)
{
- return PyLong_FromLongLong(value);
-
-}
-
-
-
+ static PyMethodDef py_arch_operand_methods[] = {
+ { NULL }
+ };
+ static PyGetSetDef py_arch_operand_getseters[] = {
+ { NULL }
+ };
+ static PyTypeObject py_arch_operand_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "pychrysalide.arch.ArchOperand",
+ .tp_basicsize = sizeof(PyGObject),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
+ .tp_doc = "PyChrysalide instruction operand.",
+ .tp_methods = py_arch_operand_methods,
+ .tp_getset = py_arch_operand_getseters,
+ };
-
-
-/******************************************************************************
-* *
-* Paramètres : - *
-* *
-* Description : Fournit le type d'objet 'arch.vmpa' pour Python. *
-* *
-* Retour : Adresse du type vivant à manipuler. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyTypeObject *get_arch_vmpa_type(void)
-{
- return &PyLong_Type;
+ return &py_arch_operand_type;
}
@@ -95,27 +82,28 @@ static PyTypeObject *get_arch_vmpa_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Ajoute l'objet 'arch.vmpa' au module Python. *
+* Description : Prend en charge l'objet 'pychrysalide.arch.ArchOperand'. *
* *
-* Retour : - *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool add_arch_vmpa_to_python_module(PyObject *module)
+bool register_python_arch_operand(PyObject *module)
{
- PyTypeObject *py_vmpa_type; /* Type défini pour Python */
- int ret; /* Bilan d'un appel */
+ PyTypeObject *py_arch_operand_type; /* Type Python 'BinContent' */
+ PyObject *dict; /* Dictionnaire du module */
- py_vmpa_type = get_arch_vmpa_type();
+ py_arch_operand_type = get_python_arch_operand_type();
- if (PyType_Ready(py_vmpa_type) < 0)
- return false;
+ APPLY_ABSTRACT_FLAG(py_arch_operand_type);
+
+ dict = PyModule_GetDict(module);
- Py_INCREF(py_vmpa_type);
- ret = PyModule_AddObject(module, "Vmpa", (PyObject *)py_vmpa_type);
+ if (!register_class_for_pygobject(dict, G_TYPE_ARCH_OPERAND, py_arch_operand_type, &PyGObject_Type))
+ return false;
- return (ret == 0);
+ return true;
}
diff --git a/plugins/pychrysa/arch/operand.h b/plugins/pychrysa/arch/operand.h
new file mode 100644
index 0000000..3c5ef6a
--- /dev/null
+++ b/plugins/pychrysa/arch/operand.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * operand.h - prototypes pour l'équivalent Python du fichier "arch/operand.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_PYOIDA_ARCH_OPERAND_H
+#define _PLUGINS_PYOIDA_ARCH_OPERAND_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_arch_operand_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.arch.ArchOperand'. */
+bool register_python_arch_operand(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYOIDA_ARCH_OPERAND_H */
diff --git a/plugins/pychrysa/debug/gdbrsp/gdb.c b/plugins/pychrysa/debug/gdbrsp/gdb.c
index cbbf66b..a4cde20 100644
--- a/plugins/pychrysa/debug/gdbrsp/gdb.c
+++ b/plugins/pychrysa/debug/gdbrsp/gdb.c
@@ -39,6 +39,7 @@
#include "../../analysis/binary.h"
+
/* Crée un nouvel objet Python de type 'GdbDebugger'. */
static PyObject *py_gdb_debugger_new(PyTypeObject *, PyObject *, PyObject *);