summaryrefslogtreecommitdiff
path: root/src/format/dex/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/dex/class.c')
-rw-r--r--src/format/dex/class.c291
1 files changed, 102 insertions, 189 deletions
diff --git a/src/format/dex/class.c b/src/format/dex/class.c
index b866cd7..657461f 100644
--- a/src/format/dex/class.c
+++ b/src/format/dex/class.c
@@ -33,11 +33,6 @@
-
-
-
-
-
/* Classe issue du code source (instance) */
struct _GDexClass
{
@@ -66,17 +61,14 @@ static void g_dex_class_class_init(GDexClassClass *);
/* Procède à l'initialisation d'une classe issue du code source. */
static void g_dex_class_init(GDexClass *);
-/* Crée une nouvelle représentation de classe issue de code. */
-static GDexClass *g_dex_class_new(const GDexFormat *, off_t);
-
-/* Inscrit les méthodes d'une classe en tant que routines. */
-static void g_dex_class_register_method(const GDexClass *, GBinFormat *);
-
-
-
-
+/* Supprime toutes les références externes. */
+static void g_dex_class_dispose(GDexClass *);
+/* Procède à la libération totale de la mémoire. */
+static void g_dex_class_finalize(GDexClass *);
+/* Inscrit les méthodes d'une classe en tant que routines. */
+//static void g_dex_class_register_method(const GDexClass *, GBinFormat *);
@@ -84,7 +76,6 @@ static void g_dex_class_register_method(const GDexClass *, GBinFormat *);
G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT);
-
/******************************************************************************
* *
* Paramètres : class = classe de composant GLib à initialiser. *
@@ -99,6 +90,12 @@ G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT);
static void g_dex_class_class_init(GDexClassClass *class)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_class_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dex_class_finalize;
}
@@ -123,8 +120,64 @@ static void g_dex_class_init(GDexClass *class)
/******************************************************************************
* *
+* Paramètres : class = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_class_dispose(GDexClass *class)
+{
+ size_t i; /* Boucle de parcours */
+
+ if (class->direct_methods != NULL)
+ for (i = 0; i < class->dmethods_count; i++)
+ if (class->direct_methods[i] != NULL)
+ g_object_unref(G_OBJECT(class->direct_methods[i]));
+
+ if (class->virtual_methods != NULL)
+ for (i = 0; i < class->vmethods_count; i++)
+ if (class->virtual_methods[i] != NULL)
+ g_object_unref(G_OBJECT(class->virtual_methods[i]));
+
+ G_OBJECT_CLASS(g_dex_class_parent_class)->dispose(G_OBJECT(class));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_class_finalize(GDexClass *class)
+{
+ if (class->direct_methods != NULL)
+ free(class->direct_methods);
+
+ if (class->virtual_methods != NULL)
+ free(class->virtual_methods);
+
+ G_OBJECT_CLASS(g_dex_class_parent_class)->finalize(G_OBJECT(class));
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = représentation interne du format DEX à consulter. *
-* offset = tête de lecture des données initiale. *
+* def = définitions générales associées à la classe. *
* *
* Description : Crée une nouvelle représentation de classe issue de code. *
* *
@@ -134,120 +187,66 @@ static void g_dex_class_init(GDexClass *class)
* *
******************************************************************************/
-static GDexClass *g_dex_class_new(const GDexFormat *format, off_t offset)
+GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
{
GDexClass *result; /* Composant à retourner */
- class_def_item def; /* Définition de la classe */
+ vmpa2t addr; /* Tête de lecture générique */
class_data_item data; /* Contenu de la classe */
uleb128_t index; /* Conservation du dernier id */
uleb128_t i; /* Boucle de parcours */
GDexMethod *method; /* Méthode chargée */
- if (!read_dex_class_def_item(format, &offset, &def))
- return NULL;
+ init_vmpa(&addr, def->class_data_off, VMPA_NO_VIRTUAL);
- offset = def.class_data_off;
-
- if (!read_dex_class_data_item(format, &offset, &data))
+ if (!read_dex_class_data_item(format, &addr, &data))
return NULL;
-
-
- //printf(" Classe :: d meth count == 0x%lld\n", data.direct_methods_size);
- //printf(" Classe :: v meth count == 0x%lld\n", data.virtual_methods_size);
-
-
-
result = g_object_new(G_TYPE_DEX_CLASS, NULL);
- result->definition = def;
+ result->definition = *def;
+
+ /**
+ * On évite ici les méthodes (virtuelles) non définies.
+ */
+ if (def->access_flags & ACC_ANNOTATION) goto gdcn_done;
index = 0;
+ result->dmethods_count = data.direct_methods_size;
+ result->direct_methods = (GDexMethod **)calloc(result->dmethods_count, sizeof(GDexMethod *));
+
for (i = 0; i < data.direct_methods_size; i++)
{
method = g_dex_method_new(format, &data.direct_methods[i], &index);
+ if (method == NULL) goto gdcn_bad_method;
- if (method != NULL)
- {
- result->dmethods_count++;
- result->direct_methods = (GDexMethod **)realloc(result->direct_methods,
- result->dmethods_count * sizeof(GDexMethod *));
-
- result->direct_methods[result->dmethods_count - 1] = method;
-
- }
+ result->direct_methods[i] = method;
}
index = 0;
+ result->vmethods_count = data.virtual_methods_size;
+ result->virtual_methods = (GDexMethod **)calloc(result->vmethods_count, sizeof(GDexMethod *));
+
for (i = 0; i < data.virtual_methods_size; i++)
{
method = g_dex_method_new(format, &data.virtual_methods[i], &index);
+ if (method == NULL) goto gdcn_bad_method;
- if (method != NULL)
- {
- result->vmethods_count++;
- result->virtual_methods = (GDexMethod **)realloc(result->virtual_methods,
- result->vmethods_count * sizeof(GDexMethod *));
-
- result->virtual_methods[result->vmethods_count - 1] = method;
-
- }
+ result->virtual_methods[i] = method;
}
-
+ gdcn_done:
return result;
-}
+ gdcn_bad_method:
+ g_object_unref(G_OBJECT(result));
-/******************************************************************************
-* *
-* Paramètres : class = informations chargées à consulter. *
-* format = format binaire à compléter. *
-* *
-* Description : Inscrit les méthodes d'une classe en tant que routines. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dex_class_register_method(const GDexClass *class, GBinFormat *format)
-{
- size_t i; /* Boucle de parcours */
- GBinRoutine *routine; /* Routine à inscrire */
-
- for (i = 0; i < class->dmethods_count; i++)
- {
- routine = g_dex_method_get_routine(class->direct_methods[i]);
- g_binary_format_add_routine(format, routine);
-
- /*
- printf("routine @ 0x%08llx :: '%s'\n",
- g_binary_routine_get_address(routine),
- g_binary_routine_get_name(routine));
- */
-
- }
-
- for (i = 0; i < class->vmethods_count; i++)
- {
- routine = g_dex_method_get_routine(class->virtual_methods[i]);
- g_binary_format_add_routine(format, routine);
-
- /*
- printf("routine @ 0x%08llx :: '%s'\n",
- g_binary_routine_get_address(routine),
- g_binary_routine_get_name(routine));
- */
-
- }
+ return NULL;
}
@@ -310,47 +309,27 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
/******************************************************************************
* *
* Paramètres : class = informations chargées à consulter. *
-* parts = liste à venir compléter. *
-* count = quantité de zones listées. [OUT] *
+* raw = portion de binaire brut à raffiner. *
* *
-* Description : Fournit les références aux zones binaires à analyser. *
+* Description : Intègre la méthode en tant que portion de code. *
* *
-* Retour : Zones binaires à analyser. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-#if 0
-GBinPart **g_dex_class_get_parts(const GDexClass *class, GBinPart **parts, size_t *count)
+
+void g_dex_class_include_as_portion(const GDexClass *class, GBinPortion *raw)
{
size_t i; /* Boucle de parcours */
- GBinPart *part; /* Partie à intégrer à la liste*/
for (i = 0; i < class->dmethods_count; i++)
- {
- part = g_dex_method_as_part(class->direct_methods[i]);
-
- parts = (GBinPart **)realloc(parts, ++(*count) * sizeof(GBinPart *));
- parts[*count - 1] = part;
-
- }
+ g_dex_method_include_as_portion(class->direct_methods[i], raw);
for (i = 0; i < class->vmethods_count; i++)
- {
- part = g_dex_method_as_part(class->virtual_methods[i]);
-
- parts = (GBinPart **)realloc(parts, ++(*count) * sizeof(GBinPart *));
- parts[*count - 1] = part;
-
- }
-
- return parts;
+ g_dex_method_include_as_portion(class->virtual_methods[i], raw);
}
-#endif
-
-
-
/******************************************************************************
@@ -428,7 +407,7 @@ const char *g_dex_class_get_source_file(const GDexClass *class, const GDexFormat
void g_dex_class_decompile(const GDexClass *class, GLangOutput *lang, GCodeBuffer *buffer, const GDexFormat *format)
{
-
+#if 0
GDataType *type;
@@ -482,7 +461,7 @@ GBufferLine *line, GLangOutput *output)
-
+#endif
}
@@ -500,69 +479,3 @@ GBufferLine *line, GLangOutput *output)
-
-
-/******************************************************************************
-* *
-* Paramètres : format = représentation interne du format DEX à compléter. *
-* *
-* Description : Charge toutes les classes listées dans le contenu binaire. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_all_dex_classes(GDexFormat *format)
-{
- const dex_header *header; /* Raccourci d'usage */
- uint32_t i; /* Boucle de parcours */
- GDexClass *class; /* Représentation chargée */
-
- header = &format->header;
-
- for (i = 0; i < header->class_defs_size; i++)
- {
- class = g_dex_class_new(format, header->class_defs_off + i * sizeof(class_def_item));
-
- if (class != NULL)
- {
- format->classes_count++;
- format->classes = (GDexClass **)realloc(format->classes,
- format->classes_count * sizeof(GDexClass *));
-
- format->classes[format->classes_count - 1] = class;
-
- }
-
- }
-
- return true;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = représentation interne du format DEX à compléter. *
-* *
-* Description : Enregistre toutes les méthodes des classes listées. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void register_all_dex_class_methods(GDexFormat *format)
-{
- size_t i; /* Boucle de parcours */
- GBinFormat *bformat; /* Autre version du format */
-
- bformat = G_BIN_FORMAT(format);
-
- for (i = 0; i < format->classes_count; i++)
- g_dex_class_register_method(format->classes[i], bformat);
-
-}