diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2019-05-07 21:53:40 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2019-05-07 21:53:40 (GMT) |
commit | dd2b41538e20de5472cd8c888c530327a1351866 (patch) | |
tree | 7f9a24a32ecd33aacb98a5d1ec4234011c1364a6 /plugins/dex/pool.c | |
parent | b92a5e56de9198c08956ce486cd12712d7034731 (diff) |
Read raw Dex items by extending the API.
Diffstat (limited to 'plugins/dex/pool.c')
-rw-r--r-- | plugins/dex/pool.c | 339 |
1 files changed, 247 insertions, 92 deletions
diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c index 6905c3b..e7dd205 100644 --- a/plugins/dex/pool.c +++ b/plugins/dex/pool.c @@ -492,6 +492,48 @@ uint32_t g_dex_pool_count_types(const GDexPool *pool) /****************************************************************************** * * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index du type recherché. * +* type_id = élément ciblé à constituer. [OUT] * +* * +* Description : Reconstitue les éléments bruts d'un type Dex. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_dex_pool_get_raw_type(GDexPool *pool, uint32_t index, type_id_item *type_id) +{ + bool result; /* Bilan à retourner */ + uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ + phys_t pos; /* Tête de lecture */ + vmpa2t addr; /* Tête de lecture générique */ + + result = false; + + count = g_dex_pool_count_types(pool); + + if (index < count) + { + format = pool->format; + + pos = format->header.type_ids_off + index * sizeof(type_id_item); + init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); + + result = read_dex_type_id_item(format, &addr, type_id); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : pool = table de resources pour format Dex à consulter. * * index = index du type recherché. * * * @@ -506,42 +548,33 @@ uint32_t g_dex_pool_count_types(const GDexPool *pool) GDataType *g_dex_pool_get_type_(GDexPool *pool, uint32_t index) { GDataType *result; /* Instance à retourner */ - uint32_t count; /* Nombre d'éléments présents */ + type_id_item type_id; /* Définition de la classe */ GDexFormat *format; /* Format associé à la table */ phys_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ - type_id_item type_id; /* Définition de la classe */ string_id_item str_id; /* Identifiant de chaîne */ string_data_item str_data; /* Description de chaîne */ result = NULL; - count = g_dex_pool_count_types(pool); - - if (index >= count) - goto gtfdp_error; - if (pool->types[index] == NULL) { - format = pool->format; + if (!g_dex_pool_get_raw_type(pool, index, &type_id)) + goto no_type_id; - pos = format->header.type_ids_off + index * sizeof(type_id_item); - init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); - - if (!read_dex_type_id_item(format, &addr, &type_id)) - goto gtfdp_error; + format = pool->format; pos = format->header.string_ids_off + type_id.descriptor_idx * sizeof(string_id_item); init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); if (!read_dex_string_id_item(format, &addr, &str_id)) - goto gtfdp_error; + goto type_error; pos = str_id.string_data_off; init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); if (!read_dex_string_data_item(format, &addr, NULL, &str_data)) - goto gtfdp_error; + goto type_error; pool->types[index] = g_binary_format_decode_type(G_BIN_FORMAT(format), (char *)str_data.data); @@ -552,7 +585,9 @@ GDataType *g_dex_pool_get_type_(GDexPool *pool, uint32_t index) if (result != NULL) g_object_ref(G_OBJECT(result)); - gtfdp_error: + type_error: + + no_type_id: return result; @@ -653,6 +688,48 @@ uint32_t g_dex_pool_count_fields(const GDexPool *pool) /****************************************************************************** * * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index du type recherché. * +* field_id = élément ciblé à constituer. [OUT] * +* * +* Description : Reconstitue les éléments bruts d'un champ Dex. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_dex_pool_get_raw_field(GDexPool *pool, uint32_t index, field_id_item *field_id) +{ + bool result; /* Bilan à retourner */ + uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ + phys_t pos; /* Tête de lecture */ + vmpa2t addr; /* Tête de lecture générique */ + + result = false; + + count = g_dex_pool_count_fields(pool); + + if (index < count) + { + format = pool->format; + + pos = format->header.field_ids_off + index * sizeof(field_id_item); + init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); + + result = read_dex_field_id_item(format, &addr, field_id); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : pool = table de resources pour format Dex à consulter. * * index = index du champ recherché. * * * @@ -667,10 +744,6 @@ uint32_t g_dex_pool_count_fields(const GDexPool *pool) GBinVariable *g_dex_pool_get_field(GDexPool *pool, uint32_t index) { GBinVariable *result; /* Instance à retourner */ - uint32_t count; /* Nombre d'éléments présents */ - GDexFormat *format; /* Format associé à la table */ - phys_t pos; /* Tête de lecture */ - vmpa2t addr; /* Tête de lecture générique */ field_id_item field_id; /* Description du champ */ GDataType *type; /* Type du champ */ const char *name; /* Désignation humaine */ @@ -679,26 +752,16 @@ GBinVariable *g_dex_pool_get_field(GDexPool *pool, uint32_t index) result = NULL; - count = g_dex_pool_count_fields(pool); - - if (index >= count) - goto gffdp_error; - if (pool->fields[index] == NULL) { - format = pool->format; - - pos = format->header.field_ids_off + index * sizeof(field_id_item); - init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); - - if (!read_dex_field_id_item(format, &addr, &field_id)) - goto gffdp_error; + if (!g_dex_pool_get_raw_field(pool, index, &field_id)) + goto no_field_id; type = g_dex_pool_get_type_(pool, field_id.type_idx); - if (type == NULL) goto gffdp_error; + if (type == NULL) goto type_error; name = g_dex_pool_get_string(pool, field_id.name_idx, NULL); - if (name == NULL) goto gffdp_bad_name; + if (name == NULL) goto bad_name; field = g_binary_variable_new(type); g_binary_variable_set_name(field, name); @@ -706,7 +769,7 @@ GBinVariable *g_dex_pool_get_field(GDexPool *pool, uint32_t index) if (field_id.class_idx != NO_INDEX) { owner = g_dex_pool_get_type_(pool, field_id.class_idx); - if (owner == NULL) goto gffdp_bad_owner; + if (owner == NULL) goto bad_owner; g_binary_variable_set_owner(field, owner); @@ -721,15 +784,17 @@ GBinVariable *g_dex_pool_get_field(GDexPool *pool, uint32_t index) if (result != NULL) g_object_ref(G_OBJECT(result)); - gffdp_error: + type_error: + + no_field_id: return result; - gffdp_bad_owner: + bad_owner: g_object_unref(G_OBJECT(field)); - gffdp_bad_name: + bad_name: g_object_unref(G_OBJECT(type)); @@ -763,6 +828,48 @@ uint32_t g_dex_pool_count_prototypes(const GDexPool *pool) /****************************************************************************** * * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index de la routine recherchée. * +* proto_id = élément ciblé à constituer. [OUT] * +* * +* Description : Reconstitue les éléments bruts d'une routine Dex. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_dex_pool_get_raw_prototype(GDexPool *pool, uint32_t index, proto_id_item *proto_id) +{ + bool result; /* Bilan à retourner */ + uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ + phys_t pos; /* Tête de lecture */ + vmpa2t addr; /* Tête de lecture générique */ + + result = false; + + count = g_dex_pool_count_prototypes(pool); + + if (index < count) + { + format = pool->format; + + pos = format->header.proto_ids_off + index * sizeof(proto_id_item); + init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); + + result = read_dex_proto_id_item(format, &addr, proto_id); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : pool = table de resources pour format Dex à consulter. * * index = index de la routine recherchée. * * * @@ -777,12 +884,10 @@ uint32_t g_dex_pool_count_prototypes(const GDexPool *pool) GBinRoutine *g_dex_pool_get_prototype(GDexPool *pool, uint32_t index) { GBinRoutine *result; /* Instance à retourner */ - uint32_t count; /* Nombre d'éléments présents */ - GDexFormat *format; /* Format associé à la table */ - phys_t pos; /* Tête de lecture */ - vmpa2t addr; /* Tête de lecture générique */ proto_id_item proto_id; /* Prototype de routine */ GDataType *type; /* Type de retour */ + phys_t pos; /* Tête de lecture */ + vmpa2t addr; /* Tête de lecture générique */ type_list args; /* Liste des arguments */ uint32_t i; /* Boucle de parcours */ GBinVariable *arg; /* Argument reconstitué */ @@ -795,21 +900,11 @@ GBinRoutine *g_dex_pool_get_prototype(GDexPool *pool, uint32_t index) * les autres éléments de la table des constantes. */ - count = g_dex_pool_count_prototypes(pool); - - if (index >= count) - goto grfdp_error; - - format = pool->format; - - pos = format->header.proto_ids_off + index * sizeof(proto_id_item); - init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); - - if (!read_dex_proto_id_item(format, &addr, &proto_id)) - goto grfdp_error; + if (!g_dex_pool_get_raw_prototype(pool, index, &proto_id)) + goto no_proto_id; /** - * On choisit d'ignore le champ proto_id.shorty_idx : c'est un descripteur + * On choisit d'ignorer le champ proto_id.shorty_idx : c'est un descripteur * qui doit correspondre au retour et aux paramètres précisés avec les * autres champs de la structure, donc l'information paraît redondante. */ @@ -817,7 +912,7 @@ GBinRoutine *g_dex_pool_get_prototype(GDexPool *pool, uint32_t index) /* Type de retour */ type = g_dex_pool_get_type_(pool, proto_id.return_type_idx); - if (type == NULL) goto grfdp_error; + if (type == NULL) goto type_error; result = G_BIN_ROUTINE(g_dex_routine_new()); @@ -831,13 +926,13 @@ GBinRoutine *g_dex_pool_get_prototype(GDexPool *pool, uint32_t index) { init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); - if (!read_dex_type_list(format, &addr, &args)) - goto grfdp_error; + if (!read_dex_type_list(pool->format, &addr, &args)) + goto arg_error; for (i = 0; i < args.size; i++) { type = g_dex_pool_get_type_(pool, args.list[i].type_idx); - if (type == NULL) goto grfdp_error; + if (type == NULL) goto arg_error; arg = g_binary_variable_new(type); g_binary_routine_add_arg(result, arg); @@ -848,11 +943,15 @@ GBinRoutine *g_dex_pool_get_prototype(GDexPool *pool, uint32_t index) return result; - grfdp_error: + arg_error: if (result != NULL) g_object_unref(G_OBJECT(result)); + type_error: + + no_proto_id: + return NULL; } @@ -970,44 +1069,72 @@ uint32_t g_dex_pool_count_methods(const GDexPool *pool) /****************************************************************************** * * -* Paramètres : pool = table de resources pour format Dex à consulter. * -* index = index de la méthode recherchée. * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index du type recherché. * +* field_id = élément ciblé à constituer. [OUT] * * * -* Description : Extrait une représentation de méthode d'une table DEX. * +* Description : Reconstitue les éléments bruts d'une méthode Dex. * * * -* Retour : Composant GLib créé. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -GDexMethod *g_dex_pool_get_method(GDexPool *pool, uint32_t index) +bool g_dex_pool_get_raw_method(GDexPool *pool, uint32_t index, method_id_item *method_id) { - GDexMethod *result; /* Instance à retourner */ + bool result; /* Bilan à retourner */ uint32_t count; /* Nombre d'éléments présents */ GDexFormat *format; /* Format associé à la table */ phys_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ - method_id_item method_id; /* Définition de la méthode */ - result = NULL; + result = false; count = g_dex_pool_count_methods(pool); - if (index >= count) - goto gmfdp_error; - - if (pool->methods[index] == NULL) + if (index < count) { format = pool->format; pos = format->header.method_ids_off + index * sizeof(method_id_item); init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); - if (!read_dex_method_id_item(format, &addr, &method_id)) - goto gmfdp_error; + result = read_dex_method_id_item(format, &addr, method_id); - pool->methods[index] = g_dex_method_new_callable(format, &method_id); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index de la méthode recherchée. * +* * +* Description : Extrait une représentation de méthode d'une table DEX. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDexMethod *g_dex_pool_get_method(GDexPool *pool, uint32_t index) +{ + GDexMethod *result; /* Instance à retourner */ + method_id_item method_id; /* Définition de la méthode */ + + result = NULL; + + if (pool->methods[index] == NULL) + { + if (!g_dex_pool_get_raw_method(pool, index, &method_id)) + goto no_method_id; + + pool->methods[index] = g_dex_method_new_callable(pool->format, &method_id); } @@ -1016,7 +1143,7 @@ GDexMethod *g_dex_pool_get_method(GDexPool *pool, uint32_t index) if (result != NULL) g_object_ref(G_OBJECT(result)); - gmfdp_error: + no_method_id: return result; @@ -1116,44 +1243,72 @@ uint32_t g_dex_pool_count_classes(const GDexPool *pool) /****************************************************************************** * * -* Paramètres : pool = table de resources pour format Dex à consulter. * -* index = index de la classe recherchée. * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index du type recherché. * +* class_def = élément ciblé à constituer. [OUT] * * * -* Description : Extrait une représentation de classe d'une table DEX. * +* Description : Reconstitue les éléments bruts d'une classe Dex. * * * -* Retour : Composant GLib créé. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -GDexClass *g_dex_pool_get_class(GDexPool *pool, uint32_t index) +bool g_dex_pool_get_raw_class(GDexPool *pool, uint32_t index, class_def_item *class_def) { - GDexClass *result; /* Instance à retourner */ + bool result; /* Bilan à retourner */ uint32_t count; /* Nombre d'éléments présents */ GDexFormat *format; /* Format associé à la table */ phys_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ - class_def_item class_def; /* Définition de la classe */ - result = NULL; + result = false; count = g_dex_pool_count_classes(pool); - if (index >= count) - goto gcfdp_error; - - if (pool->classes[index] == NULL) + if (index < count) { format = pool->format; pos = format->header.class_defs_off + index * sizeof(class_def_item); init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); - if (!read_dex_class_def_item(format, &addr, &class_def)) - goto gcfdp_error; + result = read_dex_class_def_item(format, &addr, class_def); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index de la classe recherchée. * +* * +* Description : Extrait une représentation de classe d'une table DEX. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDexClass *g_dex_pool_get_class(GDexPool *pool, uint32_t index) +{ + GDexClass *result; /* Instance à retourner */ + class_def_item class_def; /* Définition de la classe */ + + result = NULL; + + if (pool->classes[index] == NULL) + { + if (!g_dex_pool_get_raw_class(pool, index, &class_def)) + goto no_class_def; - pool->classes[index] = g_dex_class_new(format, &class_def); + pool->classes[index] = g_dex_class_new(pool->format, &class_def); } @@ -1162,7 +1317,7 @@ GDexClass *g_dex_pool_get_class(GDexPool *pool, uint32_t index) if (result != NULL) g_object_ref(G_OBJECT(result)); - gcfdp_error: + no_class_def: return result; |