summaryrefslogtreecommitdiff
path: root/plugins/dex/pool.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-05-07 21:53:40 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-05-07 21:53:40 (GMT)
commitdd2b41538e20de5472cd8c888c530327a1351866 (patch)
tree7f9a24a32ecd33aacb98a5d1ec4234011c1364a6 /plugins/dex/pool.c
parentb92a5e56de9198c08956ce486cd12712d7034731 (diff)
Read raw Dex items by extending the API.
Diffstat (limited to 'plugins/dex/pool.c')
-rw-r--r--plugins/dex/pool.c339
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;