diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2021-09-26 21:21:41 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2021-09-26 21:21:41 (GMT) |
commit | dc25699a414f0baa2265be0cfa162c77b2cdc22d (patch) | |
tree | da0d2d78716e6818aa7e1b8851f70f47da8a905f /plugins/dalvik | |
parent | ce46ff64c00a90d03e2481dcaf1e713f22b71492 (diff) |
Provide a serialization capability for operands.
Diffstat (limited to 'plugins/dalvik')
-rw-r--r-- | plugins/dalvik/operands/args.c | 279 | ||||
-rw-r--r-- | plugins/dalvik/operands/pool.c | 404 |
2 files changed, 394 insertions, 289 deletions
diff --git a/plugins/dalvik/operands/args.c b/plugins/dalvik/operands/args.c index 9aa948d..7eec5d7 100644 --- a/plugins/dalvik/operands/args.c +++ b/plugins/dalvik/operands/args.c @@ -37,6 +37,9 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */ struct _GDalvikArgsOperand { @@ -68,6 +71,11 @@ 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 *, bool); @@ -80,11 +88,6 @@ 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 *); - - -/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */ - - /* Fournit une liste de candidats embarqués par un candidat. */ static GArchOperand **g_dalvik_args_operand_list_inner_instances(const GDalvikArgsOperand *, size_t *); @@ -94,17 +97,17 @@ static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *, G /* Fournit l'empreinte d'un candidat à une centralisation. */ static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_dalvik_args_operand_load(GDalvikArgsOperand *, GObjectStorage *, packed_buffer_t *); - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_dalvik_args_operand_store(GDalvikArgsOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_dalvik_args_operand_serialize(const GDalvikArgsOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */ @@ -145,8 +148,8 @@ static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass) 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->unserialize = (unserialize_operand_fc)g_dalvik_args_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_dalvik_args_operand_serialize; + operand->load = (load_operand_fc)g_dalvik_args_operand_load; + operand->store = (store_operand_fc)g_dalvik_args_operand_store; } @@ -188,7 +191,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)); @@ -219,6 +222,99 @@ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *operand) /****************************************************************************** * * +* 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. * @@ -441,99 +537,6 @@ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *operand, GBuff /****************************************************************************** * * -* 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 = (GArchOperand **)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]; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONTROLE DU VOLUME DES INSTANCES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * * Paramètres : operand = objet dont l'instance se veut unique. * * count = quantité d'instances à l'unicité internes. * * * @@ -634,20 +637,13 @@ static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *operand, bool } - -/* ---------------------------------------------------------------------------------- */ -/* 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. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -655,33 +651,38 @@ static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *operand, bool * * ******************************************************************************/ -static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_dalvik_args_operand_load(GDalvikArgsOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - size_t count; /* Nombre d'opérandes à charger*/ + uleb128_t value; /* Valeur ULEB128 à charger */ size_t i; /* Boucle de parcours */ - GArchOperand *arg; /* Nouvel argument à intégrer */ + GSerializableObject *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); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); + result = unpack_uleb128(&value, pbuf); - for (i = 0; i < count && result; i++) + if (result) { - arg = g_arch_operand_load(storage, format, pbuf); + operand->count = value; + operand->args = calloc(operand->count, sizeof(GArchOperand *)); + } - if (arg == NULL) - result = false; + for (i = 0; i < operand->count && result; i++) + { + arg = g_object_storage_unpack_object(storage, "operands", pbuf); + if (arg == NULL) break; - else - g_dalvik_args_operand_add(operand, arg); + operand->args[operand->count - 1] = G_ARCH_OPERAND(arg); } + result = (i == operand->count); + return result; } @@ -689,11 +690,11 @@ static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *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. * * * @@ -701,21 +702,25 @@ static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *operand, GAsmS * * ******************************************************************************/ -static bool g_dalvik_args_operand_serialize(const GDalvikArgsOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_dalvik_args_operand_store(GDalvikArgsOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ size_t i; /* Boucle de parcours */ + GSerializableObject *arg; /* Nouvel argument à intégrer */ parent = G_ARCH_OPERAND_CLASS(g_dalvik_args_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->count, sizeof(size_t), true); + result = pack_uleb128((uleb128_t []){ operand->count }, pbuf); for (i = 0; i < operand->count && result; i++) - result = g_arch_operand_store(operand->args[i], storage, pbuf); + { + arg = G_SERIALIZABLE_OBJECT(operand->args[i]); + result = g_object_storage_pack_object(storage, "operands", arg, pbuf); + } return result; diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index acec518..4570c86 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -39,13 +39,25 @@ +/* -------------------------- 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 __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_DALVIK_POOL_OP_EXTRA(op) (dpoolop_extra_data_t *)&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,30 +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 *, bool); +/* 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 --------------------- */ -/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */ +/* 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 contenu depuis une mémoire tampon. */ +static bool g_dalvik_pool_operand_load(GDalvikPoolOperand *, GObjectStorage *, packed_buffer_t *); - -/* --------------------- 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_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_dalvik_pool_operand_store(GDalvikPoolOperand *, GObjectStorage *, packed_buffer_t *); @@ -109,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)); @@ -143,8 +173,8 @@ static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *klass) operand->hash = (operand_hash_fc)g_dalvik_pool_operand_hash; - operand->unserialize = (unserialize_operand_fc)g_dalvik_pool_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_dalvik_pool_operand_serialize; + operand->load = (load_operand_fc)g_dalvik_pool_operand_load; + operand->store = (store_operand_fc)g_dalvik_pool_operand_store; } @@ -201,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)); @@ -230,6 +259,152 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) /****************************************************************************** * * +* 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. * @@ -245,12 +420,12 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDalvikPoolOperand *b, bool lock) { int result; /* Bilan à renvoyer */ - lockable_obj_extra_t *ea; /* Données insérées à consulter*/ - lockable_obj_extra_t *eb; /* Données insérées à consulter*/ + 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_GOBJECT_EXTRA(G_OBJECT(a), lockable_obj_extra_t); - eb = GET_GOBJECT_EXTRA(G_OBJECT(b), lockable_obj_extra_t); + ea = GET_DALVIK_POOL_OP_EXTRA(a); + eb = GET_DALVIK_POOL_OP_EXTRA(b); if (lock) { @@ -261,7 +436,7 @@ static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDal 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); @@ -299,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 */ @@ -309,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); @@ -470,107 +648,6 @@ 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. * -* * -* 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 */ - - 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); - - g_object_ref(G_OBJECT(format)); - - result->format = format; - result->type = type; - result->index = (size == MDS_16_BITS ? index16 : index32); - - return G_ARCH_OPERAND(result); - - gdpon_exit: - - return NULL; - -} - - -/****************************************************************************** -* * -* 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) -{ - return operand->type; - -} - - -/****************************************************************************** -* * -* 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) -{ - return operand->index; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONTROLE DU VOLUME DES INSTANCES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * * Paramètres : operand = objet dont l'instance se veut unique. * * lock = précise le besoin en verrouillage. * * * @@ -600,7 +677,7 @@ static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand, bool result ^= g_direct_hash(operand->format); - type = g_dalvik_pool_operand_get_pool_type(operand); + type = _g_dalvik_pool_operand_get_pool_type(operand, !lock); result ^= type; @@ -616,20 +693,13 @@ static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand, bool } - -/* ---------------------------------------------------------------------------------- */ -/* 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. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -637,26 +707,43 @@ static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand, bool * * ******************************************************************************/ -static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_dalvik_pool_operand_load(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 */ + uleb128_t value; /* Valeur ULEB128 à charger */ parent = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + { + extra = GET_DALVIK_POOL_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = unpack_uleb128(&value, pbuf); + + if (result) + extra->type = value; + + UNLOCK_GOBJECT_EXTRA(extra); + + } 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; @@ -665,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. * * * @@ -677,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_t *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; @@ -722,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 */ @@ -729,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)); |