diff options
Diffstat (limited to 'plugins')
39 files changed, 2072 insertions, 166 deletions
diff --git a/plugins/arm/core.c b/plugins/arm/core.c index 43e82e4..6a512b2 100644 --- a/plugins/arm/core.c +++ b/plugins/arm/core.c @@ -62,6 +62,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) } + /****************************************************************************** * * * Paramètres : plugin = greffon à manipuler. * diff --git a/plugins/arm/instruction-int.h b/plugins/arm/instruction-int.h index 2b559a9..ffa10ee 100644 --- a/plugins/arm/instruction-int.h +++ b/plugins/arm/instruction-int.h @@ -37,7 +37,6 @@ struct _GArmInstruction { GArchInstruction parent; /* A laisser en premier */ - const char *keyword; /* Nom clef de l'instruction */ char *suffix; /* Complément au nom affiché */ char *cached_keyword; /* Désignation complète */ diff --git a/plugins/arm/instruction.c b/plugins/arm/instruction.c index 9af8045..a717055 100644 --- a/plugins/arm/instruction.c +++ b/plugins/arm/instruction.c @@ -30,6 +30,7 @@ #include <common/extstr.h> +#include <core/logs.h> #include "instruction-int.h" @@ -50,6 +51,17 @@ static void g_arm_instruction_finalize(GArmInstruction *); +/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ + + +/* Charge une instruction depuis une mémoire tampon. */ +static bool g_arm_instruction_unserialize(GArmInstruction *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde une instruction dans une mémoire tampon. */ +static bool g_arm_instruction_serialize(GArmInstruction *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini pour une représentation d'une instruction ARM. */ G_DEFINE_TYPE(GArmInstruction, g_arm_instruction, G_TYPE_ARCH_INSTRUCTION); @@ -69,12 +81,18 @@ G_DEFINE_TYPE(GArmInstruction, g_arm_instruction, G_TYPE_ARCH_INSTRUCTION); static void g_arm_instruction_class_init(GArmInstructionClass *klass) { GObjectClass *object_class; /* Autre version de la classe */ + GArchInstructionClass *instr; /* Encore une autre vision... */ object_class = G_OBJECT_CLASS(klass); object_class->dispose = (GObjectFinalizeFunc/* ! */)g_arm_instruction_dispose; object_class->finalize = (GObjectFinalizeFunc)g_arm_instruction_finalize; + instr = G_ARCH_INSTRUCTION_CLASS(klass); + + instr->unserialize = (unserialize_instruction_fc)g_arm_instruction_unserialize; + instr->serialize = (serialize_instruction_fc)g_arm_instruction_serialize; + } @@ -92,6 +110,9 @@ static void g_arm_instruction_class_init(GArmInstructionClass *klass) static void g_arm_instruction_init(GArmInstruction *instr) { + instr->suffix = NULL; + instr->cached_keyword = NULL; + instr->cond = ACC_AL; } @@ -243,3 +264,121 @@ ArmCondCode g_arm_instruction_get_cond(const GArmInstruction *instr) return instr->cond; } + + + +/* ---------------------------------------------------------------------------------- */ +/* CONSERVATION SUR DISQUE DES INSTRUCTIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* format = format binaire chargé associé à l'architecture. * +* pbuf = zone tampon à remplir. * +* * +* Description : Charge une instruction depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arm_instruction_unserialize(GArmInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchInstructionClass *parent; /* Classe parente à consulter */ + unsigned char len; /* Taille de textes */ + char *text; /* Texte reconstitué */ + + parent = G_ARCH_INSTRUCTION_CLASS(g_arm_instruction_parent_class); + + result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf); + + if (result) + { + result = extract_packed_buffer(pbuf, &len, sizeof(unsigned char), false); + + if (result && len > 0) + { + text = (char *)malloc(len); + + if (result) + result = extract_packed_buffer(pbuf, text, len, false); + + if (result) + result = g_arm_instruction_extend_keyword(instr, text); + + free(text); + + } + + } + + if (result) + result = extract_packed_buffer(pbuf, &instr->cond, sizeof(ArmCondCode), true); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde une instruction dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arm_instruction_serialize(GArmInstruction *instr, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchInstructionClass *parent; /* Classe parente à consulter */ + size_t len; /* Taille de textes */ + + parent = G_ARCH_INSTRUCTION_CLASS(g_arm_instruction_parent_class); + + result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf); + + if (result) + { + if (instr->suffix == NULL) + result = extend_packed_buffer(pbuf, (unsigned char []) { 0 }, sizeof(unsigned char), false); + + else + { + len = strlen(instr->suffix) + 1; + assert(len > 1); + + if (len > (2 << (sizeof(unsigned char) * 8 - 1))) + { + log_variadic_message(LMT_ERROR, "ARM suffix too long: '%s' (%zu bytes)", instr->suffix, len); + result = false; + } + + else + result = extend_packed_buffer(pbuf, (unsigned char []) { len }, sizeof(unsigned char), false); + + if (result) + result = extend_packed_buffer(pbuf, instr->suffix, len, false); + + } + + } + + if (result) + result = extend_packed_buffer(pbuf, &instr->cond, sizeof(ArmCondCode), true); + + return result; + +} diff --git a/plugins/arm/v7/core.c b/plugins/arm/v7/core.c index 4de61a2..9b4d3f3 100644 --- a/plugins/arm/v7/core.c +++ b/plugins/arm/v7/core.c @@ -25,10 +25,56 @@ #include <core/processors.h> + + #include "cregister.h" +#include "instruction.h" #include "processor.h" #include "register.h" +#include "operands/coproc.h" +#include "operands/estate.h" +#include "operands/limitation.h" +#include "operands/maccess.h" +#include "operands/offset.h" +#include "operands/register.h" +#include "operands/reglist.h" +#include "operands/rotation.h" +#include "operands/shift.h" + + + +/* Assure l'enregistrement de types pour les caches à charger. */ +static void register_armv7_gtypes(void); + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Assure l'enregistrement de types pour les caches à charger. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void register_armv7_gtypes(void) +{ + g_type_ensure(G_TYPE_ARMV7_INSTRUCTION); + + g_type_ensure(G_TYPE_ARMV7_COPROC_OPERAND); + g_type_ensure(G_TYPE_ARMV7_ENDIAN_OPERAND); + g_type_ensure(G_TYPE_ARMV7_LIMITATION_OPERAND); + g_type_ensure(G_TYPE_ARMV7_MACCESS_OPERAND); + g_type_ensure(G_TYPE_ARMV7_OFFSET_OPERAND); + g_type_ensure(G_TYPE_ARMV7_REGISTER_OPERAND); + g_type_ensure(G_TYPE_ARMV7_REGLIST_OPERAND); + g_type_ensure(G_TYPE_ARMV7_ROTATION_OPERAND); + g_type_ensure(G_TYPE_ARMV7_SHIFT_OPERAND); + +} /****************************************************************************** @@ -47,6 +93,8 @@ bool init_armv7_core(void) { bool result; /* Bilan à renvoyer */ + register_armv7_gtypes(); + result = register_processor_type("armv7", "ARM v7", G_TYPE_ARMV7_PROCESSOR); return result; diff --git a/plugins/arm/v7/helpers.h b/plugins/arm/v7/helpers.h index cb32785..ae759b8 100644 --- a/plugins/arm/v7/helpers.h +++ b/plugins/arm/v7/helpers.h @@ -26,7 +26,6 @@ #include <arch/immediate.h> -#include <arch/register.h> #include "pseudo.h" @@ -34,6 +33,7 @@ #include "operands/coproc.h" #include "operands/estate.h" #include "operands/maccess.h" +#include "operands/register.h" #include "operands/reglist.h" #include "operands/rotation.h" #include "operands/shift.h" @@ -212,7 +212,7 @@ if (__reg == NULL) \ __result = NULL; \ else \ - __result = g_register_operand_new(G_ARCH_REGISTER(__reg)); \ + __result = g_armv7_register_operand_new(__reg); \ __result; \ }) @@ -245,7 +245,7 @@ if (__reg == NULL) \ __result = NULL; \ else \ - __result = g_register_operand_new(G_ARCH_REGISTER(__reg)); \ + __result = g_armv7_register_operand_new(__reg); \ __result; \ }) @@ -383,7 +383,7 @@ if (__reg == NULL) \ __result = NULL; \ else \ - __result = g_register_operand_new(G_ARCH_REGISTER(__reg)); \ + __result = g_armv7_register_operand_new(__reg); \ __result; \ #endif diff --git a/plugins/arm/v7/instruction.c b/plugins/arm/v7/instruction.c index d45979b..9eb43ac 100644 --- a/plugins/arm/v7/instruction.c +++ b/plugins/arm/v7/instruction.c @@ -86,6 +86,17 @@ static char *g_armv7_instruction_build_tooltip(const GArmV7Instruction *); +/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ + + +/* Charge une instruction depuis une mémoire tampon. */ +static bool g_armv7_instruction_unserialize(GArmV7Instruction *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde une instruction dans une mémoire tampon. */ +static bool g_armv7_instruction_serialize(GArmV7Instruction *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini pour une représentation d'une instruction ARMv7. */ G_DEFINE_TYPE(GArmV7Instruction, g_armv7_instruction, G_TYPE_ARM_INSTRUCTION); @@ -118,6 +129,9 @@ static void g_armv7_instruction_class_init(GArmV7InstructionClass *klass) instr->call_hook = (call_instruction_hook_fc)g_armv7_instruction_call_hook; instr->build_tooltip = (build_instruction_tooltip_fc)g_armv7_instruction_build_tooltip; + instr->unserialize = (unserialize_instruction_fc)g_armv7_instruction_unserialize; + instr->serialize = (serialize_instruction_fc)g_armv7_instruction_serialize; + } @@ -397,3 +411,95 @@ bool g_armv7_instruction_get_setflags(const GArmV7Instruction *instr) return instr->setflags; } + + + +/* ---------------------------------------------------------------------------------- */ +/* CONSERVATION SUR DISQUE DES INSTRUCTIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* format = format binaire chargé associé à l'architecture. * +* pbuf = zone tampon à remplir. * +* * +* Description : Charge une instruction depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_armv7_instruction_unserialize(GArmV7Instruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchInstructionClass *parent; /* Classe parente à consulter */ + uint8_t boolean; /* Valeur booléenne */ + + parent = G_ARCH_INSTRUCTION_CLASS(g_armv7_instruction_parent_class); + + result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf); + + if (result) + result = extract_packed_buffer(pbuf, &instr->sid, sizeof(ARMv7Syntax), true); + + if (result) + result = extract_packed_buffer(pbuf, &instr->encoding, sizeof(char), false); + + if (result) + { + result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + + if (result) + instr->setflags = (boolean == 1 ? true : false); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde une instruction dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_armv7_instruction_serialize(GArmV7Instruction *instr, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchInstructionClass *parent; /* Classe parente à consulter */ + uint8_t boolean; /* Valeur booléenne */ + + parent = G_ARCH_INSTRUCTION_CLASS(g_armv7_instruction_parent_class); + + result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &instr->sid, sizeof(ARMv7Syntax), true); + + if (result) + result = extend_packed_buffer(pbuf, &instr->encoding, sizeof(char), false); + + if (result) + { + boolean = (instr->setflags ? 1 : 0); + result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + } + + return result; + +} diff --git a/plugins/arm/v7/instruction.h b/plugins/arm/v7/instruction.h index c75b71d..4315d9f 100644 --- a/plugins/arm/v7/instruction.h +++ b/plugins/arm/v7/instruction.h @@ -37,12 +37,12 @@ -#define G_TYPE_ARMV7_INSTRUCTION g_armv7_instruction_get_type() -#define G_ARMV7_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_instruction_get_type(), GArmV7Instruction)) -#define G_IS_ARMV7_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_instruction_get_type())) -#define G_ARMV7_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_INSTRUCTION, GArmV7InstructionClass)) -#define G_IS_ARMV7_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_INSTRUCTION)) -#define G_ARMV7_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_INSTRUCTION, GArmV7InstructionClass)) +#define G_TYPE_ARMV7_INSTRUCTION g_armv7_instruction_get_type() +#define G_ARMV7_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_INSTRUCTION, GArmV7Instruction)) +#define G_IS_ARMV7_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_INSTRUCTION)) +#define G_ARMV7_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_INSTRUCTION, GArmV7InstructionClass)) +#define G_IS_ARMV7_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_INSTRUCTION)) +#define G_ARMV7_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_INSTRUCTION, GArmV7InstructionClass)) /* Définition d'une instruction d'architecture ARMv7 (instance) */ diff --git a/plugins/arm/v7/operands/Makefile.am b/plugins/arm/v7/operands/Makefile.am index eca891c..7ba6d0a 100644 --- a/plugins/arm/v7/operands/Makefile.am +++ b/plugins/arm/v7/operands/Makefile.am @@ -7,6 +7,7 @@ libarmv7operands_la_SOURCES = \ limitation.h limitation.c \ maccess.h maccess.c \ offset.h offset.c \ + register.h register.c \ reglist.h reglist.c \ rotation.h rotation.c \ shift.h shift.c diff --git a/plugins/arm/v7/operands/coproc.c b/plugins/arm/v7/operands/coproc.c index 26c76d0..021aa65 100644 --- a/plugins/arm/v7/operands/coproc.c +++ b/plugins/arm/v7/operands/coproc.c @@ -67,6 +67,17 @@ static void g_armv7_coproc_operand_print(const GArmV7CoprocOperand *, GBufferLin +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_coproc_operand_unserialize(GArmV7CoprocOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_coproc_operand_serialize(const GArmV7CoprocOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour un co-processeur ARM. */ G_DEFINE_TYPE(GArmV7CoprocOperand, g_armv7_coproc_operand, G_TYPE_ARCH_OPERAND); @@ -97,6 +108,9 @@ static void g_armv7_coproc_operand_class_init(GArmV7CoprocOperandClass *klass) operand->compare = (operand_compare_fc)g_armv7_coproc_operand_compare; operand->print = (operand_print_fc)g_armv7_coproc_operand_print; + operand->unserialize = (unserialize_operand_fc)g_armv7_coproc_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_coproc_operand_serialize; + } @@ -248,3 +262,72 @@ uint8_t g_armv7_coproc_operand_get_index(const GArmV7CoprocOperand *operand) return operand->index; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_coproc_operand_unserialize(GArmV7CoprocOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_coproc_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + result = extract_packed_buffer(pbuf, &operand->index, 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_armv7_coproc_operand_serialize(const GArmV7CoprocOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_coproc_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->index, sizeof(uint8_t), false); + + return result; + +} diff --git a/plugins/arm/v7/operands/coproc.h b/plugins/arm/v7/operands/coproc.h index e203f2c..3e40d04 100644 --- a/plugins/arm/v7/operands/coproc.h +++ b/plugins/arm/v7/operands/coproc.h @@ -32,12 +32,12 @@ -#define G_TYPE_ARMV7_COPROC_OPERAND g_armv7_coproc_operand_get_type() -#define G_ARMV7_COPROC_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_coproc_operand_get_type(), GArmV7CoprocOperand)) -#define G_IS_ARMV7_COPROC_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_coproc_operand_get_type())) -#define G_ARMV7_COPROC_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_COPROC_OPERAND, GArmV7CoprocOperandClass)) -#define G_IS_ARMV7_COPROC_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_COPROC_OPERAND)) -#define G_ARMV7_COPROC_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_COPROC_OPERAND, GArmV7CoprocOperandClass)) +#define G_TYPE_ARMV7_COPROC_OPERAND g_armv7_coproc_operand_get_type() +#define G_ARMV7_COPROC_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_COPROC_OPERAND, GArmV7CoprocOperand)) +#define G_IS_ARMV7_COPROC_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_COPROC_OPERAND)) +#define G_ARMV7_COPROC_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_COPROC_OPERAND, GArmV7CoprocOperandClass)) +#define G_IS_ARMV7_COPROC_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_COPROC_OPERAND)) +#define G_ARMV7_COPROC_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_COPROC_OPERAND, GArmV7CoprocOperandClass)) /* Définition d'un opérande représentant un co-processeur (instance) */ diff --git a/plugins/arm/v7/operands/estate.c b/plugins/arm/v7/operands/estate.c index 3302f30..472ac2b 100644 --- a/plugins/arm/v7/operands/estate.c +++ b/plugins/arm/v7/operands/estate.c @@ -67,6 +67,17 @@ static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLin +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_endian_operand_unserialize(GArmV7EndianOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_endian_operand_serialize(const GArmV7EndianOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour une endian de domaine et d'accès. */ G_DEFINE_TYPE(GArmV7EndianOperand, g_armv7_endian_operand, G_TYPE_ARCH_OPERAND); @@ -97,6 +108,9 @@ static void g_armv7_endian_operand_class_init(GArmV7EndianOperandClass *klass) operand->compare = (operand_compare_fc)g_armv7_endian_operand_compare; operand->print = (operand_print_fc)g_armv7_endian_operand_print; + operand->unserialize = (unserialize_operand_fc)g_armv7_endian_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_endian_operand_serialize; + } @@ -246,3 +260,83 @@ bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *operand) return operand->big; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_endian_operand_unserialize(GArmV7EndianOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + uint8_t big; /* Grand boutisme à afficher ? */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_endian_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + { + result = extract_packed_buffer(pbuf, &big, sizeof(uint8_t), false); + + if (result) + operand->big = (big == 1 ? true : 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_armv7_endian_operand_serialize(const GArmV7EndianOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + uint8_t big; /* Grand boutisme à afficher ? */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_endian_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + { + big = (operand->big ? 1 : 0); + result = extend_packed_buffer(pbuf, &big, sizeof(uint8_t), false); + } + + return result; + +} diff --git a/plugins/arm/v7/operands/estate.h b/plugins/arm/v7/operands/estate.h index fae3188..6a1e371 100644 --- a/plugins/arm/v7/operands/estate.h +++ b/plugins/arm/v7/operands/estate.h @@ -32,12 +32,12 @@ -#define G_TYPE_ARMV7_ENDIAN_OPERAND g_armv7_endian_operand_get_type() -#define G_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_endian_operand_get_type(), GArmV7EndianOperand)) -#define G_IS_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_endian_operand_get_type())) -#define G_ARMV7_ENDIAN_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperandClass)) -#define G_IS_ARMV7_ENDIAN_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_ENDIAN_OPERAND)) -#define G_ARMV7_ENDIAN_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperandClass)) +#define G_TYPE_ARMV7_ENDIAN_OPERAND g_armv7_endian_operand_get_type() +#define G_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperand)) +#define G_IS_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_ENDIAN_OPERAND)) +#define G_ARMV7_ENDIAN_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperandClass)) +#define G_IS_ARMV7_ENDIAN_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_ENDIAN_OPERAND)) +#define G_ARMV7_ENDIAN_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperandClass)) /* Définition d'un opérande affichant le choix d'un boutisme (instance) */ diff --git a/plugins/arm/v7/operands/limitation.c b/plugins/arm/v7/operands/limitation.c index 22ca1c0..6ed32fb 100644 --- a/plugins/arm/v7/operands/limitation.c +++ b/plugins/arm/v7/operands/limitation.c @@ -67,6 +67,17 @@ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *, GB +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour une limitation de domaine et d'accès. */ G_DEFINE_TYPE(GArmV7LimitationOperand, g_armv7_limitation_operand, G_TYPE_ARCH_OPERAND); @@ -97,6 +108,9 @@ static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass * operand->compare = (operand_compare_fc)g_armv7_limitation_operand_compare; operand->print = (operand_print_fc)g_armv7_limitation_operand_print; + operand->unserialize = (unserialize_operand_fc)g_armv7_limitation_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_limitation_operand_serialize; + } @@ -285,3 +299,72 @@ BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7Limitatio return operand->type; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + result = extract_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true); + + 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_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true); + + return result; + +} diff --git a/plugins/arm/v7/operands/limitation.h b/plugins/arm/v7/operands/limitation.h index 47f38ff..e9c1617 100644 --- a/plugins/arm/v7/operands/limitation.h +++ b/plugins/arm/v7/operands/limitation.h @@ -32,12 +32,12 @@ -#define G_TYPE_ARMV7_LIMITATION_OPERAND g_armv7_limitation_operand_get_type() -#define G_ARMV7_LIMITATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_limitation_operand_get_type(), GArmV7LimitationOperand)) -#define G_IS_ARMV7_LIMITATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_limitation_operand_get_type())) -#define G_ARMV7_LIMITATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_LIMITATION_OPERAND, GArmV7LimitationOperandClass)) -#define G_IS_ARMV7_LIMITATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_LIMITATION_OPERAND)) -#define G_ARMV7_LIMITATION_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_LIMITATION_OPERAND, GArmV7LimitationOperandClass)) +#define G_TYPE_ARMV7_LIMITATION_OPERAND g_armv7_limitation_operand_get_type() +#define G_ARMV7_LIMITATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_LIMITATION_OPERAND, GArmV7LimitationOperand)) +#define G_IS_ARMV7_LIMITATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_LIMITATION_OPERAND)) +#define G_ARMV7_LIMITATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_LIMITATION_OPERAND, GArmV7LimitationOperandClass)) +#define G_IS_ARMV7_LIMITATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_LIMITATION_OPERAND)) +#define G_ARMV7_LIMITATION_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_LIMITATION_OPERAND, GArmV7LimitationOperandClass)) /* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */ diff --git a/plugins/arm/v7/operands/maccess.c b/plugins/arm/v7/operands/maccess.c index a21921f..5359527 100644 --- a/plugins/arm/v7/operands/maccess.c +++ b/plugins/arm/v7/operands/maccess.c @@ -71,6 +71,17 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *, GBufferL +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour un accès à la mémoire depuis une base. */ G_DEFINE_TYPE(GArmV7MAccessOperand, g_armv7_maccess_operand, G_TYPE_ARCH_OPERAND); @@ -101,6 +112,9 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass) operand->compare = (operand_compare_fc)g_armv7_maccess_operand_compare; operand->print = (operand_print_fc)g_armv7_maccess_operand_print; + operand->unserialize = (unserialize_operand_fc)g_armv7_maccess_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_maccess_operand_serialize; + } @@ -118,6 +132,9 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass) static void g_armv7_maccess_operand_init(GArmV7MAccessOperand *operand) { + operand->base = NULL; + operand->offset = NULL; + operand->shift = NULL; } @@ -136,7 +153,8 @@ static void g_armv7_maccess_operand_init(GArmV7MAccessOperand *operand) static void g_armv7_maccess_operand_dispose(GArmV7MAccessOperand *operand) { - g_object_unref(G_OBJECT(operand->base)); + if (operand->base != NULL) + g_object_unref(G_OBJECT(operand->base)); if (operand->offset != NULL) g_object_unref(G_OBJECT(operand->offset)); @@ -383,3 +401,182 @@ bool g_armv7_maccess_operand_has_to_write_back(const GArmV7MAccessOperand *opera return operand->write_back; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + GArchOperand *subop; /* Sous-opérande à intégrer */ + uint8_t boolean; /* Valeur booléenne */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + { + subop = g_arch_operand_load(storage, format, pbuf); + + if (subop == NULL) + result = false; + + else + operand->base = subop; + + } + + if (result) + { + result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + + if (result && boolean == 1) + { + subop = g_arch_operand_load(storage, format, pbuf); + + if (subop == NULL) + result = false; + + else + operand->offset = subop; + + } + + } + + if (result) + { + result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + + if (result && boolean == 1) + { + subop = g_arch_operand_load(storage, format, pbuf); + + if (subop == NULL) + result = false; + + else + operand->shift = subop; + + } + + } + + if (result) + { + result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + + if (result) + operand->post_indexed = (boolean == 1 ? true : false); + + } + + if (result) + { + result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + + if (result) + operand->write_back = (boolean == 1 ? true : 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_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + uint8_t boolean; /* Valeur booléenne */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = g_arch_operand_store(operand->base, storage, pbuf); + + if (result) + { + if (operand->offset == NULL) + result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false); + + else + { + result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false); + + if (result) + result = g_arch_operand_store(operand->offset, storage, pbuf); + + } + + } + + if (result) + { + if (operand->shift == NULL) + result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false); + + else + { + result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false); + + if (result) + result = g_arch_operand_store(operand->shift, storage, pbuf); + + } + + } + + if (result) + { + boolean = (operand->post_indexed ? 1 : 0); + result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + } + + if (result) + { + boolean = (operand->write_back ? 1 : 0); + result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + } + + return result; + +} diff --git a/plugins/arm/v7/operands/maccess.h b/plugins/arm/v7/operands/maccess.h index c2b11da..f9668c2 100644 --- a/plugins/arm/v7/operands/maccess.h +++ b/plugins/arm/v7/operands/maccess.h @@ -36,12 +36,12 @@ -#define G_TYPE_ARMV7_MACCESS_OPERAND g_armv7_maccess_operand_get_type() -#define G_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_maccess_operand_get_type(), GArmV7MAccessOperand)) -#define G_IS_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_maccess_operand_get_type())) -#define G_ARMV7_MACCESS_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_MACCESS_OPERAND, GArmV7MAccessOperandClass)) -#define G_IS_ARMV7_MACCESS_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_MACCESS_OPERAND)) -#define G_ARMV7_MACCESS_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_MACCESS_OPERAND, GArmV7MAccessOperandClass)) +#define G_TYPE_ARMV7_MACCESS_OPERAND g_armv7_maccess_operand_get_type() +#define G_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_MACCESS_OPERAND, GArmV7MAccessOperand)) +#define G_IS_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_MACCESS_OPERAND)) +#define G_ARMV7_MACCESS_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_MACCESS_OPERAND, GArmV7MAccessOperandClass)) +#define G_IS_ARMV7_MACCESS_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_MACCESS_OPERAND)) +#define G_ARMV7_MACCESS_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_MACCESS_OPERAND, GArmV7MAccessOperandClass)) /* Définition d'un opérande offrant un accès à la mémoire depuis une base (instance) */ diff --git a/plugins/arm/v7/operands/offset.c b/plugins/arm/v7/operands/offset.c index 10c7cb5..ffa3fac 100644 --- a/plugins/arm/v7/operands/offset.c +++ b/plugins/arm/v7/operands/offset.c @@ -68,6 +68,17 @@ static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *, GBufferLin +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_offset_operand_serialize(const GArmV7OffsetOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour un décalage relatif ARMv7. */ G_DEFINE_TYPE(GArmV7OffsetOperand, g_armv7_offset_operand, G_TYPE_ARCH_OPERAND); @@ -98,6 +109,9 @@ static void g_armv7_offset_operand_class_init(GArmV7OffsetOperandClass *klass) operand->compare = (operand_compare_fc)g_armv7_offset_operand_compare; operand->print = (operand_print_fc)g_armv7_offset_operand_print; + operand->unserialize = (unserialize_operand_fc)g_armv7_offset_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_offset_operand_serialize; + } @@ -115,6 +129,7 @@ static void g_armv7_offset_operand_class_init(GArmV7OffsetOperandClass *klass) static void g_armv7_offset_operand_init(GArmV7OffsetOperand *operand) { + operand->value = NULL; } @@ -133,7 +148,8 @@ static void g_armv7_offset_operand_init(GArmV7OffsetOperand *operand) static void g_armv7_offset_operand_dispose(GArmV7OffsetOperand *operand) { - g_object_unref(G_OBJECT(operand->value)); + if (operand->value != NULL) + g_object_unref(G_OBJECT(operand->value)); G_OBJECT_CLASS(g_armv7_offset_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -281,3 +297,99 @@ GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *operan return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_offset_operand_unserialize(GArmV7OffsetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + GArchOperand *value; /* Valeur à intégrer */ + uint8_t positive; /* Sens du décalage */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + { + value = g_arch_operand_load(storage, format, pbuf); + + if (value == NULL) + result = false; + + else + operand->value = value; + + } + + if (result) + { + result = extract_packed_buffer(pbuf, &positive, sizeof(uint8_t), false); + + if (result) + operand->positive = (positive == 1 ? true : 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_armv7_offset_operand_serialize(const GArmV7OffsetOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + uint8_t positive; /* Sens du décalage */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + { + positive = (operand->positive ? 1 : 0); + result = extend_packed_buffer(pbuf, &positive, sizeof(uint8_t), false); + } + + if (result) + result = g_arch_operand_store(operand->value, storage, pbuf); + + return result; + +} diff --git a/plugins/arm/v7/operands/offset.h b/plugins/arm/v7/operands/offset.h index 18b626d..88c80a9 100644 --- a/plugins/arm/v7/operands/offset.h +++ b/plugins/arm/v7/operands/offset.h @@ -36,12 +36,12 @@ -#define G_TYPE_ARMV7_OFFSET_OPERAND g_armv7_offset_operand_get_type() -#define G_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_offset_operand_get_type(), GArmV7OffsetOperand)) -#define G_IS_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_offset_operand_get_type())) -#define G_ARMV7_OFFSET_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_OFFSET_OPERAND, GArmV7OffsetOperandClass)) -#define G_IS_ARMV7_OFFSET_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_OFFSET_OPERAND)) -#define G_ARMV7_OFFSET_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_OFFSET_OPERAND, GArmV7OffsetOperandClass)) +#define G_TYPE_ARMV7_OFFSET_OPERAND g_armv7_offset_operand_get_type() +#define G_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_OFFSET_OPERAND, GArmV7OffsetOperand)) +#define G_IS_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_OFFSET_OPERAND)) +#define G_ARMV7_OFFSET_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_OFFSET_OPERAND, GArmV7OffsetOperandClass)) +#define G_IS_ARMV7_OFFSET_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_OFFSET_OPERAND)) +#define G_ARMV7_OFFSET_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_OFFSET_OPERAND, GArmV7OffsetOperandClass)) /* Définition d'un opérande visant à constituer un décalage relatif ARMv7 (instance) */ diff --git a/plugins/arm/v7/operands/register.c b/plugins/arm/v7/operands/register.c new file mode 100644 index 0000000..33a14f6 --- /dev/null +++ b/plugins/arm/v7/operands/register.c @@ -0,0 +1,297 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * register.c - opérandes visant un registre ARMv7 + * + * Copyright (C) 2010-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 "register.h" + + +#include <arch/register-int.h> + + +#include "../../register.h" + + + +/* Définition d'un opérande visant un registre ARMv7 (instance) */ +struct _GArmV7RegisterOperand +{ + GRegisterOperand parent; /* Instance parente */ + +}; + + +/* Définition d'un opérande visant un registre ARMv7 (classe) */ +struct _GArmV7RegisterOperandClass +{ + GRegisterOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes de registre ARMv7. */ +static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *); + +/* Initialise une instance d'opérande de registre ARMv7. */ +static void g_armv7_register_operand_init(GArmV7RegisterOperand *); + +/* Supprime toutes les références externes. */ +static void g_armv7_register_operand_dispose(GArmV7RegisterOperand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_armv7_register_operand_finalize(GArmV7RegisterOperand *); + + + +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_register_operand_serialize(const GArmV7RegisterOperand *, GAsmStorage *, packed_buffer *); + + + +/* Indique le type défini par la GLib pour un opérande de registre ARMv7. */ +G_DEFINE_TYPE(GArmV7RegisterOperand, g_armv7_register_operand, G_TYPE_REGISTER_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes de registre ARMv7. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GArchOperandClass *operand; /* Version de classe parente */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_register_operand_dispose; + object->finalize = (GObjectFinalizeFunc)g_armv7_register_operand_finalize; + + operand = G_ARCH_OPERAND_CLASS(klass); + + operand->unserialize = (unserialize_operand_fc)g_armv7_register_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_register_operand_serialize; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de registre ARMv7. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_register_operand_init(GArmV7RegisterOperand *operand) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_register_operand_dispose(GArmV7RegisterOperand *operand) +{ + G_OBJECT_CLASS(g_armv7_register_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_armv7_register_operand_finalize(GArmV7RegisterOperand *operand) +{ + G_OBJECT_CLASS(g_armv7_register_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre déjà en place. * +* * +* Description : Crée un opérande visant un registre ARMv7. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_register_operand_new(GArmV7Register *reg) +{ + GArmV7RegisterOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_REGISTER_OPERAND, NULL); + + G_REGISTER_OPERAND(result)->reg = G_ARCH_REGISTER(reg); + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande représentant un registre. * +* * +* Description : Fournit le registre ARMv7 associé à l'opérande. * +* * +* Retour : Représentation interne du registre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const GArmV7Register *g_armv7_register_operand_get(const GArmV7RegisterOperand *operand) +{ + GArmV7Register *result; /* Instance à retourner */ + + result = G_ARMV7_REGISTER(G_REGISTER_OPERAND(operand)->reg); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + uint8_t index; /* Identifiant de registre */ + GArmV7Register *reg; /* Registre à intégrer */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + { + result = extract_packed_buffer(pbuf, &index, sizeof(uint8_t), false); + + if (result) + { + reg = g_armv7_register_new(index); + result = (reg != NULL); + } + + if (result) + G_REGISTER_OPERAND(operand)->reg = G_ARCH_REGISTER(reg); + + } + + 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_armv7_register_operand_serialize(const GArmV7RegisterOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + uint8_t index; /* Identifiant de registre */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + { + index = g_arm_register_get_index(G_ARM_REGISTER(G_REGISTER_OPERAND(operand)->reg)); + result = extend_packed_buffer(pbuf, &index, sizeof(uint8_t), false); + } + + return result; + +} diff --git a/plugins/arm/v7/operands/register.h b/plugins/arm/v7/operands/register.h new file mode 100644 index 0000000..61f5d6e --- /dev/null +++ b/plugins/arm/v7/operands/register.h @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * register.h - prototypes pour les opérandes visant un registre ARMv7 + * + * Copyright (C) 2010-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 _PLUGINS_ARM_V7_OPERANDS_REGISTER_H +#define _PLUGINS_ARM_V7_OPERANDS_REGISTER_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include <arch/operand.h> + + +#include "../register.h" + + + +#define G_TYPE_ARMV7_REGISTER_OPERAND g_armv7_register_operand_get_type() +#define G_ARMV7_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_REGISTER_OPERAND, GArmV7RegisterOperand)) +#define G_IS_ARMV7_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_REGISTER_OPERAND)) +#define G_ARMV7_REGISTER_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_REGISTER_OPERAND, GArmV7RegisterOperandClass)) +#define G_IS_ARMV7_REGISTER_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_REGISTER_OPERAND)) +#define G_ARMV7_REGISTER_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_REGISTER_OPERAND, GArmV7RegisterOperandClass)) + + +/* Définition d'un opérande visant un registre ARMv7 (instance) */ +typedef struct _GArmV7RegisterOperand GArmV7RegisterOperand; + +/* Définition d'un opérande visant un registre ARMv7 (classe) */ +typedef struct _GArmV7RegisterOperandClass GArmV7RegisterOperandClass; + + +/* Indique le type défini par la GLib pour un opérande de registre ARMv7. */ +GType g_armv7_register_operand_get_type(void); + +/* Crée un opérande visant un registre ARMv7. */ +GArchOperand *g_armv7_register_operand_new(GArmV7Register *); + +/* Fournit le registre ARMv7 associé à l'opérande. */ +const GArmV7Register *g_armv7_register_operand_get(const GArmV7RegisterOperand *); + + + +#endif /* _PLUGINS_ARM_V7_OPERANDS_REGISTER_H */ diff --git a/plugins/arm/v7/operands/reglist.c b/plugins/arm/v7/operands/reglist.c index 5fc1f08..005aff7 100644 --- a/plugins/arm/v7/operands/reglist.c +++ b/plugins/arm/v7/operands/reglist.c @@ -33,6 +33,9 @@ #include <common/sort.h> +#include "../../register.h" + + /* Définition d'un opérande listant une série de registres ARM (instance) */ struct _GArmV7RegListOperand @@ -73,6 +76,17 @@ static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *, GBufferL +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_reglist_operand_serialize(const GArmV7RegListOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour une liste de registres ARM. */ G_DEFINE_TYPE(GArmV7RegListOperand, g_armv7_reglist_operand, G_TYPE_ARCH_OPERAND); @@ -103,6 +117,9 @@ static void g_armv7_reglist_operand_class_init(GArmV7RegListOperandClass *klass) operand->compare = (operand_compare_fc)g_armv7_reglist_operand_compare; operand->print = (operand_print_fc)g_armv7_reglist_operand_print; + operand->unserialize = (unserialize_operand_fc)g_armv7_reglist_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_reglist_operand_serialize; + } @@ -352,3 +369,98 @@ GArmV7Register *g_armv7_reglist_operand_get_register(const GArmV7RegListOperand return operand->registers[index]; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + size_t count; /* Quantité de registres */ + size_t i; /* Boucle de parcours */ + uint8_t index; /* Identifiant de registre */ + GArmV7Register *reg; /* Nouveau registre à intégrer */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); + + for (i = 0; i < count && result; i++) + { + result = extract_packed_buffer(pbuf, &index, sizeof(uint8_t), false); + + if (result) + { + reg = g_armv7_register_new(index); + g_armv7_reglist_add_register(operand, reg); + } + + } + + 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_armv7_reglist_operand_serialize(const GArmV7RegListOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + size_t i; /* Boucle de parcours */ + uint8_t index; /* Identifiant de registre */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true); + + for (i = 0; i < operand->count && result; i++) + { + index = g_arm_register_get_index(G_ARM_REGISTER(operand->registers[i])); + + result = extend_packed_buffer(pbuf, &index, sizeof(uint8_t), false); + + } + + return result; + +} diff --git a/plugins/arm/v7/operands/reglist.h b/plugins/arm/v7/operands/reglist.h index cb5d462..a8adc47 100644 --- a/plugins/arm/v7/operands/reglist.h +++ b/plugins/arm/v7/operands/reglist.h @@ -36,12 +36,12 @@ -#define G_TYPE_ARMV7_REGLIST_OPERAND g_armv7_reglist_operand_get_type() -#define G_ARMV7_REGLIST_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_reglist_operand_get_type(), GArmV7RegListOperand)) -#define G_IS_ARMV7_REGLIST_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_reglist_operand_get_type())) -#define G_ARMV7_REGLIST_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_REGLIST_OPERAND, GArmV7RegListOperandClass)) -#define G_IS_ARMV7_REGLIST_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_REGLIST_OPERAND)) -#define G_ARMV7_REGLIST_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_REGLIST_OPERAND, GArmV7RegListOperandClass)) +#define G_TYPE_ARMV7_REGLIST_OPERAND g_armv7_reglist_operand_get_type() +#define G_ARMV7_REGLIST_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_REGLIST_OPERAND, GArmV7RegListOperand)) +#define G_IS_ARMV7_REGLIST_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_REGLIST_OPERAND)) +#define G_ARMV7_REGLIST_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_REGLIST_OPERAND, GArmV7RegListOperandClass)) +#define G_IS_ARMV7_REGLIST_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_REGLIST_OPERAND)) +#define G_ARMV7_REGLIST_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_REGLIST_OPERAND, GArmV7RegListOperandClass)) /* Définition d'un opérande listant une série de registres ARM (instance) */ diff --git a/plugins/arm/v7/operands/rotation.c b/plugins/arm/v7/operands/rotation.c index 2b47d73..c091044 100644 --- a/plugins/arm/v7/operands/rotation.c +++ b/plugins/arm/v7/operands/rotation.c @@ -66,6 +66,17 @@ static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *, GBuffe +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_rotation_operand_serialize(const GArmV7RotationOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour une opérande de rotation ARMv7. */ G_DEFINE_TYPE(GArmV7RotationOperand, g_armv7_rotation_operand, G_TYPE_ARCH_OPERAND); @@ -96,6 +107,9 @@ static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klas operand->compare = (operand_compare_fc)g_armv7_rotation_operand_compare; operand->print = (operand_print_fc)g_armv7_rotation_operand_print; + operand->unserialize = (unserialize_operand_fc)g_armv7_rotation_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_rotation_operand_serialize; + } @@ -113,6 +127,7 @@ static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klas static void g_armv7_rotation_operand_init(GArmV7RotationOperand *operand) { + operand->value = NULL; } @@ -131,7 +146,8 @@ static void g_armv7_rotation_operand_init(GArmV7RotationOperand *operand) static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *operand) { - g_object_unref(G_OBJECT(operand->value)); + if (operand->value != NULL) + g_object_unref(G_OBJECT(operand->value)); G_OBJECT_CLASS(g_armv7_rotation_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -254,3 +270,82 @@ GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *op return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_rotation_operand_unserialize(GArmV7RotationOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + GArchOperand *value; /* Valeur à intégrer */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + { + value = g_arch_operand_load(storage, format, pbuf); + + if (value == NULL) + result = false; + + else + operand->value = value; + + } + + 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_armv7_rotation_operand_serialize(const GArmV7RotationOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = g_arch_operand_store(operand->value, storage, pbuf); + + return result; + +} diff --git a/plugins/arm/v7/operands/rotation.h b/plugins/arm/v7/operands/rotation.h index 33dbfe7..8fd569f 100644 --- a/plugins/arm/v7/operands/rotation.h +++ b/plugins/arm/v7/operands/rotation.h @@ -32,12 +32,12 @@ -#define G_TYPE_ARMV7_ROTATION_OPERAND g_armv7_rotation_operand_get_type() -#define G_ARMV7_ROTATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_rotation_operand_get_type(), GArmV7RotationOperand)) -#define G_IS_ARMV7_ROTATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_rotation_operand_get_type())) -#define G_ARMV7_ROTATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_ROTATION_OPERAND, GArmV7RotationOperandClass)) -#define G_IS_ARMV7_ROTATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_ROTATION_OPERAND)) -#define G_ARMV7_ROTATION_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_ROTATION_OPERAND, GArmV7RotationOperandClass)) +#define G_TYPE_ARMV7_ROTATION_OPERAND g_armv7_rotation_operand_get_type() +#define G_ARMV7_ROTATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_ROTATION_OPERAND, GArmV7RotationOperand)) +#define G_IS_ARMV7_ROTATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_ROTATION_OPERAND)) +#define G_ARMV7_ROTATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_ROTATION_OPERAND, GArmV7RotationOperandClass)) +#define G_IS_ARMV7_ROTATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_ROTATION_OPERAND)) +#define G_ARMV7_ROTATION_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_ROTATION_OPERAND, GArmV7RotationOperandClass)) /* Définition d'un opérande visant une opérande de rotation ARMv7 (instance) */ diff --git a/plugins/arm/v7/operands/shift.c b/plugins/arm/v7/operands/shift.c index 3e8b8b7..e0637ee 100644 --- a/plugins/arm/v7/operands/shift.c +++ b/plugins/arm/v7/operands/shift.c @@ -68,6 +68,17 @@ static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *, GBufferLine +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_armv7_shift_operand_serialize(const GArmV7ShiftOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour une opérande de décalage ARMv7. */ G_DEFINE_TYPE(GArmV7ShiftOperand, g_armv7_shift_operand, G_TYPE_ARCH_OPERAND); @@ -98,6 +109,9 @@ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *klass) operand->compare = (operand_compare_fc)g_armv7_shift_operand_compare; operand->print = (operand_print_fc)g_armv7_shift_operand_print; + operand->unserialize = (unserialize_operand_fc)g_armv7_shift_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_armv7_shift_operand_serialize; + } @@ -115,6 +129,7 @@ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *klass) static void g_armv7_shift_operand_init(GArmV7ShiftOperand *operand) { + operand->shift_value = NULL; } @@ -133,7 +148,8 @@ static void g_armv7_shift_operand_init(GArmV7ShiftOperand *operand) static void g_armv7_shift_operand_dispose(GArmV7ShiftOperand *operand) { - g_object_unref(G_OBJECT(operand->shift_value)); + if (operand->shift_value != NULL) + g_object_unref(G_OBJECT(operand->shift_value)); G_OBJECT_CLASS(g_armv7_shift_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -298,3 +314,88 @@ GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *op return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_armv7_shift_operand_unserialize(GArmV7ShiftOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + GArchOperand *value; /* Valeur à intégrer */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + result = extract_packed_buffer(pbuf, &operand->shift_type, sizeof(SRType), true); + + if (result) + { + value = g_arch_operand_load(storage, format, pbuf); + + if (value == NULL) + result = false; + + else + operand->shift_value = value; + + } + + 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_armv7_shift_operand_serialize(const GArmV7ShiftOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->shift_type, sizeof(SRType), true); + + if (result) + result = g_arch_operand_store(operand->shift_value, storage, pbuf); + + return result; + +} diff --git a/plugins/arm/v7/operands/shift.h b/plugins/arm/v7/operands/shift.h index b5a2905..44a1a32 100644 --- a/plugins/arm/v7/operands/shift.h +++ b/plugins/arm/v7/operands/shift.h @@ -35,12 +35,12 @@ -#define G_TYPE_ARMV7_SHIFT_OPERAND g_armv7_shift_operand_get_type() -#define G_ARMV7_SHIFT_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_shift_operand_get_type(), GArmV7ShiftOperand)) -#define G_IS_ARMV7_SHIFT_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_shift_operand_get_type())) -#define G_ARMV7_SHIFT_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_SHIFT_OPERAND, GArmV7ShiftOperandClass)) -#define G_IS_ARMV7_SHIFT_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_SHIFT_OPERAND)) -#define G_ARMV7_SHIFT_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_SHIFT_OPERAND, GArmV7ShiftOperandClass)) +#define G_TYPE_ARMV7_SHIFT_OPERAND g_armv7_shift_operand_get_type() +#define G_ARMV7_SHIFT_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_SHIFT_OPERAND, GArmV7ShiftOperand)) +#define G_IS_ARMV7_SHIFT_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_SHIFT_OPERAND)) +#define G_ARMV7_SHIFT_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_SHIFT_OPERAND, GArmV7ShiftOperandClass)) +#define G_IS_ARMV7_SHIFT_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_SHIFT_OPERAND)) +#define G_ARMV7_SHIFT_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_SHIFT_OPERAND, GArmV7ShiftOperandClass)) /* Définition d'un opérande visant une opérande de décalage ARMv7 (instance) */ diff --git a/plugins/arm/v7/post.c b/plugins/arm/v7/post.c index fccd835..ad839cf 100644 --- a/plugins/arm/v7/post.c +++ b/plugins/arm/v7/post.c @@ -46,7 +46,7 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GExeFormat *format) { GArchOperand *op; /* Opérande numérique en place */ - uint32_t addr; /* Adresse visée par le saut */ + virt_t addr; /* Adresse visée par le saut */ GBinFormat *bfmt; /* Version basique du format */ GTargetOperand *new; /* Instruction de ciblage */ vmpa2t target; /* Défination finale précise */ @@ -62,7 +62,7 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc if (!G_IS_IMM_OPERAND(op)) goto ppli_release; - if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr) + if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &addr) && g_exe_format_translate_address_into_vmpa(format, addr, &target)) { bfmt = G_BIN_FORMAT(format); diff --git a/plugins/arm/v7/post.h b/plugins/arm/v7/post.h index 7d6e0a8..e808efd 100644 --- a/plugins/arm/v7/post.h +++ b/plugins/arm/v7/post.h @@ -25,7 +25,6 @@ #define _PLUGINS_ARM_V7_POST_H -#include <arch/instruction.h> #include <arch/post.h> diff --git a/plugins/dalvik/core.c b/plugins/dalvik/core.c index f945c18..cc96843 100644 --- a/plugins/dalvik/core.c +++ b/plugins/dalvik/core.c @@ -24,12 +24,14 @@ #include "core.h" -#include <core/processors.h> #include <plugins/plugin-def.h> #include "register.h" -#include "v35/processor.h" +#include "operands/args.h" +#include "operands/pool.h" +#include "operands/register.h" +#include "v35/core.h" @@ -38,6 +40,32 @@ DEFINE_CHRYSALIDE_PLUGIN("dalvik", "Add support for the Dalvik architecture", "0 +/* Assure l'enregistrement de types pour les caches à charger. */ +static void register_dalvik_gtypes(void); + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Assure l'enregistrement de types pour les caches à charger. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_dalvik_gtypes(void) +{ + g_type_ensure(G_TYPE_DALVIK_ARGS_OPERAND); + g_type_ensure(G_TYPE_DALVIK_POOL_OPERAND); + g_type_ensure(G_TYPE_DALVIK_REGISTER_OPERAND); + +} + + /****************************************************************************** * * * Paramètres : plugin = greffon à manipuler. * @@ -54,12 +82,15 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) { bool result; /* Bilan à retourner */ - result = register_processor_type("dalvik35", "Dalvik Virtual Machine v35", G_TYPE_DALVIK35_PROCESSOR); + register_dalvik_gtypes(); + + result = init_dalvik35_core(); return result; } + /****************************************************************************** * * * Paramètres : plugin = greffon à manipuler. * @@ -74,6 +105,8 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *plugin) { + exit_dalvik35_core(); + clean_dalvik_register_cache(); } diff --git a/plugins/dalvik/operand.c b/plugins/dalvik/operand.c index ae57498..4d8fc73 100644 --- a/plugins/dalvik/operand.c +++ b/plugins/dalvik/operand.c @@ -747,7 +747,7 @@ void dalvik_mark_first_operand_as_written(GArchInstruction *instr) operand = g_arch_instruction_get_operand(instr, 0); - g_dalvik_register_operand_mark_as_written(G_DALVIK_REGISTER_OPERAND(operand)); + g_register_operand_mark_as_written(G_REGISTER_OPERAND(operand)); g_object_unref(G_OBJECT(operand)); diff --git a/plugins/dalvik/operands/args.c b/plugins/dalvik/operands/args.c index f35a11f..5224567 100644 --- a/plugins/dalvik/operands/args.c +++ b/plugins/dalvik/operands/args.c @@ -72,6 +72,17 @@ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *, GBufferLine +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_dalvik_args_operand_serialize(const GDalvikArgsOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */ G_DEFINE_TYPE(GDalvikArgsOperand, g_dalvik_args_operand, G_TYPE_ARCH_OPERAND); @@ -102,6 +113,9 @@ static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass) operand->compare = (operand_compare_fc)g_dalvik_args_operand_compare; operand->print = (operand_print_fc)g_dalvik_args_operand_print; + operand->unserialize = (unserialize_operand_fc)g_dalvik_args_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_dalvik_args_operand_serialize; + } @@ -119,6 +133,8 @@ static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass) static void g_dalvik_args_operand_init(GDalvikArgsOperand *operand) { + operand->args = NULL; + operand->count = 0; } @@ -161,6 +177,9 @@ static void g_dalvik_args_operand_dispose(GDalvikArgsOperand *operand) static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *operand) { + if (operand->args != NULL) + free(operand->args); + G_OBJECT_CLASS(g_dalvik_args_operand_parent_class)->finalize(G_OBJECT(operand)); } @@ -280,7 +299,6 @@ GArchOperand *g_dalvik_args_operand_new(void) void g_dalvik_args_operand_add(GDalvikArgsOperand *operand, GArchOperand *arg) { - operand->count++; operand->args = (GArchOperand **)realloc(operand->args, operand->count * sizeof(GArchOperand *)); @@ -328,3 +346,91 @@ GArchOperand *g_dalvik_args_operand_get(const GDalvikArgsOperand *operand, size_ return operand->args[index]; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_dalvik_args_operand_unserialize(GDalvikArgsOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + size_t count; /* Nombre d'opérandes à charger*/ + size_t i; /* Boucle de parcours */ + GArchOperand *arg; /* Nouvel argument à intégrer */ + + parent = G_ARCH_OPERAND_CLASS(g_dalvik_args_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); + + for (i = 0; i < count && result; i++) + { + arg = g_arch_operand_load(storage, format, pbuf); + + if (arg == NULL) + result = false; + + else + g_dalvik_args_operand_add(operand, arg); + + } + + 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_dalvik_args_operand_serialize(const GDalvikArgsOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + size_t i; /* Boucle de parcours */ + + parent = G_ARCH_OPERAND_CLASS(g_dalvik_args_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true); + + for (i = 0; i < operand->count && result; i++) + result = g_arch_operand_store(operand->args[i], storage, pbuf); + + return result; + +} diff --git a/plugins/dalvik/operands/args.h b/plugins/dalvik/operands/args.h index bf2fac4..3852e6d 100644 --- a/plugins/dalvik/operands/args.h +++ b/plugins/dalvik/operands/args.h @@ -32,12 +32,12 @@ -#define G_TYPE_DALVIK_ARGS_OPERAND g_dalvik_args_operand_get_type() -#define G_DALVIK_ARGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_args_operand_get_type(), GDalvikArgsOperand)) -#define G_IS_DALVIK_ARGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_args_operand_get_type())) -#define G_DALVIK_ARGS_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_ARGS_OPERAND, GDalvikArgsOperandClass)) -#define G_IS_DALVIK_ARGS_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_ARGS_OPERAND)) -#define G_DALVIK_ARGS_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_ARGS_OPERAND, GDalvikArgsOperandClass)) +#define G_TYPE_DALVIK_ARGS_OPERAND g_dalvik_args_operand_get_type() +#define G_DALVIK_ARGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DALVIK_ARGS_OPERAND, GDalvikArgsOperand)) +#define G_IS_DALVIK_ARGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DALVIK_ARGS_OPERAND)) +#define G_DALVIK_ARGS_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_ARGS_OPERAND, GDalvikArgsOperandClass)) +#define G_IS_DALVIK_ARGS_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_ARGS_OPERAND)) +#define G_DALVIK_ARGS_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_ARGS_OPERAND, GDalvikArgsOperandClass)) /* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */ diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index 9acfdb6..6bb1323 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -77,6 +77,17 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *, GBufferLine +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini par la GLib pour un un élément de table de constantes Dalvik. */ G_DEFINE_TYPE(GDalvikPoolOperand, g_dalvik_pool_operand, G_TYPE_ARCH_OPERAND); @@ -108,6 +119,9 @@ static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *klass) operand->compare = (operand_compare_fc)g_dalvik_pool_operand_compare; operand->print = (operand_print_fc)g_dalvik_pool_operand_print; + operand->unserialize = (unserialize_operand_fc)g_dalvik_pool_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_dalvik_pool_operand_serialize; + } @@ -125,6 +139,7 @@ static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *klass) static void g_dalvik_pool_operand_init(GDalvikPoolOperand *operand) { + operand->format = NULL; } @@ -143,7 +158,8 @@ static void g_dalvik_pool_operand_init(GDalvikPoolOperand *operand) static void g_dalvik_pool_operand_dispose(GDalvikPoolOperand *operand) { - g_object_unref(G_OBJECT(operand->format)); + if (operand->format != NULL) + g_object_unref(G_OBJECT(operand->format)); G_OBJECT_CLASS(g_dalvik_pool_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -453,3 +469,84 @@ uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand) return operand->index; } + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_dalvik_pool_operand_unserialize(GDalvikPoolOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + { + operand->format = G_DEX_FORMAT(format); + g_object_ref(G_OBJECT(format)); + } + + if (result) + result = extract_packed_buffer(pbuf, &operand->type, sizeof(DalvikPoolType), true); + + if (result) + result = extract_packed_buffer(pbuf, &operand->index, sizeof(uint32_t), true); + + 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_dalvik_pool_operand_serialize(const GDalvikPoolOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + + parent = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->type, sizeof(DalvikPoolType), true); + + if (result) + result = extend_packed_buffer(pbuf, &operand->index, sizeof(uint32_t), true); + + return result; + +} diff --git a/plugins/dalvik/operands/register.c b/plugins/dalvik/operands/register.c index d2dd174..7d011a0 100644 --- a/plugins/dalvik/operands/register.c +++ b/plugins/dalvik/operands/register.c @@ -24,18 +24,14 @@ #include "register.h" -#include <arch/operand-int.h> -#include <arch/register.h> +#include <arch/register-int.h> /* Définition d'un opérande visant un registre Dalvik (instance) */ struct _GDalvikRegisterOperand { - GArchOperand parent; /* Instance parente */ - - GDalvikRegister *reg; /* Registre représenté */ - bool is_written; /* Changement de contenu */ + GRegisterOperand parent; /* Instance parente */ }; @@ -43,7 +39,7 @@ struct _GDalvikRegisterOperand /* Définition d'un opérande visant un registre Dalvik (classe) */ struct _GDalvikRegisterOperandClass { - GArchOperandClass parent; /* Classe parente */ + GRegisterOperandClass parent; /* Classe parente */ }; @@ -60,16 +56,21 @@ static void g_dalvik_register_operand_dispose(GDalvikRegisterOperand *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_register_operand_finalize(GDalvikRegisterOperand *); -/* Compare un opérande avec un autre. */ -static int g_dalvik_register_operand_compare(const GDalvikRegisterOperand *, const GDalvikRegisterOperand *); -/* Traduit un opérande en version humainement lisible. */ -static void g_dalvik_register_operand_print(const GDalvikRegisterOperand *, GBufferLine *, AsmSyntax); + +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_dalvik_register_operand_unserialize(GDalvikRegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_dalvik_register_operand_serialize(const GDalvikRegisterOperand *, GAsmStorage *, packed_buffer *); /* Indique le type défini par la GLib pour un opérande de registre Dalvik. */ -G_DEFINE_TYPE(GDalvikRegisterOperand, g_dalvik_register_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GDalvikRegisterOperand, g_dalvik_register_operand, G_TYPE_REGISTER_OPERAND); /****************************************************************************** @@ -96,8 +97,8 @@ static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *kl operand = G_ARCH_OPERAND_CLASS(klass); - operand->compare = (operand_compare_fc)g_dalvik_register_operand_compare; - operand->print = (operand_print_fc)g_dalvik_register_operand_print; + operand->unserialize = (unserialize_operand_fc)g_dalvik_register_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_dalvik_register_operand_serialize; } @@ -116,8 +117,6 @@ static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *kl static void g_dalvik_register_operand_init(GDalvikRegisterOperand *operand) { - operand->reg = NULL; - operand->is_written = false; } @@ -136,9 +135,6 @@ static void g_dalvik_register_operand_init(GDalvikRegisterOperand *operand) static void g_dalvik_register_operand_dispose(GDalvikRegisterOperand *operand) { - if (operand->reg != NULL) - g_object_unref(G_OBJECT(operand->reg)); - G_OBJECT_CLASS(g_dalvik_register_operand_parent_class)->dispose(G_OBJECT(operand)); } @@ -165,51 +161,6 @@ static void g_dalvik_register_operand_finalize(GDalvikRegisterOperand *operand) /****************************************************************************** * * -* 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_dalvik_register_operand_compare(const GDalvikRegisterOperand *a, const GDalvikRegisterOperand *b) -{ - int result; /* Bilan à retourner */ - - result = g_dalvik_register_compare(a->reg, b->reg); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* syntax = type de représentation demandée. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_dalvik_register_operand_print(const GDalvikRegisterOperand *operand, GBufferLine *line, AsmSyntax syntax) -{ - g_arch_register_print(G_ARCH_REGISTER(operand->reg), line, syntax); - -} - - -/****************************************************************************** -* * * Paramètres : content = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * low = position éventuelle des 4 bits visés. [OUT] * @@ -303,7 +254,7 @@ GArchOperand *g_dalvik_register_operand_new_from_existing(GDalvikRegister *reg) result = g_object_new(G_TYPE_DALVIK_REGISTER_OPERAND, NULL); - result->reg = reg; + G_REGISTER_OPERAND(result)->reg = G_ARCH_REGISTER(reg); return G_ARCH_OPERAND(result); @@ -324,44 +275,97 @@ GArchOperand *g_dalvik_register_operand_new_from_existing(GDalvikRegister *reg) const GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *operand) { - return operand->reg; + GDalvikRegister *result; /* Instance à retourner */ + + result = G_DALVIK_REGISTER(G_REGISTER_OPERAND(operand)->reg); + + return result; } + +/* ---------------------------------------------------------------------------------- */ +/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * -* Paramètres : operand = opérande représentant un registre à mettre à jour. * +* 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 : Marque l'opérande comme étant écrit plutôt que consulté. * +* Description : Charge un opérande depuis une mémoire tampon. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -void g_dalvik_register_operand_mark_as_written(GDalvikRegisterOperand *operand) +static bool g_dalvik_register_operand_unserialize(GDalvikRegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) { - operand->is_written = true; + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + uint16_t index; /* Identifiant de registre */ + GDalvikRegister *reg; /* Registre à intégrer */ + + parent = G_ARCH_OPERAND_CLASS(g_dalvik_register_operand_parent_class); + + result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + + if (result) + { + result = extract_packed_buffer(pbuf, &index, sizeof(uint16_t), true); + + if (result) + { + reg = g_dalvik_register_new(index); + result = (reg != NULL); + } + + if (result) + G_REGISTER_OPERAND(operand)->reg = G_ARCH_REGISTER(reg); + + } + + return result; } /****************************************************************************** * * -* Paramètres : operand = opérande représentant un registre à consulter. * +* Paramètres : operand = opérande d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* pbuf = zone tampon à remplir. * * * -* Description : Indique le type d'accès réalisé sur l'opérande. * +* Description : Sauvegarde un opérande dans une mémoire tampon. * * * -* Retour : Type d'accès : true en cas d'écriture, false sinon. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -bool g_dalvik_register_operand_is_written(const GDalvikRegisterOperand *operand) +static bool g_dalvik_register_operand_serialize(const GDalvikRegisterOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) { - return operand->is_written; + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + uint16_t index; /* Identifiant de registre */ + + parent = G_ARCH_OPERAND_CLASS(g_dalvik_register_operand_parent_class); + + result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + { + index = g_dalvik_register_get_index(G_DALVIK_REGISTER(G_REGISTER_OPERAND(operand)->reg)); + result = extend_packed_buffer(pbuf, &index, sizeof(uint16_t), true); + } + + return result; } diff --git a/plugins/dalvik/operands/register.h b/plugins/dalvik/operands/register.h index efc3651..29b14c8 100644 --- a/plugins/dalvik/operands/register.h +++ b/plugins/dalvik/operands/register.h @@ -64,12 +64,6 @@ GArchOperand *g_dalvik_register_operand_new_from_existing(GDalvikRegister *); /* Fournit le registre Dalvik associé à l'opérande. */ const GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *); -/* Marque l'opérande comme étant écrit plutôt que consulté. */ -void g_dalvik_register_operand_mark_as_written(GDalvikRegisterOperand *); - -/* Indique le type d'accès réalisé sur l'opérande. */ -bool g_dalvik_register_operand_is_written(const GDalvikRegisterOperand *); - #endif /* _PLUGINS_DALVIK_OPERANDS_REGISTER_H */ diff --git a/plugins/dalvik/register.h b/plugins/dalvik/register.h index ffa44e4..42206c8 100644 --- a/plugins/dalvik/register.h +++ b/plugins/dalvik/register.h @@ -33,12 +33,12 @@ /* ------------------------- GESTION UNITAIRE DES REGISTRES ------------------------- */ -#define G_TYPE_DALVIK_REGISTER g_dalvik_register_get_type() -#define G_DALVIK_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_register_get_type(), GDalvikRegister)) -#define G_IS_DALVIK_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_register_get_type())) -#define G_DALVIK_REGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_REGISTER, GDalvikRegisterClass)) -#define G_IS_DALVIK_REGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_REGISTER)) -#define G_DALVIK_REGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_REGISTER, GDalvikRegisterClass)) +#define G_TYPE_DALVIK_REGISTER g_dalvik_register_get_type() +#define G_DALVIK_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DALVIK_REGISTER, GDalvikRegister)) +#define G_IS_DALVIK_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DALVIK_REGISTER)) +#define G_DALVIK_REGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_REGISTER, GDalvikRegisterClass)) +#define G_IS_DALVIK_REGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_REGISTER)) +#define G_DALVIK_REGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_REGISTER, GDalvikRegisterClass)) /* Représentation d'un registre Dalvik (instance) */ diff --git a/plugins/dalvik/v35/Makefile.am b/plugins/dalvik/v35/Makefile.am index ad179c0..eecdeba 100644 --- a/plugins/dalvik/v35/Makefile.am +++ b/plugins/dalvik/v35/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libdalvik35.la libdalvik35_la_SOURCES = \ + core.h core.c \ instruction.h instruction.c \ operand.h \ processor.h processor.c diff --git a/plugins/dalvik/v35/core.c b/plugins/dalvik/v35/core.c new file mode 100644 index 0000000..7e36691 --- /dev/null +++ b/plugins/dalvik/v35/core.c @@ -0,0 +1,99 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * core.c - chargement et déchargement des mécanismes internes de l'architecture Dalvik v35 + * + * 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 "core.h" + + +#include <core/processors.h> + + +#include "instruction.h" +#include "processor.h" + + + +/* Assure l'enregistrement de types pour les caches à charger. */ +static void register_dalvik35_gtypes(void); + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Assure l'enregistrement de types pour les caches à charger. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_dalvik35_gtypes(void) +{ + g_type_ensure(G_TYPE_DALVIK35_INSTRUCTION); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Met en place les mécanismes internes de l'archi. Dalvik v35. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_dalvik35_core(void) +{ + bool result; /* Bilan à renvoyer */ + + register_dalvik35_gtypes(); + + result = register_processor_type("dalvik35", "Dalvik Virtual Machine v35", G_TYPE_DALVIK35_PROCESSOR); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Supprime les mécanismes internes de l'archi. Dalvik v35. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_dalvik35_core(void) +{ + +} diff --git a/plugins/dalvik/v35/core.h b/plugins/dalvik/v35/core.h new file mode 100644 index 0000000..1ee4bf6 --- /dev/null +++ b/plugins/dalvik/v35/core.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * core.h - prototypes pour le chargement et le déchargement des mécanismes internes de l'architecture Dalvik v35 + * + * 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 _PLUGINS_DALVIK_V35_CORE_H +#define _PLUGINS_DALVIK_V35_CORE_H + + +#include <stdbool.h> + + + +/* Met en place les mécanismes internes de l'architecture Dalvik v35. */ +bool init_dalvik35_core(void); + +/* Supprime les mécanismes internes de l'architecture Dalvik v35. */ +void exit_dalvik35_core(void); + + + +#endif /* _PLUGINS_DALVIK_V35_CORE_H */ |