diff options
Diffstat (limited to 'src/arch/operands')
-rw-r--r-- | src/arch/operands/Makefile.am | 5 | ||||
-rw-r--r-- | src/arch/operands/immediate.c | 1533 | ||||
-rw-r--r-- | src/arch/operands/immediate.h | 157 | ||||
-rw-r--r-- | src/arch/operands/targetable-int.h | 51 | ||||
-rw-r--r-- | src/arch/operands/targetable.c | 85 | ||||
-rw-r--r-- | src/arch/operands/targetable.h | 61 |
6 files changed, 1891 insertions, 1 deletions
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 <http://www.gnu.org/licenses/>. + */ + + +#include "immediate.h" + + +#include <assert.h> +#include <ctype.h> +#include <inttypes.h> +#include <limits.h> +#include <malloc.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + + +#include <i18n.h> + + +#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, "<? undef value ?>"); + 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_IMMEDIATE_H +#define _ARCH_OPERANDS_IMMEDIATE_H + + +#include <glib-object.h> +#include <stdbool.h> +#include <stdint.h> + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_TARGETABLE_H +#define _ARCH_OPERANDS_TARGETABLE_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#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 */ |