diff options
Diffstat (limited to 'src/arch/dalvik/operand.c')
-rw-r--r-- | src/arch/dalvik/operand.c | 1127 |
1 files changed, 1127 insertions, 0 deletions
diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c new file mode 100644 index 0000000..cc36cb5 --- /dev/null +++ b/src/arch/dalvik/operand.c @@ -0,0 +1,1127 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * operand.c - gestion des operandes de l'architecture Dalvik + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "operand.h" + + +#include <malloc.h> + + +#include "register.h" +#include "../immediate.h" +#include "../operand-int.h" + + + +/* ----------------------- COQUILLE VIDE POUR OPERANDE DALVIK ----------------------- */ + + +/* Définition d'un opérande de Dalvik (instance) */ +struct _GDalvikOperand +{ + GArchOperand parent; /* Instance parente */ + +}; + + +/* Définition d'un opérande de Dalvik (classe) */ +struct _GDalvikOperandClass +{ + GArchOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes Dalvik de base. */ +static void g_dalvik_operand_class_init(GDalvikOperandClass *); + +/* Initialise une instance d'opérande de base pour Dalvik. */ +static void g_dalvik_operand_init(GDalvikOperand *); + + + +/* --------------------- OPERANDES VISANT UN REGISTRE DE DALVIK --------------------- */ + + +/* Définition d'un opérande visant un registre Dalvik (instance) */ +struct _GDalvikRegisterOperand +{ + GDalvikOperand parent; /* Instance parente */ + + GDalvikRegister *reg; /* Registre représenté */ + +}; + + +/* Définition d'un opérande visant un registre Dalvik (classe) */ +struct _GDalvikRegisterOperandClass +{ + GDalvikOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes de registre Dalvik. */ +static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *); + +/* Initialise une instance d'opérande de registre Dalvik. */ +static void g_dalvik_register_operand_init(GDalvikRegisterOperand *); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_dalvik_register_operand_add_text(const GDalvikRegisterOperand *, GRenderingOptions *, MainRendering, FILE *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_register_operand_to_buffer(const GDalvikRegisterOperand *, GBufferLine *, GRenderingOptions *); + + + +/* -------------------- LISTE D'OPERANDES RASSEMBLES EN ARGUMENT -------------------- */ + + + +/* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */ +struct _GDalvikArgsOperand +{ + GDalvikOperand parent; /* Instance parente */ + + GArchOperand **args; /* Liste d'arguments */ + size_t count; /* Taille de cette liste */ + +}; + + +/* Définition d'un opérande visant une liste d'opérandes Dalvik (classe) */ +struct _GDalvikArgsOperandClass +{ + GDalvikOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des listes d'opérandes Dalvik. */ +static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *); + +/* Initialise une instance de liste d'opérandes Dalvik. */ +static void g_dalvik_args_operand_init(GDalvikArgsOperand *); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_dalvik_args_operand_add_text(const GDalvikArgsOperand *, GRenderingOptions *, MainRendering, FILE *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_args_operand_to_buffer(const GDalvikArgsOperand *, GBufferLine *, GRenderingOptions *); + + + +/* ----------------- OPERANDES POINTANT VERS LA TABLE DE CONSTANTES ----------------- */ + + +/* Définition d'un opérande visant un élément de table de constantes Dalvik (instance) */ +struct _GDalvikPoolOperand +{ + GDalvikOperand parent; /* Instance parente */ + + DalvikPoolType type; /* Type de table visée */ + uint32_t index; /* Indice de l'élément visé */ + +}; + + +/* Définition d'un opérande visant un élément de table de constantes Dalvik (classe) */ +struct _GDalvikPoolOperandClass +{ + GDalvikOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes de constante Dalvik. */ +static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *); + +/* Initialise une instance d'opérande de constante Dalvik. */ +static void g_dalvik_pool_operand_init(GDalvikPoolOperand *); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_dalvik_pool_operand_add_text(const GDalvikPoolOperand *, GRenderingOptions *, MainRendering, FILE *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_pool_operand_to_buffer(const GDalvikPoolOperand *, GBufferLine *, GRenderingOptions *); + + + +/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */ + + +/* Liste de tous les types d'opérandes */ +typedef enum _DalvikOperandID +{ + DOI_INVALID, + + DOI_REGISTER_4, + DOI_REGISTER_8, + + DOI_IMMEDIATE_4, + DOI_IMMEDIATE_16, + DOI_IMMEDIATE_H16, + + DOI_POOL_CONST + + +} DalvikOperandID; + + +/* Procède à la lecture d'opérandes pour une instruction. */ +static bool dalvik_read_basic_operands(GArchInstruction *, const bin_t *, off_t *, off_t, bool *, SourceEndian, DalvikOperandType); + +/* Procède à la lecture d'opérandes pour une instruction. */ +static bool dalvik_read_fixed_operands(GArchInstruction *, const bin_t *, off_t *, off_t, bool *, SourceEndian, DalvikOperandType); + + + +/* ---------------------------------------------------------------------------------- */ +/* COQUILLE VIDE POUR OPERANDE DALVIK */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour un opérande de Dalvik. */ +G_DEFINE_TYPE(GDalvikOperand, g_dalvik_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes Dalvik de base. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_operand_class_init(GDalvikOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de base pour Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_operand_init(GDalvikOperand *operand) +{ + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERANDES VISANT UN REGISTRE DE DALVIK */ +/* ---------------------------------------------------------------------------------- */ + + +/* 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_DALVIK_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes de registre Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de registre Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_operand_init(GDalvikRegisterOperand *operand) +{ + GContentExporter *parent; /* Instance parente */ + + parent = G_CONTENT_EXPORTER(operand); + + parent->add_text = (add_text_fc)g_dalvik_register_operand_add_text; + parent->export_buffer = (export_buffer_fc)g_dalvik_register_operand_to_buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* low = position éventuelle des 4 bits visés. [OUT] * +* size = taille de l'opérande, et donc du registre. * +* endian = ordre des bits dans la source. * +* * +* Description : Crée un opérande visant un registre Dalvik. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_register_operand_new(const bin_t *data, off_t *pos, off_t len, bool *low, MemoryDataSize size, SourceEndian endian) +{ + GDalvikRegisterOperand *result; /* Structure à retourner */ + uint8_t index8; /* Indice sur 8 bits */ + uint16_t index16; /* Indice sur 16 bits */ + bool test; /* Bilan de lecture */ + + switch (size) + { + case MDS_4_BITS: + test = read_u4(&index8, data, pos, len, low, endian); + break; + case MDS_8_BITS: + test = read_u8(&index8, data, pos, len, endian); + break; + case MDS_16_BITS: + test = read_u16(&index16, data, pos, len, endian); + break; + default: + test = false; + break; + } + + if (!test) + return NULL; + + result = g_object_new(G_TYPE_DALVIK_REGISTER_OPERAND, NULL); + + switch (size) + { + case MDS_4_BITS: + case MDS_8_BITS: + result->reg = g_dalvik_register_new(index8); + break; + case MDS_16_BITS: + result->reg = g_dalvik_register_new(index16); + break; + default: + break; + } + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* options = options de rendu. * +* rendering = support effectif final des lignes de code. * +* stream = flux ouvert en écriture. * +* * +* Description : Ajoute du texte simple à un fichier ouvert en écriture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_operand_add_text(const GDalvikRegisterOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ + g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->reg), options, rendering, stream); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* buffer = espace où placer ledit contenu. * +* options = options de rendu. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_operand_to_buffer(const GDalvikRegisterOperand *operand, GBufferLine *buffer, GRenderingOptions *options) +{ + g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->reg), buffer, options); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* LISTE D'OPERANDES RASSEMBLES EN ARGUMENT */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */ +G_DEFINE_TYPE(GDalvikArgsOperand, g_dalvik_args_operand, G_TYPE_DALVIK_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des listes d'opérandes Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance de liste d'opérandes Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_args_operand_init(GDalvikArgsOperand *operand) +{ + GContentExporter *parent; /* Instance parente */ + + parent = G_CONTENT_EXPORTER(operand); + + parent->add_text = (add_text_fc)g_dalvik_args_operand_add_text; + parent->export_buffer = (export_buffer_fc)g_dalvik_args_operand_to_buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un réceptacle pour opérandes Dalvik servant d'arguments.* +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_args_operand_new(void) +{ + GDalvikArgsOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_ARGS_OPERAND, NULL); + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à compléter. * +* arg = nouvel argument pour un appel. * +* * +* Description : Ajoute un élément à la liste d'arguments Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_dalvik_args_operand_add(GDalvikArgsOperand *operand, GArchOperand *arg) +{ + operand->args = (GArchOperand **)realloc(operand->args, ++operand->count * sizeof(GArchOperand *)); + + operand->args[operand->count - 1] = arg; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* options = options de rendu. * +* rendering = support effectif final des lignes de code. * +* stream = flux ouvert en écriture. * +* * +* Description : Ajoute du texte simple à un fichier ouvert en écriture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_args_operand_add_text(const GDalvikArgsOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ + GContentExporter *exporter; /* Autre vision de l'objet */ + size_t i; /* Boucle de parcours */ + + exporter = G_CONTENT_EXPORTER(operand); + + g_content_exporter_insert_text(exporter, stream, "{", 1, RTT_HOOK); + + if (operand->count > 0) + { + g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->args[0]), + options, rendering, stream); + + for (i = 1; i < operand->count; i++) + { + g_content_exporter_insert_text(exporter, stream, ",", 1, RTT_NONE/* FIXME */); + + g_content_exporter_insert_text(exporter, stream, " ", 1, RTT_NONE); + + g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->args[i]), + options, rendering, stream); + + } + + } + + g_content_exporter_insert_text(exporter, stream, "}", 1, RTT_HOOK); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* buffer = espace où placer ledit contenu. * +* options = options de rendu. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_args_operand_to_buffer(const GDalvikArgsOperand *operand, GBufferLine *buffer, GRenderingOptions *options) +{ + GContentExporter *exporter; /* Autre vision de l'objet */ + size_t i; /* Boucle de parcours */ + + exporter = G_CONTENT_EXPORTER(operand); + + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "{", 1, RTT_HOOK); + + if (operand->count > 0) + { + g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->args[0]), buffer, options); + + for (i = 1; i < operand->count; i++) + { + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + ",", 1, RTT_NONE/* FIXME */); + + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + " ", 1, RTT_NONE); + + g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->args[i]), buffer, options); + + } + + } + + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "}", 1, RTT_HOOK); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERANDES POINTANT VERS LA TABLE DE CONSTANTES */ +/* ---------------------------------------------------------------------------------- */ + + +/* 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_DALVIK_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes de constante Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de constante Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_pool_operand_init(GDalvikPoolOperand *operand) +{ + GContentExporter *parent; /* Instance parente */ + + parent = G_CONTENT_EXPORTER(operand); + + parent->add_text = (add_text_fc)g_dalvik_pool_operand_add_text; + parent->export_buffer = (export_buffer_fc)g_dalvik_pool_operand_to_buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type de table visée avec la référence. * +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* size = taille de l'opérande, et donc du registre. * +* endian = ordre des bits dans la source. * +* * +* Description : Crée un opérande visant un élément constant Dalvik. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_pool_operand_new(DalvikPoolType type, const bin_t *data, off_t *pos, off_t len, MemoryDataSize size, SourceEndian endian) +{ + GDalvikPoolOperand *result; /* Structure à retourner */ + uint8_t index8; /* Indice sur 8 bits */ + uint16_t index16; /* Indice sur 16 bits */ + bool test; /* Bilan de lecture */ + + switch (size) + { + case MDS_8_BITS: + test = read_u8(&index8, data, pos, len, endian); + break; + case MDS_16_BITS: + test = read_u16(&index16, data, pos, len, endian); + break; + default: + test = false; + break; + } + + if (!test) + return NULL; + + result = g_object_new(G_TYPE_DALVIK_POOL_OPERAND, NULL); + + result->type = type; + result->index = (size == MDS_8_BITS ? index8 : index16); + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* options = options de rendu. * +* rendering = support effectif final des lignes de code. * +* stream = flux ouvert en écriture. * +* * +* Description : Ajoute du texte simple à un fichier ouvert en écriture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_pool_operand_add_text(const GDalvikPoolOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ + //g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->reg), options, rendering, stream); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* buffer = espace où placer ledit contenu. * +* options = options de rendu. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_pool_operand_to_buffer(const GDalvikPoolOperand *operand, GBufferLine *buffer, GRenderingOptions *options) +{ + GContentExporter *exporter; /* Autre vision de l'opérande */ + + char value[20]; /* Chaîne à imprimer */ + size_t len; /* Taille de l'élément inséré */ + + + + + exporter = G_CONTENT_EXPORTER(operand); + + switch (operand->type) + { + case DPT_NONE: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "????", 4, RTT_SECTION); + break; + case DPT_STRING: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "string", 6, RTT_SECTION); + break; + case DPT_TYPE: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "type", 4, RTT_SECTION); + break; + case DPT_PROTO: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "proto", 5, RTT_SECTION); + break; + case DPT_FIELD: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "field", 5, RTT_SECTION); + break; + case DPT_METHOD: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "method", 6, RTT_SECTION); + break; + } + + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "@", 1, RTT_SIGNS); + + + //g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->reg), buffer, options); + + len = snprintf(value, 20, "%d", operand->index); + /* + strcpy(value, "12345"); + + len = 5; + */ + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + value, len, RTT_IMMEDIATE); + +} + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* AIDE A LA CREATION D'OPERANDES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est incomplète. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* low = position éventuelle des 4 bits visés. [OUT] * +* endian = boutisme lié au binaire accompagnant. * +* model = type d'opérandes attendues. * +* * +* Description : Procède à la lecture d'opérandes pour une instruction. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian, DalvikOperandType model) +{ + bool result; /* Bilan à retourner */ + DalvikOperandID *types; /* Liste des chargements */ + DalvikOperandID *iter; /* Boucle de parcours */ + GArchOperand *op; /* Opérande unique décodé */ + uint16_t value16; /* Valeur sur 16 bits */ + + result = true; + + /* Choix des opérandes à charger */ + + switch (model & ~DALVIK_OP_POOL_MASK) + { + case DALVIK_OPT_12X: + types = (DalvikOperandID []) { + DOI_REGISTER_4, + DOI_REGISTER_4, + DOI_INVALID + }; + break; + + case DALVIK_OPT_11N: + types = (DalvikOperandID []) { + DOI_REGISTER_4, + DOI_IMMEDIATE_4, + DOI_INVALID + }; + break; + + case DALVIK_OPT_11X: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_INVALID + }; + break; + + case DALVIK_OPT_21C: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_POOL_CONST, + DOI_INVALID + }; + break; + + case DALVIK_OPT_21H: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_IMMEDIATE_H16, + DOI_INVALID + }; + break; + + case DALVIK_OPT_21S: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_IMMEDIATE_16, + DOI_INVALID + }; + break; + + default: + types = (DalvikOperandID []) { + DOI_INVALID + }; + break; + + } + + /* Chargement des opérandes */ + + for (iter = types; *iter != G_TYPE_INVALID && result; iter++) + { + switch (*iter) + { + case DOI_REGISTER_4: + op = g_dalvik_register_operand_new(data, pos, len, low, MDS_4_BITS, endian); + break; + + case DOI_REGISTER_8: + op = g_dalvik_register_operand_new(data, pos, len, NULL, MDS_8_BITS, endian); + break; + + case DOI_IMMEDIATE_4: + op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, len, low, endian); + break; + + case DOI_IMMEDIATE_16: + op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, len, endian); + break; + + case DOI_IMMEDIATE_H16: + result = read_u16(&value16, data, pos, len, endian); + if (result) + op = g_imm_operand_new_from_value(MDS_32_BITS_SIGNED, ((uint32_t)value16) << 16); + break; + + case DOI_POOL_CONST: + op = g_dalvik_pool_operand_new(DALVIK_OP_GET_POOL(model), data, pos, len, MDS_16_BITS, endian); + break; + + default: + op = NULL; + break; + + } + + if (op == NULL) result = false; + else g_arch_instruction_attach_extra_operand(instr, op); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est incomplète. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* low = position éventuelle des 4 bits visés. [OUT] * +* endian = boutisme lié au binaire accompagnant. * +* model = type d'opérandes attendues. * +* * +* Description : Procède à la lecture d'opérandes pour une instruction. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool dalvik_read_fixed_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian, DalvikOperandType model) +{ + GArchOperand *opa; /* Opérande vA décodé */ + uint8_t b; /* Nbre. de registres utilisés */ + GArchOperand *target1; /* Opérande visant la table #1 */ + GArchOperand *target2; /* Opérande visant la table #2 */ + GArchOperand *args; /* Liste des opérandes */ + uint8_t i; /* Boucle de parcours */ + GArchOperand *op; /* Opérande unique décodé */ + + + + opa = g_dalvik_register_operand_new(data, pos, len, low, MDS_4_BITS, endian); + + if (!read_u4(&b, data, pos, len, low, endian)) + goto err_va; + + + target1 = g_dalvik_pool_operand_new(DALVIK_OP_GET_POOL(model), data, pos, len, MDS_16_BITS, endian); + if (target1 == NULL) goto err_target1; + + + + target2 = NULL; + + if (0) + { + if (target2 == NULL) goto err_target2; + } + + + args = g_dalvik_args_operand_new(); + g_arch_instruction_attach_extra_operand(instr, args); + + + /* Mise en place des arguments */ + + for (i = 0; i < MIN(b, 4); i++) + { + op = g_dalvik_register_operand_new(data, pos, len, low, MDS_4_BITS, endian); + if (op == NULL) goto err_registers; + + g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op); + + } + + /* Rajout des éléments finaux déjà chargés */ + + if (b < 5) g_object_unref(G_OBJECT(opa)); + else g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), opa); + + g_arch_instruction_attach_extra_operand(instr, target1); + + if (target2 != NULL) + g_arch_instruction_attach_extra_operand(instr, target2); + + return true; + + err_registers: + + if (target2 != NULL) + g_object_unref(G_OBJECT(target2)); + + err_target2: + + g_object_unref(G_OBJECT(target1)); + + err_target1: + + g_object_unref(G_OBJECT(opa)); + + err_va: + + return false; + +} + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est incomplète. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* endian = boutisme lié au binaire accompagnant. * +* model = type d'opérandes attendues. * +* * +* Description : Procède à la lecture d'opérandes pour une instruction. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, SourceEndian endian, DalvikOperandType model) +{ + bool result; /* Bilan à retourner */ + + + bool low; + + off_t old_pos; + + off_t length; + + result = true; + + + old_pos = *pos; + + + low = true; + + + + switch (model & ~DALVIK_OP_POOL_MASK) + { + case DALVIK_OPT_12X: + case DALVIK_OPT_11N: + case DALVIK_OPT_11X: + case DALVIK_OPT_21C: + case DALVIK_OPT_21H: + case DALVIK_OPT_21S: + result = dalvik_read_basic_operands(instr, data, pos, len, &low, endian, model); + break; + + case DALVIK_OPT_35C: + result = dalvik_read_fixed_operands(instr, data, pos, len, &low, endian, model); + break; + + default: + break; + + } + + + + *pos = old_pos; + + + + if (*pos < len) + { + (*pos)++; + + length = DALVIK_OP_GET_LEN(model); + + if (length > 1) + *pos += (length - 1) * sizeof(uint16_t); + + } + + + + + return result; + +} |