summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/arch/operands
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-01-15 19:19:40 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-01-15 19:19:40 (GMT)
commitd75fe33356f22c1c41925bffe179a55b9cea6cd1 (patch)
tree37b9a32d3a2b688326791392b338e025bb4c84f3 /plugins/pychrysalide/arch/operands
parent55935908085677432f746f8378e600f4fd8234b0 (diff)
Reorganized the architecture operands.
Diffstat (limited to 'plugins/pychrysalide/arch/operands')
-rw-r--r--plugins/pychrysalide/arch/operands/Makefile.am5
-rw-r--r--plugins/pychrysalide/arch/operands/constants.c75
-rw-r--r--plugins/pychrysalide/arch/operands/constants.h39
-rw-r--r--plugins/pychrysalide/arch/operands/immediate.c670
-rw-r--r--plugins/pychrysalide/arch/operands/immediate.h42
-rw-r--r--plugins/pychrysalide/arch/operands/module.c12
-rw-r--r--plugins/pychrysalide/arch/operands/register.c25
-rw-r--r--plugins/pychrysalide/arch/operands/targetable.c202
-rw-r--r--plugins/pychrysalide/arch/operands/targetable.h42
9 files changed, 1105 insertions, 7 deletions
diff --git a/plugins/pychrysalide/arch/operands/Makefile.am b/plugins/pychrysalide/arch/operands/Makefile.am
index 94da1d1..7974c42 100644
--- a/plugins/pychrysalide/arch/operands/Makefile.am
+++ b/plugins/pychrysalide/arch/operands/Makefile.am
@@ -2,8 +2,11 @@
noinst_LTLIBRARIES = libpychrysaarchoperands.la
libpychrysaarchoperands_la_SOURCES = \
+ constants.h constants.c \
+ immediate.h immediate.c \
module.h module.c \
- register.h register.c
+ register.h register.c \
+ targetable.h targetable.c
libpychrysaarchoperands_la_LIBADD =
diff --git a/plugins/pychrysalide/arch/operands/constants.c b/plugins/pychrysalide/arch/operands/constants.c
new file mode 100644
index 0000000..daec562
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/constants.c
@@ -0,0 +1,75 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes de base pour les opérandes
+ *
+ * Copyright (C) 2019 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 "constants.h"
+
+
+#include <arch/operands/immediate.h>
+
+
+#include "../../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes relatives aux opérandes d'immédiats. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_imm_operand_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "BIN", IOD_BIN);
+ if (result) result = add_const_to_group(values, "OCT", IOD_OCT);
+ if (result) result = add_const_to_group(values, "DEC", IOD_DEC);
+ if (result) result = add_const_to_group(values, "HEX", IOD_HEX);
+ if (result) result = add_const_to_group(values, "CHAR", IOD_CHAR);
+ if (result) result = add_const_to_group(values, "COUNT", IOD_COUNT);
+ if (result) result = add_const_to_group(values, "LAST_VALID", IOD_LAST_VALID);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "ImmOperandDisplay", values,
+ "Kind of display format for immediate operands.");
+
+ exit:
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/arch/operands/constants.h b/plugins/pychrysalide/arch/operands/constants.h
new file mode 100644
index 0000000..cea74f5
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/constants.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes de base pour les opérandes
+ *
+ * Copyright (C) 2019 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_ARCH_OPERANDS_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes relatives aux opérandes d'immédiats. */
+bool define_imm_operand_constants(PyTypeObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/arch/operands/immediate.c b/plugins/pychrysalide/arch/operands/immediate.c
new file mode 100644
index 0000000..ab9e16c
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/immediate.c
@@ -0,0 +1,670 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * immediate.c - équivalent Python du fichier "arch/operands/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 <assert.h>
+#include <pygobject.h>
+
+
+#include <i18n.h>
+
+
+#include <arch/operands/immediate.h>
+
+
+#include "constants.h"
+#include "targetable.h"
+#include "../operand.h"
+#include "../../access.h"
+#include "../../helpers.h"
+#include "../../analysis/content.h"
+
+
+
+/* Crée un nouvel objet Python de type 'ImmOperand'. */
+static PyObject *py_imm_operand_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Renseigne la taille de la valeur indiquée à la construction. */
+static PyObject *py_imm_operand_get_size(PyObject *, void *);
+
+/* 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_default_padding(PyObject *self, void *);
+
+/* Précise si des zéro doivent compléter l'affichage ou non. */
+static int py_imm_operand_set_default_padding(PyObject *, 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 *);
+
+
+
+/******************************************************************************
+* *
+* 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 */
+
+#define IMM_OPERAND_DOC \
+ "The ImmOperand deals with immediate value as operand." \
+ "\n" \
+ "There are several ways to display these values in a disassembly," \
+ " the operand handles that."
+
+ 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 : 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 */
+
+#define IMM_OPERAND_SIZE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ size, py_imm_operand, \
+ "Get or set the size of the value contained in the operand." \
+ "\n" \
+ "The property is a value of type" \
+ " pychrysalide.analysis.BinContent.MemoryDataSize." \
+)
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ size = g_imm_operand_get_size(operand);
+
+ result = cast_with_constants_group_from_type(get_python_binary_content_type(), "MemoryDataSize", 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 */
+
+#define IMM_OPERAND_VALUE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ value, py_imm_operand, \
+ "Value of the immediate operand, as an integer." \
+)
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+
+ 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;
+
+ /* Pour GCC... */
+ default:
+ assert(false);
+ result = Py_None;
+ Py_INCREF(result);
+ 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_default_padding(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GImmOperand *operand; /* Version GLib de l'opérande */
+ bool padding; /* Bourrage en préfixe ? */
+
+#define IMM_OPERAND_DEFAULT_PADDING_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ default_padding, py_imm_operand, \
+ "Get or set the status of default padding with zeros in front of the" \
+ " textual representation." \
+ "\n" \
+ "The status is a boolean value." \
+)
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+
+ padding = g_imm_operand_get_default_padding(operand);
+
+ result = padding ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ 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_default_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));
+
+ g_imm_operand_set_default_padding(operand, padding);
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
+* 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 ? */
+
+#define IMM_OPERAND_PADDING_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ padding, py_imm_operand, \
+ "Get or set the status of padding with zeros in front of the" \
+ " textual representation." \
+ "\n" \
+ "The status is a boolean value." \
+)
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+
+ padding = g_imm_operand_does_padding(operand);
+
+ result = padding ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ 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));
+
+ 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 */
+
+#define IMM_OPERAND_DEFAULT_DISPLAY_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ default_display, py_imm_operand, \
+ "Define of the immediate operand default textual representation." \
+ "\n" \
+ "The property is a value of type" \
+ " pychrysalide.arch.operands.ImmOperand.ImmOperandDisplay." \
+)
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ display = g_imm_operand_get_default_display(operand);
+
+ result = cast_with_constants_group_from_type(get_python_imm_operand_type(), "ImmOperandDisplay", 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));
+
+ 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 */
+
+#define IMM_OPERAND_DISPLAY_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ display, py_imm_operand, \
+ "Define of the immediate operand current textual representation." \
+ "\n" \
+ "The property is a value of type" \
+ " pychrysalide.arch.operands.ImmOperand.ImmOperandDisplay." \
+)
+
+ operand = G_IMM_OPERAND(pygobject_get(self));
+ display = g_imm_operand_get_display(operand);
+
+ result = cast_with_constants_group_from_type(get_python_imm_operand_type(), "ImmOperandDisplay", 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));
+
+ g_imm_operand_set_display(operand, display);
+
+ 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_imm_operand_type(void)
+{
+ static PyMethodDef py_imm_operand_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_imm_operand_getseters[] = {
+ IMM_OPERAND_SIZE_ATTRIB,
+ IMM_OPERAND_VALUE_ATTRIB,
+ IMM_OPERAND_DEFAULT_PADDING_ATTRIB,
+ IMM_OPERAND_PADDING_ATTRIB,
+ IMM_OPERAND_DEFAULT_DISPLAY_ATTRIB,
+ IMM_OPERAND_DISPLAY_ATTRIB,
+ { NULL }
+ };
+
+ static PyTypeObject py_imm_operand_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.arch.operands.ImmOperand",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = IMM_OPERAND_DOC,
+
+ .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 ensure_python_imm_operand_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'ImmOperand' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_imm_operand_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.arch.operands");
+
+ dict = PyModule_GetDict(module);
+
+ if (!ensure_python_arch_operand_is_registered())
+ return false;
+
+ if (!ensure_python_targetable_operand_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_IMM_OPERAND, type, get_python_arch_operand_type()))
+ return false;
+
+ if (!define_imm_operand_constants(type))
+ return false;
+
+ }
+
+ return true;
+
+}
diff --git a/plugins/pychrysalide/arch/operands/immediate.h b/plugins/pychrysalide/arch/operands/immediate.h
new file mode 100644
index 0000000..9f32758
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/immediate.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * immediate.h - prototypes pour l'équivalent Python du fichier "arch/operands/immediate.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_ARCH_OPERANDS_IMMEDIATE_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_IMMEDIATE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* 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 ensure_python_imm_operand_is_registered(void);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_IMMEDIATE_H */
diff --git a/plugins/pychrysalide/arch/operands/module.c b/plugins/pychrysalide/arch/operands/module.c
index 47a806a..f800e38 100644
--- a/plugins/pychrysalide/arch/operands/module.c
+++ b/plugins/pychrysalide/arch/operands/module.c
@@ -28,7 +28,9 @@
#include <assert.h>
+#include "immediate.h"
#include "register.h"
+#include "targetable.h"
#include "../../helpers.h"
@@ -50,12 +52,18 @@ bool add_arch_operands_module(PyObject *super)
bool result; /* Bilan à retourner */
PyObject *module; /* Sous-module mis en place */
+#define PYCHRYSALIDE_ARCH_OPERANDS_DOC \
+ "This module contains implementations for most common operand usages." \
+ "\n" \
+ "These operands are usually added to objects such as" \
+ " pychrysalide.arch.ArchInstruction when disassembling a binary."
+
static PyModuleDef py_chrysalide_arch_operands_module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "pychrysalide.arch.operands",
- .m_doc = "Python module for Chrysalide.arch.operands",
+ .m_doc = PYCHRYSALIDE_ARCH_OPERANDS_DOC,
.m_size = -1,
@@ -88,7 +96,9 @@ bool populate_arch_operands_module(void)
result = true;
+ if (result) result = ensure_python_imm_operand_is_registered();
if (result) result = ensure_python_register_operand_is_registered();
+ if (result) result = ensure_python_targetable_operand_is_registered();
assert(result);
diff --git a/plugins/pychrysalide/arch/operands/register.c b/plugins/pychrysalide/arch/operands/register.c
index 3e77c9b..28d79f1 100644
--- a/plugins/pychrysalide/arch/operands/register.c
+++ b/plugins/pychrysalide/arch/operands/register.c
@@ -169,6 +169,17 @@ static int py_register_operand_init(PyObject *self, PyObject *args, PyObject *kw
PyObject *new_kwds; /* Nouveau dictionnaire épuré */
GRegisterOperand *operand; /* Opérande à manipuler */
+#define REGISTER_OPERAND_DOC \
+ "The RegisterOperand object handles an operand carrying an" \
+ " architecture register.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " RegisterOperand(reg)" \
+ "\n" \
+ "Where reg is an architecture register defined from a subclass of" \
+ " pychrysalide.arch.ArchRegister."
+
/* Récupération des paramètres */
ret = PyArg_ParseTuple(args, "O&", convert_to_arch_register, &reg);
@@ -223,6 +234,13 @@ static PyObject *py_register_operand_get_register(PyObject *self, void *closure)
GRegisterOperand *operand; /* Version GLib de l'opérande */
GArchRegister *reg; /* Registre lié à l'opérande */
+#define REGISTER_OPERAND_REGISTER_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ register, py_register_operand, \
+ "Provide the register used by the operand, as an" \
+ " instance of type pychrysalide.arch.ArchRegister." \
+)
+
operand = G_REGISTER_OPERAND(pygobject_get(self));
reg = g_register_operand_get_register(operand);
@@ -263,10 +281,7 @@ PyTypeObject *get_python_register_operand_type(void)
};
static PyGetSetDef py_register_operand_getseters[] = {
- {
- "register", py_register_operand_get_register, NULL,
- "Provide the register used by the operand.", NULL
- },
+ REGISTER_OPERAND_REGISTER_ATTRIB,
{ NULL }
};
@@ -279,7 +294,7 @@ PyTypeObject *get_python_register_operand_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide instruction register operand.",
+ .tp_doc = REGISTER_OPERAND_DOC,
.tp_methods = py_register_operand_methods,
.tp_getset = py_register_operand_getseters,
diff --git a/plugins/pychrysalide/arch/operands/targetable.c b/plugins/pychrysalide/arch/operands/targetable.c
new file mode 100644
index 0000000..a633b82
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/targetable.c
@@ -0,0 +1,202 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * targetable.c - prototypes pour l'équivalent Python du fichier "arch/operands/targetable.c"
+ *
+ * Copyright (C) 2018 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 "targetable.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+
+
+#include <arch/operands/targetable.h>
+
+
+#include "../processor.h"
+#include "../vmpa.h"
+#include "../../access.h"
+#include "../../helpers.h"
+#include "../../format/format.h"
+
+
+
+#define TARGETABLE_OPERAND_DOC \
+ "The TargetableOperand interface depicts operands which can drive to" \
+ " another location.\n" \
+ "\n" \
+ "By instance, an immediate value can target a given address into" \
+ " some function code."
+
+
+
+/* Obtient l'adresse de la cible visée par un opérande. */
+static PyObject *py_targetable_operand_get_addr(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = non utilisé ici. *
+* *
+* Description : Obtient l'adresse de la cible visée par un opérande. *
+* *
+* Retour : Localisation de la cible ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_targetable_operand_get_addr(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ vmpa2t *src; /* Version native d'adresse */
+ GBinFormat *format; /* Instance GLib du format */
+ GArchProcessor *proc; /* Instance GLib de l'archi. */
+ int ret; /* Bilan de lecture des args. */
+ GTargetableOperand *operand; /* Instance à manipuler */
+ vmpa2t addr; /* Localisation à cibler */
+ bool defined; /* Cible définie ? */
+
+#define TARGETABLE_OPERAND_GET_ADDR_METHOD PYTHON_METHOD_DEF \
+( \
+ get_addr, "$self, src, format, proc", \
+ METH_VARARGS, py_targetable_operand, \
+ "Compute a target address from an operand." \
+ "\n" \
+ "The following arguments are required:\n" \
+ "* src is the location of the instruction owning the operand, as a" \
+ " pychrysalide.arch.vmpa instance.\n" \
+ "* format is a pychrysalide.format.BinFormat instance, providing" \
+ " all needed information.\n" \
+ "* proc is a pychrysalide.arch.ArchProcessor instance, providing" \
+ " all needed information too.\n" \
+ "\n" \
+ "The result is a pychrysalide.arch.vmpa address or None." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&O&O&",
+ convert_any_to_vmpa, &src,
+ convert_to_binary_format, &format,
+ convert_to_arch_processor, &proc);
+ if (!ret) return NULL;
+
+ operand = G_TARGETABLE_OPERAND(pygobject_get(self));
+
+ defined = g_targetable_operand_get_addr(operand, src, format, proc, &addr);
+
+ if (defined)
+ result = build_from_internal_vmpa(&addr);
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ clean_vmpa_arg(src);
+
+ 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_targetable_operand_type(void)
+{
+ static PyMethodDef py_targetable_operand_methods[] = {
+ TARGETABLE_OPERAND_GET_ADDR_METHOD,
+ { NULL }
+ };
+
+ static PyGetSetDef py_targetable_operand_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_targetable_operand_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.arch.operands.TargetableOperand",
+ .tp_basicsize = sizeof(PyObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = TARGETABLE_OPERAND_DOC,
+
+ .tp_methods = py_targetable_operand_methods,
+ .tp_getset = py_targetable_operand_getseters
+
+ };
+
+ return &py_targetable_operand_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.....TargetableOperand'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_targetable_operand_is_registered(void)
+{
+ PyTypeObject *type; /* Type 'TargetableOperand' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_targetable_operand_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.arch.operands");
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_interface_for_pygobject(dict, G_TYPE_TARGETABLE_OPERAND, type))
+ return false;
+
+ }
+
+ return true;
+
+}
diff --git a/plugins/pychrysalide/arch/operands/targetable.h b/plugins/pychrysalide/arch/operands/targetable.h
new file mode 100644
index 0000000..8a751fc
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/targetable.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * targetable.h - prototypes pour l'équivalent Python du fichier "arch/operands/targetable.h"
+ *
+ * Copyright (C) 2018 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_ARCH_OPERANDS_TARGETABLE_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_TARGETABLE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_targetable_operand_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.arch.TargetableOperand'. */
+bool ensure_python_targetable_operand_is_registered(void);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_TARGETABLE_H */