summaryrefslogtreecommitdiff
path: root/plugins/dex
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-05-07 14:24:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-05-07 14:24:16 (GMT)
commitc136e2c4c1ad02ea2e363fbe71ce54c6255793e2 (patch)
treeba19cc948ac23a3930d9943e94f8e37ec86991c1 /plugins/dex
parentb38035259b6e09c77d87950fe409fb72d09887d3 (diff)
Extended the Python bindings for the Dex format.
Diffstat (limited to 'plugins/dex')
-rwxr-xr-xplugins/dex/Makefile.am1
-rw-r--r--plugins/dex/class.c254
-rw-r--r--plugins/dex/class.h30
-rw-r--r--plugins/dex/dex-int.c2
-rwxr-xr-xplugins/dex/dex_def.h2
-rw-r--r--plugins/dex/field.c230
-rw-r--r--plugins/dex/field.h70
-rwxr-xr-xplugins/dex/format.c15
-rw-r--r--plugins/dex/method.c8
-rw-r--r--plugins/dex/method.h12
-rw-r--r--plugins/dex/pool.c180
-rw-r--r--plugins/dex/pool.h19
-rw-r--r--plugins/dex/python/Makefile.am6
-rw-r--r--plugins/dex/python/class.c449
-rw-r--r--plugins/dex/python/constants.c104
-rw-r--r--plugins/dex/python/constants.h39
-rw-r--r--plugins/dex/python/field.c186
-rw-r--r--plugins/dex/python/field.h42
-rw-r--r--plugins/dex/python/format.c354
-rw-r--r--plugins/dex/python/method.c223
-rw-r--r--plugins/dex/python/method.h42
-rw-r--r--plugins/dex/python/module.c8
-rw-r--r--plugins/dex/python/translate.c293
-rw-r--r--plugins/dex/python/translate.h53
24 files changed, 2556 insertions, 66 deletions
diff --git a/plugins/dex/Makefile.am b/plugins/dex/Makefile.am
index 50c1dcc..c72d1c6 100755
--- a/plugins/dex/Makefile.am
+++ b/plugins/dex/Makefile.am
@@ -9,6 +9,7 @@ libdex_la_SOURCES = \
class.h class.c \
dex-int.h dex-int.c \
dex_def.h \
+ field.h field.c \
format.h format.c \
loading.h loading.c \
method.h method.c \
diff --git a/plugins/dex/class.c b/plugins/dex/class.c
index 5cd159b..ef3ed85 100644
--- a/plugins/dex/class.c
+++ b/plugins/dex/class.c
@@ -28,7 +28,6 @@
#include "dex-int.h"
-#include "method.h"
#include "pool.h"
@@ -38,10 +37,17 @@ struct _GDexClass
{
GObject parent; /* A laisser en premier */
+ GDexFormat *format; /* Lien vers la table globale */
+
class_def_item definition; /* Définition de la classe */
bool has_data; /* Indicateur de présence */
class_data_item data; /* Contenu de la classe */
+ GDexField **static_fields; /* Champs statiques */
+ size_t sfields_count; /* Quantité de ces champs */
+ GDexField **instance_fields; /* Champs propres à la classe */
+ size_t ifields_count; /* Quantité de ces champs */
+
GDexMethod **direct_methods; /* Méthodes propres */
size_t dmethods_count; /* Quantité de ces méthodes */
GDexMethod **virtual_methods; /* Méthodes virtuelles */
@@ -69,9 +75,6 @@ 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 *);
-
/* Détermine le type d'une classe issue du code source. */
@@ -136,6 +139,16 @@ static void g_dex_class_dispose(GDexClass *class)
{
size_t i; /* Boucle de parcours */
+ if (class->static_fields != NULL)
+ for (i = 0; i < class->sfields_count; i++)
+ if (class->static_fields[i] != NULL)
+ g_object_unref(G_OBJECT(class->static_fields[i]));
+
+ if (class->instance_fields != NULL)
+ for (i = 0; i < class->ifields_count; i++)
+ if (class->instance_fields[i] != NULL)
+ g_object_unref(G_OBJECT(class->instance_fields[i]));
+
if (class->direct_methods != NULL)
for (i = 0; i < class->dmethods_count; i++)
if (class->direct_methods[i] != NULL)
@@ -146,6 +159,8 @@ static void g_dex_class_dispose(GDexClass *class)
if (class->virtual_methods[i] != NULL)
g_object_unref(G_OBJECT(class->virtual_methods[i]));
+ g_object_unref(G_OBJECT(class->format));
+
G_OBJECT_CLASS(g_dex_class_parent_class)->dispose(G_OBJECT(class));
}
@@ -165,6 +180,15 @@ static void g_dex_class_dispose(GDexClass *class)
static void g_dex_class_finalize(GDexClass *class)
{
+ if (class->has_data)
+ reset_dex_class_data_item(&class->data);
+
+ if (class->static_fields != NULL)
+ free(class->static_fields);
+
+ if (class->instance_fields != NULL)
+ free(class->instance_fields);
+
if (class->direct_methods != NULL)
free(class->direct_methods);
@@ -194,15 +218,19 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
GDexClass *result; /* Composant à retourner */
vmpa2t addr; /* Tête de lecture générique */
class_data_item data; /* Contenu de la classe */
- GDataType *ctype; /* Type créé par la classe */
- GBinFormat *base; /* Autre version du format */
uleb128_t index; /* Conservation du dernier id */
uleb128_t i; /* Boucle de parcours */
+ GDexField *field; /* Champ chargé */
+ GDataType *ctype; /* Type créé par la classe */
+ GBinFormat *base; /* Autre version du format */
GDexMethod *method; /* Méthode chargée */
GBinRoutine *routine; /* Version interne de méthode */
result = g_object_new(G_TYPE_DEX_CLASS, NULL);
+ result->format = format;
+ g_object_ref(G_OBJECT(format));
+
result->definition = *def;
result->has_data = (def->class_data_off != 0);
@@ -227,6 +255,42 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
result->data = data;
/**
+ * Chargement des champs de classe.
+ */
+
+ index = 0;
+
+ result->sfields_count = data.static_fields_size;
+ result->static_fields = (GDexField **)calloc(result->sfields_count, sizeof(GDexField *));
+
+ for (i = 0; i < result->sfields_count; i++)
+ {
+ field = g_dex_field_new(format, &data.static_fields[i], &index);
+ if (field == NULL) goto gdcn_bad_field;
+
+ result->static_fields[i] = field;
+
+ }
+
+ index = 0;
+
+ result->ifields_count = data.instance_fields_size;
+ result->instance_fields = (GDexField **)calloc(result->ifields_count, sizeof(GDexField *));
+
+ for (i = 0; i < result->ifields_count; i++)
+ {
+ field = g_dex_field_new(format, &data.instance_fields[i], &index);
+ if (field == NULL) goto gdcn_bad_field;
+
+ result->instance_fields[i] = field;
+
+ }
+
+ /**
+ * Chargement des méthodes de classe.
+ */
+
+ /**
* On évite ici les méthodes (virtuelles) non définies.
*/
if (def->access_flags & ACC_ANNOTATION) goto gdcn_done;
@@ -241,7 +305,7 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
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++)
+ for (i = 0; i < result->dmethods_count; i++)
{
method = g_dex_method_new_defined(format, &data.direct_methods[i], &index);
if (method == NULL) goto gdcn_bad_method;
@@ -267,7 +331,7 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
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++)
+ for (i = 0; i < result->vmethods_count; i++)
{
method = g_dex_method_new_defined(format, &data.virtual_methods[i], &index);
if (method == NULL) goto gdcn_bad_method;
@@ -300,6 +364,8 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
gdcn_unknown_type:
+ gdcn_bad_field:
+
gdcn_bad_item:
g_object_unref(G_OBJECT(result));
@@ -349,6 +415,166 @@ const class_data_item *g_dex_class_get_data(const GDexClass *class)
/******************************************************************************
* *
+* Paramètres : class = informations chargées à consulter. *
+* *
+* Description : Indique le type Android d'une classe. *
+* *
+* Retour : Type de classe ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDataType *g_dex_class_get_class_type(const GDexClass *class)
+{
+ GDataType *result; /* Type à renvoyer */
+
+ result = get_type_from_dex_pool(class->format, class->definition.class_idx);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = informations chargées à consulter. *
+* *
+* Description : Indique le type Android parent d'une classe. *
+* *
+* Retour : Type de classe ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDataType *g_dex_class_get_superclass_type(const GDexClass *class)
+{
+ GDataType *result; /* Type à renvoyer */
+
+ result = get_type_from_dex_pool(class->format, class->definition.superclass_idx);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = informations chargées à consulter. *
+* count = taille de la liste constituée. [OUT] *
+* *
+* Description : Indique le type Android des interfaces d'une classe. *
+* *
+* Retour : Types d'interfaces ou NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDataType **g_dex_class_get_interface_types(const GDexClass *class, size_t *count)
+{
+ GDataType **result; /* Types à renvoyer */
+ vmpa2t addr; /* Tête de lecture générique */
+ type_list interfaces; /* Liste des interfaces */
+ bool status; /* Bilan d'une lecture */
+ size_t i; /* Boucle de parcours */
+
+ if (class->definition.interfaces_off == 0)
+ {
+ *count = 0;
+ result = NULL;
+ }
+
+ else
+ {
+ init_vmpa(&addr, class->definition.interfaces_off, VMPA_NO_VIRTUAL);
+
+ status = read_dex_type_list(class->format, &addr, &interfaces);
+
+ if (status)
+ {
+ *count = interfaces.size;
+ result = (GDataType **)malloc(*count * sizeof(GDataType *));
+
+ for (i = 0; i < *count; i++)
+ result[i] = get_type_from_dex_pool(class->format, interfaces.list[i].type_idx);
+
+ }
+
+ else
+ {
+ *count = 0;
+ result = NULL;
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = informations chargées à consulter. *
+* instance = précise la nature des champs ciblés. *
+* *
+* Description : Dénombre les champs de classe chargés d'une classe donnée. *
+* *
+* Retour : Quantité de champs trouvés. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_dex_class_count_fields(const GDexClass *class, bool instance)
+{
+ size_t result; /* Compte à retourner */
+
+ if (instance)
+ result = class->ifields_count;
+ else
+ result = class->sfields_count;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = informations chargées à consulter. *
+* instance = précise la nature des champs ciblés. *
+* index = indique l'indice du champ désiré. *
+* *
+* Description : Fournit un champ chargé correspondant à une classe donnée. *
+* *
+* Retour : Champ intégré ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDexField *g_dex_class_get_field(const GDexClass *class, bool instance, size_t index)
+{
+ GDexField *result; /* Instance à renvoyer */
+
+ if (instance)
+ result = class->instance_fields[index];
+ else
+ result = class->static_fields[index];
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : class = informations chargées à consulter. *
* virtual = précise la nature des méthodes ciblées. *
* *
@@ -382,7 +608,7 @@ size_t g_dex_class_count_methods(const GDexClass *class, bool virtual)
* *
* Description : Fournit une méthode chargée correspondant à un type donné. *
* *
-* Retour : Quantité de méthodes trouvées. *
+* Retour : Méthode intégrée ou NULL. *
* *
* Remarques : - *
* *
@@ -397,6 +623,9 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
else
result = class->direct_methods[index];
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
return result;
}
@@ -475,8 +704,7 @@ bool g_dex_method_get_offset(const GDexMethod *method, phys_t *offset)
/******************************************************************************
* *
-* Paramètres : class = informations chargées à consulter. *
-* format = représentation interne du format DEX à compléter. *
+* Paramètres : class = informations chargées à consulter. *
* *
* Description : Retrouve si possible le nom du fichier source d'une classe. *
* *
@@ -486,11 +714,11 @@ bool g_dex_method_get_offset(const GDexMethod *method, phys_t *offset)
* *
******************************************************************************/
-const char *g_dex_class_get_source_file(const GDexClass *class, const GDexFormat *format)
+const char *g_dex_class_get_source_file(const GDexClass *class)
{
const char *result; /* Trouvaille à renvoyer */
- result = get_string_from_dex_pool(format, class->definition.source_file_idx, NULL);
+ result = get_string_from_dex_pool(class->format, class->definition.source_file_idx, NULL);
return result;
diff --git a/plugins/dex/class.h b/plugins/dex/class.h
index 71fd4c9..9d4e426 100644
--- a/plugins/dex/class.h
+++ b/plugins/dex/class.h
@@ -28,17 +28,18 @@
#include <glib-object.h>
+#include "field.h"
#include "format.h"
#include "method.h"
-#define G_TYPE_DEX_CLASS (g_dex_class_get_type())
-#define G_DEX_CLASS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_CLASS, GDexClass))
-#define G_DEX_CLASS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_CLASS, GDexClassClass))
-#define G_IS_DEX_CLASS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_CLASS))
-#define G_IS_DEX_CLASS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_CLASS))
-#define G_DEX_CLASS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_CLASS, GDexClassClass))
+#define G_TYPE_DEX_CLASS (g_dex_class_get_type())
+#define G_DEX_CLASS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_CLASS, GDexClass))
+#define G_DEX_CLASS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_CLASS, GDexClassClass))
+#define G_IS_DEX_CLASS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_CLASS))
+#define G_IS_DEX_CLASS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_CLASS))
+#define G_DEX_CLASS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_CLASS, GDexClassClass))
@@ -62,6 +63,21 @@ const class_def_item *g_dex_class_get_definition(const GDexClass *);
/* Fournit la définition brute des données d'une classe. */
const class_data_item *g_dex_class_get_data(const GDexClass *);
+/* Indique le type Android d'une classe. */
+GDataType *g_dex_class_get_class_type(const GDexClass *);
+
+/* Indique le type Android parent d'une classe. */
+GDataType *g_dex_class_get_superclass_type(const GDexClass *);
+
+/* Indique le type Android des interfaces d'une classe. */
+GDataType **g_dex_class_get_interface_types(const GDexClass *, size_t *);
+
+/* Dénombre les champs de classe chargés d'une classe donnée. */
+size_t g_dex_class_count_fields(const GDexClass *, bool);
+
+/* Fournit un champ chargé correspondant à une classe donnée. */
+GDexField *g_dex_class_get_field(const GDexClass *, bool, size_t);
+
/* Dénombre les méthodes chargées d'un type donné. */
size_t g_dex_class_count_methods(const GDexClass *, bool);
@@ -75,7 +91,7 @@ void g_dex_class_include_as_portion(const GDexClass *, GExeFormat *);
GDexMethod *g_dex_class_find_method_by_address(const GDexClass *, vmpa_t);
/* Retrouve si possible le nom du fichier source d'une classe. */
-const char *g_dex_class_get_source_file(const GDexClass *, const GDexFormat *);
+const char *g_dex_class_get_source_file(const GDexClass *);
/* Procède à la décompilation complète d'une classe donnée. */
//void g_dex_class_decompile(const GDexClass *, GLangOutput *, GCodeBuffer *, const GDexFormat *);
diff --git a/plugins/dex/dex-int.c b/plugins/dex/dex-int.c
index 150d401..e3121b6 100644
--- a/plugins/dex/dex-int.c
+++ b/plugins/dex/dex-int.c
@@ -470,7 +470,7 @@ bool read_dex_type_list(const GDexFormat *format, vmpa2t *pos, type_list *list)
result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &list->size);
- list->list = (type_item *)g_binary_content_get_raw_access(content, pos, list->size * sizeof(type_item));
+ list->list = (const type_item *)g_binary_content_get_raw_access(content, pos, list->size * sizeof(type_item));
result &= (list->list != NULL);
return result;
diff --git a/plugins/dex/dex_def.h b/plugins/dex/dex_def.h
index 61f51c2..913e20c 100755
--- a/plugins/dex/dex_def.h
+++ b/plugins/dex/dex_def.h
@@ -206,7 +206,7 @@ typedef struct _type_item
typedef struct _type_list
{
uint32_t size; /* Nombre d'éléments présents */
- type_item *list; /* Liste des éléments inscrits */
+ const type_item *list; /* Liste des éléments inscrits */
} type_list;
diff --git a/plugins/dex/field.c b/plugins/dex/field.c
new file mode 100644
index 0000000..620d159
--- /dev/null
+++ b/plugins/dex/field.c
@@ -0,0 +1,230 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * field.c - manipulation des champs de classe du format DEX
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "field.h"
+
+
+#include "dex-int.h"
+#include "pool.h"
+
+
+
+/* Champ d'une classe Dex (instance) */
+struct _GDexField
+{
+ GObject parent; /* A laisser en premier */
+
+ GBinVariable *variable; /* Représentation interne */
+
+ encoded_field info; /* Propriétés de la méthode */
+
+};
+
+/* Champ d'une classe Dex (classe) */
+struct _GDexFieldClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Procède à l'initialisation des champs de classe Dex. */
+static void g_dex_field_class_init(GDexFieldClass *);
+
+/* Procède à l'initialisation d'un champ de classe Dex. */
+static void g_dex_field_init(GDexField *);
+
+/* Supprime toutes les références externes. */
+static void g_dex_field_dispose(GDexField *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_dex_field_finalize(GDexField *);
+
+
+
+/* Détermine le type d'une fielde issue du code source. */
+G_DEFINE_TYPE(GDexField, g_dex_field, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe de composant GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation des champs de classe Dex. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_field_class_init(GDexFieldClass *class)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_field_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dex_field_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = composant GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation d'un champ de classe Dex. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_field_init(GDexField *field)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_field_dispose(GDexField *field)
+{
+ if (field->variable != NULL)
+ g_object_unref(G_OBJECT(field->variable));
+
+ G_OBJECT_CLASS(g_dex_field_parent_class)->dispose(G_OBJECT(field));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_field_finalize(GDexField *field)
+{
+ G_OBJECT_CLASS(g_dex_field_parent_class)->finalize(G_OBJECT(field));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à consulter. *
+* seed = graine des informations à extraire. *
+* last = dernier indice utilisé (à mettre à jour). [OUT] *
+* *
+* Description : Crée une nouvelle représentation de champ de classe. *
+* *
+* Retour : Composant GLib créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDexField *g_dex_field_new(GDexFormat *format, const encoded_field *seed, uleb128_t *last)
+{
+ GDexField *result; /* Composant à retourner */
+ GBinVariable *variable; /* Variable de représentation */
+
+ *last += seed->field_idx_diff;
+
+ variable = get_field_from_dex_pool(format, *last);
+
+ if (variable == NULL)
+ return NULL;
+
+ result = g_object_new(G_TYPE_DEX_FIELD, NULL);
+
+ result->variable = variable;
+
+ result->info = *seed;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = représentation interne du champ à consulter. *
+* *
+* Description : Fournit les indications Dex concernant le champ de classe. *
+* *
+* Retour : Données brutes du binaire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const encoded_field *g_dex_field_get_dex_info(const GDexField *field)
+{
+ return &field->info;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = représentation interne du format DEX à consulter. *
+* *
+* Description : Fournit la variable Chrysalide correspondant au champ. *
+* *
+* Retour : Instance de routine mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinVariable *g_dex_field_get_variable(const GDexField *field)
+{
+ GBinVariable *result; /* Instance à retourner */
+
+ result = field->variable;
+
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
diff --git a/plugins/dex/field.h b/plugins/dex/field.h
new file mode 100644
index 0000000..e430d7f
--- /dev/null
+++ b/plugins/dex/field.h
@@ -0,0 +1,70 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * field.h - prototypes pour la manipulation des champs de classe du format DEX
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_DEX_FIELD_H
+#define _PLUGINS_DEX_FIELD_H
+
+
+#include <glib-object.h>
+
+
+#include <analysis/routine.h>
+
+
+#include "dex_def.h"
+#include "format.h"
+
+
+
+#define G_TYPE_DEX_FIELD (g_dex_field_get_type())
+#define G_DEX_FIELD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_FIELD, GDexField))
+#define G_DEX_FIELD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_FIELD, GDexFieldClass))
+#define G_IS_DEX_FIELD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_FIELD))
+#define G_IS_DEX_FIELD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_FIELD))
+#define G_DEX_FIELD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_FIELD, GDexFieldClass))
+
+
+
+/* Champ d'une classe Dex (instance) */
+typedef struct _GDexField GDexField;
+
+/* Champ d'une classe Dex (classe) */
+typedef struct _GDexFieldClass GDexFieldClass;
+
+
+
+/* Détermine le type d'une fielde issue du code source. */
+GType g_dex_field_get_type(void);
+
+/* Crée une nouvelle représentation de champ de classe. */
+GDexField *g_dex_field_new(GDexFormat *, const encoded_field *, uleb128_t *);
+
+/* Fournit les indications Dex concernant le champ de classe. */
+const encoded_field *g_dex_field_get_dex_info(const GDexField *);
+
+/* Fournit la variable Chrysalide correspondant au champ. */
+GBinVariable *g_dex_field_get_variable(const GDexField *);
+
+
+
+#endif /* _PLUGINS_DEX_FIELD_H */
diff --git a/plugins/dex/format.c b/plugins/dex/format.c
index 371684f..1fa5a7d 100755
--- a/plugins/dex/format.c
+++ b/plugins/dex/format.c
@@ -657,9 +657,20 @@ size_t g_dex_format_count_classes(const GDexFormat *format)
GDexClass *g_dex_format_get_class(const GDexFormat *format, size_t index)
{
- /* TODO : ref() */
+ GDexClass *result; /* Classe trouvée à retourner */
- return format->classes[index];
+ assert(index < format->header.class_defs_size);
+
+ if (index < format->header.class_defs_size)
+ {
+ result = format->classes[index];
+ g_object_ref(G_OBJECT(result));
+ }
+
+ else
+ result = NULL;
+
+ return result;
}
diff --git a/plugins/dex/method.c b/plugins/dex/method.c
index 409261f..4013436 100644
--- a/plugins/dex/method.c
+++ b/plugins/dex/method.c
@@ -36,7 +36,6 @@
-
/* Methode issue du code source (instance) */
struct _GDexMethod
{
@@ -78,12 +77,11 @@ static void g_dex_method_finalize(GDexMethod *);
G_DEFINE_TYPE(GDexMethod, g_dex_method, G_TYPE_OBJECT);
-
/******************************************************************************
* *
* Paramètres : class = classe de composant GLib à initialiser. *
* *
-* Description : Procède à l'initialisation d'une methode issue du code. *
+* Description : Procède à l'initialisation des methodes issues du code. *
* *
* Retour : - *
* *
@@ -123,7 +121,7 @@ static void g_dex_method_init(GDexMethod *method)
/******************************************************************************
* *
-* Paramètres : format = instance d'objet GLib à traiter. *
+* Paramètres : method = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -335,7 +333,7 @@ const code_item *g_dex_method_get_dex_body(const GDexMethod *method)
* *
* Paramètres : method = représentation interne du format DEX à consulter. *
* *
-* Description : Fournit la routine Chrysalide correspondant à la méthode. *
+* Description : Fournit la routine Chrysalide correspondant à la méthode. *
* *
* Retour : Instance de routine mise en place. *
* *
diff --git a/plugins/dex/method.h b/plugins/dex/method.h
index fe6abf0..2b99715 100644
--- a/plugins/dex/method.h
+++ b/plugins/dex/method.h
@@ -36,12 +36,12 @@
-#define G_TYPE_DEX_METHOD (g_dex_method_get_type())
-#define G_DEX_METHOD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_METHOD, GDexMethod))
-#define G_DEX_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_METHOD, GDexMethodClass))
-#define G_IS_DEX_METHOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_METHOD))
-#define G_IS_DEX_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_METHOD))
-#define G_DEX_METHOD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_METHOD, GDexMethodClass))
+#define G_TYPE_DEX_METHOD (g_dex_method_get_type())
+#define G_DEX_METHOD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_METHOD, GDexMethod))
+#define G_DEX_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_METHOD, GDexMethodClass))
+#define G_IS_DEX_METHOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_METHOD))
+#define G_IS_DEX_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_METHOD))
+#define G_DEX_METHOD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_METHOD, GDexMethodClass))
diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c
index 9f3d55d..bfc463a 100644
--- a/plugins/dex/pool.c
+++ b/plugins/dex/pool.c
@@ -53,6 +53,7 @@
bool find_all_dex_strings(GDexFormat *format)
{
GBinFormat *base; /* Autre version du format */
+ uint32_t count; /* Nombre d'éléments présents */
uint32_t i; /* Boucle de parcours */
mrange_t range; /* Couverture associée */
const char *text; /* Texte issu du binaire */
@@ -61,7 +62,9 @@ bool find_all_dex_strings(GDexFormat *format)
base = G_BIN_FORMAT(format);
- for (i = 0; i < format->header.string_ids_size; i++)
+ count = count_strings_in_dex_pool(format);
+
+ for (i = 0; i < count; i++)
{
text = get_string_from_dex_pool(format, i, &range);
if (text == NULL) continue;
@@ -86,6 +89,29 @@ bool find_all_dex_strings(GDexFormat *format)
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
+* *
+* Description : Compte le nombre de chaînes de caractères dans une table DEX.*
+* *
+* Retour : Valeur positive ou nulle. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint32_t count_strings_in_dex_pool(const GDexFormat *format)
+{
+ uint32_t result; /* Quantité à retourner */
+
+ result = format->header.string_ids_size;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à consulter. *
* index = index du type recherchée. *
* range = éventuelle couverture à renseigner ou NULL. [OUT] *
* *
@@ -99,6 +125,7 @@ bool find_all_dex_strings(GDexFormat *format)
const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, mrange_t *range)
{
+ uint32_t count; /* Nombre d'éléments présents */
off_t pos; /* Tête de lecture */
vmpa2t addr; /* Tête de lecture générique */
string_id_item str_id; /* Identifiant de chaîne */
@@ -106,7 +133,9 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m
vmpa2t start; /* Début de la chaîne */
phys_t diff; /* Avancée de tête de lecture */
- if (index >= format->header.string_ids_size)
+ count = count_strings_in_dex_pool(format);
+
+ if (index >= count)
return NULL;
pos = format->header.string_ids_off + index * sizeof(string_id_item);
@@ -135,16 +164,6 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m
}
-
-
-
-
-
-
-
-
-
-
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
@@ -162,6 +181,7 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m
bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
+ uint32_t count; /* Nombre d'éléments présents */
guint runs_count; /* Qté d'exécutions parallèles */
uint32_t run_size; /* Volume réparti par exécution*/
GWorkQueue *queue; /* Gestionnaire de différés */
@@ -175,25 +195,26 @@ bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *sta
/* Préparation du réceptacle */
- format->types = (GDataType **)calloc(format->header.type_ids_size, sizeof(GDataType *));
+ count = count_types_in_dex_pool(format);
+
+ format->types = (GDataType **)calloc(count, sizeof(GDataType *));
/* Lancement des chargements */
runs_count = g_get_num_processors();
- run_size = format->header.type_ids_size / runs_count;
+ run_size = count / runs_count;
queue = get_work_queue();
- msg = gtk_status_stack_add_activity(status, _("Loading all types from the Dex pool..."),
- format->header.type_ids_size);
+ msg = gtk_status_stack_add_activity(status, _("Loading all types from the Dex pool..."), count);
for (i = 0; i < runs_count; i++)
{
begin = i * run_size;
if ((i + 1) == runs_count)
- end = format->header.type_ids_size;
+ end = count;
else
end = begin + run_size;
@@ -216,6 +237,29 @@ bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *sta
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
+* *
+* Description : Compte le nombre de types dans une table DEX. *
+* *
+* Retour : Valeur positive ou nulle. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint32_t count_types_in_dex_pool(const GDexFormat *format)
+{
+ uint32_t result; /* Quantité à retourner */
+
+ result = format->header.type_ids_size;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à consulter. *
* index = index du type recherchée. *
* *
* Description : Extrait une représentation de type d'une table DEX. *
@@ -229,6 +273,7 @@ bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *sta
GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
{
GDataType *result; /* Instance à retourner */
+ uint32_t count; /* Nombre d'éléments présents */
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 */
@@ -238,7 +283,9 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
result = NULL;
- if (index >= format->header.type_ids_size)
+ count = count_types_in_dex_pool(format);
+
+ if (index >= count)
goto gtfdp_error;
if (format->types[index] == NULL)
@@ -295,6 +342,7 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
+ uint32_t count; /* Nombre d'éléments présents */
guint runs_count; /* Qté d'exécutions parallèles */
uint32_t run_size; /* Volume réparti par exécution*/
GWorkQueue *queue; /* Gestionnaire de différés */
@@ -308,25 +356,27 @@ bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *st
/* Préparation du réceptacle */
- format->fields = (GBinVariable **)calloc(format->header.field_ids_size, sizeof(GBinVariable *));
+ count = count_fields_in_dex_pool(format);
+
+ format->fields = (GBinVariable **)calloc(count, sizeof(GBinVariable *));
/* Lancement des chargements */
runs_count = g_get_num_processors();
- run_size = format->header.field_ids_size / runs_count;
+ run_size = count / runs_count;
queue = get_work_queue();
msg = gtk_status_stack_add_activity(status, _("Loading all fields from the Dex pool..."),
- format->header.field_ids_size);
+ count);
for (i = 0; i < runs_count; i++)
{
begin = i * run_size;
if ((i + 1) == runs_count)
- end = format->header.field_ids_size;
+ end = count;
else
end = begin + run_size;
@@ -349,6 +399,29 @@ bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *st
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
+* *
+* Description : Compte le nombre de champs dans une table DEX. *
+* *
+* Retour : Valeur positive ou nulle. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint32_t count_fields_in_dex_pool(const GDexFormat *format)
+{
+ uint32_t result; /* Quantité à retourner */
+
+ result = format->header.field_ids_size;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à consulter. *
* index = index du champ recherché. *
* *
* Description : Extrait une représentation de champ d'une table DEX. *
@@ -362,6 +435,7 @@ bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *st
GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index)
{
GBinVariable *result; /* Instance à retourner */
+ uint32_t count; /* Nombre d'éléments présents */
phys_t pos; /* Tête de lecture */
vmpa2t addr; /* Tête de lecture générique */
field_id_item field_id; /* Description du champ */
@@ -372,7 +446,9 @@ GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index)
result = NULL;
- if (index >= format->header.field_ids_size)
+ count = count_fields_in_dex_pool(format);
+
+ if (index >= count)
goto gffdp_error;
if (format->fields[index] == NULL)
@@ -430,6 +506,29 @@ GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index)
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
+* *
+* Description : Compte le nombre de prototypes dans une table DEX. *
+* *
+* Retour : Valeur positive ou nulle. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint32_t count_prototypes_in_dex_pool(const GDexFormat *format)
+{
+ uint32_t result; /* Quantité à retourner */
+
+ result = format->header.proto_ids_size;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à consulter. *
* index = index de la routine recherchée. *
* *
* Description : Extrait une représentation de routine d'une table DEX. *
@@ -443,6 +542,7 @@ GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index)
GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
{
GBinRoutine *result; /* Instance à retourner */
+ uint32_t count; /* Nombre d'éléments présents */
phys_t pos; /* Tête de lecture */
vmpa2t addr; /* Tête de lecture générique */
proto_id_item proto_id; /* Prototype de routine */
@@ -460,7 +560,9 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
* les autres éléments de la table des constantes.
*/
- if (index >= format->header.proto_ids_size)
+ count = count_prototypes_in_dex_pool(format);
+
+ if (index >= count)
goto grfdp_error;
pos = format->header.proto_ids_off + index * sizeof(proto_id_item);
@@ -499,7 +601,7 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
///////result = demangle_routine(G_TYPE_DEX_DEMANGLER, name);
- g_binary_routine_set_name(result, strdup("..."));
+ //g_binary_routine_set_name(result, strdup("..."));
#if 1
if (result != NULL)///////////////////////
@@ -521,6 +623,29 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
+* *
+* Description : Compte le nombre de méthodes dans une table DEX. *
+* *
+* Retour : Valeur positive ou nulle. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint32_t count_methods_in_dex_pool(const GDexFormat *format)
+{
+ uint32_t result; /* Quantité à retourner */
+
+ result = format->header.method_ids_size;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à consulter. *
* index = index de la classe recherchée. *
* *
* Description : Extrait une représentation de méthode d'une table DEX. *
@@ -534,13 +659,16 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index)
{
GDexMethod *result; /* Instance à retourner */
+ uint32_t count; /* Nombre d'éléments présents */
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;
- if (index >= format->header.method_ids_size)
+ count = count_methods_in_dex_pool(format);
+
+ if (index >= count)
goto gmfdp_error;
/**
diff --git a/plugins/dex/pool.h b/plugins/dex/pool.h
index 45df801..ed5b447 100644
--- a/plugins/dex/pool.h
+++ b/plugins/dex/pool.h
@@ -38,28 +38,39 @@
/* Charge en mémoire toutes les chaînes trouvées. */
bool find_all_dex_strings(GDexFormat *);
+/* Compte le nombre de chaînes de caractères dans une table DEX. */
+uint32_t count_strings_in_dex_pool(const GDexFormat *);
+
/* Extrait une chaîne de caractères d'une table DEX. */
const char *get_string_from_dex_pool(const GDexFormat *, uint32_t, mrange_t *);
-
-
-
-
/* Charge en mémoire l'ensemble des types du format DEX. */
bool load_all_dex_types(GDexFormat *, wgroup_id_t, GtkStatusStack *);
+/* Compte le nombre de types dans une table DEX. */
+uint32_t count_types_in_dex_pool(const GDexFormat *);
+
/* Extrait une représentation de type d'une table DEX. */
GDataType *get_type_from_dex_pool(GDexFormat *, uint32_t);
/* Charge en mémoire l'ensemble des champs du format DEX. */
bool load_all_dex_fields(GDexFormat *, wgroup_id_t, GtkStatusStack *);
+/* Compte le nombre de champs dans une table DEX. */
+uint32_t count_fields_in_dex_pool(const GDexFormat *);
+
/* Extrait une représentation de champ d'une table DEX. */
GBinVariable *get_field_from_dex_pool(GDexFormat *, uint32_t);
+/* Compte le nombre de prototypes dans une table DEX. */
+uint32_t count_prototypes_in_dex_pool(const GDexFormat *);
+
/* Extrait une représentation de routine d'une table DEX. */
GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t);
+/* Compte le nombre de méthodes dans une table DEX. */
+uint32_t count_methods_in_dex_pool(const GDexFormat *);
+
/* Extrait une représentation de méthode d'une table DEX. */
GDexMethod *get_method_from_dex_pool(GDexFormat *, uint32_t);
diff --git a/plugins/dex/python/Makefile.am b/plugins/dex/python/Makefile.am
index d23ca65..8988eb8 100644
--- a/plugins/dex/python/Makefile.am
+++ b/plugins/dex/python/Makefile.am
@@ -3,8 +3,12 @@ noinst_LTLIBRARIES = libdexpython.la
libdexpython_la_SOURCES = \
class.h class.c \
+ constants.h constants.c \
+ field.h field.c \
format.h format.c \
- module.h module.c
+ method.h method.c \
+ module.h module.c \
+ translate.h translate.c
libdexpython_la_LDFLAGS =
diff --git a/plugins/dex/python/class.c b/plugins/dex/python/class.c
index ab7754e..a68e426 100644
--- a/plugins/dex/python/class.c
+++ b/plugins/dex/python/class.c
@@ -31,10 +31,419 @@
#include <plugins/pychrysalide/helpers.h>
+#include "format.h"
+#include "translate.h"
#include "../class.h"
+/* Fournit la définition brute d'une classe. */
+static PyObject *py_dex_class_get_definition(PyObject *, void *);
+
+/* Fournit la définition brute des données d'une classe. */
+static PyObject *py_dex_class_get_data(PyObject *, void *);
+
+/* Indique le type Android d'une classe. */
+static PyObject *py_dex_class_get_class_type(PyObject *, void *);
+
+/* Indique le type Android parent d'une classe. */
+static PyObject *py_dex_class_get_superclass_type(PyObject *, void *);
+
+/* Indique le type Android des interfaces d'une classe. */
+static PyObject *py_dex_class_get_interface_types(PyObject *, void *);
+
+/* Fournit les champs chargés correspondant à une classe donnée. */
+static PyObject *py_dex_class_get_fields(PyObject *, void *);
+
+/* Fournit les méthodes chargées correspondant à un type donné. */
+static PyObject *py_dex_class_get_methods(PyObject *, void *);
+
+/* Retrouve si possible le nom du fichier source d'une classe. */
+static PyObject *py_dex_class_get_source_file(PyObject *, void *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la définition brute d'une classe. *
+* *
+* Retour : Données brutes issues du binaire chargé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_class_get_definition(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexClass *class; /* Version native */
+ const class_def_item *item; /* Elément à traiter */
+
+ class = G_DEX_CLASS(pygobject_get(self));
+
+ item = g_dex_class_get_definition(class);
+
+ result = translate_dex_class_definition_to_python(item);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la définition brute des données d'une classe. *
+* *
+* Retour : Données brutes issues du binaire chargé ou None si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_class_get_data(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexClass *class; /* Version native */
+ const class_data_item *item; /* Elément à traiter */
+
+ class = G_DEX_CLASS(pygobject_get(self));
+
+ item = g_dex_class_get_data(class);
+
+ if (item == NULL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ result = translate_dex_class_data_to_python(item);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique le type Android d'une classe. *
+* *
+* Retour : Type de classe ou None en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_class_get_class_type(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexClass *class; /* Version native */
+ GDataType *type; /* Type de classe */
+
+ class = G_DEX_CLASS(pygobject_get(self));
+
+ type = g_dex_class_get_class_type(class);
+
+ if (type == NULL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ {
+ result = pygobject_new(G_OBJECT(type));
+
+ g_object_unref(G_OBJECT(type));
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique le type Android parent d'une classe. *
+* *
+* Retour : Type de classe ou None en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_class_get_superclass_type(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexClass *class; /* Version native */
+ GDataType *type; /* Type de classe */
+
+ class = G_DEX_CLASS(pygobject_get(self));
+
+ type = g_dex_class_get_superclass_type(class);
+
+ if (type == NULL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ {
+ result = pygobject_new(G_OBJECT(type));
+
+ g_object_unref(G_OBJECT(type));
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique le type Android des interfaces d'une classe. *
+* *
+* Retour : Types de classe ou None en cas d'erreur ou d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_class_get_interface_types(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexClass *class; /* Version native */
+ size_t count; /* Nombre d'interfaces */
+ GDataType **types; /* Types d'interfaces */
+ size_t i; /* Boucle de parcours */
+ PyObject *type; /* Type à ajouter à la liste */
+
+ class = G_DEX_CLASS(pygobject_get(self));
+
+ types = g_dex_class_get_interface_types(class, &count);
+
+ if (count == 0)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ {
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ if (types[i] == NULL)
+ {
+ type = Py_None;
+ Py_INCREF(type);
+ }
+ else
+ {
+ type = pygobject_new(G_OBJECT(types[i]));
+ g_object_unref(G_OBJECT(types[i]));
+ }
+
+ PyTuple_SetItem(result, i, type);
+
+ }
+
+ }
+
+ if (types != NULL)
+ free(types);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = méthodes d'instance si non nul, statiques sinon. *
+* *
+* Description : Fournit les champs chargés correspondant à une classe donnée.*
+* *
+* Retour : Champs de classe ou None en cas d'erreur ou d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_class_get_fields(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexClass *class; /* Version native */
+ bool instance; /* Type de champs ciblés */
+ size_t count; /* Nombre d'interfaces */
+ size_t i; /* Boucle de parcours */
+ GDexField *field; /* Champ à convertir */
+ PyObject *fld; /* Objet à ajouter à la liste */
+
+ class = G_DEX_CLASS(pygobject_get(self));
+
+ instance = (closure != NULL);
+
+ count = g_dex_class_count_fields(class, instance);
+
+ if (count == 0)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ {
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ field = g_dex_class_get_field(class, instance, i);
+
+ if (field == NULL)
+ {
+ fld = Py_None;
+ Py_INCREF(fld);
+ }
+ else
+ {
+ fld = pygobject_new(G_OBJECT(field));
+ g_object_unref(G_OBJECT(field));
+ }
+
+ PyTuple_SetItem(result, i, fld);
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = méthodes directes si non nul, virtuelles sinon. *
+* *
+* Description : Fournit les méthodes chargées correspondant à un type donné. *
+* *
+* Retour : Types de classe ou None en cas d'erreur ou d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_class_get_methods(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexClass *class; /* Version native */
+ bool virtual; /* Type de méthodes ciblées */
+ size_t count; /* Nombre d'interfaces */
+ size_t i; /* Boucle de parcours */
+ GDexMethod *method; /* Méthode à convertir */
+ PyObject *meth; /* Objet à ajouter à la liste */
+
+ class = G_DEX_CLASS(pygobject_get(self));
+
+ virtual = (closure == NULL);
+
+ count = g_dex_class_count_methods(class, virtual);
+
+ if (count == 0)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ {
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ method = g_dex_class_get_method(class, virtual, i);
+
+ if (method == NULL)
+ {
+ meth = Py_None;
+ Py_INCREF(meth);
+ }
+ else
+ {
+ meth = pygobject_new(G_OBJECT(method));
+ g_object_unref(G_OBJECT(method));
+ }
+
+ PyTuple_SetItem(result, i, meth);
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Retrouve si possible le nom du fichier source d'une classe. *
+* *
+* Retour : Nom du fichier trouvé ou None si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_class_get_source_file(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexClass *class; /* Version native */
+ const char *file; /* Fichier à l'origine du code */
+
+ class = G_DEX_CLASS(pygobject_get(self));
+
+ file = g_dex_class_get_source_file(class);
+
+ if (file == NULL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ result = PyUnicode_FromString(file);
+
+ return result;
+
+}
+
+
/******************************************************************************
* *
* Paramètres : - *
@@ -54,6 +463,46 @@ PyTypeObject *get_python_dex_class_type(void)
};
static PyGetSetDef py_dex_class_getseters[] = {
+ {
+ "definition", py_dex_class_get_definition, NULL,
+ "Native definition of the Dex class.", NULL
+ },
+ {
+ "data", py_dex_class_get_data, NULL,
+ "Native data of the Dex class, if any.", NULL
+ },
+ {
+ "type", py_dex_class_get_class_type, NULL,
+ "Android type of the Dex class, None on error.", NULL
+ },
+ {
+ "super", py_dex_class_get_superclass_type, NULL,
+ "Android type of the parent Dex class, None on error.", NULL
+ },
+ {
+ "interfaces", py_dex_class_get_interface_types, NULL,
+ "Interface Android types of the Dex class, None if none and None on error.", NULL
+ },
+ {
+ "static_fields", py_dex_class_get_fields, NULL,
+ "List of static fields of the Dex class, None if none and None on error.", NULL
+ },
+ {
+ "instance_fields", py_dex_class_get_fields, NULL,
+ "List of static fields of the Dex class, None if none and None on error.", py_dex_class_get_fields
+ },
+ {
+ "direct_methods", py_dex_class_get_methods, NULL,
+ "List of direct methods of the Dex class, None if none and None on error.", py_dex_class_get_methods
+ },
+ {
+ "virtual_methods", py_dex_class_get_methods, NULL,
+ "List of virtual methods of the Dex class, None if none and None on error.", NULL
+ },
+ {
+ "source_file", py_dex_class_get_source_file, NULL,
+ "Source file of the Dex class, None on error.", NULL
+ },
{ NULL }
};
diff --git a/plugins/dex/python/constants.c b/plugins/dex/python/constants.c
new file mode 100644
index 0000000..ac50eb8
--- /dev/null
+++ b/plugins/dex/python/constants.c
@@ -0,0 +1,104 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - équivalent Python partiel du fichier "plugins/dex/dex_def.h"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "constants.h"
+
+
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../dex_def.h"
+
+
+
+/* Définit les constantes communes pour le format Dex. */
+static bool define_python_dex_format_common_constants(PyTypeObject *);
+
+
+/******************************************************************************
+* *
+* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes communes pour le format Dex. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool define_python_dex_format_common_constants(PyTypeObject *obj_type)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ /* Définition des drapeaux d'accès */
+
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_PUBLIC);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_PRIVATE);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_PROTECTED);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_STATIC);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_FINAL);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_SYNCHRONIZED);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_VOLATILE);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_BRIDGE);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_TRANSIENT);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_VARARGS);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_NATIVE);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_INTERFACE);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_ABSTRACT);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_STRICT);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_SYNTHETIC);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_ANNOTATION);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_ENUM);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_CONSTRUCTOR);
+ if (result) result = PyDict_AddIntMacro(obj_type, ACC_DECLARED_SYNCHRONIZED);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes pour le format Dex. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_python_dex_format_constants(PyTypeObject *obj_type)
+{
+ bool result; /* Bilan à retourner */
+
+ result = define_python_dex_format_common_constants(obj_type);
+
+ return result;
+
+}
diff --git a/plugins/dex/python/constants.h b/plugins/dex/python/constants.h
new file mode 100644
index 0000000..802bf2f
--- /dev/null
+++ b/plugins/dex/python/constants.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'équivalent Python partiel du fichier "plugins/dex/dex_def.h"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_DEX_PYTHON_CONSTANTS_H
+#define _PLUGINS_DEX_PYTHON_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes pour le format Dex. */
+bool define_python_dex_format_constants(PyTypeObject *);
+
+
+
+#endif /* _PLUGINS_DEX_PYTHON_CONSTANTS_H */
diff --git a/plugins/dex/python/field.c b/plugins/dex/python/field.c
new file mode 100644
index 0000000..69faccc
--- /dev/null
+++ b/plugins/dex/python/field.c
@@ -0,0 +1,186 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * field.c - équivalent Python du fichier "plugins/dex/field.c"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "field.h"
+
+
+#include <pygobject.h>
+
+
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "translate.h"
+#include "../field.h"
+
+
+
+/* Fournit les indications Dex concernant le champ de classe. */
+static PyObject *py_dex_field_get_encoded(PyObject *, void *);
+
+/* Fournit la variable Chrysalide correspondant au champ. */
+static PyObject *py_dex_field_get_variable(PyObject *, void *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit les indications Dex concernant le champ de classe. *
+* *
+* Retour : Données brutes du binaire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_field_get_encoded(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexField *field; /* Version native */
+ const encoded_field *info; /* Elément à traiter */
+
+ field = G_DEX_FIELD(pygobject_get(self));
+
+ info = g_dex_field_get_dex_info(field);
+
+ result = translate_dex_field_info_to_python(info);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la variable Chrysalide correspondant au champ. *
+* *
+* Retour : Instance de routine mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_field_get_variable(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexField *field; /* Version native */
+ GBinVariable *variable; /* Variable correspondante */
+
+ field = G_DEX_FIELD(pygobject_get(self));
+
+ variable = g_dex_field_get_variable(field);
+
+ result = pygobject_new(G_OBJECT(variable));
+
+ g_object_unref(G_OBJECT(variable));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_dex_field_type(void)
+{
+ static PyMethodDef py_dex_field_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_dex_field_getseters[] = {
+ {
+ "encoded", py_dex_field_get_encoded, NULL,
+ "Encoded information about the Dex field.", NULL
+ },
+ {
+ "variable", py_dex_field_get_variable, NULL,
+ "Chrysalide variable for the Dex field.", NULL
+ },
+ { NULL }
+ };
+
+ static PyTypeObject py_dex_field_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.format.dex.DexField",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "PyChrysalide Dex class field.",
+
+ .tp_methods = py_dex_field_methods,
+ .tp_getset = py_dex_field_getseters
+
+ };
+
+ return &py_dex_field_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.format.dex.DexField'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_dex_field(PyObject *module)
+{
+ PyTypeObject *py_dex_field_type; /* Type Python 'DexField' */
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_dex_field_type = get_python_dex_field_type();
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_class_for_pygobject(dict, G_TYPE_DEX_FIELD, py_dex_field_type, &PyGObject_Type))
+ return false;
+
+ return true;
+
+}
diff --git a/plugins/dex/python/field.h b/plugins/dex/python/field.h
new file mode 100644
index 0000000..fab0dce
--- /dev/null
+++ b/plugins/dex/python/field.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * field.h - prototypes pour l'équivalent Python du fichier "plugins/dex/field.h"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_DEX_PYTHON_FIELD_H
+#define _PLUGINS_DEX_PYTHON_FIELD_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_dex_field_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.format.dex.DexField'. */
+bool register_python_dex_field(PyObject *module);
+
+
+
+#endif /* _PLUGINS_DEX_PYTHON_FIELD_H */
diff --git a/plugins/dex/python/format.c b/plugins/dex/python/format.c
index a421549..81db02f 100644
--- a/plugins/dex/python/format.c
+++ b/plugins/dex/python/format.c
@@ -36,8 +36,10 @@
#include <plugins/pychrysalide/format/executable.h>
+#include "constants.h"
#include "../class.h"
#include "../format.h"
+#include "../pool.h"
@@ -50,6 +52,24 @@ static PyObject *py_dex_format_count_classes(PyObject *, PyObject *);
/* Fournit une classe du format chargée en mémoire. */
static PyObject *py_dex_format_get_class(PyObject *, PyObject *);
+/* Fournit la liste de toutes les chaînes de la table globale. */
+static PyObject *py_dex_format_get_pool_strings(PyObject *, void *);
+
+/* Fournit la liste de tous les types de la table globale. */
+static PyObject *py_dex_format_get_pool_types(PyObject *, void *);
+
+/* Fournit la liste de tous les prototypes de la table globale. */
+static PyObject *py_dex_format_get_pool_prototypes(PyObject *, void *);
+
+/* Fournit la liste de tous les champs de la table globale. */
+static PyObject *py_dex_format_get_pool_fields(PyObject *, void *);
+
+/* Fournit la liste de toutes les méthodes de la table globale. */
+static PyObject *py_dex_format_get_pool_methods(PyObject *, void *);
+
+/* Fournit la liste de toutes les classes du format. */
+static PyObject *py_dex_format_get_classes(PyObject *, void *);
+
/******************************************************************************
@@ -152,6 +172,313 @@ static PyObject *py_dex_format_get_class(PyObject *self, PyObject *args)
result = pygobject_new(G_OBJECT(class));
+ g_object_unref(G_OBJECT(class));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la liste de toutes les chaînes de la table globale. *
+* *
+* Retour : Liste vide ou remplie de chaînes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_format_get_pool_strings(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexFormat *format; /* Version native */
+ uint32_t count; /* Nombre d'éléments à traiter */
+ uint32_t i; /* Boucle de parcours */
+ const char *string; /* Chaîne à intégrer */
+ PyObject *str; /* Chaîne au format Python */
+
+ format = G_DEX_FORMAT(pygobject_get(self));
+
+ count = count_strings_in_dex_pool(format);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ string = get_string_from_dex_pool(format, i, NULL);
+
+ if (string == NULL)
+ {
+ str = Py_None;
+ Py_INCREF(str);
+ }
+
+ else
+ str = PyUnicode_FromString(string);
+
+ PyTuple_SetItem(result, i, str);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la liste de tous les types de la table globale. *
+* *
+* Retour : Liste vide ou remplie de types. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_format_get_pool_types(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexFormat *format; /* Version native */
+ uint32_t count; /* Nombre d'éléments à traiter */
+ uint32_t i; /* Boucle de parcours */
+ GDataType *type; /* Type à intégrer */
+ PyObject *tp; /* Type au format Python */
+
+ format = G_DEX_FORMAT(pygobject_get(self));
+
+ count = count_types_in_dex_pool(format);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ type = get_type_from_dex_pool(format, i);
+
+ if (type == NULL)
+ {
+ tp = Py_None;
+ Py_INCREF(tp);
+ }
+
+ else
+ {
+ tp = pygobject_new(G_OBJECT(type));
+ g_object_unref(type);
+ }
+
+ PyTuple_SetItem(result, i, tp);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la liste de tous les champs de la table globale. *
+* *
+* Retour : Liste vide ou remplie de méthodes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_format_get_pool_fields(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexFormat *format; /* Version native */
+ uint32_t count; /* Nombre d'éléments à traiter */
+ uint32_t i; /* Boucle de parcours */
+ GBinVariable *variable; /* Champ à intégrer */
+ PyObject *var; /* Champ au format Python */
+
+ format = G_DEX_FORMAT(pygobject_get(self));
+
+ count = count_fields_in_dex_pool(format);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ variable = get_field_from_dex_pool(format, i);
+
+ if (variable == NULL)
+ {
+ var = Py_None;
+ Py_INCREF(var);
+ }
+
+ else
+ {
+ var = pygobject_new(G_OBJECT(variable));
+ g_object_unref(variable);
+ }
+
+ PyTuple_SetItem(result, i, var);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la liste de toutes les méthodes de la table globale. *
+* *
+* Retour : Liste vide ou remplie de méthodes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_format_get_pool_methods(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexFormat *format; /* Version native */
+ uint32_t count; /* Nombre d'éléments à traiter */
+ uint32_t i; /* Boucle de parcours */
+ GDexMethod *method; /* Méthode à intégrer */
+ PyObject *meth; /* Méthode au format Python */
+
+ format = G_DEX_FORMAT(pygobject_get(self));
+
+ count = count_methods_in_dex_pool(format);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ method = get_method_from_dex_pool(format, i);
+
+ if (method == NULL)
+ {
+ meth = Py_None;
+ Py_INCREF(meth);
+ }
+
+ else
+ {
+ meth = pygobject_new(G_OBJECT(method));
+ g_object_unref(method);
+ }
+
+ PyTuple_SetItem(result, i, meth);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la liste de tous les prototypes de la table globale. *
+* *
+* Retour : Liste vide ou remplie de méthodes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_format_get_pool_prototypes(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexFormat *format; /* Version native */
+ uint32_t count; /* Nombre d'éléments à traiter */
+ uint32_t i; /* Boucle de parcours */
+ GBinRoutine *routine; /* Routine à intégrer */
+ PyObject *rtn; /* Routine au format Python */
+
+ format = G_DEX_FORMAT(pygobject_get(self));
+
+ count = count_prototypes_in_dex_pool(format);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ routine = get_prototype_from_dex_pool(format, i);
+
+ if (routine == NULL)
+ {
+ rtn = Py_None;
+ Py_INCREF(rtn);
+ }
+
+ else
+ {
+ rtn = pygobject_new(G_OBJECT(routine));
+ g_object_unref(routine);
+ }
+
+ PyTuple_SetItem(result, i, rtn);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la liste de toutes les classes du format. *
+* *
+* Retour : Liste vide ou remplie de classes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_format_get_classes(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexFormat *format; /* Version native */
+ size_t count; /* Nombre d'éléments à traiter */
+ size_t i; /* Boucle de parcours */
+ GDexClass *class; /* Classe du format à intégrer */
+
+ format = G_DEX_FORMAT(pygobject_get(self));
+
+ count = g_dex_format_count_classes(format);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ class = g_dex_format_get_class(format, i);
+ assert(class != NULL);
+
+ PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(class)));
+
+ g_object_unref(G_OBJECT(class));
+
+ }
+
return result;
}
@@ -186,6 +513,30 @@ PyTypeObject *get_python_dex_format_type(void)
};
static PyGetSetDef py_dex_format_getseters[] = {
+ {
+ "pool_strings", py_dex_format_get_pool_strings, NULL,
+ "Strings inside the Dex pool.", NULL
+ },
+ {
+ "pool_types", py_dex_format_get_pool_types, NULL,
+ "Types inside the Dex pool.", NULL
+ },
+ {
+ "pool_prototypes", py_dex_format_get_pool_prototypes, NULL,
+ "Prototypes inside the Dex pool.", NULL
+ },
+ {
+ "pool_fields", py_dex_format_get_pool_fields, NULL,
+ "Fields inside the Dex pool.", NULL
+ },
+ {
+ "pool_methods", py_dex_format_get_pool_methods, NULL,
+ "Methods inside the Dex pool.", NULL
+ },
+ {
+ "classes", py_dex_format_get_classes, NULL,
+ "Classes inside the Dex format.", NULL
+ },
{ NULL }
};
@@ -236,6 +587,9 @@ bool register_python_dex_format(PyObject *module)
py_dex_format_type, get_python_executable_format_type()))
return false;
+ if (!define_python_dex_format_constants(py_dex_format_type))
+ return false;
+
return true;
}
diff --git a/plugins/dex/python/method.c b/plugins/dex/python/method.c
new file mode 100644
index 0000000..4f35e1a
--- /dev/null
+++ b/plugins/dex/python/method.c
@@ -0,0 +1,223 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * method.c - équivalent Python du fichier "plugins/dex/method.c"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "method.h"
+
+
+#include <pygobject.h>
+
+
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "translate.h"
+#include "../method.h"
+
+
+
+/* Fournit les indications Dex concernant la méthode. */
+static PyObject *py_dex_method_get_encoded(PyObject *, void *);
+
+/* Fournit les indications Dex relatives au corps de la méthode. */
+static PyObject *py_dex_method_get_code_item(PyObject *, void *);
+
+/* Fournit la routine Chrysalide correspondant à la méthode. */
+static PyObject *py_dex_method_get_routine(PyObject *, void *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit les indications Dex concernant la méthode. *
+* *
+* Retour : Données brutes issues du binaire chargé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_method_get_encoded(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexMethod *method; /* Version native */
+ const encoded_method *info; /* Elément à traiter */
+
+ method = G_DEX_METHOD(pygobject_get(self));
+
+ info = g_dex_method_get_dex_info(method);
+
+ result = translate_dex_method_info_to_python(info);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit les indications Dex relatives au corps de la méthode.*
+* *
+* Retour : Données brutes du binaire, ou None si aucunes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_method_get_code_item(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexMethod *method; /* Version native */
+ const code_item *body; /* Elément à traiter */
+
+ method = G_DEX_METHOD(pygobject_get(self));
+
+ body = g_dex_method_get_dex_body(method);
+
+ result = translate_dex_method_body_to_python(body);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit la routine Chrysalide correspondant à la méthode. *
+* *
+* Retour : Instance de routine mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_dex_method_get_routine(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDexMethod *method; /* Version native */
+ GBinRoutine *routine; /* Routine correspondante */
+
+ method = G_DEX_METHOD(pygobject_get(self));
+
+ routine = g_dex_method_get_routine(method);
+
+ result = pygobject_new(G_OBJECT(routine));
+
+ g_object_unref(G_OBJECT(routine));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_dex_method_type(void)
+{
+ static PyMethodDef py_dex_method_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_dex_method_getseters[] = {
+ {
+ "encoded", py_dex_method_get_encoded, NULL,
+ "Encoded information about the Dex method.", NULL
+ },
+ {
+ "code_item", py_dex_method_get_code_item, NULL,
+ "Code information about the Dex method, None if none.", NULL
+ },
+ {
+ "routine", py_dex_method_get_routine, NULL,
+ "Chrysalide routine for the Dex method.", NULL
+ },
+ { NULL }
+ };
+
+ static PyTypeObject py_dex_method_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.format.dex.DexMethod",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "PyChrysalide Dex method.",
+
+ .tp_methods = py_dex_method_methods,
+ .tp_getset = py_dex_method_getseters
+
+ };
+
+ return &py_dex_method_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.format.dex.DexMethod'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_dex_method(PyObject *module)
+{
+ PyTypeObject *py_dex_method_type; /* Type Python 'DexMethod' */
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_dex_method_type = get_python_dex_method_type();
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_class_for_pygobject(dict, G_TYPE_DEX_METHOD, py_dex_method_type, &PyGObject_Type))
+ return false;
+
+ return true;
+
+}
diff --git a/plugins/dex/python/method.h b/plugins/dex/python/method.h
new file mode 100644
index 0000000..9c0c917
--- /dev/null
+++ b/plugins/dex/python/method.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * method.h - prototypes pour l'équivalent Python du fichier "plugins/dex/method.h"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_DEX_PYTHON_METHOD_H
+#define _PLUGINS_DEX_PYTHON_METHOD_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_dex_method_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.format.dex.DexMethod'. */
+bool register_python_dex_method(PyObject *module);
+
+
+
+#endif /* _PLUGINS_DEX_PYTHON_METHOD_H */
diff --git a/plugins/dex/python/module.c b/plugins/dex/python/module.c
index acb2370..6a84af3 100644
--- a/plugins/dex/python/module.c
+++ b/plugins/dex/python/module.c
@@ -32,7 +32,9 @@
#include "class.h"
+#include "field.h"
#include "format.h"
+#include "method.h"
@@ -86,8 +88,14 @@ bool add_format_dex_module_to_python_module(void)
result = register_python_dex_class(module);
if (result)
+ result = register_python_dex_field(module);
+
+ if (result)
result = register_python_dex_format(module);
+ if (result)
+ result = register_python_dex_method(module);
+
loading_failed:
return result;
diff --git a/plugins/dex/python/translate.c b/plugins/dex/python/translate.c
new file mode 100644
index 0000000..eb80c43
--- /dev/null
+++ b/plugins/dex/python/translate.c
@@ -0,0 +1,293 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * translate.c - conversion de structures Dex en objets Python
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "translate.h"
+
+
+#include <assert.h>
+
+
+#include <plugins/pychrysalide/struct.h>
+
+
+#include "../dex_def.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : info = ensemble d'informations Dex à décrire en Python. *
+* *
+* Description : Traduit des informations de champ de classe Dex en Python. *
+* *
+* Retour : Structure mise en place ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *translate_dex_field_info_to_python(const encoded_field *info)
+{
+ PyObject *result; /* Construction à retourner */
+ PyTypeObject *base; /* Modèle d'objet à créer */
+ PyObject *attrib; /* Attribut à constituer */
+ int ret; /* Bilan d'une mise en place */
+
+ base = get_python_py_struct_type();
+
+ result = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(result != NULL);
+
+ /* Champs réguliers */
+
+#define TRANSLATE_ENCODED_FIELD_PROP(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(info->_f); \
+ ret = PyDict_SetItemString(result, #_f, attrib); \
+ if (ret != 0) goto tdcdtp_failed; \
+ } \
+ while (0);
+
+ TRANSLATE_ENCODED_FIELD_PROP(field_idx_diff);
+ TRANSLATE_ENCODED_FIELD_PROP(access_flags);
+
+ return result;
+
+ tdcdtp_failed:
+
+ Py_DECREF(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = ensemble d'informations Dex à décrire en Python. *
+* *
+* Description : Traduit des informations de méthode Dex en Python. *
+* *
+* Retour : Structure mise en place ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *translate_dex_method_info_to_python(const encoded_method *info)
+{
+ PyObject *result; /* Construction à retourner */
+ PyTypeObject *base; /* Modèle d'objet à créer */
+ PyObject *attrib; /* Attribut à constituer */
+ int ret; /* Bilan d'une mise en place */
+
+ base = get_python_py_struct_type();
+
+ result = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(result != NULL);
+
+ /* Champs réguliers */
+
+#define TRANSLATE_ENCODED_METHOD_PROP(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(info->_f); \
+ ret = PyDict_SetItemString(result, #_f, attrib); \
+ if (ret != 0) goto tdcdtp_failed; \
+ } \
+ while (0);
+
+ TRANSLATE_ENCODED_METHOD_PROP(method_idx_diff);
+ TRANSLATE_ENCODED_METHOD_PROP(access_flags);
+ TRANSLATE_ENCODED_METHOD_PROP(code_off);
+
+ return result;
+
+ tdcdtp_failed:
+
+ Py_DECREF(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = ensemble d'informations Dex à décrire en Python. *
+* *
+* Description : Traduit des informations de corps de méthode Dex en Python. *
+* *
+* Retour : Structure mise en place ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *translate_dex_method_body_to_python(const code_item *body)
+{
+ PyObject *result; /* Construction à retourner */
+ PyTypeObject *base; /* Modèle d'objet à créer */
+ PyObject *attrib; /* Attribut à constituer */
+ int ret; /* Bilan d'une mise en place */
+
+ base = get_python_py_struct_type();
+
+ result = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(result != NULL);
+
+ /* Champs réguliers */
+
+#define TRANSLATE_CODE_ITEM_PROP(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(body->_f); \
+ ret = PyDict_SetItemString(result, #_f, attrib); \
+ if (ret != 0) goto tdcdtp_failed; \
+ } \
+ while (0);
+
+ TRANSLATE_CODE_ITEM_PROP(registers_size);
+ TRANSLATE_CODE_ITEM_PROP(ins_size);
+ TRANSLATE_CODE_ITEM_PROP(outs_size);
+ TRANSLATE_CODE_ITEM_PROP(tries_size);
+ TRANSLATE_CODE_ITEM_PROP(debug_info_off);
+ TRANSLATE_CODE_ITEM_PROP(insns_size);
+
+ return result;
+
+ tdcdtp_failed:
+
+ Py_DECREF(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = ensemble d'informations Dex à décrire en Python. *
+* *
+* Description : Traduit une définition de classe Dex en Python. *
+* *
+* Retour : Structure mise en place ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *translate_dex_class_definition_to_python(const class_def_item *item)
+{
+ PyObject *result; /* Construction à retourner */
+ PyTypeObject *base; /* Modèle d'objet à créer */
+ PyObject *attrib; /* Attribut à constituer */
+ int ret; /* Bilan d'une mise en place */
+
+ base = get_python_py_struct_type();
+
+ result = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(result != NULL);
+
+ /* Champs réguliers */
+
+#define TRANSLATE_CLASS_DEF_PROP(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(item->_f); \
+ ret = PyDict_SetItemString(result, #_f, attrib); \
+ if (ret != 0) goto tdcdtp_failed; \
+ } \
+ while (0);
+
+ TRANSLATE_CLASS_DEF_PROP(class_idx);
+ TRANSLATE_CLASS_DEF_PROP(access_flags);
+ TRANSLATE_CLASS_DEF_PROP(superclass_idx);
+ TRANSLATE_CLASS_DEF_PROP(interfaces_off);
+ TRANSLATE_CLASS_DEF_PROP(source_file_idx);
+ TRANSLATE_CLASS_DEF_PROP(annotations_off);
+ TRANSLATE_CLASS_DEF_PROP(class_data_off);
+ TRANSLATE_CLASS_DEF_PROP(static_values_off);
+
+ return result;
+
+ tdcdtp_failed:
+
+ Py_DECREF(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = ensemble d'informations Dex à décrire en Python. *
+* *
+* Description : Traduit des données de classe Dex en Python. *
+* *
+* Retour : Structure mise en place ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *translate_dex_class_data_to_python(const class_data_item *item)
+{
+ PyObject *result; /* Construction à retourner */
+ PyTypeObject *base; /* Modèle d'objet à créer */
+ PyObject *attrib; /* Attribut à constituer */
+ int ret; /* Bilan d'une mise en place */
+
+ base = get_python_py_struct_type();
+
+ result = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(result != NULL);
+
+ /* Champs réguliers */
+
+#define TRANSLATE_CLASS_DATA_PROP(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(item->_f); \
+ ret = PyDict_SetItemString(result, #_f, attrib); \
+ if (ret != 0) goto tdcdtp_failed; \
+ } \
+ while (0);
+
+ TRANSLATE_CLASS_DATA_PROP(static_fields_size);
+ TRANSLATE_CLASS_DATA_PROP(instance_fields_size);
+ TRANSLATE_CLASS_DATA_PROP(direct_methods_size);
+ TRANSLATE_CLASS_DATA_PROP(virtual_methods_size);
+
+ return result;
+
+ tdcdtp_failed:
+
+ Py_DECREF(result);
+
+ return NULL;
+
+}
diff --git a/plugins/dex/python/translate.h b/plugins/dex/python/translate.h
new file mode 100644
index 0000000..29a0155
--- /dev/null
+++ b/plugins/dex/python/translate.h
@@ -0,0 +1,53 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * translate.h - prototypes pour la conversion de structures Dex en objets Python
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_DEX_PYTHON_TRANSLATE_H
+#define _PLUGINS_DEX_PYTHON_TRANSLATE_H
+
+
+#include <Python.h>
+
+
+#include "../format.h"
+
+
+
+/* Traduit des informations de champ de classe Dex en Python. */
+PyObject *translate_dex_field_info_to_python(const encoded_field *);
+
+/* Traduit des informations de méthode Dex en Python. */
+PyObject *translate_dex_method_info_to_python(const encoded_method *);
+
+/* Traduit des informations de corps de méthode Dex en Python. */
+PyObject *translate_dex_method_body_to_python(const code_item *);
+
+/* Traduit une définition de classe Dex en Python. */
+PyObject *translate_dex_class_definition_to_python(const class_def_item *);
+
+/* Traduit des données de classe Dex en Python. */
+PyObject *translate_dex_class_data_to_python(const class_data_item *);
+
+
+
+#endif /* _PLUGINS_DEX_PYTHON_TRANSLATE_H */