diff options
Diffstat (limited to 'plugins/dalvik/operands')
-rw-r--r-- | plugins/dalvik/operands/Makefile.am | 16 | ||||
-rw-r--r-- | plugins/dalvik/operands/args.c | 321 | ||||
-rw-r--r-- | plugins/dalvik/operands/pool.c | 416 |
3 files changed, 498 insertions, 255 deletions
diff --git a/plugins/dalvik/operands/Makefile.am b/plugins/dalvik/operands/Makefile.am index 4ce597a..3a4ddc1 100644 --- a/plugins/dalvik/operands/Makefile.am +++ b/plugins/dalvik/operands/Makefile.am @@ -1,20 +1,14 @@ noinst_LTLIBRARIES = libdalvikoperands.la -libdalvikoperands_la_SOURCES = \ - args.h args.c \ - pool.h pool.c \ +libdalvikoperands_la_SOURCES = \ + args.h args.c \ + pool.h pool.c \ register.h register.c +libdalvikoperands_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src + devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libdalvikoperands_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) - - -SUBDIRS = diff --git a/plugins/dalvik/operands/args.c b/plugins/dalvik/operands/args.c index 4b87e5e..64f8eea 100644 --- a/plugins/dalvik/operands/args.c +++ b/plugins/dalvik/operands/args.c @@ -32,11 +32,14 @@ #include <arch/operand-int.h> #include <common/sort.h> +#include <core/columns.h> #include <core/logs.h> -#include <gtkext/gtkblockdisplay.h> +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */ struct _GDalvikArgsOperand { @@ -68,8 +71,13 @@ static void g_dalvik_args_operand_dispose(GDalvikArgsOperand *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *, const GDalvikArgsOperand *); +static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *, const GDalvikArgsOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_dalvik_args_operand_find_inner_operand_path(const GDalvikArgsOperand *, const GArchOperand *); @@ -80,17 +88,20 @@ static GArchOperand *g_dalvik_args_operand_get_inner_operand_from_path(const GDa /* Traduit un opérande en version humainement lisible. */ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *, GBufferLine *); +/* Fournit une liste de candidats embarqués par un candidat. */ +static GArchOperand **g_dalvik_args_operand_list_inner_instances(const GDalvikArgsOperand *, size_t *); +/* Met à jour une liste de candidats embarqués par un candidat. */ +static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *, GArchOperand **, size_t); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *, bool); -/* 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 *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */ @@ -127,8 +138,12 @@ static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass) 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; + operand->list_inner = (operand_list_inners_fc)g_dalvik_args_operand_list_inner_instances; + operand->update_inner = (operand_update_inners_fc)g_dalvik_args_operand_update_inner_instances; + operand->hash = (operand_hash_fc)g_dalvik_args_operand_hash; + + operand->load = g_arch_operand_load_generic_variadic; + operand->store = g_arch_operand_store_generic_variadic; } @@ -170,7 +185,7 @@ static void g_dalvik_args_operand_dispose(GDalvikArgsOperand *operand) size_t i; for (i = 0; i < operand->count; i++) - g_object_unref(G_OBJECT(operand->args[i])); + g_clear_object(&operand->args[i]); G_OBJECT_CLASS(g_dalvik_args_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -201,8 +216,102 @@ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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) +{ + GArchOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_ARGS_OPERAND, NULL); + + return 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->count++; + operand->args = realloc(operand->args, operand->count * sizeof(GArchOperand *)); + + operand->args[operand->count - 1] = arg; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à compléter. * +* * +* Description : Fournit le nombre d'arguments pris en charge. * +* * +* Retour : Nombre positif ou nul. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_dalvik_args_count(const GDalvikArgsOperand *operand) +{ + return operand->count; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à compléter. * +* index = indice de l'argument recherché. * +* * +* Description : Founit un élément de la liste d'arguments Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_args_operand_get(const GDalvikArgsOperand *operand, size_t index) +{ + assert(index < operand->count); + + return operand->args[index]; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -212,10 +321,13 @@ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *operand) * * ******************************************************************************/ -static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *a, const GDalvikArgsOperand *b) +static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *a, const GDalvikArgsOperand *b, bool lock) { int result; /* Bilan à renvoyer */ + operand_extra_data_t *ea; /* Données insérées à consulter*/ + operand_extra_data_t *eb; /* Données insérées à consulter*/ size_t i; /* Boucle de parcours */ + GArchOperandClass *class; /* Classe parente normalisée */ /* Création de l'objet... */ if (b == NULL) @@ -223,11 +335,32 @@ static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *a, const GDal else { + ea = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(a)); + eb = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(b)); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } + result = sort_unsigned_long(a->count, b->count); for (i = 0; i < a->count && result == 0; i++) result = g_arch_operand_compare(a->args[i], b->args[i]); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_dalvik_args_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + + if (lock) + { + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); + } + } return result; @@ -398,75 +531,44 @@ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *operand, GBuff /****************************************************************************** * * -* Paramètres : - * +* Paramètres : operand = objet dont l'instance se veut unique. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Crée un réceptacle pour opérandes Dalvik servant d'arguments.* +* Description : Fournit une liste de candidats embarqués par un candidat. * * * -* Retour : Opérande mis en place. * +* Retour : Liste de candidats internes ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_dalvik_args_operand_new(void) +static GArchOperand **g_dalvik_args_operand_list_inner_instances(const GDalvikArgsOperand *operand, size_t *count) { - GArchOperand *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_DALVIK_ARGS_OPERAND, NULL); - - return 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->count++; - operand->args = (GArchOperand **)realloc(operand->args, operand->count * sizeof(GArchOperand *)); - - operand->args[operand->count - 1] = arg; + GArchOperand **result; /* Instances à retourner */ + size_t i; /* Boucle de parcours */ -} + *count = operand->count; + result = malloc(*count * sizeof(GArchOperand *)); -/****************************************************************************** -* * -* Paramètres : operand = opérande à compléter. * -* * -* Description : Fournit le nombre d'arguments pris en charge. * -* * -* Retour : Nombre positif ou nul. * -* * -* Remarques : - * -* * -******************************************************************************/ + for (i = 0; i < *count; i++) + { + result[i] = operand->args[i]; + g_object_ref(G_OBJECT(result[i])); + } -size_t g_dalvik_args_count(const GDalvikArgsOperand *operand) -{ - return operand->count; + return result; } /****************************************************************************** * * -* Paramètres : operand = opérande à compléter. * -* index = indice de l'argument recherché. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* instances = liste de candidats internes devenus singletons. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Founit un élément de la liste d'arguments Dalvik. * +* Description : Met à jour une liste de candidats embarqués par un candidat. * * * * Retour : - * * * @@ -474,97 +576,56 @@ size_t g_dalvik_args_count(const GDalvikArgsOperand *operand) * * ******************************************************************************/ -GArchOperand *g_dalvik_args_operand_get(const GDalvikArgsOperand *operand, size_t index) +static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *operand, GArchOperand **instances, size_t count) { - assert(index < operand->count); - - 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); + for (i = 0; i < count; i++) + g_object_unref(G_OBJECT(operand->args[i])); - if (result) - result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); + operand->count = count; + operand->args = realloc(operand->args, operand->count * sizeof(GArchOperand *)); - for (i = 0; i < count && result; i++) + for (i = 0; i < count; i++) { - arg = g_arch_operand_load(storage, format, pbuf); - - if (arg == NULL) - result = false; - - else - g_dalvik_args_operand_add(operand, arg); - + operand->args[i] = instances[i]; + g_object_ref(G_OBJECT(instances[i])); } - return result; - } /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * * * -* Retour : Bilan de l'opération. * +* Retour : Empreinte de l'élément représenté. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_dalvik_args_operand_serialize(const GDalvikArgsOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *operand, bool lock) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - size_t i; /* Boucle de parcours */ + guint result; /* Valeur à retourner */ + operand_extra_data_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + + extra = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(operand)); - parent = G_ARCH_OPERAND_CLASS(g_dalvik_args_operand_parent_class); + if (lock) + LOCK_GOBJECT_EXTRA(extra); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + class = G_ARCH_OPERAND_CLASS(g_dalvik_args_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); - if (result) - result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true); + result ^= operand->count; - for (i = 0; i < operand->count && result; i++) - result = g_arch_operand_store(operand->args[i], storage, pbuf); + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); return result; diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index 6f16cdc..5b99b45 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -34,18 +34,30 @@ #include <arch/operand-int.h> #include <arch/operands/targetable-int.h> #include <common/sort.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> #include <plugins/dex/pool.h> +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _dpoolop_extra_data_t +{ + operand_extra_data_t parent; /* A laisser en premier */ + + DalvikPoolType type; /* Type de table visée */ + +} dpoolop_extra_data_t; + + /* Définition d'un opérande visant un élément de table de constantes Dalvik (instance) */ struct _GDalvikPoolOperand { GArchOperand parent; /* Instance parente */ GDexFormat *format; /* Lien vers le contenu réel */ - DalvikPoolType type; /* Type de table visée */ uint32_t index; /* Indice de l'élément visé */ }; @@ -59,6 +71,21 @@ struct _GDalvikPoolOperandClass }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_DALVIK_POOL_OP_EXTRA(op) ((dpoolop_extra_data_t *)&((GArchOperand *)op)->extra) + +#else + +# define GET_DALVIK_POOL_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), dpoolop_extra_data_t) + +#endif + + /* Initialise la classe des opérandes de constante Dalvik. */ static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *); @@ -74,22 +101,28 @@ static void g_dalvik_pool_operand_dispose(GDalvikPoolOperand *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *); -/* Compare un opérande avec un autre. */ -static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *, const GDalvikPoolOperand *); +/* Indique la nature de la table de constantes visée ici. */ +static DalvikPoolType _g_dalvik_pool_operand_get_pool_type(const GDalvikPoolOperand *, bool); + -/* Traduit un opérande en version humainement lisible. */ -static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *, GBufferLine *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Compare un opérande avec un autre. */ +static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *, const GDalvikPoolOperand *, bool); + +/* Traduit un opérande en version humainement lisible. */ +static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *, bool); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_dalvik_pool_operand_load(GDalvikPoolOperand *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *, GAsmStorage *, packed_buffer *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_dalvik_pool_operand_store(GDalvikPoolOperand *, GObjectStorage *, packed_buffer_t *); @@ -101,6 +134,11 @@ static bool g_dalvik_pool_operand_get_addr(const GDalvikPoolOperand *, const vmp +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ + + /* Indique le type défini par la GLib pour un un élément de table de constantes Dalvik. */ G_DEFINE_TYPE_WITH_CODE(GDalvikPoolOperand, g_dalvik_pool_operand, G_TYPE_ARCH_OPERAND, G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_dalvik_pool_operand_targetable_interface_init)); @@ -133,8 +171,10 @@ 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; + operand->hash = (operand_hash_fc)g_dalvik_pool_operand_hash; + + operand->load = (load_operand_fc)g_dalvik_pool_operand_load; + operand->store = (store_operand_fc)g_dalvik_pool_operand_store; } @@ -191,8 +231,7 @@ static void g_dalvik_pool_operand_targetable_interface_init(GTargetableOperandIn static void g_dalvik_pool_operand_dispose(GDalvikPoolOperand *operand) { - if (operand->format != NULL) - g_object_unref(G_OBJECT(operand->format)); + g_clear_object(&operand->format); G_OBJECT_CLASS(g_dalvik_pool_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -220,8 +259,155 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : format = format du fichier contenant le code. * +* type = type de table visée avec la référence. * +* content = flux de données à analyser. * +* pos = position courante dans ce flux. [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 élément constant Dalvik. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_pool_operand_new(GDexFormat *format, DalvikPoolType type, const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian) +{ + GDalvikPoolOperand *result; /* Structure à retourner */ + uint16_t index16; /* Indice sur 16 bits */ + uint32_t index32; /* Indice sur 32 bits */ + bool test; /* Bilan de lecture */ + dpoolop_extra_data_t *extra; /* Données insérées à modifier */ + + switch (size) + { + case MDS_16_BITS: + test = g_binary_content_read_u16(content, pos, endian, &index16); + break; + case MDS_32_BITS: + test = g_binary_content_read_u32(content, pos, endian, &index32); + break; + default: + test = false; + break; + } + + if (!test) + goto gdpon_exit; + + result = g_object_new(G_TYPE_DALVIK_POOL_OPERAND, NULL); + + extra = GET_DALVIK_POOL_OP_EXTRA(result); + + extra->type = type; + + result->format = format; + g_object_ref(G_OBJECT(format)); + + result->index = (size == MDS_16_BITS ? index16 : index32); + + return G_ARCH_OPERAND(result); + + gdpon_exit: + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Indique la nature de la table de constantes visée ici. * +* * +* Retour : Type de table constantes visée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static DalvikPoolType _g_dalvik_pool_operand_get_pool_type(const GDalvikPoolOperand *operand, bool lock) +{ + DalvikPoolType result; /* Type à retourner */ + dpoolop_extra_data_t *extra; /* Données insérées à consulter*/ + + extra = GET_DALVIK_POOL_OP_EXTRA(operand); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + result = extra->type; + + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique la nature de la table de constantes visée ici. * +* * +* Retour : Type de table constantes visée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +DalvikPoolType g_dalvik_pool_operand_get_pool_type(const GDalvikPoolOperand *operand) +{ + DalvikPoolType result; /* Type à retourner */ + + result = _g_dalvik_pool_operand_get_pool_type(operand, true); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique l'indice de l'élément dans la table de constantes. * +* * +* Retour : Indice de l'élément visé dans la table de constantes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand) +{ + uint32_t result; /* Indice à retourner */ + + result = operand->index; + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -231,18 +417,42 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) * * ******************************************************************************/ -static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDalvikPoolOperand *b) +static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDalvikPoolOperand *b, bool lock) { int result; /* Bilan à renvoyer */ + dpoolop_extra_data_t *ea; /* Données insérées à consulter*/ + dpoolop_extra_data_t *eb; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + + ea = GET_DALVIK_POOL_OP_EXTRA(a); + eb = GET_DALVIK_POOL_OP_EXTRA(b); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } result = sort_unsigned_long((unsigned long)a->format, (unsigned long)b->format); if (result == 0) - result = sort_unsigned_long(a->type, b->type); + result = sort_unsigned_long(ea->type, eb->type); if (result == 0) result = sort_unsigned_long(a->index, b->index); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + + if (lock) + { + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); + } + return result; } @@ -264,6 +474,7 @@ static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDal static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBufferLine *line) { GDexPool *pool; /* Table de ressources */ + DalvikPoolType pool_type; /* Type de table visé */ const char *string; /* Chaîne de caractères #1 */ GDataType *type; /* Type à représenter */ size_t len; /* Taille du texte à créer */ @@ -274,7 +485,9 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff pool = g_dex_format_get_pool(operand->format); - switch (operand->type) + pool_type = g_dalvik_pool_operand_get_pool_type(operand); + + switch (pool_type) { case DPT_NONE: g_buffer_line_append_text(line, DLC_ASSEMBLY, "????", 4, RTT_ERROR, NULL); @@ -435,140 +648,102 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff /****************************************************************************** * * -* Paramètres : format = format du fichier contenant le code. * -* type = type de table visée avec la référence. * -* content = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* size = taille de l'opérande, et donc du registre. * -* endian = ordre des bits dans la source. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * -* Description : Crée un opérande visant un élément constant Dalvik. * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * * * -* Retour : Opérande mis en place. * +* Retour : Empreinte de l'élément représenté. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_dalvik_pool_operand_new(GDexFormat *format, DalvikPoolType type, const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian) +static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand, bool lock) { - GDalvikPoolOperand *result; /* Structure à retourner */ - uint16_t index16; /* Indice sur 16 bits */ - uint32_t index32; /* Indice sur 32 bits */ - bool test; /* Bilan de lecture */ - - switch (size) - { - case MDS_16_BITS: - test = g_binary_content_read_u16(content, pos, endian, &index16); - break; - case MDS_32_BITS: - test = g_binary_content_read_u32(content, pos, endian, &index32); - break; - default: - test = false; - break; - } - - if (!test) - goto gdpon_exit; + guint result; /* Valeur à retourner */ + dpoolop_extra_data_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + DalvikPoolType type; /* Type porté par l'opérande */ + uint32_t index; /* Indice de l'élément */ - result = g_object_new(G_TYPE_DALVIK_POOL_OPERAND, NULL); + extra = GET_DALVIK_POOL_OP_EXTRA(G_DALVIK_POOL_OPERAND(operand)); - g_object_ref(G_OBJECT(format)); + if (lock) + LOCK_GOBJECT_EXTRA(extra); - result->format = format; - result->type = type; - result->index = (size == MDS_16_BITS ? index16 : index32); + class = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); - return G_ARCH_OPERAND(result); + result ^= g_direct_hash(operand->format); - gdpon_exit: + type = _g_dalvik_pool_operand_get_pool_type(operand, !lock); - return NULL; + result ^= type; -} + index = g_dalvik_pool_operand_get_index(operand); + result ^= index; -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique la nature de la table de constantes visée ici. * -* * -* Retour : Type de table constantes visée. * -* * -* Remarques : - * -* * -******************************************************************************/ + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); -DalvikPoolType g_dalvik_pool_operand_get_pool_type(const GDalvikPoolOperand *operand) -{ - return operand->type; + return result; } /****************************************************************************** * * -* Paramètres : operand = opérande à consulter. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Indique l'indice de l'élément dans la table de constantes. * +* Description : Charge un contenu depuis une mémoire tampon. * * * -* Retour : Indice de l'élément visé dans la table de constantes. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand) +static bool g_dalvik_pool_operand_load(GDalvikPoolOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { - return operand->index; - -} + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + dpoolop_extra_data_t *extra; /* Données insérées à modifier */ + uleb128_t value; /* Valeur ULEB128 à charger */ + parent = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ + if (result) + { + extra = GET_DALVIK_POOL_OP_EXTRA(operand); + LOCK_GOBJECT_EXTRA(extra); -/****************************************************************************** -* * -* 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 : - * -* * -******************************************************************************/ + result = unpack_uleb128(&value, pbuf); -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 */ + if (result) + extra->type = value; - parent = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); + UNLOCK_GOBJECT_EXTRA(extra); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + } if (result) { - operand->format = G_DEX_FORMAT(format); - g_object_ref(G_OBJECT(format)); + operand->format = get_storage_linked_format(storage); + result = G_IS_DEX_FORMAT(operand->format); } if (result) - result = extract_packed_buffer(pbuf, &operand->type, sizeof(DalvikPoolType), true); + result = unpack_uleb128(&value, pbuf); if (result) - result = extract_packed_buffer(pbuf, &operand->index, sizeof(uint32_t), true); + operand->index = value; return result; @@ -577,11 +752,11 @@ static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *operand, GAsmS /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -589,20 +764,30 @@ static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *operand, GAsmS * * ******************************************************************************/ -static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +static bool g_dalvik_pool_operand_store(GDalvikPoolOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + dpoolop_extra_data_t *extra; /* Données insérées à modifier */ parent = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extend_packed_buffer(pbuf, &operand->type, sizeof(DalvikPoolType), true); + { + extra = GET_DALVIK_POOL_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = pack_uleb128((uleb128_t []){ extra->type }, pbuf); + + UNLOCK_GOBJECT_EXTRA(extra); + + } if (result) - result = extend_packed_buffer(pbuf, &operand->index, sizeof(uint32_t), true); + result = pack_uleb128((uleb128_t []){ operand->index }, pbuf); return result; @@ -634,6 +819,7 @@ static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *operand, G static bool g_dalvik_pool_operand_get_addr(const GDalvikPoolOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) { bool result; /* Bilan à retourner */ + DalvikPoolType type; /* Type de table visé */ GDexPool *pool; /* Table de ressources */ GDexMethod *method; /* Méthode ciblée ici */ GBinRoutine *routine; /* Routine liée à la méthode */ @@ -641,7 +827,9 @@ static bool g_dalvik_pool_operand_get_addr(const GDalvikPoolOperand *operand, co result = false; - if (operand->type == DPT_METHOD) + type = g_dalvik_pool_operand_get_pool_type(operand); + + if (type == DPT_METHOD) { pool = g_dex_format_get_pool(G_DEX_FORMAT(format)); |