From d75fe33356f22c1c41925bffe179a55b9cea6cd1 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 15 Jan 2020 20:19:40 +0100 Subject: Reorganized the architecture operands. --- plugins/androhelpers/switch.c | 2 +- plugins/arm/v7/fetch.c | 1 + plugins/arm/v7/helpers.h | 2 +- plugins/arm/v7/post.c | 1 + plugins/dalvik/fetch.c | 3 + plugins/dalvik/link.c | 2 +- plugins/dalvik/operand.c | 1 + plugins/dalvik/operands/pool.c | 2 +- plugins/dalvik/post.c | 1 + plugins/fmtp/def.h | 1 + plugins/lnxsyscalls/hops_armv7.c | 1 + plugins/pychrysalide/analysis/constants.c | 23 + plugins/pychrysalide/arch/Makefile.am | 2 - plugins/pychrysalide/arch/constants.h | 1 + plugins/pychrysalide/arch/immediate.c | 709 ----------- plugins/pychrysalide/arch/immediate.h | 42 - plugins/pychrysalide/arch/module.c | 4 - plugins/pychrysalide/arch/operands/Makefile.am | 5 +- plugins/pychrysalide/arch/operands/constants.c | 75 ++ plugins/pychrysalide/arch/operands/constants.h | 39 + plugins/pychrysalide/arch/operands/immediate.c | 670 ++++++++++ plugins/pychrysalide/arch/operands/immediate.h | 42 + plugins/pychrysalide/arch/operands/module.c | 12 +- plugins/pychrysalide/arch/operands/register.c | 25 +- plugins/pychrysalide/arch/operands/targetable.c | 202 +++ plugins/pychrysalide/arch/operands/targetable.h | 42 + plugins/pychrysalide/arch/targetableop.c | 189 --- plugins/pychrysalide/arch/targetableop.h | 42 - plugins/pychrysalide/format/format.c | 45 + plugins/pychrysalide/format/format.h | 3 + src/analysis/db/items/switcher.h | 2 +- src/analysis/disass/links.c | 3 +- src/arch/Makefile.am | 3 - src/arch/immediate.c | 1533 ----------------------- src/arch/immediate.h | 157 --- src/arch/instruction.h | 2 +- src/arch/link.c | 3 +- src/arch/operands/Makefile.am | 5 +- src/arch/operands/immediate.c | 1533 +++++++++++++++++++++++ src/arch/operands/immediate.h | 157 +++ src/arch/operands/targetable-int.h | 51 + src/arch/operands/targetable.c | 85 ++ src/arch/operands/targetable.h | 61 + src/arch/post.c | 1 + src/arch/raw.c | 2 +- src/arch/target.c | 3 +- src/arch/targetableop-int.h | 51 - src/arch/targetableop.c | 85 -- src/arch/targetableop.h | 61 - src/core/processors.c | 2 +- src/gui/menus/edition.c | 2 +- 51 files changed, 3093 insertions(+), 2898 deletions(-) delete mode 100644 plugins/pychrysalide/arch/immediate.c delete mode 100644 plugins/pychrysalide/arch/immediate.h create mode 100644 plugins/pychrysalide/arch/operands/constants.c create mode 100644 plugins/pychrysalide/arch/operands/constants.h create mode 100644 plugins/pychrysalide/arch/operands/immediate.c create mode 100644 plugins/pychrysalide/arch/operands/immediate.h create mode 100644 plugins/pychrysalide/arch/operands/targetable.c create mode 100644 plugins/pychrysalide/arch/operands/targetable.h delete mode 100644 plugins/pychrysalide/arch/targetableop.c delete mode 100644 plugins/pychrysalide/arch/targetableop.h delete mode 100644 src/arch/immediate.c delete mode 100644 src/arch/immediate.h create mode 100644 src/arch/operands/immediate.c create mode 100644 src/arch/operands/immediate.h create mode 100644 src/arch/operands/targetable-int.h create mode 100644 src/arch/operands/targetable.c create mode 100644 src/arch/operands/targetable.h delete mode 100644 src/arch/targetableop-int.h delete mode 100644 src/arch/targetableop.c delete mode 100644 src/arch/targetableop.h diff --git a/plugins/androhelpers/switch.c b/plugins/androhelpers/switch.c index 57e3830..15daf97 100644 --- a/plugins/androhelpers/switch.c +++ b/plugins/androhelpers/switch.c @@ -27,9 +27,9 @@ #include -#include #include #include +#include #include #include <../i18n.h> diff --git a/plugins/arm/v7/fetch.c b/plugins/arm/v7/fetch.c index 6777fdc..cf71037 100644 --- a/plugins/arm/v7/fetch.c +++ b/plugins/arm/v7/fetch.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/plugins/arm/v7/helpers.h b/plugins/arm/v7/helpers.h index 08b14e2..882b2f9 100644 --- a/plugins/arm/v7/helpers.h +++ b/plugins/arm/v7/helpers.h @@ -25,7 +25,7 @@ #define _PLUGINS_ARM_V7_HELPERS_H -#include +#include #include diff --git a/plugins/arm/v7/post.c b/plugins/arm/v7/post.c index c430d65..44b4459 100644 --- a/plugins/arm/v7/post.c +++ b/plugins/arm/v7/post.c @@ -25,6 +25,7 @@ #include +#include diff --git a/plugins/dalvik/fetch.c b/plugins/dalvik/fetch.c index a4d0300..73cb882 100644 --- a/plugins/dalvik/fetch.c +++ b/plugins/dalvik/fetch.c @@ -27,6 +27,9 @@ #include +#include + + /****************************************************************************** * * diff --git a/plugins/dalvik/link.c b/plugins/dalvik/link.c index 8aa8ff7..bbdb7ea 100644 --- a/plugins/dalvik/link.c +++ b/plugins/dalvik/link.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include diff --git a/plugins/dalvik/operand.c b/plugins/dalvik/operand.c index 3470736..a8c9764 100644 --- a/plugins/dalvik/operand.c +++ b/plugins/dalvik/operand.c @@ -29,6 +29,7 @@ #include +#include #include diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index cbf3ea3..dc6a694 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -32,7 +32,7 @@ #include -#include +#include #include #include diff --git a/plugins/dalvik/post.c b/plugins/dalvik/post.c index 4a98c64..c201252 100644 --- a/plugins/dalvik/post.c +++ b/plugins/dalvik/post.c @@ -28,6 +28,7 @@ #include +#include diff --git a/plugins/fmtp/def.h b/plugins/fmtp/def.h index 2fa4761..15fd2f5 100644 --- a/plugins/fmtp/def.h +++ b/plugins/fmtp/def.h @@ -28,6 +28,7 @@ #include +#include #include diff --git a/plugins/lnxsyscalls/hops_armv7.c b/plugins/lnxsyscalls/hops_armv7.c index cde092c..07d4631 100644 --- a/plugins/lnxsyscalls/hops_armv7.c +++ b/plugins/lnxsyscalls/hops_armv7.c @@ -28,6 +28,7 @@ #include +#include #include diff --git a/plugins/pychrysalide/analysis/constants.c b/plugins/pychrysalide/analysis/constants.c index efb88e2..36a46fe 100644 --- a/plugins/pychrysalide/analysis/constants.c +++ b/plugins/pychrysalide/analysis/constants.c @@ -65,6 +65,29 @@ bool define_analysis_content_constants(PyTypeObject *type) result = attach_constants_group_to_type(type, false, "SourceEndian", values, "Endianness of handled data."); + values = PyDict_New(); + + result = add_const_to_group(values, "UNDEFINED", MDS_UNDEFINED); + if (result) result = add_const_to_group(values, "4_BITS_UNSIGNED", MDS_4_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "8_BITS_UNSIGNED", MDS_8_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "16_BITS_UNSIGNED", MDS_16_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "32_BITS_UNSIGNED", MDS_32_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "64_BITS_UNSIGNED", MDS_64_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "4_BITS_SIGNED", MDS_4_BITS_SIGNED); + if (result) result = add_const_to_group(values, "8_BITS_SIGNED", MDS_8_BITS_SIGNED); + if (result) result = add_const_to_group(values, "16_BITS_SIGNED", MDS_16_BITS_SIGNED); + if (result) result = add_const_to_group(values, "32_BITS_SIGNED", MDS_32_BITS_SIGNED); + if (result) result = add_const_to_group(values, "64_BITS_SIGNED", MDS_64_BITS_SIGNED); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_type(type, false, "MemoryDataSize", values, + "Size of processed data."); + exit: return result; diff --git a/plugins/pychrysalide/arch/Makefile.am b/plugins/pychrysalide/arch/Makefile.am index 8b0e992..e167459 100644 --- a/plugins/pychrysalide/arch/Makefile.am +++ b/plugins/pychrysalide/arch/Makefile.am @@ -5,7 +5,6 @@ libpychrysaarch_la_SOURCES = \ constants.h constants.c \ context.h context.c \ feeder.h feeder.c \ - immediate.h immediate.c \ instriter.h instriter.c \ instruction.h instruction.c \ module.h module.c \ @@ -13,7 +12,6 @@ libpychrysaarch_la_SOURCES = \ processor.h processor.c \ raw.h raw.c \ register.h register.c \ - targetableop.h targetableop.c \ undefined.h undefined.c \ vmpa.h vmpa.c diff --git a/plugins/pychrysalide/arch/constants.h b/plugins/pychrysalide/arch/constants.h index d1fc2d4..5273bbd 100644 --- a/plugins/pychrysalide/arch/constants.h +++ b/plugins/pychrysalide/arch/constants.h @@ -30,6 +30,7 @@ #include + /* Définit les constantes relatives aux emplacements. */ bool define_arch_vmpa_constants(PyTypeObject *); diff --git a/plugins/pychrysalide/arch/immediate.c b/plugins/pychrysalide/arch/immediate.c deleted file mode 100644 index 4c538e4..0000000 --- a/plugins/pychrysalide/arch/immediate.c +++ /dev/null @@ -1,709 +0,0 @@ - -/* 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 -#include - - -#include - - -#include - - -#include "operand.h" -#include "targetableop.h" -#include "../access.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_by_default(PyObject *self, void *); - -/* Précise si des zéro doivent compléter l'affichage ou non. */ -static int py_imm_operand_set_padding_by_default(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 *); - -/* 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; - - /* 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_padding_by_default(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_by_default(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_by_default(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_by_default(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 ? */ - - 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 */ - char value[IMM_MAX_SIZE]; /* Valeur humainement lisible */ - - operand = G_IMM_OPERAND(pygobject_get(self)); - assert(operand != NULL); - - g_imm_operand_to_string(operand, 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_AddULongMacro(obj_type, IOD_BIN); - result &= PyDict_AddULongMacro(obj_type, IOD_OCT); - result &= PyDict_AddULongMacro(obj_type, IOD_DEC); - result &= PyDict_AddULongMacro(obj_type, IOD_HEX); - result &= PyDict_AddULongMacro(obj_type, IOD_CHAR); - result &= PyDict_AddULongMacro(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_NOARGS, - "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_padding", py_imm_operand_get_padding_by_default, py_imm_operand_set_padding_by_default, - "Status of default 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 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"); - - 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 (!py_imm_operand_define_constants(type)) - return false; - - } - - return true; - -} diff --git a/plugins/pychrysalide/arch/immediate.h b/plugins/pychrysalide/arch/immediate.h deleted file mode 100644 index fd456e4..0000000 --- a/plugins/pychrysalide/arch/immediate.h +++ /dev/null @@ -1,42 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * immediate.h - prototypes pour l'équivalent Python du fichier "arch/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_IMMEDIATE_H -#define _PLUGINS_PYCHRYSALIDE_ARCH_IMMEDIATE_H - - -#include -#include - - - -/* 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_IMMEDIATE_H */ diff --git a/plugins/pychrysalide/arch/module.c b/plugins/pychrysalide/arch/module.c index cacc167..3266194 100644 --- a/plugins/pychrysalide/arch/module.c +++ b/plugins/pychrysalide/arch/module.c @@ -34,14 +34,12 @@ #include "context.h" #include "feeder.h" -#include "immediate.h" #include "instriter.h" #include "instruction.h" #include "operand.h" #include "processor.h" #include "raw.h" #include "register.h" -#include "targetableop.h" #include "undefined.h" #include "vmpa.h" #include "operands/module.h" @@ -171,14 +169,12 @@ bool populate_arch_module(void) if (result) result = ensure_python_proc_context_is_registered(); if (result) result = ensure_python_proxy_feeder_is_registered(); - if (result) result = ensure_python_imm_operand_is_registered(); if (result) result = ensure_python_instr_iterator_is_registered(); if (result) result = ensure_python_arch_instruction_is_registered(); if (result) result = ensure_python_arch_operand_is_registered(); if (result) result = ensure_python_arch_processor_is_registered(); if (result) result = ensure_python_raw_instruction_is_registered(); if (result) result = ensure_python_arch_register_is_registered(); - if (result) result = ensure_python_targetable_operand_is_registered(); if (result) result = ensure_python_undefined_instruction_is_registered(); if (result) result = ensure_python_vmpa_is_registered(); if (result) result = ensure_python_mrange_is_registered(); 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 + + +#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 +#include + + + +/* 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 +#include + + +#include + + +#include + + +#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 +#include + + + +/* 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 +#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, ®); @@ -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 + + +#include + + +#include + + +#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 +#include + + + +/* 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 */ diff --git a/plugins/pychrysalide/arch/targetableop.c b/plugins/pychrysalide/arch/targetableop.c deleted file mode 100644 index bc9e3af..0000000 --- a/plugins/pychrysalide/arch/targetableop.c +++ /dev/null @@ -1,189 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * targetableop.c - prototypes pour l'équivalent Python du fichier "arch/targetableop.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 "targetableop.h" - - -#include -#include - - -#include - - -#include - - -#include "processor.h" -#include "vmpa.h" -#include "../access.h" -#include "../helpers.h" -#include "../format/format.h" - - - -/* 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 */ - PyObject *src_obj; /* Objet pour une position */ - PyObject *format_obj; /* Objet pour un format */ - PyObject *proc_obj; /* Objet pour une architecture */ - int ret; /* Bilan de lecture des args. */ - vmpa2t *src; /* Version native d'adresse */ - GBinFormat *format; /* Instance GLib du format */ - GArchProcessor *proc; /* Instance GLib de l'archi. */ - GTargetableOperand *operand; /* Instance à manipuler */ - vmpa2t addr; /* Localisation à cibler */ - bool defined; /* Cible définie ? */ - - ret = PyArg_ParseTuple(args, "O!O!O!", - get_python_vmpa_type(), &src_obj, - get_python_binary_format_type(), &format_obj, - get_python_arch_processor_type(), &proc_obj); - if (!ret) return NULL; - - src = get_internal_vmpa(src_obj); - assert(src != NULL); - - format = G_BIN_FORMAT(pygobject_get(format_obj)); - proc = G_ARCH_PROCESSOR(pygobject_get(proc_obj)); - - operand = G_TARGETABLE_OPERAND(pygobject_get(self)); - assert(operand != NULL); - - 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); - } - - 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[] = { - { - "get_addr", py_targetable_operand_get_addr, - METH_VARARGS, - "get_addr($self, src, format, proc, /)\n--\n\nGet a target address from an operand." - }, - { NULL } - }; - - static PyGetSetDef py_targetable_operand_getseters[] = { - { NULL } - }; - - static PyTypeObject py_targetable_operand_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.arch.TargetableOperand", - .tp_basicsize = sizeof(PyObject), - - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - - .tp_doc = "PyChrysalide targetable operand", - - .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"); - - 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/targetableop.h b/plugins/pychrysalide/arch/targetableop.h deleted file mode 100644 index 4c41a4d..0000000 --- a/plugins/pychrysalide/arch/targetableop.h +++ /dev/null @@ -1,42 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * targetableop.h - prototypes pour l'équivalent Python du fichier "arch/targetableop.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_TARGETABLEOP_H -#define _PLUGINS_PYCHRYSALIDE_ARCH_TARGETABLEOP_H - - -#include -#include - - - -/* 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_TARGETABLEOP_H */ diff --git a/plugins/pychrysalide/format/format.c b/plugins/pychrysalide/format/format.c index 8afbca9..409e085 100644 --- a/plugins/pychrysalide/format/format.c +++ b/plugins/pychrysalide/format/format.c @@ -796,3 +796,48 @@ bool ensure_python_binary_format_is_registered(void) 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 format de binaire. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_binary_format(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_binary_format_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 binary format"); + break; + + case 1: + *((GBinFormat **)dst) = G_BIN_FORMAT(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/format/format.h b/plugins/pychrysalide/format/format.h index 6423821..c7d5ee6 100644 --- a/plugins/pychrysalide/format/format.h +++ b/plugins/pychrysalide/format/format.h @@ -51,6 +51,9 @@ PyTypeObject *get_python_binary_format_type(void); /* Prend en charge l'objet 'pychrysalide.format.BinFormat'. */ bool ensure_python_binary_format_is_registered(void); +/* Tente de convertir en format de binaire. */ +int convert_to_binary_format(PyObject *, void *); + #endif /* _PLUGINS_PYCHRYSALIDE_FORMAT_FORMAT_H */ diff --git a/src/analysis/db/items/switcher.h b/src/analysis/db/items/switcher.h index 4947383..c362b1b 100644 --- a/src/analysis/db/items/switcher.h +++ b/src/analysis/db/items/switcher.h @@ -28,8 +28,8 @@ #include -#include "../../../arch/immediate.h" #include "../../../arch/instruction.h" +#include "../../../arch/operands/immediate.h" diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 4eba0d7..5fc8321 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -30,7 +30,8 @@ #include "../../arch/instruction.h" #include "../../arch/raw.h" #include "../../arch/target.h" -#include "../../arch/targetableop.h" +#include "../../arch/operands/immediate.h" +#include "../../arch/operands/targetable.h" diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index c83dd0c..e22c1d8 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -7,7 +7,6 @@ libarch_la_SOURCES = \ context.h context.c \ feeder-int.h \ feeder.h feeder.c \ - immediate.h immediate.c \ instriter.h instriter.c \ instruction-int.h \ instruction.h instruction.c \ @@ -24,8 +23,6 @@ libarch_la_SOURCES = \ register.h register.c \ storage.h storage.c \ target.h target.c \ - targetableop-int.h \ - targetableop.h targetableop.c \ undefined-int.h \ undefined.h undefined.c \ vmpa.h vmpa.c diff --git a/src/arch/immediate.c b/src/arch/immediate.c deleted file mode 100644 index 2d021be..0000000 --- a/src/arch/immediate.c +++ /dev/null @@ -1,1533 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * immediate.c - opérandes représentant des valeurs numériques - * - * Copyright (C) 2009-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 Chrysalide. If not, see . - */ - - -#include "immediate.h" - - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include - - -#include "operand-int.h" -#include "targetableop-int.h" -#include "../common/asm.h" -#include "../common/extstr.h" -#include "../format/format.h" - - - -/* Définition d'un opérande de valeur numérique (instance) */ -struct _GImmOperand -{ - GArchOperand parent; /* Instance parente */ - - uint64_t raw; /* Valeur transtypée */ - MemoryDataSize size; /* Taille de l'opérande */ - - ImmOperandDisplay def_display; /* Type par défaut d'affichage */ - ImmOperandDisplay display; /* Format général d'affichage */ - unsigned char misc; /* Informations diverses */ - -}; - - -#define IMM_GET_DEF_ZERO_PADDING(op) ((op)->misc & (1 << 0)) -#define IMM_SET_DEF_ZERO_PADDING(op, v) (op)->misc = ((op)->misc & ~(1 << 0)) | ((v) ? (1 << 0) : 0) - -#define IMM_HAS_ZERO_PADDING(op) ((op)->misc & (1 << 1)) -#define IMM_SET_ZERO_PADDING(op) (op)->misc |= (1 << 1) - -#define IMM_GET_ZERO_PADDING_VALUE(op) ((op)->misc & (1 << 2)) -#define IMM_SET_ZERO_PADDING_VALUE(op, v) (op)->misc = ((op)->misc & ~(1 << 2)) | ((v) ? (1 << 2) : 0) - -#define IMM_HAS_DISPLAY(op) ((op)->misc & (1 << 3)) -#define IMM_SET_DISPLAY(op) (op)->misc |= (1 << 3) - - -/* Définition d'un opérande de valeur numérique (classe) */ -struct _GImmOperandClass -{ - GArchOperandClass parent; /* Classe parente */ - -}; - - -/* Initialise la classe des lignes de descriptions initiales. */ -static void g_imm_operand_class_init(GImmOperandClass *); - -/* Initialise la classe des lignes de descriptions initiales. */ -static void g_imm_operand_init(GImmOperand *); - -/* Procède à l'initialisation de l'interface de ciblage. */ -static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface *); - -/* Supprime toutes les références externes. */ -static void g_imm_operand_dispose(GImmOperand *); - -/* Procède à la libération totale de la mémoire. */ -static void g_imm_operand_finalize(GImmOperand *); - -/* Compare un opérande avec un autre. */ -static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *); - -/* Indique si une valeur est complétée par des zéros. */ -static bool g_imm_operand_does_padding_for_display(const GImmOperand *, ImmOperandDisplay); - -/* Construit la chaîne de caractères correspondant à l'opérande. */ -static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]); - -/* Traduit un opérande en version humainement lisible. */ -static void g_imm_operand_print(const GImmOperand *, GBufferLine *); - -/* Construit un petit résumé concis de l'opérande. */ -static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *); - - - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_imm_operand_unserialize(GImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_imm_operand_serialize(const GImmOperand *, GAsmStorage *, packed_buffer *); - - - -/* ----------------------- INTERFACE DE CIBLAGE POUR OPERANDE ----------------------- */ - - -/* Obtient l'adresse de la cible visée par un opérande. */ -static bool g_imm_operand_get_addr(const GImmOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); - - - -/* Indique le type défini pour un opérande de valeur numérique. */ -G_DEFINE_TYPE_WITH_CODE(GImmOperand, g_imm_operand, G_TYPE_ARCH_OPERAND, - G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_imm_operand_targetable_interface_init)); - - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des lignes de descriptions initiales. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_class_init(GImmOperandClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GArchOperandClass *operand; /* Version de classe parente */ - - object = G_OBJECT_CLASS(klass); - operand = G_ARCH_OPERAND_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_imm_operand_dispose; - object->finalize = (GObjectFinalizeFunc)g_imm_operand_finalize; - - operand->compare = (operand_compare_fc)g_imm_operand_compare; - operand->print = (operand_print_fc)g_imm_operand_print; - operand->build_tooltip = (operand_build_tooltip_fc)g_imm_operand_build_tooltip; - - operand->unserialize = (unserialize_operand_fc)g_imm_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_imm_operand_serialize; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instance à initialiser. * -* * -* Description : Initialise la classe des lignes de descriptions initiales. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_init(GImmOperand *operand) -{ - operand->def_display = IOD_HEX; - operand->misc = 0; - - IMM_SET_DEF_ZERO_PADDING(operand, false); - -} - - -/****************************************************************************** -* * -* Paramètres : iface = interface GLib à initialiser. * -* * -* Description : Procède à l'initialisation de l'interface de ciblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface *iface) -{ - iface->get_addr = (get_targetable_addr_fc)g_imm_operand_get_addr; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_dispose(GImmOperand *operand) -{ - G_OBJECT_CLASS(g_imm_operand_parent_class)->dispose(G_OBJECT(operand)); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_finalize(GImmOperand *operand) -{ - G_OBJECT_CLASS(g_imm_operand_parent_class)->finalize(G_OBJECT(operand)); - -} - - -/****************************************************************************** -* * -* Paramètres : size = taille de l'opérande souhaitée. * -* content = flux de données à analyser. * -* addr = position courante dans ce flux. [OUT] * -* low = position éventuelle des 4 bits visés. [OUT] * -* endian = ordre des bits dans la source. * -* * -* Description : Crée un opérande réprésentant une valeur numérique. * -* * -* Retour : Instruction mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian) -{ - GImmOperand *result; /* Opérande à retourner */ - 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 */ - - result = g_object_new(G_TYPE_IMM_OPERAND, NULL); - - result->size = size; - - switch (size) - { - case MDS_4_BITS_UNSIGNED: - if (!g_binary_content_read_u4(content, addr, low, &uval8)) - goto gionfd_error; - result->raw = uval8; - break; - - case MDS_8_BITS_UNSIGNED: - if (!g_binary_content_read_u8(content, addr, &uval8)) - goto gionfd_error; - result->raw = uval8; - break; - - case MDS_16_BITS_UNSIGNED: - if (!g_binary_content_read_u16(content, addr, endian, &uval16)) - goto gionfd_error; - result->raw = uval16; - break; - - case MDS_32_BITS_UNSIGNED: - if (!g_binary_content_read_u32(content, addr, endian, &uval32)) - goto gionfd_error; - result->raw = uval32; - break; - - case MDS_64_BITS_UNSIGNED: - if (!g_binary_content_read_u64(content, addr, endian, &uval64)) - goto gionfd_error; - result->raw = uval64; - break; - - case MDS_4_BITS_SIGNED: - if (!g_binary_content_read_s4(content, addr, low, &sval8)) - goto gionfd_error; - result->raw = sval8; - break; - - case MDS_8_BITS_SIGNED: - if (!g_binary_content_read_s8(content, addr, &sval8)) - goto gionfd_error; - result->raw = sval8; - break; - - case MDS_16_BITS_SIGNED: - if (!g_binary_content_read_s16(content, addr, endian, &sval16)) - goto gionfd_error; - result->raw = sval16; - break; - - case MDS_32_BITS_SIGNED: - if (!g_binary_content_read_s32(content, addr, endian, &sval32)) - goto gionfd_error; - result->raw = sval32; - break; - - case MDS_64_BITS_SIGNED: - if (!g_binary_content_read_s64(content, addr, endian, &sval64)) - goto gionfd_error; - result->raw = sval64; - break; - - case MDS_UNDEFINED: - goto gionfd_error; - break; - - } - - return G_ARCH_OPERAND(result); - - gionfd_error: - - g_object_unref(G_OBJECT(result)); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : size = taille de l'opérande souhaitée. * -* value = valeur sur x bits à venir récupérer. * -* * -* Description : Crée un opérande réprésentant une valeur numérique. * -* * -* Retour : Instruction mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value) -{ - GImmOperand *result; /* Opérande à retourner */ - - if (size == MDS_UNDEFINED) - result = NULL; - - else - { - result = g_object_new(G_TYPE_IMM_OPERAND, NULL); - - result->size = size; - result->raw = value; - - } - - return (result != NULL ? G_ARCH_OPERAND(result) : NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * -* * -* Description : Compare un opérande avec un autre. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b) -{ - int result; /* Bilan à retourner */ - - if (a->size < b->size) - { - result = -1; - goto gioc_done; - } - else if (a->size > b->size) - { - result = 1; - goto gioc_done; - } - - if (a->raw < b->raw) - { - result = -1; - goto gioc_done; - } - else if (a->raw > b->raw) - { - result = 1; - goto gioc_done; - } - - if (a->def_display < b->def_display) - { - result = -1; - goto gioc_done; - } - else if (a->def_display > b->def_display) - { - result = 1; - goto gioc_done; - } - - if (IMM_HAS_DISPLAY(a) != IMM_HAS_DISPLAY(b)) - { - result = (IMM_HAS_DISPLAY(a) ? 1 : -1); - goto gioc_done; - } - - if (IMM_HAS_DISPLAY(a)) - { - if (a->display < b->display) - { - result = -1; - goto gioc_done; - } - else if (a->display > b->display) - { - result = 1; - goto gioc_done; - } - } - - if (IMM_GET_DEF_ZERO_PADDING(a) != IMM_GET_DEF_ZERO_PADDING(b)) - { - result = (IMM_GET_DEF_ZERO_PADDING(a) ? 1 : -1); - goto gioc_done; - } - - if (IMM_HAS_ZERO_PADDING(a) != IMM_HAS_ZERO_PADDING(b)) - { - result = (IMM_HAS_ZERO_PADDING(a) ? 1 : -1); - goto gioc_done; - } - - if (IMM_HAS_ZERO_PADDING(a)) - { - if (IMM_GET_ZERO_PADDING_VALUE(a) != IMM_GET_ZERO_PADDING_VALUE(b)) - { - result = (IMM_GET_ZERO_PADDING_VALUE(a) ? 1 : -1); - goto gioc_done; - } - } - - result = 0; - - gioc_done: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Renseigne la taille de la valeur indiquée à la construction. * -* * -* Retour : Taille de la valeur représentée en mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand) -{ - return operand->size; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* size = taille de l'opérande souhaitée. * -* ... = valeur sur x bits à venir récupérer. * -* * -* Description : Fournit la valeur portée par une opérande numérique. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...) -{ - bool result; /* Bilan à retourner */ - va_list ap; /* Liste des compléments */ - 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 */ - - if (operand->size != size) return false; - - result = true; - - va_start(ap, size); - - switch (size) - { - /* Pour GCC... */ - case MDS_UNDEFINED: - result = false; - break; - case MDS_4_BITS_UNSIGNED: - case MDS_8_BITS_UNSIGNED: - uval8 = va_arg(ap, uint8_t *); - *uval8 = operand->raw; - break; - case MDS_16_BITS_UNSIGNED: - uval16 = va_arg(ap, uint16_t *); - *uval16 = operand->raw; - break; - case MDS_32_BITS_UNSIGNED: - uval32 = va_arg(ap, uint32_t *); - *uval32 = operand->raw; - break; - case MDS_64_BITS_UNSIGNED: - uval64 = va_arg(ap, uint64_t *); - *uval64 = operand->raw; - break; - case MDS_4_BITS_SIGNED: - case MDS_8_BITS_SIGNED: - sval8 = va_arg(ap, int8_t *); - *sval8 = operand->raw; - break; - case MDS_16_BITS_SIGNED: - sval16 = va_arg(ap, int16_t *); - *sval16 = operand->raw; - break; - case MDS_32_BITS_SIGNED: - sval32 = va_arg(ap, int32_t *); - *sval32 = operand->raw; - break; - case MDS_64_BITS_SIGNED: - sval64 = va_arg(ap, int64_t *); - *sval64 = operand->raw; - break; - } - - va_end(ap); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Fournit la valeur brute représentée par l'opérande. * -* * -* Retour : Valeur destinée à un usage interne. * -* * -* Remarques : - * -* * -******************************************************************************/ - -uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand) -{ - return operand->raw; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* size = taille de l'opérande souhaitée. * -* value = valeur sur x bits à venir récupérer. * -* * -* Description : Définit la nouvelle valeur de l'opérande à une valeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value) -{ - assert(size != MDS_UNDEFINED); - - operand->size = size; - operand->raw = value; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* state = true si des zéro sont à ajouter, false sinon. * -* * -* Description : Précise si des zéro doivent compléter l'affichage ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_pad_by_default(GImmOperand *operand, bool state) -{ - IMM_SET_DEF_ZERO_PADDING(operand, state); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique si une valeur est complétée par des zéros par défaut.* -* * -* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_does_padding_by_default(const GImmOperand *operand) -{ - bool result; /* Statut à retourner */ - - result = IMM_GET_DEF_ZERO_PADDING(operand); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* state = true si des zéro sont à ajouter, false sinon. * -* * -* Description : Précise si des zéro doivent compléter l'affichage ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_pad(GImmOperand *operand, bool state) -{ - IMM_SET_ZERO_PADDING(operand); - IMM_SET_ZERO_PADDING_VALUE(operand, state); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique si une valeur est complétée par des zéros. * -* * -* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_does_padding(const GImmOperand *operand) -{ - bool result; /* Statut à retourner */ - - if (IMM_HAS_ZERO_PADDING(operand)) - result = IMM_GET_ZERO_PADDING_VALUE(operand); - else - result = IMM_GET_DEF_ZERO_PADDING(operand); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* display = type d'affichage à considérer. * -* * -* Description : Indique si une valeur est complétée par des zéros. * -* * -* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_imm_operand_does_padding_for_display(const GImmOperand *operand, ImmOperandDisplay display) -{ - bool result; /* Statut à retourner */ - - result = g_imm_operand_does_padding(operand); - - if (result) - { - display = g_imm_operand_get_display(operand); - - if (display != IOD_BIN && display != IOD_HEX) - result = false; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* display = format global d'un affichage de valeur. * -* * -* Description : Définit le format textuel par défaut de la valeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display) -{ - operand->def_display = display; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique le format textuel par défaut de la valeur. * -* * -* Retour : Format global d'un affichage de valeur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand) -{ - return operand->def_display; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* display = format global d'un affichage de valeur. * -* * -* Description : Définit la grande ligne du format textuel de la valeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display) -{ - IMM_SET_DISPLAY(operand); - operand->display = display; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique la grande ligne du format textuel de la valeur. * -* * -* Retour : Format global d'un affichage de valeur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand) -{ - ImmOperandDisplay result; /* Affichage à retourner */ - - if (IMM_HAS_DISPLAY(operand)) - result = operand->display; - else - result = operand->def_display; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique le signe d'une valeur immédiate. * -* * -* Retour : true si la valeur est strictement négative, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_is_negative(const GImmOperand *operand) -{ - bool result; /* Bilan à renvoyer */ - - switch (operand->size) - { - case MDS_4_BITS_SIGNED: - case MDS_8_BITS_SIGNED: - case MDS_16_BITS_SIGNED: - case MDS_32_BITS_SIGNED: - case MDS_64_BITS_SIGNED: - /** - * Pour les valeurs plus petites que 64 bits, le compilateur - * réalise une extension de signe lors du transtypage. - */ - result = (operand->raw & 0x8000000000000000ll); - break; - default: - result = false; - break; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique si une valeur immédiate est nulle ou non. * -* * -* Retour : true si la valeur est nulle, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_is_null(const GImmOperand *operand) -{ - return (operand->raw == 0ll); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à transcrire. * -* display = type d'affichage demandé. * -* value = valeur portée par l'opérande transcrite. [OUT] * -* * -* Description : Construit la chaîne de caractères correspondant à l'opérande.* -* * -* Retour : Nombre de caractères utilisés. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE]) -{ - size_t result; /* Longueur à retourner */ - unsigned int range; /* Catégorie de la taille */ - const char *prefix; /* Entrée en matière */ - const char *suffix; /* Sortie de matière */ - const char *alternate; /* Préfixe de forme alternative*/ - const char *intro; /* Introduction du formatage */ - bool do_padding; /* Indication de bourrage */ - const char *zpad; /* Remplissage par des zéros */ - const char *lmod; /* Modification de longueur */ - const char *conv; /* Opérateur de conversion */ - char binval[65]; /* Conversion intégrée */ - unsigned int max; /* Indice du plus fort bit */ - unsigned int i; /* Boucle de parcours */ - char format[16 + 65]; /* Format d'impression final */ - - static const char *zpad_defs[] = { "", "02", "04", "08", "016" }; - static const char *lmod_defs[] = { "hh", "hh", "h", "", __PRI64_PREFIX }; - static const char *conv_si_defs[] = { "", "o", "d", "x", "c" }; - static const char *conv_us_defs[] = { "", "o", "u", "x", "c" }; - - assert(display <= IOD_LAST_VALID); - - range = MDS_RANGE(operand->size); - - /* Encadrement pour les caractères */ - if (display == IOD_CHAR) - { - prefix = "'"; - suffix = "'"; - } - else - { - prefix = ""; - suffix = ""; - } - - /* Préfix de forme '0x', 'b' ou '0' */ - switch (display) - { - case IOD_BIN: - alternate = "b"; - break; - case IOD_OCT: - alternate = "0"; - break; - case IOD_HEX: - alternate = "0x"; - break; - default: - alternate = ""; - break; - } - - /* Va-t-on réellement avoir besoin d'un formatage ? */ - if (display != IOD_BIN) - intro = "%"; - else - intro = ""; - - /* Drapeau de remplissage ? */ - - do_padding = g_imm_operand_does_padding_for_display(operand, display); - - switch (display) - { - case IOD_BIN: - case IOD_CHAR: - case IOD_OCT: - case IOD_DEC: - zpad = ""; - break; - default: - zpad = (do_padding ? zpad_defs[range] : ""); - break; - } - - /* Modification de la longueur fournie */ - - if (display != IOD_BIN) - lmod = lmod_defs[range]; - else - lmod = ""; - - /* Spécification de la conversion */ - - if (display != IOD_BIN) - { - if (MDS_IS_SIGNED(operand->size)) - conv = conv_si_defs[display]; - else - conv = conv_us_defs[display]; - - } - else - { - if (do_padding) - max = range * 8; - - else - { - if (!msb_64(operand->raw, &max)) - { - conv = "0"; - max = 0; - } - } - - if (max > 0) - { - conv = binval; - - for (i = max; i > 0; i--) - binval[max - i] = (operand->raw & (1llu << (i - 1)) ? '1' : '0'); - - binval[max] = '\0'; - - } - - } - - /* Impression finale */ - - snprintf(format, sizeof(format), "%s%s%s%s%s%s%s", prefix, alternate, intro, zpad, lmod, conv, suffix); - - switch (operand->size) - { - case MDS_UNDEFINED: - result = snprintf(value, IMM_MAX_SIZE, ""); - break; - - case MDS_4_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint8_t)operand->raw); - break; - - case MDS_8_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint8_t)operand->raw); - break; - - case MDS_16_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint16_t)operand->raw); - break; - - case MDS_32_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint32_t)operand->raw); - break; - - case MDS_64_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint64_t)operand->raw); - break; - - case MDS_4_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int8_t)operand->raw); - break; - - case MDS_8_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int8_t)operand->raw); - break; - - case MDS_16_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int16_t)operand->raw); - break; - - case MDS_32_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int32_t)operand->raw); - break; - - case MDS_64_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int64_t)operand->raw); - break; - - default: - assert(false); - result = 0; - break; - - } - - assert(result > 0); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à transcrire. * -* syntax = type de représentation demandée. * -* value = valeur portée par l'opérande transcrite. [OUT] * -* * -* Description : Construit la chaîne de caractères correspondant à l'opérande.* -* * -* Retour : Nombre de caractères utilisés. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_imm_operand_to_string(const GImmOperand *operand, char value[IMM_MAX_SIZE]) -{ - size_t result; /* Longueur à retourner */ - ImmOperandDisplay display; /* Type d'affichage courant */ - - display = g_imm_operand_get_display(operand); - - result = _g_imm_operand_to_string(operand, display, value); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_print(const GImmOperand *operand, GBufferLine *line) -{ - char value[IMM_MAX_SIZE]; /* Chaîne à imprimer */ - size_t len; /* Taille de l'élément inséré */ - - len = g_imm_operand_to_string(operand, value); - - g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_IMMEDIATE, G_OBJECT(operand)); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* binary = informations relatives au binaire chargé. * -* * -* Description : Construit un petit résumé concis de l'opérande. * -* * -* Retour : Chaîne de caractères à libérer après usage ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary) -{ - char *result; /* Description à retourner */ - char value[IMM_MAX_SIZE]; /* Conversion artificielle */ - char *conv; /* Affichage de la Conversion */ - - if (operand->raw <= UCHAR_MAX && isprint(operand->raw)) - switch (operand->raw) - { - case '&': - asprintf(&result, _("Character: '&'")); - break; - case '<': - asprintf(&result, _("Character: '<'")); - break; - case '>': - asprintf(&result, _("Character: '>'")); - break; - default: - asprintf(&result, _("Character: '%c'"), (char)operand->raw); - break; - } - - else - asprintf(&result, _("Character: <not printable>")); - - /* Binaire */ - - _g_imm_operand_to_string(operand, IOD_BIN, value); - - asprintf(&conv, _("Binary: %s"), value); - - result = stradd(result, "\n"); - result = stradd(result, conv); - - free(conv); - - /* Octal */ - - _g_imm_operand_to_string(operand, IOD_OCT, value); - - asprintf(&conv, _("Octal: %s"), value); - - result = stradd(result, "\n"); - result = stradd(result, conv); - - free(conv); - - /* Décimal */ - - _g_imm_operand_to_string(operand, IOD_DEC, value); - - asprintf(&conv, _("Decimal: %s"), value); - - result = stradd(result, "\n"); - result = stradd(result, conv); - - free(conv); - - /* Hexadécimal */ - - _g_imm_operand_to_string(operand, IOD_HEX, value); - - asprintf(&conv, _("Hexadecimal: %s"), value); - - result = stradd(result, "\n"); - result = stradd(result, conv); - - free(conv); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* pos = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en position de type phys_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos) -{ - bool result; /* Bilan à renvoyer */ - - result = !MDS_IS_SIGNED(operand->size); - - if (result) - *pos = operand->raw; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* addr = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en adresse de type virt_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr) -{ - bool result; /* Bilan à renvoyer */ - - result = !MDS_IS_SIGNED(operand->size); - - if (result) - *addr = operand->raw; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* val = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en valeur de type leb128_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val) -{ - *val = operand->raw; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* val = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en valeur de type uleb128_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val) -{ - *val = operand->raw; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* addr = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en adresse de type vmpa_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr) -{ - return false; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* value = valeur résultante. [OUT] * -* negative = indique si la valeur était négative à l'origine. * -* * -* Description : Convertit une valeur immédiate en valeur de type size_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_size_t(const GImmOperand *operand, size_t *value, bool *negative) -{ - return false; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* value = valeur résultante. [OUT] * -* negative = indique si la valeur était négative à l'origine. * -* * -* Description : Convertit une valeur immédiate en valeur de type off_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_off_t(const GImmOperand *operand, off_t *value, bool *negative) -{ - return false; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un opérande depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - - parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); - - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); - - if (result) - result = extract_packed_buffer(pbuf, &operand->size, sizeof(MemoryDataSize), true); - - if (result) - result = extract_packed_buffer(pbuf, &operand->def_display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extract_packed_buffer(pbuf, &operand->display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extract_packed_buffer(pbuf, &operand->misc, sizeof(uint8_t), false); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Sauvegarde un opérande dans une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - - parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); - - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); - - if (result) - result = extend_packed_buffer(pbuf, &operand->size, sizeof(MemoryDataSize), true); - - if (result) - result = extend_packed_buffer(pbuf, &operand->def_display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extend_packed_buffer(pbuf, &operand->display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extend_packed_buffer(pbuf, &operand->misc, sizeof(uint8_t), false); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* INTERFACE DE CIBLAGE POUR OPERANDE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : operand = operande à consulter. * -* src = localisation de l'instruction mère. * -* format = format reconnu pour le binaire chargé. * -* proc = architecture associée à ce même binaire. * -* addr = localisation de la cible. [OUT] * -* * -* Description : Obtient l'adresse de la cible visée par un opérande. * -* * -* Retour : true si la cible est valide, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_imm_operand_get_addr(const GImmOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) -{ - bool result; /* Bilan à retourner */ - virt_t virt; /* Adresse virtuelle */ - - result = g_imm_operand_to_virt_t(operand, &virt); - - if (result) - result = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, addr); - - return result; - -} diff --git a/src/arch/immediate.h b/src/arch/immediate.h deleted file mode 100644 index 149eff8..0000000 --- a/src/arch/immediate.h +++ /dev/null @@ -1,157 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * immediate.h - prototypes pour les opérandes représentant des valeurs numériques - * - * Copyright (C) 2009-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 Chrysalide. If not, see . - */ - - -#ifndef _ARCH_IMMEDIATE_H -#define _ARCH_IMMEDIATE_H - - -#include -#include -#include - - -#include "archbase.h" -#include "operand.h" -#include "../analysis/content.h" - - - -/* Grande ligne d'un format d'affichage */ -typedef enum _ImmOperandDisplay -{ - IOD_BIN, /* Impression en binaire */ - IOD_OCT, /* Impression en octal */ - IOD_DEC, /* Impression en décimal */ - IOD_HEX, /* Impression en hexadécimal */ - IOD_CHAR, /* Impression en base 26 */ - - IOD_COUNT - -} ImmOperandDisplay; - - -#define IOD_LAST_VALID IOD_CHAR - - -#define G_TYPE_IMM_OPERAND g_imm_operand_get_type() -#define G_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_IMM_OPERAND, GImmOperand)) -#define G_IS_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_IMM_OPERAND)) -#define G_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_IMM_OPERAND, GImmOperandClass)) -#define G_IS_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_IMM_OPERAND)) -#define G_IMM_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_IMM_OPERAND, GImmOperandClass)) - - -/* Définition d'un opérande de valeur numérique (instance) */ -typedef struct _GImmOperand GImmOperand; - -/* Définition d'un opérande de valeur numérique (classe) */ -typedef struct _GImmOperandClass GImmOperandClass; - - -/* Indique le type défini pour un opérande d'architecture. */ -GType g_imm_operand_get_type(void); - -/* Crée un opérande réprésentant une valeur numérique. */ -GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const GBinContent *, vmpa2t *, bool *, SourceEndian); - -#define g_imm_operand_new_from_data(size, content, addr, endian) \ - _g_imm_operand_new_from_data(size, content, addr, NULL, endian) - -/* Crée un opérande réprésentant une valeur numérique. */ -GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, uint64_t); - -/* Renseigne la taille de la valeur indiquée à la construction. */ -MemoryDataSize g_imm_operand_get_size(const GImmOperand *); - -/* Fournit la valeur portée par une opérande numérique. */ -bool g_imm_operand_get_value(const GImmOperand *, MemoryDataSize, ...); - -/* Fournit la valeur brute représentée par l'opérande. */ -uint64_t g_imm_operand_get_raw_value(const GImmOperand *); - -/* Définit la nouvelle valeur de l'opérande à une valeur. */ -void g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t); - -/* Précise si des zéro doivent compléter l'affichage ou non. */ -void g_imm_operand_pad_by_default(GImmOperand *, bool); - -/* Indique si une valeur est complétée par des zéros par défaut. */ -bool g_imm_operand_does_padding_by_default(const GImmOperand *); - -/* Précise si des zéro doivent compléter l'affichage ou non. */ -void g_imm_operand_pad(GImmOperand *, bool); - -/* Indique si une valeur est complétée par des zéros. */ -bool g_imm_operand_does_padding(const GImmOperand *); - -/* Définit le format textuel par défaut de la valeur. */ -void g_imm_operand_set_default_display(GImmOperand *, ImmOperandDisplay); - -/* Indique le format textuel par défaut de la valeur. */ -ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *); - -/* Définit la grande ligne du format textuel de la valeur. */ -void g_imm_operand_set_display(GImmOperand *, ImmOperandDisplay); - -/* Indique la grande ligne du format textuel de la valeur. */ -ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *); - -/* Indique le signe d'une valeur immédiate. */ -bool g_imm_operand_is_negative(const GImmOperand *); - -/* Indique si une valeur immédiate est nulle ou non. */ -bool g_imm_operand_is_null(const GImmOperand *); - -/** - * La taille d'impression d'un opérande n'est pas VMPA_MAX_SIZE, - * mais 1 + 64 caractères + octet nul final en cas d'impression en binaire. - */ -#define IMM_MAX_SIZE 66 - -/* Construit la chaîne de caractères correspondant à l'opérande. */ -size_t g_imm_operand_to_string(const GImmOperand *, char [IMM_MAX_SIZE]); - -/* Convertit une valeur immédiate en position de type phys_t. */ -bool g_imm_operand_to_phys_t(const GImmOperand *, phys_t *); - -/* Convertit une valeur immédiate en adresse de type virt_t. */ -bool g_imm_operand_to_virt_t(const GImmOperand *, virt_t *); - -/* Convertit une valeur immédiate en valeur de type leb128_t. */ -void g_imm_operand_as_leb128(const GImmOperand *, leb128_t *); - -/* Convertit une valeur immédiate en valeur de type uleb128_t. */ -void g_imm_operand_as_uleb128(const GImmOperand *, uleb128_t *); - -/* Convertit une valeur immédiate en adresse de type vmpa_t. */ -bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *) __attribute__ ((deprecated)); - -/* Convertit une valeur immédiate en valeur de type size_t. */ -bool g_imm_operand_to_size_t(const GImmOperand *, size_t *, bool *) __attribute__ ((deprecated)); - -/* Convertit une valeur immédiate en valeur de type off_t. */ -bool g_imm_operand_to_off_t(const GImmOperand *, off_t *, bool *) __attribute__ ((deprecated)); - - - -#endif /* _ARCH_IMMEDIATE_H */ diff --git a/src/arch/instruction.h b/src/arch/instruction.h index d1bfbe2..af6b03a 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -29,7 +29,7 @@ #include "context.h" -#include "immediate.h" +#include "operand.h" #include "register.h" #include "vmpa.h" #include "../analysis/type.h" diff --git a/src/arch/link.c b/src/arch/link.c index 7eaa1d9..cba722b 100644 --- a/src/arch/link.c +++ b/src/arch/link.c @@ -27,7 +27,8 @@ #include -#include "targetableop.h" +#include "operands/immediate.h" +#include "operands/targetable.h" diff --git a/src/arch/operands/Makefile.am b/src/arch/operands/Makefile.am index fb43a22..3d464e3 100644 --- a/src/arch/operands/Makefile.am +++ b/src/arch/operands/Makefile.am @@ -2,8 +2,11 @@ noinst_LTLIBRARIES = libarchoperands.la libarchoperands_la_SOURCES = \ + immediate.h immediate.c \ register-int.h \ - register.h register.c + register.h register.c \ + targetable-int.h \ + targetable.h targetable.c libarchoperands_la_LIBADD = diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c new file mode 100644 index 0000000..0ecb5f7 --- /dev/null +++ b/src/arch/operands/immediate.c @@ -0,0 +1,1533 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * immediate.c - opérandes représentant des valeurs numériques + * + * Copyright (C) 2009-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 Chrysalide. If not, see . + */ + + +#include "immediate.h" + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + + +#include "targetable-int.h" +#include "../operand-int.h" +#include "../../common/asm.h" +#include "../../common/extstr.h" +#include "../../format/format.h" + + + +/* Définition d'un opérande de valeur numérique (instance) */ +struct _GImmOperand +{ + GArchOperand parent; /* Instance parente */ + + uint64_t raw; /* Valeur transtypée */ + MemoryDataSize size; /* Taille de l'opérande */ + + ImmOperandDisplay def_display; /* Type par défaut d'affichage */ + ImmOperandDisplay display; /* Format général d'affichage */ + unsigned char misc; /* Informations diverses */ + +}; + + +#define IMM_GET_DEF_ZERO_PADDING(op) ((op)->misc & (1 << 0)) +#define IMM_SET_DEF_ZERO_PADDING(op, v) (op)->misc = ((op)->misc & ~(1 << 0)) | ((v) ? (1 << 0) : 0) + +#define IMM_HAS_ZERO_PADDING(op) ((op)->misc & (1 << 1)) +#define IMM_SET_ZERO_PADDING(op) (op)->misc |= (1 << 1) + +#define IMM_GET_ZERO_PADDING_VALUE(op) ((op)->misc & (1 << 2)) +#define IMM_SET_ZERO_PADDING_VALUE(op, v) (op)->misc = ((op)->misc & ~(1 << 2)) | ((v) ? (1 << 2) : 0) + +#define IMM_HAS_DISPLAY(op) ((op)->misc & (1 << 3)) +#define IMM_SET_DISPLAY(op) (op)->misc |= (1 << 3) + + +/* Définition d'un opérande de valeur numérique (classe) */ +struct _GImmOperandClass +{ + GArchOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des lignes de descriptions initiales. */ +static void g_imm_operand_class_init(GImmOperandClass *); + +/* Initialise la classe des lignes de descriptions initiales. */ +static void g_imm_operand_init(GImmOperand *); + +/* Procède à l'initialisation de l'interface de ciblage. */ +static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface *); + +/* Supprime toutes les références externes. */ +static void g_imm_operand_dispose(GImmOperand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_imm_operand_finalize(GImmOperand *); + +/* Compare un opérande avec un autre. */ +static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *); + +/* Indique si une valeur est complétée par des zéros. */ +static bool g_imm_operand_does_padding_for_display(const GImmOperand *, ImmOperandDisplay); + +/* Construit la chaîne de caractères correspondant à l'opérande. */ +static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]); + +/* Traduit un opérande en version humainement lisible. */ +static void g_imm_operand_print(const GImmOperand *, GBufferLine *); + +/* Construit un petit résumé concis de l'opérande. */ +static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *); + + + +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_imm_operand_unserialize(GImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_imm_operand_serialize(const GImmOperand *, GAsmStorage *, packed_buffer *); + + + +/* ----------------------- INTERFACE DE CIBLAGE POUR OPERANDE ----------------------- */ + + +/* Obtient l'adresse de la cible visée par un opérande. */ +static bool g_imm_operand_get_addr(const GImmOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); + + + +/* Indique le type défini pour un opérande de valeur numérique. */ +G_DEFINE_TYPE_WITH_CODE(GImmOperand, g_imm_operand, G_TYPE_ARCH_OPERAND, + G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_imm_operand_targetable_interface_init)); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des lignes de descriptions initiales. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_imm_operand_class_init(GImmOperandClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GArchOperandClass *operand; /* Version de classe parente */ + + object = G_OBJECT_CLASS(klass); + operand = G_ARCH_OPERAND_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_imm_operand_dispose; + object->finalize = (GObjectFinalizeFunc)g_imm_operand_finalize; + + operand->compare = (operand_compare_fc)g_imm_operand_compare; + operand->print = (operand_print_fc)g_imm_operand_print; + operand->build_tooltip = (operand_build_tooltip_fc)g_imm_operand_build_tooltip; + + operand->unserialize = (unserialize_operand_fc)g_imm_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_imm_operand_serialize; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise la classe des lignes de descriptions initiales. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_imm_operand_init(GImmOperand *operand) +{ + operand->def_display = IOD_HEX; + operand->misc = 0; + + IMM_SET_DEF_ZERO_PADDING(operand, false); + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de ciblage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface *iface) +{ + iface->get_addr = (get_targetable_addr_fc)g_imm_operand_get_addr; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_imm_operand_dispose(GImmOperand *operand) +{ + G_OBJECT_CLASS(g_imm_operand_parent_class)->dispose(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_imm_operand_finalize(GImmOperand *operand) +{ + G_OBJECT_CLASS(g_imm_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : size = taille de l'opérande souhaitée. * +* content = flux de données à analyser. * +* addr = position courante dans ce flux. [OUT] * +* low = position éventuelle des 4 bits visés. [OUT] * +* endian = ordre des bits dans la source. * +* * +* Description : Crée un opérande réprésentant une valeur numérique. * +* * +* Retour : Instruction mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian) +{ + GImmOperand *result; /* Opérande à retourner */ + 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 */ + + result = g_object_new(G_TYPE_IMM_OPERAND, NULL); + + result->size = size; + + switch (size) + { + case MDS_4_BITS_UNSIGNED: + if (!g_binary_content_read_u4(content, addr, low, &uval8)) + goto gionfd_error; + result->raw = uval8; + break; + + case MDS_8_BITS_UNSIGNED: + if (!g_binary_content_read_u8(content, addr, &uval8)) + goto gionfd_error; + result->raw = uval8; + break; + + case MDS_16_BITS_UNSIGNED: + if (!g_binary_content_read_u16(content, addr, endian, &uval16)) + goto gionfd_error; + result->raw = uval16; + break; + + case MDS_32_BITS_UNSIGNED: + if (!g_binary_content_read_u32(content, addr, endian, &uval32)) + goto gionfd_error; + result->raw = uval32; + break; + + case MDS_64_BITS_UNSIGNED: + if (!g_binary_content_read_u64(content, addr, endian, &uval64)) + goto gionfd_error; + result->raw = uval64; + break; + + case MDS_4_BITS_SIGNED: + if (!g_binary_content_read_s4(content, addr, low, &sval8)) + goto gionfd_error; + result->raw = sval8; + break; + + case MDS_8_BITS_SIGNED: + if (!g_binary_content_read_s8(content, addr, &sval8)) + goto gionfd_error; + result->raw = sval8; + break; + + case MDS_16_BITS_SIGNED: + if (!g_binary_content_read_s16(content, addr, endian, &sval16)) + goto gionfd_error; + result->raw = sval16; + break; + + case MDS_32_BITS_SIGNED: + if (!g_binary_content_read_s32(content, addr, endian, &sval32)) + goto gionfd_error; + result->raw = sval32; + break; + + case MDS_64_BITS_SIGNED: + if (!g_binary_content_read_s64(content, addr, endian, &sval64)) + goto gionfd_error; + result->raw = sval64; + break; + + case MDS_UNDEFINED: + goto gionfd_error; + break; + + } + + return G_ARCH_OPERAND(result); + + gionfd_error: + + g_object_unref(G_OBJECT(result)); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : size = taille de l'opérande souhaitée. * +* value = valeur sur x bits à venir récupérer. * +* * +* Description : Crée un opérande réprésentant une valeur numérique. * +* * +* Retour : Instruction mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value) +{ + GImmOperand *result; /* Opérande à retourner */ + + if (size == MDS_UNDEFINED) + result = NULL; + + else + { + result = g_object_new(G_TYPE_IMM_OPERAND, NULL); + + result->size = size; + result->raw = value; + + } + + return (result != NULL ? G_ARCH_OPERAND(result) : NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b) +{ + int result; /* Bilan à retourner */ + + if (a->size < b->size) + { + result = -1; + goto gioc_done; + } + else if (a->size > b->size) + { + result = 1; + goto gioc_done; + } + + if (a->raw < b->raw) + { + result = -1; + goto gioc_done; + } + else if (a->raw > b->raw) + { + result = 1; + goto gioc_done; + } + + if (a->def_display < b->def_display) + { + result = -1; + goto gioc_done; + } + else if (a->def_display > b->def_display) + { + result = 1; + goto gioc_done; + } + + if (IMM_HAS_DISPLAY(a) != IMM_HAS_DISPLAY(b)) + { + result = (IMM_HAS_DISPLAY(a) ? 1 : -1); + goto gioc_done; + } + + if (IMM_HAS_DISPLAY(a)) + { + if (a->display < b->display) + { + result = -1; + goto gioc_done; + } + else if (a->display > b->display) + { + result = 1; + goto gioc_done; + } + } + + if (IMM_GET_DEF_ZERO_PADDING(a) != IMM_GET_DEF_ZERO_PADDING(b)) + { + result = (IMM_GET_DEF_ZERO_PADDING(a) ? 1 : -1); + goto gioc_done; + } + + if (IMM_HAS_ZERO_PADDING(a) != IMM_HAS_ZERO_PADDING(b)) + { + result = (IMM_HAS_ZERO_PADDING(a) ? 1 : -1); + goto gioc_done; + } + + if (IMM_HAS_ZERO_PADDING(a)) + { + if (IMM_GET_ZERO_PADDING_VALUE(a) != IMM_GET_ZERO_PADDING_VALUE(b)) + { + result = (IMM_GET_ZERO_PADDING_VALUE(a) ? 1 : -1); + goto gioc_done; + } + } + + result = 0; + + gioc_done: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* * +* Description : Renseigne la taille de la valeur indiquée à la construction. * +* * +* Retour : Taille de la valeur représentée en mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand) +{ + return operand->size; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* size = taille de l'opérande souhaitée. * +* ... = valeur sur x bits à venir récupérer. * +* * +* Description : Fournit la valeur portée par une opérande numérique. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...) +{ + bool result; /* Bilan à retourner */ + va_list ap; /* Liste des compléments */ + 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 */ + + if (operand->size != size) return false; + + result = true; + + va_start(ap, size); + + switch (size) + { + /* Pour GCC... */ + case MDS_UNDEFINED: + result = false; + break; + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: + uval8 = va_arg(ap, uint8_t *); + *uval8 = operand->raw; + break; + case MDS_16_BITS_UNSIGNED: + uval16 = va_arg(ap, uint16_t *); + *uval16 = operand->raw; + break; + case MDS_32_BITS_UNSIGNED: + uval32 = va_arg(ap, uint32_t *); + *uval32 = operand->raw; + break; + case MDS_64_BITS_UNSIGNED: + uval64 = va_arg(ap, uint64_t *); + *uval64 = operand->raw; + break; + case MDS_4_BITS_SIGNED: + case MDS_8_BITS_SIGNED: + sval8 = va_arg(ap, int8_t *); + *sval8 = operand->raw; + break; + case MDS_16_BITS_SIGNED: + sval16 = va_arg(ap, int16_t *); + *sval16 = operand->raw; + break; + case MDS_32_BITS_SIGNED: + sval32 = va_arg(ap, int32_t *); + *sval32 = operand->raw; + break; + case MDS_64_BITS_SIGNED: + sval64 = va_arg(ap, int64_t *); + *sval64 = operand->raw; + break; + } + + va_end(ap); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Fournit la valeur brute représentée par l'opérande. * +* * +* Retour : Valeur destinée à un usage interne. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand) +{ + return operand->raw; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * +* size = taille de l'opérande souhaitée. * +* value = valeur sur x bits à venir récupérer. * +* * +* Description : Définit la nouvelle valeur de l'opérande à une valeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value) +{ + assert(size != MDS_UNDEFINED); + + operand->size = size; + operand->raw = value; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* * +* Description : Indique si une valeur est complétée par des zéros par défaut.* +* * +* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_get_default_padding(const GImmOperand *operand) +{ + bool result; /* Statut à retourner */ + + result = IMM_GET_DEF_ZERO_PADDING(operand); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * +* state = true si des zéro sont à ajouter, false sinon. * +* * +* Description : Précise si des zéro doivent compléter l'affichage ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_set_default_padding(GImmOperand *operand, bool state) +{ + IMM_SET_DEF_ZERO_PADDING(operand, state); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * +* state = true si des zéro sont à ajouter, false sinon. * +* * +* Description : Précise si des zéro doivent compléter l'affichage ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_pad(GImmOperand *operand, bool state) +{ + IMM_SET_ZERO_PADDING(operand); + IMM_SET_ZERO_PADDING_VALUE(operand, state); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* * +* Description : Indique si une valeur est complétée par des zéros. * +* * +* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_does_padding(const GImmOperand *operand) +{ + bool result; /* Statut à retourner */ + + if (IMM_HAS_ZERO_PADDING(operand)) + result = IMM_GET_ZERO_PADDING_VALUE(operand); + else + result = IMM_GET_DEF_ZERO_PADDING(operand); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* display = type d'affichage à considérer. * +* * +* Description : Indique si une valeur est complétée par des zéros. * +* * +* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_imm_operand_does_padding_for_display(const GImmOperand *operand, ImmOperandDisplay display) +{ + bool result; /* Statut à retourner */ + + result = g_imm_operand_does_padding(operand); + + if (result) + { + display = g_imm_operand_get_display(operand); + + if (display != IOD_BIN && display != IOD_HEX) + result = false; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * +* display = format global d'un affichage de valeur. * +* * +* Description : Définit le format textuel par défaut de la valeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display) +{ + operand->def_display = display; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* * +* Description : Indique le format textuel par défaut de la valeur. * +* * +* Retour : Format global d'un affichage de valeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand) +{ + return operand->def_display; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * +* display = format global d'un affichage de valeur. * +* * +* Description : Définit la grande ligne du format textuel de la valeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display) +{ + IMM_SET_DISPLAY(operand); + operand->display = display; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* * +* Description : Indique la grande ligne du format textuel de la valeur. * +* * +* Retour : Format global d'un affichage de valeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand) +{ + ImmOperandDisplay result; /* Affichage à retourner */ + + if (IMM_HAS_DISPLAY(operand)) + result = operand->display; + else + result = operand->def_display; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* * +* Description : Indique le signe d'une valeur immédiate. * +* * +* Retour : true si la valeur est strictement négative, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_is_negative(const GImmOperand *operand) +{ + bool result; /* Bilan à renvoyer */ + + switch (operand->size) + { + case MDS_4_BITS_SIGNED: + case MDS_8_BITS_SIGNED: + case MDS_16_BITS_SIGNED: + case MDS_32_BITS_SIGNED: + case MDS_64_BITS_SIGNED: + /** + * Pour les valeurs plus petites que 64 bits, le compilateur + * réalise une extension de signe lors du transtypage. + */ + result = (operand->raw & 0x8000000000000000ll); + break; + default: + result = false; + break; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* * +* Description : Indique si une valeur immédiate est nulle ou non. * +* * +* Retour : true si la valeur est nulle, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_is_null(const GImmOperand *operand) +{ + return (operand->raw == 0ll); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* display = type d'affichage demandé. * +* value = valeur portée par l'opérande transcrite. [OUT] * +* * +* Description : Construit la chaîne de caractères correspondant à l'opérande.* +* * +* Retour : Nombre de caractères utilisés. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE]) +{ + size_t result; /* Longueur à retourner */ + unsigned int range; /* Catégorie de la taille */ + const char *prefix; /* Entrée en matière */ + const char *suffix; /* Sortie de matière */ + const char *alternate; /* Préfixe de forme alternative*/ + const char *intro; /* Introduction du formatage */ + bool do_padding; /* Indication de bourrage */ + const char *zpad; /* Remplissage par des zéros */ + const char *lmod; /* Modification de longueur */ + const char *conv; /* Opérateur de conversion */ + char binval[65]; /* Conversion intégrée */ + unsigned int max; /* Indice du plus fort bit */ + unsigned int i; /* Boucle de parcours */ + char format[16 + 65]; /* Format d'impression final */ + + static const char *zpad_defs[] = { "", "02", "04", "08", "016" }; + static const char *lmod_defs[] = { "hh", "hh", "h", "", __PRI64_PREFIX }; + static const char *conv_si_defs[] = { "", "o", "d", "x", "c" }; + static const char *conv_us_defs[] = { "", "o", "u", "x", "c" }; + + assert(display <= IOD_LAST_VALID); + + range = MDS_RANGE(operand->size); + + /* Encadrement pour les caractères */ + if (display == IOD_CHAR) + { + prefix = "'"; + suffix = "'"; + } + else + { + prefix = ""; + suffix = ""; + } + + /* Préfix de forme '0x', 'b' ou '0' */ + switch (display) + { + case IOD_BIN: + alternate = "b"; + break; + case IOD_OCT: + alternate = "0"; + break; + case IOD_HEX: + alternate = "0x"; + break; + default: + alternate = ""; + break; + } + + /* Va-t-on réellement avoir besoin d'un formatage ? */ + if (display != IOD_BIN) + intro = "%"; + else + intro = ""; + + /* Drapeau de remplissage ? */ + + do_padding = g_imm_operand_does_padding_for_display(operand, display); + + switch (display) + { + case IOD_BIN: + case IOD_CHAR: + case IOD_OCT: + case IOD_DEC: + zpad = ""; + break; + default: + zpad = (do_padding ? zpad_defs[range] : ""); + break; + } + + /* Modification de la longueur fournie */ + + if (display != IOD_BIN) + lmod = lmod_defs[range]; + else + lmod = ""; + + /* Spécification de la conversion */ + + if (display != IOD_BIN) + { + if (MDS_IS_SIGNED(operand->size)) + conv = conv_si_defs[display]; + else + conv = conv_us_defs[display]; + + } + else + { + if (do_padding) + max = range * 8; + + else + { + if (!msb_64(operand->raw, &max)) + { + conv = "0"; + max = 0; + } + } + + if (max > 0) + { + conv = binval; + + for (i = max; i > 0; i--) + binval[max - i] = (operand->raw & (1llu << (i - 1)) ? '1' : '0'); + + binval[max] = '\0'; + + } + + } + + /* Impression finale */ + + snprintf(format, sizeof(format), "%s%s%s%s%s%s%s", prefix, alternate, intro, zpad, lmod, conv, suffix); + + switch (operand->size) + { + case MDS_UNDEFINED: + result = snprintf(value, IMM_MAX_SIZE, ""); + break; + + case MDS_4_BITS_UNSIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (uint8_t)operand->raw); + break; + + case MDS_8_BITS_UNSIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (uint8_t)operand->raw); + break; + + case MDS_16_BITS_UNSIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (uint16_t)operand->raw); + break; + + case MDS_32_BITS_UNSIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (uint32_t)operand->raw); + break; + + case MDS_64_BITS_UNSIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (uint64_t)operand->raw); + break; + + case MDS_4_BITS_SIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (int8_t)operand->raw); + break; + + case MDS_8_BITS_SIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (int8_t)operand->raw); + break; + + case MDS_16_BITS_SIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (int16_t)operand->raw); + break; + + case MDS_32_BITS_SIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (int32_t)operand->raw); + break; + + case MDS_64_BITS_SIGNED: + result = snprintf(value, IMM_MAX_SIZE, format, (int64_t)operand->raw); + break; + + default: + assert(false); + result = 0; + break; + + } + + assert(result > 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* syntax = type de représentation demandée. * +* value = valeur portée par l'opérande transcrite. [OUT] * +* * +* Description : Construit la chaîne de caractères correspondant à l'opérande.* +* * +* Retour : Nombre de caractères utilisés. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_imm_operand_to_string(const GImmOperand *operand, char value[IMM_MAX_SIZE]) +{ + size_t result; /* Longueur à retourner */ + ImmOperandDisplay display; /* Type d'affichage courant */ + + display = g_imm_operand_get_display(operand); + + result = _g_imm_operand_to_string(operand, display, value); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_imm_operand_print(const GImmOperand *operand, GBufferLine *line) +{ + char value[IMM_MAX_SIZE]; /* Chaîne à imprimer */ + size_t len; /* Taille de l'élément inséré */ + + len = g_imm_operand_to_string(operand, value); + + g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_IMMEDIATE, G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* binary = informations relatives au binaire chargé. * +* * +* Description : Construit un petit résumé concis de l'opérande. * +* * +* Retour : Chaîne de caractères à libérer après usage ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary) +{ + char *result; /* Description à retourner */ + char value[IMM_MAX_SIZE]; /* Conversion artificielle */ + char *conv; /* Affichage de la Conversion */ + + if (operand->raw <= UCHAR_MAX && isprint(operand->raw)) + switch (operand->raw) + { + case '&': + asprintf(&result, _("Character: '&'")); + break; + case '<': + asprintf(&result, _("Character: '<'")); + break; + case '>': + asprintf(&result, _("Character: '>'")); + break; + default: + asprintf(&result, _("Character: '%c'"), (char)operand->raw); + break; + } + + else + asprintf(&result, _("Character: <not printable>")); + + /* Binaire */ + + _g_imm_operand_to_string(operand, IOD_BIN, value); + + asprintf(&conv, _("Binary: %s"), value); + + result = stradd(result, "\n"); + result = stradd(result, conv); + + free(conv); + + /* Octal */ + + _g_imm_operand_to_string(operand, IOD_OCT, value); + + asprintf(&conv, _("Octal: %s"), value); + + result = stradd(result, "\n"); + result = stradd(result, conv); + + free(conv); + + /* Décimal */ + + _g_imm_operand_to_string(operand, IOD_DEC, value); + + asprintf(&conv, _("Decimal: %s"), value); + + result = stradd(result, "\n"); + result = stradd(result, conv); + + free(conv); + + /* Hexadécimal */ + + _g_imm_operand_to_string(operand, IOD_HEX, value); + + asprintf(&conv, _("Hexadecimal: %s"), value); + + result = stradd(result, "\n"); + result = stradd(result, conv); + + free(conv); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* pos = valeur résultante. [OUT] * +* * +* Description : Convertit une valeur immédiate en position de type phys_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos) +{ + bool result; /* Bilan à renvoyer */ + + result = !MDS_IS_SIGNED(operand->size); + + if (result) + *pos = operand->raw; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* addr = valeur résultante. [OUT] * +* * +* Description : Convertit une valeur immédiate en adresse de type virt_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr) +{ + bool result; /* Bilan à renvoyer */ + + result = !MDS_IS_SIGNED(operand->size); + + if (result) + *addr = operand->raw; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* val = valeur résultante. [OUT] * +* * +* Description : Convertit une valeur immédiate en valeur de type leb128_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val) +{ + *val = operand->raw; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* val = valeur résultante. [OUT] * +* * +* Description : Convertit une valeur immédiate en valeur de type uleb128_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val) +{ + *val = operand->raw; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* addr = valeur résultante. [OUT] * +* * +* Description : Convertit une valeur immédiate en adresse de type vmpa_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr) +{ + return false; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* value = valeur résultante. [OUT] * +* negative = indique si la valeur était négative à l'origine. * +* * +* Description : Convertit une valeur immédiate en valeur de type size_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_to_size_t(const GImmOperand *operand, size_t *value, bool *negative) +{ + return false; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* value = valeur résultante. [OUT] * +* negative = indique si la valeur était négative à l'origine. * +* * +* Description : Convertit une valeur immédiate en valeur de type off_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_to_off_t(const GImmOperand *operand, off_t *value, bool *negative) +{ + return false; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : operand = opérande d'assemblage à constituer. * +* storage = mécanisme de sauvegarde à manipuler. * +* format = format binaire chargé associé à l'architecture. * +* pbuf = zone tampon à remplir. * +* * +* Description : Charge un opérande depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); + + if (result) + result = extract_packed_buffer(pbuf, &operand->size, sizeof(MemoryDataSize), true); + + if (result) + result = extract_packed_buffer(pbuf, &operand->def_display, sizeof(ImmOperandDisplay), true); + + if (result) + result = extract_packed_buffer(pbuf, &operand->display, sizeof(ImmOperandDisplay), true); + + if (result) + result = extract_packed_buffer(pbuf, &operand->misc, sizeof(uint8_t), false); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un opérande dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); + + if (result) + result = extend_packed_buffer(pbuf, &operand->size, sizeof(MemoryDataSize), true); + + if (result) + result = extend_packed_buffer(pbuf, &operand->def_display, sizeof(ImmOperandDisplay), true); + + if (result) + result = extend_packed_buffer(pbuf, &operand->display, sizeof(ImmOperandDisplay), true); + + if (result) + result = extend_packed_buffer(pbuf, &operand->misc, sizeof(uint8_t), false); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERFACE DE CIBLAGE POUR OPERANDE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : operand = operande à consulter. * +* src = localisation de l'instruction mère. * +* format = format reconnu pour le binaire chargé. * +* proc = architecture associée à ce même binaire. * +* addr = localisation de la cible. [OUT] * +* * +* Description : Obtient l'adresse de la cible visée par un opérande. * +* * +* Retour : true si la cible est valide, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_imm_operand_get_addr(const GImmOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + virt_t virt; /* Adresse virtuelle */ + + result = g_imm_operand_to_virt_t(operand, &virt); + + if (result) + result = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, addr); + + return result; + +} diff --git a/src/arch/operands/immediate.h b/src/arch/operands/immediate.h new file mode 100644 index 0000000..4d9a77e --- /dev/null +++ b/src/arch/operands/immediate.h @@ -0,0 +1,157 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * immediate.h - prototypes pour les opérandes représentant des valeurs numériques + * + * Copyright (C) 2009-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 Chrysalide. If not, see . + */ + + +#ifndef _ARCH_OPERANDS_IMMEDIATE_H +#define _ARCH_OPERANDS_IMMEDIATE_H + + +#include +#include +#include + + +#include "../archbase.h" +#include "../operand.h" +#include "../../analysis/content.h" + + + +/* Grande ligne d'un format d'affichage */ +typedef enum _ImmOperandDisplay +{ + IOD_BIN, /* Impression en binaire */ + IOD_OCT, /* Impression en octal */ + IOD_DEC, /* Impression en décimal */ + IOD_HEX, /* Impression en hexadécimal */ + IOD_CHAR, /* Impression en base 26 */ + + IOD_COUNT + +} ImmOperandDisplay; + + +#define IOD_LAST_VALID IOD_CHAR + + +#define G_TYPE_IMM_OPERAND g_imm_operand_get_type() +#define G_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_IMM_OPERAND, GImmOperand)) +#define G_IS_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_IMM_OPERAND)) +#define G_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_IMM_OPERAND, GImmOperandClass)) +#define G_IS_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_IMM_OPERAND)) +#define G_IMM_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_IMM_OPERAND, GImmOperandClass)) + + +/* Définition d'un opérande de valeur numérique (instance) */ +typedef struct _GImmOperand GImmOperand; + +/* Définition d'un opérande de valeur numérique (classe) */ +typedef struct _GImmOperandClass GImmOperandClass; + + +/* Indique le type défini pour un opérande d'architecture. */ +GType g_imm_operand_get_type(void); + +/* Crée un opérande réprésentant une valeur numérique. */ +GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const GBinContent *, vmpa2t *, bool *, SourceEndian); + +#define g_imm_operand_new_from_data(size, content, addr, endian) \ + _g_imm_operand_new_from_data(size, content, addr, NULL, endian) + +/* Crée un opérande réprésentant une valeur numérique. */ +GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, uint64_t); + +/* Renseigne la taille de la valeur indiquée à la construction. */ +MemoryDataSize g_imm_operand_get_size(const GImmOperand *); + +/* Fournit la valeur portée par une opérande numérique. */ +bool g_imm_operand_get_value(const GImmOperand *, MemoryDataSize, ...); + +/* Fournit la valeur brute représentée par l'opérande. */ +uint64_t g_imm_operand_get_raw_value(const GImmOperand *); + +/* Définit la nouvelle valeur de l'opérande à une valeur. */ +void g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t); + +/* Indique si une valeur est complétée par des zéros par défaut. */ +bool g_imm_operand_get_default_padding(const GImmOperand *); + +/* Précise si des zéro doivent compléter l'affichage ou non. */ +void g_imm_operand_set_default_padding(GImmOperand *, bool); + +/* Précise si des zéro doivent compléter l'affichage ou non. */ +void g_imm_operand_pad(GImmOperand *, bool); + +/* Indique si une valeur est complétée par des zéros. */ +bool g_imm_operand_does_padding(const GImmOperand *); + +/* Définit le format textuel par défaut de la valeur. */ +void g_imm_operand_set_default_display(GImmOperand *, ImmOperandDisplay); + +/* Indique le format textuel par défaut de la valeur. */ +ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *); + +/* Définit la grande ligne du format textuel de la valeur. */ +void g_imm_operand_set_display(GImmOperand *, ImmOperandDisplay); + +/* Indique la grande ligne du format textuel de la valeur. */ +ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *); + +/* Indique le signe d'une valeur immédiate. */ +bool g_imm_operand_is_negative(const GImmOperand *); + +/* Indique si une valeur immédiate est nulle ou non. */ +bool g_imm_operand_is_null(const GImmOperand *); + +/** + * La taille d'impression d'un opérande n'est pas VMPA_MAX_SIZE, + * mais 1 + 64 caractères + octet nul final en cas d'impression en binaire. + */ +#define IMM_MAX_SIZE 66 + +/* Construit la chaîne de caractères correspondant à l'opérande. */ +size_t g_imm_operand_to_string(const GImmOperand *, char [IMM_MAX_SIZE]); + +/* Convertit une valeur immédiate en position de type phys_t. */ +bool g_imm_operand_to_phys_t(const GImmOperand *, phys_t *); + +/* Convertit une valeur immédiate en adresse de type virt_t. */ +bool g_imm_operand_to_virt_t(const GImmOperand *, virt_t *); + +/* Convertit une valeur immédiate en valeur de type leb128_t. */ +void g_imm_operand_as_leb128(const GImmOperand *, leb128_t *); + +/* Convertit une valeur immédiate en valeur de type uleb128_t. */ +void g_imm_operand_as_uleb128(const GImmOperand *, uleb128_t *); + +/* Convertit une valeur immédiate en adresse de type vmpa_t. */ +bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *) __attribute__ ((deprecated)); + +/* Convertit une valeur immédiate en valeur de type size_t. */ +bool g_imm_operand_to_size_t(const GImmOperand *, size_t *, bool *) __attribute__ ((deprecated)); + +/* Convertit une valeur immédiate en valeur de type off_t. */ +bool g_imm_operand_to_off_t(const GImmOperand *, off_t *, bool *) __attribute__ ((deprecated)); + + + +#endif /* _ARCH_OPERANDS_IMMEDIATE_H */ diff --git a/src/arch/operands/targetable-int.h b/src/arch/operands/targetable-int.h new file mode 100644 index 0000000..2aec35d --- /dev/null +++ b/src/arch/operands/targetable-int.h @@ -0,0 +1,51 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * targetable-int.h - définitions internes propres aux opérandes ciblant une portion de désassemblage + * + * 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 Chrysalide. If not, see . + */ + + +#ifndef _ARCH_OPERANDS_TARGETABLE_INT_H +#define _ARCH_OPERANDS_TARGETABLE_INT_H + + +#include "targetable.h" + + + +/* Obtient l'adresse de la cible visée par un opérande. */ +typedef bool (* get_targetable_addr_fc) (const GTargetableOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); + + +/* Opérande ciblant une portion de désassemblage (interface) */ +struct _GTargetableOperandIface +{ + GTypeInterface base_iface; /* A laisser en premier */ + + get_targetable_addr_fc get_addr; /* Obtention de la cible */ + +}; + + +/* Redéfinition */ +typedef GTargetableOperandIface GTargetableOperandInterface; + + + +#endif /* _ARCH_OPERANDS_TARGETABLE_INT_H */ diff --git a/src/arch/operands/targetable.c b/src/arch/operands/targetable.c new file mode 100644 index 0000000..2491e11 --- /dev/null +++ b/src/arch/operands/targetable.c @@ -0,0 +1,85 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * targetable.c - opérandes ciblant une portion de désassemblage + * + * 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 Chrysalide. If not, see . + */ + + +#include "targetable.h" + + +#include "targetable-int.h" + + + +/* Procède à l'initialisation de l'interface de ciblage. */ +static void g_targetable_operand_default_init(GTargetableOperandInterface *); + + + +/* Détermine le type d'une interface pour le ciblage d'une portion de désassemblage. */ +G_DEFINE_INTERFACE(GTargetableOperand, g_targetable_operand, G_TYPE_OBJECT) + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de ciblage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_targetable_operand_default_init(GTargetableOperandInterface *iface) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = operande à consulter. * +* src = localisation de l'instruction mère. * +* format = format reconnu pour le binaire chargé. * +* proc = architecture associée à ce même binaire. * +* addr = localisation de la cible. [OUT] * +* * +* Description : Obtient l'adresse de la cible visée par un opérande. * +* * +* Retour : true si la cible est valide, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_targetable_operand_get_addr(const GTargetableOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + GTargetableOperandIface *iface; /* Interface utilisée */ + + iface = G_TARGETABLE_OPERAND_GET_IFACE(operand); + + result = iface->get_addr(operand, src, format, proc, addr); + + return result; + +} diff --git a/src/arch/operands/targetable.h b/src/arch/operands/targetable.h new file mode 100644 index 0000000..a0f30a4 --- /dev/null +++ b/src/arch/operands/targetable.h @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * targetable.h - prototypes pour les opérandes ciblant une portion de désassemblage + * + * 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 Chrysalide. If not, see . + */ + + +#ifndef _ARCH_OPERANDS_TARGETABLE_H +#define _ARCH_OPERANDS_TARGETABLE_H + + +#include +#include + + +#include "../vmpa.h" +#include "../processor.h" +#include "../../format/format.h" + + + +#define G_TYPE_TARGETABLE_OPERAND (g_targetable_operand_get_type()) +#define G_TARGETABLE_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TARGETABLE_OPERAND, GTargetableOperand)) +#define G_TARGETABLE_OPERAND_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_TARGETABLE_OPERAND, GTargetableOperandIface)) +#define G_IS_TARGETABLE_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TARGETABLE_OPERAND)) +#define G_IS_TARGETABLE_OPERAND_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_TARGETABLE_OPERAND)) +#define G_TARGETABLE_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_TARGETABLE_OPERAND, GTargetableOperandIface)) + + +/* Opérande ciblant une portion de désassemblage (coquille vide) */ +typedef struct _GTargetableOperand GTargetableOperand; + +/* Opérande ciblant une portion de désassemblage (interface) */ +typedef struct _GTargetableOperandIface GTargetableOperandIface; + + +/* Détermine le type d'une interface pour le ciblage d'une portion de désassemblage. */ +GType g_targetable_operand_get_type(void) G_GNUC_CONST; + +/* Obtient l'adresse de la cible visée par un opérande. */ +bool g_targetable_operand_get_addr(const GTargetableOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); + + + +#endif /* _ARCH_OPERANDS_TARGETABLE_H */ diff --git a/src/arch/post.c b/src/arch/post.c index de07499..d6ada4c 100644 --- a/src/arch/post.c +++ b/src/arch/post.c @@ -29,6 +29,7 @@ #include "processor.h" #include "target.h" +#include "operands/immediate.h" #include "../analysis/routine.h" diff --git a/src/arch/raw.c b/src/arch/raw.c index 17f1ea6..9d597fa 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -32,9 +32,9 @@ #include -#include "immediate.h" #include "instruction-int.h" #include "target.h" +#include "operands/immediate.h" diff --git a/src/arch/target.c b/src/arch/target.c index a8acd67..1a708d0 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -33,7 +33,8 @@ #include "operand-int.h" -#include "targetableop-int.h" +#include "operands/immediate.h" +#include "operands/targetable-int.h" #include "../analysis/routine.h" #include "../common/extstr.h" #include "../format/format.h" diff --git a/src/arch/targetableop-int.h b/src/arch/targetableop-int.h deleted file mode 100644 index 9afce11..0000000 --- a/src/arch/targetableop-int.h +++ /dev/null @@ -1,51 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * targetableop-int.h - définitions internes propres aux opérandes ciblant une portion de désassemblage - * - * 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 Chrysalide. If not, see . - */ - - -#ifndef _GLIBEXT_TARGETABLEOP_INT_H -#define _GLIBEXT_TARGETABLEOP_INT_H - - -#include "targetableop.h" - - - -/* Obtient l'adresse de la cible visée par un opérande. */ -typedef bool (* get_targetable_addr_fc) (const GTargetableOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); - - -/* Opérande ciblant une portion de désassemblage (interface) */ -struct _GTargetableOperandIface -{ - GTypeInterface base_iface; /* A laisser en premier */ - - get_targetable_addr_fc get_addr; /* Obtention de la cible */ - -}; - - -/* Redéfinition */ -typedef GTargetableOperandIface GTargetableOperandInterface; - - - -#endif /* _GLIBEXT_TARGETABLEOP_INT_H */ diff --git a/src/arch/targetableop.c b/src/arch/targetableop.c deleted file mode 100644 index eab26a8..0000000 --- a/src/arch/targetableop.c +++ /dev/null @@ -1,85 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * targetableop.c - opérandes ciblant une portion de désassemblage - * - * 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 Chrysalide. If not, see . - */ - - -#include "targetableop.h" - - -#include "targetableop-int.h" - - - -/* Procède à l'initialisation de l'interface de ciblage. */ -static void g_targetable_operand_default_init(GTargetableOperandInterface *); - - - -/* Détermine le type d'une interface pour le ciblage d'une portion de désassemblage. */ -G_DEFINE_INTERFACE(GTargetableOperand, g_targetable_operand, G_TYPE_OBJECT) - - -/****************************************************************************** -* * -* Paramètres : iface = interface GLib à initialiser. * -* * -* Description : Procède à l'initialisation de l'interface de ciblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_targetable_operand_default_init(GTargetableOperandInterface *iface) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : operand = operande à consulter. * -* src = localisation de l'instruction mère. * -* format = format reconnu pour le binaire chargé. * -* proc = architecture associée à ce même binaire. * -* addr = localisation de la cible. [OUT] * -* * -* Description : Obtient l'adresse de la cible visée par un opérande. * -* * -* Retour : true si la cible est valide, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_targetable_operand_get_addr(const GTargetableOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) -{ - bool result; /* Bilan à retourner */ - GTargetableOperandIface *iface; /* Interface utilisée */ - - iface = G_TARGETABLE_OPERAND_GET_IFACE(operand); - - result = iface->get_addr(operand, src, format, proc, addr); - - return result; - -} diff --git a/src/arch/targetableop.h b/src/arch/targetableop.h deleted file mode 100644 index f6cc7bf..0000000 --- a/src/arch/targetableop.h +++ /dev/null @@ -1,61 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * targetableop.h - prototypes pour les opérandes ciblant une portion de désassemblage - * - * 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 Chrysalide. If not, see . - */ - - -#ifndef _GLIBEXT_TARGETABLEOP_H -#define _GLIBEXT_TARGETABLEOP_H - - -#include -#include - - -#include "vmpa.h" -#include "../arch/processor.h" -#include "../format/format.h" - - - -#define G_TYPE_TARGETABLE_OPERAND (g_targetable_operand_get_type()) -#define G_TARGETABLE_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TARGETABLE_OPERAND, GTargetableOperand)) -#define G_TARGETABLE_OPERAND_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_TARGETABLE_OPERAND, GTargetableOperandIface)) -#define G_IS_TARGETABLE_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TARGETABLE_OPERAND)) -#define G_IS_TARGETABLE_OPERAND_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_TARGETABLE_OPERAND)) -#define G_TARGETABLE_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_TARGETABLE_OPERAND, GTargetableOperandIface)) - - -/* Opérande ciblant une portion de désassemblage (coquille vide) */ -typedef struct _GTargetableOperand GTargetableOperand; - -/* Opérande ciblant une portion de désassemblage (interface) */ -typedef struct _GTargetableOperandIface GTargetableOperandIface; - - -/* Détermine le type d'une interface pour le ciblage d'une portion de désassemblage. */ -GType g_targetable_operand_get_type(void) G_GNUC_CONST; - -/* Obtient l'adresse de la cible visée par un opérande. */ -bool g_targetable_operand_get_addr(const GTargetableOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); - - - -#endif /* _GLIBEXT_TARGETABLEOP_H */ diff --git a/src/core/processors.c b/src/core/processors.c index 42d4e4b..1255129 100644 --- a/src/core/processors.c +++ b/src/core/processors.c @@ -29,10 +29,10 @@ #include -#include "../arch/immediate.h" #include "../arch/raw.h" #include "../arch/target.h" #include "../arch/undefined.h" +#include "../arch/operands/immediate.h" #include "../arch/operands/register.h" diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c index e1ef696..f3f1fb2 100644 --- a/src/gui/menus/edition.c +++ b/src/gui/menus/edition.c @@ -38,7 +38,7 @@ #include "../dialogs/gotox.h" #include "../../analysis/binary.h" #include "../../analysis/db/items/switcher.h" -#include "../../arch/targetableop.h" +#include "../../arch/operands/targetable.h" #include "../../glibext/gbinarycursor.h" #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkblockdisplay.h" -- cgit v0.11.2-87-g4458