From 33880cfe5e5de8b81e8a825878b3bbe8ef736f3f Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 30 Apr 2017 21:21:29 +0200
Subject: Parsed Dex format fields using the new generic parser.

---
 ChangeLog                 |  21 ++
 plugins/fmtp/def.h        |  18 +-
 plugins/fmtp/parser.c     |  39 +++-
 plugins/fmtp/parser.h     |   2 +-
 plugins/readdex/class.c   | 451 +++++++++++++++++--------------------
 plugins/readdex/code.c    | 560 ++++++++++++++++++++++++++--------------------
 plugins/readdex/header.c  | 311 ++++++++++++++-----------
 plugins/readdex/ids.c     | 505 +++++++++++++++++++++++------------------
 plugins/readelf/header.c  |  10 +-
 plugins/readelf/program.c |  12 +-
 plugins/readelf/section.c |  12 +-
 src/format/dex/dex.c      |  27 +++
 12 files changed, 1103 insertions(+), 865 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a005921..fe4f659 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+17-04-30  Cyrille Bagard <nocbos@gmail.com>
+
+	* plugins/fmtp/def.h:
+	* plugins/fmtp/parser.c:
+	* plugins/fmtp/parser.h:
+	Extend the generic parser features.
+
+	* plugins/readdex/class.c:
+	* plugins/readdex/code.c:
+	* plugins/readdex/header.c:
+	* plugins/readdex/ids.c:
+	Parse Dex format fields using the new generic parser.
+
+	* plugins/readelf/header.c:
+	* plugins/readelf/program.c:
+	* plugins/readelf/section.c:
+	Update code.
+
+	* src/format/dex/dex.c:
+	Provide the endianness of (most) Dex files.
+
 17-04-29  Cyrille Bagard <nocbos@gmail.com>
 
 	* plugins/fmtp/parser.c:
diff --git a/plugins/fmtp/def.h b/plugins/fmtp/def.h
index d69d20a..f1ec7c7 100644
--- a/plugins/fmtp/def.h
+++ b/plugins/fmtp/def.h
@@ -34,16 +34,24 @@
 
 
 /**
- * Assurément utile pour les déclarations...
+ * Assurément utile pour les déclarations ou les appels...
  */
 
 #define __(s) s
 
+#define PARSING_DEFS(a) a, ARRAY_SIZE(a)
+
 
 /**
  * Méthodes de définitions des déclarations.
  */
 
+/* Définition générale */
+typedef struct _fmt_field_def fmt_field_def;
+
+/* Eventuel appel préalable */
+typedef bool (* get_fdef_value_cb) (const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, void *);
+
 /* Possibilités pour un champ à commenter */
 typedef struct _field_desc_switch
 {
@@ -89,10 +97,14 @@ typedef enum _FieldCommentType
 } FieldCommentType;
 
 /* Définition générale */
-typedef struct _fmt_field_def
+struct _fmt_field_def
 {
     const char *name;                       /* Nom du champ                */
 
+    get_fdef_value_cb get_value;            /* Obtention de la valeur      */
+
+    bool is_uleb128;                        /* Element de type uleb128     */
+    bool is_leb128;                        /* Element de type sleb128     */
     MemoryDataSize size;                    /* Taille d'un élément         */
     size_t repeat;                          /* Quantité d'éléments présents*/
 
@@ -122,7 +134,7 @@ typedef struct _fmt_field_def
 
     } comment;
 
-} fmt_field_def;
+};
 
 
 /* Règles d'affichage */
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c
index b484a0e..8fc693f 100644
--- a/plugins/fmtp/parser.c
+++ b/plugins/fmtp/parser.c
@@ -33,8 +33,7 @@
 
 
 /* Effectue l'interprétation d'une définition de champ. */
-static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *);
-
+static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *, void *);
 
 
 
@@ -43,6 +42,7 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *
 *  Paramètres  : def    = définition de champ à considérer.                   *
 *                format = description de l'exécutable à compléter.            *
 *                pos    = tête de lecture pour les données.                   *
+*                data   = infos complémentaires éventuellement fournies.      *
 *                                                                             *
 *  Description : Effectue l'interprétation d'une définition de champ.         *
 *                                                                             *
@@ -52,10 +52,11 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *
 *                                                                             *
 ******************************************************************************/
 
-static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos)
+static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos, void *data)
 {
     GBinContent *content;                   /* Contenu binaire à lire      */
     SourceEndian endian;                    /* Boutisme utilisé            */
+    vmpa2t mod;                             /* Position  modifiable        */
     bool result;                            /* Bilan à retourner           */
     GArchInstruction *instr;                /* Instruction décodée         */
     GImmOperand *imm;                       /* Opérande à transformer      */
@@ -74,9 +75,28 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
     content = g_binary_format_get_content(format);
     endian = g_binary_format_get_endianness(format);
 
-    assert(def->repeat > 0);
+    if (def->get_value != NULL)
+    {
+        copy_vmpa(&mod, pos);
+
+        result = def->get_value(def, content, &mod, endian, data);
+
+        if (!result)
+            goto pfd_exit;
+
+    }
+
+    if (def->is_uleb128)
+        instr = g_raw_instruction_new_uleb128(content, pos);
+
+    else if (def->is_leb128)
+        instr = g_raw_instruction_new_sleb128(content, pos);
 
-    instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian);
+    else
+    {
+        assert(def->repeat > 0);
+        instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian);
+    }
 
     result = (instr != NULL);
 
@@ -88,7 +108,9 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
 
     if (def->has_display_rules)
     {
-        assert(def->disp_count <= def->repeat);
+        assert((def->is_uleb128 && def->disp_count == 1)
+               || (def->is_leb128 && def->disp_count == 1)
+               || (!def->is_uleb128 && !def->is_leb128 && def->disp_count <= def->repeat));
 
         for (i = 0; i < def->disp_count; i++)
         {
@@ -198,6 +220,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
 *                count  = taille de cette liste.                              *
 *                format = description de l'exécutable à compléter.            *
 *                pos    = tête de lecture pour les données.                   *
+*                data   = infos complémentaires éventuellement fournies.      *
 *                                                                             *
 *  Description : Lance l'interprétation d'une série de définitions de champs. *
 *                                                                             *
@@ -207,7 +230,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
 *                                                                             *
 ******************************************************************************/
 
-bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos)
+bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos, void *data)
 {
     bool result;                            /* Bilan à retourner           */
     size_t i;                               /* Boucle de parcours          */
@@ -215,7 +238,7 @@ bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat
     result = true;
 
     for (i = 0; i < count && result; i++)
-        result = parse_field_definition(defs + i, format, pos);
+        result = parse_field_definition(defs + i, format, pos, data);
 
     return result;
 
diff --git a/plugins/fmtp/parser.h b/plugins/fmtp/parser.h
index dcd9bf2..0d5dff3 100644
--- a/plugins/fmtp/parser.h
+++ b/plugins/fmtp/parser.h
@@ -36,7 +36,7 @@
 
 
 /* Lance l'interprétation d'une série de définitions de champs. */
-bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, vmpa2t *);
+bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, vmpa2t *, void *);
 
 
 
diff --git a/plugins/readdex/class.c b/plugins/readdex/class.c
index c08fe4a..7b7b253 100644
--- a/plugins/readdex/class.c
+++ b/plugins/readdex/class.c
@@ -24,206 +24,232 @@
 #include "class.h"
 
 
-#include <assert.h>
-#include <malloc.h>
-#include <stdio.h>
-
-
 #include <i18n.h>
-#include <arch/raw.h>
-#include <format/symbol.h>
 #include <format/dex/class.h>
 #include <format/dex/dex_def.h>
+#include <plugins/fmtp/parser.h>
 
 
 #include "code.h"
 
 
 
-/* Commente les définitions des classes pour la VM Dalvik. */
-static bool annotate_dex_class_data(const GDexFormat *, const GDexClass *, uint32_t );
+/* Définition des champs */
 
-/* Commente les définitions des champs encodés. */
-static bool annotate_dex_encoded_field(const GDexFormat *, vmpa2t *);
+static fmt_field_def _dex_class_defs[] = {
 
-/* Commente les définitions des méthodes encodées. */
-static bool annotate_dex_encoded_method(const GDexFormat *, const encoded_method *, vmpa2t *);
+    {
+        .name = "class_idx",
 
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
+        DISPLAY_RULES(IOD_DEC),
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : format = description de l'exécutable à compléter.            *
-*                status = barre de statut à tenir informée.                   *
-*                                                                             *
-*  Description : Commente les définitions des classes pour la VM Dalvik.      *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+        PLAIN_COMMENT(__("Index into the type_ids list for this class"))
 
-bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
-{
-    bool result;                            /* Bilan à retourner           */
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    const dex_header *header;               /* En-tête principale          */
-    SourceEndian endian;                    /* Boutisme utilisé            */
-    vmpa2t pos;                             /* Tête de lecture des symboles*/
-    activity_id_t msg;                      /* Message de progression      */
-    uint32_t i;                             /* Boucle de parcours          */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-    GDexClass *class;                       /* Classe chargée à manipuler  */
-    const class_def_item *def;              /* Définition brute à lire     */
+    },
 
-    result = true;
+    {
+        .name = "access_flags",
 
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    header = g_dex_format_get_header(format);
-    endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+        PLAIN_COMMENT(__("Access flags for the class"))
 
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->class_defs_off, &pos))
-        return false;
+    },
 
-    msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex classes..."),
-                                        header->class_defs_size);
+    {
+        .name = "superclass_idx",
+
+        .size = MDS_32_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the superclass or NO_INDEX if this class has no superclass"))
+
+    },
+
+    {
+        .name = "interfaces_off",
+
+        .size = MDS_32_BITS,
+        .repeat = 1,
+
+        PLAIN_COMMENT(__("Offset to the list of interfaces"))
+
+    },
 
-    for (i = 0; i < header->class_defs_size && result; i++)
     {
-        /* class_idx */
+        .name = "source_file_idx",
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        DISPLAY_RULES(IOD_DEC),
 
-        asprintf(&text, _("Index into the type_ids list for this class"));
+        PLAIN_COMMENT(__("Index for the name of the file containing the original source or NO_INDEX"))
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    },
 
-        free(text);
+    {
+        .name = "annotations_off",
 
-        if (i == 0)
-            g_binary_symbol_define_as_block_start(symbol, true);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-        /* access_flags */
+        PLAIN_COMMENT(__("Offset to the annotations structure for this class"))
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    },
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    {
+        .name = "class_data_off",
 
-        asprintf(&text, _("Access flags for the class"));
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        PLAIN_COMMENT(__("Offset to the associated class data for this item"))
 
-        free(text);
+    },
 
-        /* superclass_idx */
+    {
+        .name = "static_values_off",
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        PLAIN_COMMENT(__("Offset to the list of initial values for static fields"))
 
-        asprintf(&text, _("Index for the superclass or NO_INDEX if this class has no superclass"));
+    }
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+};
 
-        free(text);
+static fmt_field_def _dex_class_data[] = {
 
-        /* interfaces_off */
+    {
+        .name = "static_fields_size",
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        .is_uleb128 = true,
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+        DISPLAY_RULES(IOD_DEC),
 
-        asprintf(&text, _("Offset to the list of interfaces"));
+        PLAIN_COMMENT(__("Number of static fields defined in this item"))
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    },
 
-        free(text);
+    {
+        .name = "instance_fields_size",
 
-        /* source_file_idx */
+        .is_uleb128 = true,
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        DISPLAY_RULES(IOD_DEC),
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        PLAIN_COMMENT(__("Number of instance fields defined in this item"))
 
-        asprintf(&text, _("Index for the name of the file containing the original source or NO_INDEX"));
+    },
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    {
+        .name = "direct_methods_size",
 
-        free(text);
+        .is_uleb128 = true,
 
-        /* annotations_off */
+        DISPLAY_RULES(IOD_DEC),
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        PLAIN_COMMENT(__("Number of direct methods defined in this item"))
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    },
 
-        asprintf(&text, _("Offset to the annotations structure for this class"));
+    {
+        .name = "virtual_methods_size",
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        .is_uleb128 = true,
 
-        free(text);
+        DISPLAY_RULES(IOD_DEC),
 
-        /* class_data_off */
+        PLAIN_COMMENT(__("Number of virtual methods defined in this item"))
+
+    }
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+};
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+static fmt_field_def _dex_encoded_field[] = {
 
-        asprintf(&text, _("Offset to the associated class data for this item"));
+    {
+        .name = "field_idx_diff",
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        .is_uleb128 = true,
 
-        free(text);
+        DISPLAY_RULES(IOD_DEC),
 
-        /* static_values_off */
+        PLAIN_COMMENT(__("Index into the field_ids list for the identity of this field"))
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    },
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    {
+        .name = "access_flags",
 
-        asprintf(&text, _("Offset to the list of initial values for static fields"));
+        .is_uleb128 = true,
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        PLAIN_COMMENT(__("Access flags for the field"))
 
-        free(text);
+    }
 
-        /* Annotations supplémentaires */
+};
 
-        class = g_dex_format_get_class(format, i);
+static fmt_field_def _dex_encoded_method[] = {
 
-        def = g_dex_class_get_definition(class);
+    {
+        .name = "method_idx_diff",
 
-        if (def->class_data_off > 0)
-            result = annotate_dex_class_data(format, class, def->class_data_off);
+        .is_uleb128 = true,
 
-        /* TODO : g_object_unref(G_OBJECT(class));*/
+        DISPLAY_RULES(IOD_DEC),
 
-        gtk_status_stack_update_activity_value(status, msg, 1);
+        PLAIN_COMMENT(__("Index into the method_ids list for the identity of this method"))
+
+    },
+
+    {
+        .name = "access_flags",
+
+        .is_uleb128 = true,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Access flags for the method"))
+
+    },
+
+    {
+        .name = "code_off",
+
+        .is_uleb128 = true,
+
+        PLAIN_COMMENT(__("Offset to the code structure for this method"))
 
     }
 
-    gtk_status_stack_remove_activity(status, msg);
+};
 
-    g_object_unref(G_OBJECT(content));
 
-    return result;
 
-}
+/* Commente les définitions des classes pour la VM Dalvik. */
+static bool annotate_dex_class_data(const GDexFormat *, const GDexClass *, uint32_t );
+
+/* Commente les définitions des champs encodés. */
+static bool annotate_dex_encoded_field(const GDexFormat *, vmpa2t *);
+
+/* Commente les définitions des méthodes encodées. */
+static bool annotate_dex_encoded_method(const GDexFormat *, const encoded_method *, vmpa2t *);
+
 
 
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format = description de l'exécutable à compléter.            *
-*                class  = classe Dex dont les données sont à commenter.       *
-*                offset = tête de lecture physique des symboles.              *
+*                status = barre de statut à tenir informée.                   *
 *                                                                             *
 *  Description : Commente les définitions des classes pour la VM Dalvik.      *
 *                                                                             *
@@ -233,78 +259,94 @@ bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
 *                                                                             *
 ******************************************************************************/
 
-static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *class, uint32_t offset)
+bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
 {
     bool result;                            /* Bilan à retourner           */
-    GBinContent *content;                   /* Contenu binaire à lire      */
+    const dex_header *header;               /* En-tête principale          */
     vmpa2t pos;                             /* Tête de lecture des symboles*/
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-    const class_data_item *data;            /* Données chargées à lire     */
-    uleb128_t i;                            /* Boucle de parcours          */
-
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
-
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos))
-        return false;
+    activity_id_t msg;                      /* Message de progression      */
+    GBinFormat *bformat;                    /* Autre version du format     */
+    uint32_t i;                             /* Boucle de parcours          */
+    GDexClass *class;                       /* Classe chargée à manipuler  */
+    const class_def_item *def;              /* Définition brute à lire     */
 
-    /* static_fields_size */
+    header = g_dex_format_get_header(format);
 
-    instr = g_raw_instruction_new_uleb128(content, &pos);
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->class_defs_off, &pos);
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    if (!result)
+        goto adcd_exit;
 
-    asprintf(&text, _("Number of static fields defined in this item"));
+    msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex classes..."),
+                                        header->class_defs_size);
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    bformat = G_BIN_FORMAT(format);
 
-    free(text);
+    for (i = 0; i < header->class_defs_size && result; i++)
+    {
+        result = parse_field_definitions(PARSING_DEFS(_dex_class_defs), bformat, &pos, NULL);
+        if (!result) break;
 
-    g_binary_symbol_define_as_block_start(symbol, true);
+        /* Annotations supplémentaires */
 
-    /* instance_fields_size */
+        class = g_dex_format_get_class(format, i);
 
-    instr = g_raw_instruction_new_uleb128(content, &pos);
+        def = g_dex_class_get_definition(class);
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        if (def->class_data_off > 0)
+            result = annotate_dex_class_data(format, class, def->class_data_off);
 
-    asprintf(&text, _("Number of instance fields defined in this item"));
+        /* TODO : g_object_unref(G_OBJECT(class));*/
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        gtk_status_stack_update_activity_value(status, msg, 1);
 
-    free(text);
+    }
 
-    /* direct_methods_size */
+    gtk_status_stack_remove_activity(status, msg);
 
-    instr = g_raw_instruction_new_uleb128(content, &pos);
+ adcd_exit:
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    return result;
 
-    asprintf(&text, _("Number of direct methods defined in this item"));
+}
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
 
-    free(text);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = description de l'exécutable à compléter.            *
+*                class  = classe Dex dont les données sont à commenter.       *
+*                offset = tête de lecture physique des symboles.              *
+*                                                                             *
+*  Description : Commente les définitions des classes pour la VM Dalvik.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    /* virtual_methods_size */
+static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *class, uint32_t offset)
+{
+    bool result;                            /* Bilan à retourner           */
+    vmpa2t pos;                             /* Tête de lecture des symboles*/
+    GBinFormat *bformat;                    /* Autre version du format     */
+    const class_data_item *data;            /* Données chargées à lire     */
+    uleb128_t i;                            /* Boucle de parcours          */
 
-    instr = g_raw_instruction_new_uleb128(content, &pos);
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos);
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    if (!result)
+        goto adcd_exit;
 
-    asprintf(&text, _("Number of virtual methods defined in this item"));
+    bformat = G_BIN_FORMAT(format);
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    result = parse_field_definitions(PARSING_DEFS(_dex_class_data), bformat, &pos, NULL);
 
-    free(text);
+    if (!result)
+        goto adcd_exit;
 
     /* Chargements complémentaires */
 
-    result = true;
-
     data = g_dex_class_get_data(class);
 
     if (data != NULL)
@@ -323,9 +365,7 @@ static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *c
 
     }
 
-    /* Nettoyage final */
-
-    g_object_unref(G_OBJECT(content));
+ adcd_exit:
 
     return result;
 
@@ -347,46 +387,14 @@ static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *c
 
 static bool annotate_dex_encoded_field(const GDexFormat *format, vmpa2t *pos)
 {
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
-
-    /* field_idx_diff */
-
-    instr = g_raw_instruction_new_uleb128(content, pos);
-
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-    asprintf(&text, _("Index into the field_ids list for the identity of this field"));
-
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-    free(text);
-
-    g_binary_symbol_define_as_block_start(symbol, true);
-
-    /* access_flags */
-
-    instr = g_raw_instruction_new_uleb128(content, pos);
-
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
-
-    asprintf(&text, _("Access flags for the field"));
-
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-    free(text);
+    bool result;                            /* Bilan à retourner           */
+    GBinFormat *bformat;                    /* Autre version du format     */
 
-    /* Nettoyage final */
+    bformat = G_BIN_FORMAT(format);
 
-    g_object_unref(G_OBJECT(content));
+    result = parse_field_definitions(PARSING_DEFS(_dex_encoded_field), bformat, pos, NULL);
 
-    return true;
+    return result;
 
 }
 
@@ -408,63 +416,16 @@ static bool annotate_dex_encoded_field(const GDexFormat *format, vmpa2t *pos)
 static bool annotate_dex_encoded_method(const GDexFormat *format, const encoded_method *method, vmpa2t *pos)
 {
     bool result;                            /* Bilan à retourner           */
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
-
-    /* method_idx_diff */
-
-    instr = g_raw_instruction_new_uleb128(content, pos);
-
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-    asprintf(&text, _("Index into the method_ids list for the identity of this method"));
-
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-    free(text);
-
-    g_binary_symbol_define_as_block_start(symbol, true);
-
-    /* access_flags */
+    GBinFormat *bformat;                    /* Autre version du format     */
 
-    instr = g_raw_instruction_new_uleb128(content, pos);
+    bformat = G_BIN_FORMAT(format);
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
-
-    asprintf(&text, _("Access flags for the method"));
-
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-    free(text);
-
-    /* code_off */
-
-    instr = g_raw_instruction_new_uleb128(content, pos);
-
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
-
-    asprintf(&text, _("Offset to the code structure for this method"));
-
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-    free(text);
+    result = parse_field_definitions(PARSING_DEFS(_dex_encoded_method), bformat, pos, NULL);
 
     /* Chargements complémentaires, si non abstraite ni native */
 
-    if (method->code_off > 0)
+    if (result && method->code_off > 0)
         result = annotate_dex_code_item(format, method->code_off);
-    else
-        result = true;
-
-    /* Nettoyage final */
-
-    g_object_unref(G_OBJECT(content));
 
     return result;
 
diff --git a/plugins/readdex/code.c b/plugins/readdex/code.c
index 2f43e86..23e82ac 100644
--- a/plugins/readdex/code.c
+++ b/plugins/readdex/code.c
@@ -24,254 +24,271 @@
 #include "code.h"
 
 
-#include <assert.h>
-#include <malloc.h>
-#include <stdio.h>
+#include <format/dex/dex_def.h>
+#include <plugins/fmtp/parser.h>
 
 
-#include <i18n.h>
-#include <arch/raw.h>
-#include <format/symbol.h>
-#include <format/dex/dex_def.h>
 
+/* Définition des champs */
 
+typedef struct _code_item_data
+{
+    uint16_t tries_size;                    /* Nombre de gestionnaires     */
+    uint32_t insns_size;                    /* Nombre d'instructions       */
 
-/* Commente les définitions d'une protection contre exceptions. */
-static bool annotate_dex_try_item(const GDexFormat *, vmpa2t *);
+} code_item_data;
 
-/*Commente les définitions des listes de gestion d'exceptions. */
-static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *, vmpa2t *);
+/* Récupère le nombre de couvertures pour exceptions. */
+static bool get_code_tries_size_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, code_item_data *);
 
-/* Commente les définitions d'une prise en compte d'exceptions. */
-static bool annotate_dex_encoded_catch_handler(const GDexFormat *, vmpa2t *);
+/* Récupère le nombre de blocs d'instructions. */
+static bool get_code_insns_size_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, code_item_data *);
 
-/* Commente les définitions des gestions d'exceptions par type. */
-static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *, vmpa2t *);
+/* Récupère le nombre d'éléments d'une liste de couvertures. */
+static bool get_encoded_catch_handler_list_size_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, uleb128_t *);
 
+/* Récupère le nombre d'exécptions gérées dans une couverture. */
+static bool get_encoded_catch_handler_size_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, leb128_t *);
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : format = description de l'exécutable à compléter.            *
-*                                                                             *
-*  Description : Commente les définitions d'un corps de méthode.              *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+static fmt_field_def _dex_code_item[] = {
 
-bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
-{
-    bool result;                            /* Bilan à retourner           */
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    SourceEndian endian;                    /* Boutisme utilisé            */
-    vmpa2t pos;                             /* Tête de lecture des symboles*/
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-    uint16_t tries_size;                    /* Nombre de gestionnaires     */
-    uint32_t insns_size;                    /* Nombre d'instructions       */
-    uint16_t i;                             /* Boucle de parcours          */
+    {
+        .name = "registers_size",
 
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
+        .size = MDS_16_BITS,
+        .repeat = 1,
 
-    endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+        DISPLAY_RULES(IOD_DEC),
 
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos))
-        return false;
+        PLAIN_COMMENT(__("Number of registers used by this code"))
 
-    /* registers_size */
+    },
 
-    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+    {
+        .name = "ins_size",
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        .size = MDS_16_BITS,
+        .repeat = 1,
 
-    asprintf(&text, _("Number of registers used by this code"));
+        DISPLAY_RULES(IOD_DEC),
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        PLAIN_COMMENT(__("Number of words of incoming arguments to the method that this code is for"))
 
-    free(text);
+    },
 
-    g_binary_symbol_define_as_block_start(symbol, true);
+    {
+        .name = "outs_size",
 
-    /* ins_size */
+        .size = MDS_16_BITS,
+        .repeat = 1,
 
-    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+        DISPLAY_RULES(IOD_DEC),
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        PLAIN_COMMENT(__("Number of words of outgoing argument space required by this code for method invocation"))
 
-    asprintf(&text, _("Number of words of incoming arguments to the method that this code is for"));
+    },
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    {
+        .name = "tries_size",
 
-    free(text);
+        .get_value = (get_fdef_value_cb)get_code_tries_size_value,
 
-    /* outs_size */
+        .size = MDS_16_BITS,
+        .repeat = 1,
 
-    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+        DISPLAY_RULES(IOD_DEC),
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        PLAIN_COMMENT(__("Number of try_items for this instance"))
 
-    asprintf(&text, _("Number of words of outgoing argument space required by this code for method invocation"));
+    },
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    {
+        .name = "debug_info_off",
 
-    free(text);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    /* tries_size */
+        PLAIN_COMMENT(__("Offset to the debug info sequence for this code"))
 
-    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+    },
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    {
+        .name = "insns_size",
 
-    asprintf(&text, _("Number of try_items for this instance"));
+        .get_value = (get_fdef_value_cb)get_code_insns_size_value,
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    free(text);
+        DISPLAY_RULES(IOD_DEC),
 
-    g_imm_operand_get_value(G_IMM_OPERAND(operand), MDS_16_BITS, &tries_size);
+        PLAIN_COMMENT(__("Size of the instructions list, in 16-bit code units"))
 
-    /* debug_info_off */
+    }
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+};
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+static fmt_field_def _dex_code_item_padding[] = {
 
-    asprintf(&text, _("Offset to the debug info sequence for this code"));
+    {
+        .name = "padding",
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        .size = MDS_16_BITS,
+        .repeat = 1,
 
-    free(text);
+        PLAIN_COMMENT(__("Padding"))
 
-    /* insns_size */
+    }
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+};
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+static fmt_field_def _dex_try_item[] = {
 
-    asprintf(&text, _("Size of the instructions list, in 16-bit code units"));
+    {
+        .name = "start_addr",
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    free(text);
+        PLAIN_COMMENT(__("Start address of the block of code covered by this entry"))
 
-    /* insns */
+    },
 
-    g_imm_operand_get_value(G_IMM_OPERAND(operand), MDS_32_BITS, &insns_size);
+    {
+        .name = "insn_count",
 
-    advance_vmpa(&pos, insns_size * 2);
+        .size = MDS_16_BITS,
+        .repeat = 1,
 
-    /* padding */
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Number of 16-bit code units covered by this entry"))
+
+    },
 
-    if (insns_size % 2 != 0)
     {
-        instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+        .name = "handler_off",
+
+        .size = MDS_16_BITS,
+        .repeat = 1,
+
+        PLAIN_COMMENT(__("Offset to the encoded_catch_handler for this entry"))
+
+    }
+
+};
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+static fmt_field_def _dex_encoded_catch_handler_list[] = {
+
+    {
+        .name = "size",
 
-        asprintf(&text, _("Pading"));
+        .get_value = (get_fdef_value_cb)get_encoded_catch_handler_list_size_value,
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        .is_uleb128 = true,
 
-        free(text);
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Size of the list, in entries"))
 
     }
 
-    /* tries */
+};
 
-    result = true;
+static fmt_field_def _dex_encoded_catch_handler[] = {
 
-    for (i = 0; i < tries_size && result; i++)
-        result = annotate_dex_try_item(format, &pos);
+    {
+        .name = "size",
 
-    if (tries_size > 0 && result)
-        result = annotate_dex_encoded_catch_handler_list(format, &pos);
+        .get_value = (get_fdef_value_cb)get_encoded_catch_handler_size_value,
 
-    /* Nettoyage final */
+        .is_leb128 = true,
 
-    g_object_unref(G_OBJECT(content));
+        DISPLAY_RULES(IOD_DEC),
 
-    return result;
+        PLAIN_COMMENT(__("Number of static fields defined in this item"))
 
-}
+    }
 
+};
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : format = description de l'exécutable à compléter.            *
-*                pos    = tête de lecture pour les symboles.                  *
-*                                                                             *
-*  Description : Commente les définitions d'une protection contre exceptions. *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+static fmt_field_def _dex_encoded_catch_handler_all[] = {
 
-static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
-{
-    bool result;                            /* Bilan à retourner           */
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    SourceEndian endian;                    /* Boutisme utilisé            */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
+    {
+        .name = "catch_all_addr",
 
-    result = true;
+        .is_uleb128 = true,
 
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
+        PLAIN_COMMENT(__("Bytecode address of the catch-all handler"))
 
-    endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+    }
 
-    /* start_addr */
+};
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian);
+static fmt_field_def _dex_encoded_type_addr_pair[] = {
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    {
+        .name = "type_idx",
 
-    asprintf(&text, _("Start address of the block of code covered by this entry"));
+        .is_uleb128 = true,
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+        DISPLAY_RULES(IOD_DEC),
 
-    free(text);
+        PLAIN_COMMENT(__("Index for the type of the exception to catch"))
 
-    g_binary_symbol_define_as_block_start(symbol, true);
+    },
 
-    /* insn_count */
+    {
+        .name = "addr",
 
-    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, endian);
+        .is_uleb128 = true,
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        DISPLAY_RULES(IOD_DEC),
 
-    asprintf(&text, _("Number of 16-bit code units covered by this entry"));
+        PLAIN_COMMENT(__("Bytecode address of the associated exception handler"))
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    }
 
-    free(text);
+};
 
-    /* handler_off */
 
-    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, endian);
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+/* Commente les définitions d'une protection contre exceptions. */
+static bool annotate_dex_try_item(const GDexFormat *, vmpa2t *);
 
-    asprintf(&text, _("Offset to the encoded_catch_handler for this entry"));
+/*Commente les définitions des listes de gestion d'exceptions. */
+static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *, vmpa2t *);
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+/* Commente les définitions d'une prise en compte d'exceptions. */
+static bool annotate_dex_encoded_catch_handler(const GDexFormat *, vmpa2t *);
 
-    free(text);
+/* Commente les définitions des gestions d'exceptions par type. */
+static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *, vmpa2t *);
 
-    /* Nettoyage final */
 
-    g_object_unref(G_OBJECT(content));
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : def     = définition à l'origine de l'appel.                 *
+*                content = contenu binaire à venir lire.                      *
+*                pos     = position de la tête de lecture.                    *
+*                endian  = ordre des bits dans la source.                     *
+*                data    = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Récupère le nombre de couvertures pour exceptions.           *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool get_code_tries_size_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, code_item_data *data)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = g_binary_content_read_u16(content, pos, endian, &data->tries_size);
 
     return result;
 
@@ -280,10 +297,13 @@ static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : format = description de l'exécutable à compléter.            *
-*                pos    = tête de lecture physique des symboles.              *
+*  Paramètres  : def     = définition à l'origine de l'appel.                 *
+*                content = contenu binaire à venir lire.                      *
+*                pos     = position de la tête de lecture.                    *
+*                endian  = ordre des bits dans la source.                     *
+*                data    = lieu d'enregistrement de la lecture. [OUT]         *
 *                                                                             *
-*  Description : Commente les définitions des listes de gestion d'exceptions. *
+*  Description : Récupère le nombre de blocs d'instructions.                  *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -291,46 +311,65 @@ static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
 *                                                                             *
 ******************************************************************************/
 
-static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vmpa2t *pos)
+static bool get_code_insns_size_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, code_item_data *data)
 {
     bool result;                            /* Bilan à retourner           */
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-    uleb128_t size;                         /* Nombre d'entrées            */
-    uleb128_t i;                            /* Boucle de parcours          */
 
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
+    result = g_binary_content_read_u32(content, pos, endian, &data->insns_size);
 
-    /* static_fields_size */
-
-    instr = g_raw_instruction_new_uleb128(content, pos);
+    return result;
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+}
 
-    asprintf(&text, _("Size of the list, in entries"));
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : def     = définition à l'origine de l'appel.                 *
+*                content = contenu binaire à venir lire.                      *
+*                pos     = position de la tête de lecture.                    *
+*                endian  = ordre des bits dans la source.                     *
+*                size    = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Récupère le nombre d'éléments d'une liste de couvertures.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    free(text);
+static bool get_encoded_catch_handler_list_size_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, uleb128_t *size)
+{
+    bool result;                            /* Bilan à retourner           */
 
-    g_binary_symbol_define_as_block_start(symbol, true);
+    result = g_binary_content_read_uleb128(content, pos, size);
 
-    /* instance_fields_size */
+    return result;
 
-    g_imm_operand_as_uleb128(G_IMM_OPERAND(operand), &size);
+}
 
-    result = true;
 
-    for (i = 0; i < size && result; i++)
-        result = annotate_dex_encoded_catch_handler(format, pos);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : def     = définition à l'origine de l'appel.                 *
+*                content = contenu binaire à venir lire.                      *
+*                pos     = position de la tête de lecture.                    *
+*                endian  = ordre des bits dans la source.                     *
+*                size    = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Récupère le nombre d'exécptions gérées dans une couverture.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    /* Nettoyage final */
+static bool get_encoded_catch_handler_size_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, leb128_t *size)
+{
+    bool result;                            /* Bilan à retourner           */
 
-    g_object_unref(G_OBJECT(content));
+    result = g_binary_content_read_leb128(content, pos, size);
 
     return result;
 
@@ -340,9 +379,8 @@ static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vm
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format = description de l'exécutable à compléter.            *
-*                pos    = tête de lecture physique des symboles.              *
 *                                                                             *
-*  Description : Commente les définitions d'une prise en compte d'exceptions. *
+*  Description : Commente les définitions d'un corps de méthode.              *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -350,68 +388,95 @@ static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vm
 *                                                                             *
 ******************************************************************************/
 
-static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t *pos)
+bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
 {
     bool result;                            /* Bilan à retourner           */
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-    leb128_t size;                          /* Nombre de gestionnaires     */
-    bool has_catch_all;                     /* Gestion par défaut ?        */
-    uleb128_t i;                            /* Boucle de parcours          */
+    vmpa2t pos;                             /* Tête de lecture des symboles*/
+    code_item_data data;                    /* Valeurs brutes lues         */
+    uint16_t i;                             /* Boucle de parcours          */
 
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos);
 
-    /* size */
+    if (!result)
+        goto adci_exit;
 
-    instr = g_raw_instruction_new_sleb128(content, pos);
+    result = parse_field_definitions(PARSING_DEFS(_dex_code_item), G_BIN_FORMAT(format), &pos, &data);
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    if (!result)
+        goto adci_exit;
 
-    asprintf(&text, _("Number of static fields defined in this item"));
+    /* insns */
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    advance_vmpa(&pos, data.insns_size * 2);
 
-    free(text);
+    /* padding */
 
-    g_binary_symbol_define_as_block_start(symbol, true);
+    if (data.insns_size % 2 != 0)
+        result = parse_field_definitions(PARSING_DEFS(_dex_code_item_padding), G_BIN_FORMAT(format), &pos, NULL);
 
-    g_imm_operand_as_leb128(G_IMM_OPERAND(operand), &size);
+    /* tries */
 
-    has_catch_all = (size <= 0);
+    for (i = 0; i < data.tries_size && result; i++)
+        result = annotate_dex_try_item(format, &pos);
 
-    if (size < 0)
-        size *= -1;
+    if (data.tries_size > 0 && result)
+        result = annotate_dex_encoded_catch_handler_list(format, &pos);
 
-    /* handlers */
+ adci_exit:
 
-    result = true;
+    return result;
 
-    for (i = 0; i < size && result; i++)
-        result = annotate_dex_encoded_type_addr_pair(format, pos);
+}
 
-    /* catch_all_addr */
 
-    if (has_catch_all)
-    {
-        instr = g_raw_instruction_new_uleb128(content, pos);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = description de l'exécutable à compléter.            *
+*                pos    = tête de lecture pour les symboles.                  *
+*                                                                             *
+*  Description : Commente les définitions d'une protection contre exceptions. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
+{
+    bool result;                            /* Bilan à retourner           */
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    result = parse_field_definitions(PARSING_DEFS(_dex_try_item), G_BIN_FORMAT(format), pos, NULL);
 
-        asprintf(&text, _("Bytecode address of the catch-all handler"));
+    return result;
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+}
 
-        free(text);
 
-    }
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = description de l'exécutable à compléter.            *
+*                pos    = tête de lecture physique des symboles.              *
+*                                                                             *
+*  Description : Commente les définitions des listes de gestion d'exceptions. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    /* Nettoyage final */
+static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vmpa2t *pos)
+{
+    bool result;                            /* Bilan à retourner           */
+    uleb128_t size;                         /* Nombre d'entrées            */
+    uleb128_t i;                            /* Boucle de parcours          */
 
-    g_object_unref(G_OBJECT(content));
+    result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler_list),
+                                     G_BIN_FORMAT(format), pos, &size);
+
+    for (i = 0; i < size && result; i++)
+        result = annotate_dex_encoded_catch_handler(format, pos);
 
     return result;
 
@@ -421,9 +486,9 @@ static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format = description de l'exécutable à compléter.            *
-*                pos    = tête de lecture des symboles.                       *
+*                pos    = tête de lecture physique des symboles.              *
 *                                                                             *
-*  Description : Commente les définitions des gestions d'exceptions par type. *
+*  Description : Commente les définitions d'une prise en compte d'exceptions. *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -431,45 +496,60 @@ static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t
 *                                                                             *
 ******************************************************************************/
 
-static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *format, vmpa2t *pos)
+static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t *pos)
 {
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
+    bool result;                            /* Bilan à retourner           */
+    leb128_t size;                          /* Nombre de gestionnaires     */
+    bool has_catch_all;                     /* Gestion par défaut ?        */
+    uleb128_t i;                            /* Boucle de parcours          */
 
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
+    result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler), G_BIN_FORMAT(format), pos, &size);
 
-    /* type_idx */
+    if (!result)
+        goto adech_exit;
 
-    instr = g_raw_instruction_new_uleb128(content, pos);
+    has_catch_all = (size <= 0);
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    if (size < 0)
+        size *= -1;
 
-    asprintf(&text, _("Index for the type of the exception to catch"));
+    /* handlers */
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    for (i = 0; i < size && result; i++)
+        result = annotate_dex_encoded_type_addr_pair(format, pos);
 
-    free(text);
+    /* catch_all_addr */
 
-    /* addr */
+    if (result && has_catch_all)
+        result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler_all),
+                                         G_BIN_FORMAT(format), pos, &size);
 
-    instr = g_raw_instruction_new_uleb128(content, pos);
+ adech_exit:
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    return result;
 
-    asprintf(&text, _("Bytecode address of the associated exception handler"));
+}
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
 
-    free(text);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = description de l'exécutable à compléter.            *
+*                pos    = tête de lecture des symboles.                       *
+*                                                                             *
+*  Description : Commente les définitions des gestions d'exceptions par type. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    /* Nettoyage final */
+static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *format, vmpa2t *pos)
+{
+    bool result;                            /* Bilan à retourner           */
 
-    g_object_unref(G_OBJECT(content));
+    result = parse_field_definitions(PARSING_DEFS(_dex_encoded_type_addr_pair), G_BIN_FORMAT(format), pos, NULL);
 
-    return true;
+    return result;
 
 }
diff --git a/plugins/readdex/header.c b/plugins/readdex/header.c
index f3928ca..d0d0cd7 100644
--- a/plugins/readdex/header.c
+++ b/plugins/readdex/header.c
@@ -25,241 +25,294 @@
 
 
 #include <i18n.h>
-#include <arch/raw.h>
-#include <format/symbol.h>
 #include <format/dex/dex_def.h>
+#include <plugins/fmtp/parser.h>
 
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : format = description de l'exécutable à compléter.            *
-*                                                                             *
-*  Description : Charge tous les symboles de l'en-tête DEX.                   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+/* Définition des champs */
 
-bool annotate_dex_header(GDexFormat *format)
-{
-    GBinContent *content;                   /* Contenu binaire à lire      */
-    SourceEndian endian;                    /* Boutisme utilisé            */
-    vmpa2t pos;                             /* Tête de lecture des symboles*/
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
+static fmt_field_def _dex_header[] = {
+
+    {
+        .name = "magic",
+
+        .size = MDS_8_BITS,
+        .repeat = DEX_FILE_MAGIC_LEN ,
+
+        DISPLAY_RULES(IOD_CHAR, IOD_CHAR, IOD_CHAR, IOD_HEX, IOD_CHAR, IOD_CHAR, IOD_CHAR, IOD_HEX),
+
+        PLAIN_COMMENT(__("DEX magic number"))
+
+    },
 
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
+    {
+        .name = "checksum",
 
-    endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos))
-        return false;
+        PLAIN_COMMENT(__("adler32 checksum used to detect file corruption"))
 
-    /* magic */
+    },
 
-    instr = g_raw_instruction_new_array(content, MDS_8_BITS, DEX_FILE_MAGIC_LEN, &pos, endian);
+    {
+        .name = "signature",
 
-    g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true);
+        .size = MDS_32_BITS,
+        .repeat = 5,
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_CHAR);
-    SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR);
-    SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR);
+        PLAIN_COMMENT(__("SHA-1 signature used to uniquely identify files"))
 
-    SET_IMM_DISPLAY(instr, operand, 3, IOD_HEX);
+    },
 
-    SET_IMM_DISPLAY(instr, operand, 4, IOD_CHAR);
-    SET_IMM_DISPLAY(instr, operand, 5, IOD_CHAR);
-    SET_IMM_DISPLAY(instr, operand, 6, IOD_CHAR);
+    {
+        .name = "file_size",
 
-    SET_IMM_DISPLAY(instr, operand, 7, IOD_HEX);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("DEX magic number"));
+        DISPLAY_RULES(IOD_DEC),
 
-    g_binary_symbol_define_as_block_start(symbol, true);
+        PLAIN_COMMENT(__("Size of the entire file in bytes"))
 
-    /* checksum */
+    },
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    {
+        .name = "header_size",
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("adler32 checksum used to detect file corruption"));
+        DISPLAY_RULES(IOD_DEC),
 
-    /* signature */
+        PLAIN_COMMENT(__("Size of the header in bytes"))
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 5, &pos, endian);
+    },
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    {
+        .name = "endian_tag",
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("SHA-1 signature used to uniquely identify files"));
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    /* file_size */
+        PLAIN_COMMENT(__("Endianness tag ; 0x12345678 for little-endian"))
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    },
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    {
+        .name = "link_size",
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Size of the entire file in bytes"));
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    /* header_size */
+        DISPLAY_RULES(IOD_DEC),
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        PLAIN_COMMENT(__("Size of the link section"))
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    },
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Size of the header in bytes"));
+    {
+        .name = "link_off",
 
-    /* endian_tag */
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        PLAIN_COMMENT(__("Offset to the link section"))
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    },
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Endianness tag ; 0x12345678 for little-endian"));
+    {
+        .name = "map_off",
 
-    /* link_size */
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        PLAIN_COMMENT(__("Offset to the map item"))
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    },
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Size of the link section"));
+    {
+        .name = "string_ids_size",
 
-    /* link_off */
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        DISPLAY_RULES(IOD_DEC),
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+        PLAIN_COMMENT(__("Count of strings in the string identifiers list"))
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the link section"));
+    },
 
-    /* map_off */
+    {
+        .name = "string_ids_off",
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+        PLAIN_COMMENT(__("Offset to the string identifiers list"))
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the map item"));
+    },
 
-    /* string_ids_size */
+    {
+        .name = "type_ids_size",
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        DISPLAY_RULES(IOD_DEC),
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of strings in the string identifiers list"));
+        PLAIN_COMMENT(__("Count of elements in the type identifiers list"))
 
-    /* string_ids_off */
+    },
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    {
+        .name = "type_ids_off",
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the string identifiers list"));
+        PLAIN_COMMENT(__("Offset to the type identifiers list"))
 
-    /* type_ids_size */
+    },
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    {
+        .name = "proto_ids_size",
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the type identifiers list"));
+        DISPLAY_RULES(IOD_DEC),
 
-    /* type_ids_off */
+        PLAIN_COMMENT(__("Count of elements in the prototype identifiers list"))
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    },
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    {
+        .name = "proto_ids_off",
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the type identifiers list"));
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    /* proto_ids_size */
+        PLAIN_COMMENT(__("Offset to the prototype identifiers list"))
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    },
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    {
+        .name = "field_ids_size",
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the prototype identifiers list"));
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    /* proto_ids_off */
+        DISPLAY_RULES(IOD_DEC),
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        PLAIN_COMMENT(__("Count of elements in the field identifiers list"))
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    },
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the prototype identifiers list"));
+    {
+        .name = "field_ids_off",
 
-    /* field_ids_size */
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        PLAIN_COMMENT(__("Offset to the field identifiers list"))
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    },
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the field identifiers list"));
+    {
+        .name = "method_ids_size",
 
-    /* field_ids_off */
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        DISPLAY_RULES(IOD_DEC),
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+        PLAIN_COMMENT(__("Count of elements in the method identifiers list"))
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the field identifiers list"));
+    },
 
-    /* method_ids_size */
+    {
+        .name = "method_ids_off",
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        DISPLAY_RULES(IOD_DEC),
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the method identifiers list"));
+        PLAIN_COMMENT(__("Offset to the method identifiers list"))
 
-    /* method_ids_off */
+    },
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    {
+        .name = "class_defs_size",
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the method identifiers list"));
+        DISPLAY_RULES(IOD_DEC),
 
-    /* class_defs_size */
+        PLAIN_COMMENT(__("Count of elements in the class definitions list"))
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    },
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    {
+        .name = "class_defs_off",
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the class definitions list"));
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    /* class_defs_off */
+        PLAIN_COMMENT(__("Offset to the class definitions list"))
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+    },
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    {
+        .name = "data_size",
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the class definitions list"));
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    /* data_size */
+        DISPLAY_RULES(IOD_DEC),
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        PLAIN_COMMENT(__("Size of data section in bytes"))
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    },
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Size of data section in bytes"));
+    {
+        .name = "data_off",
 
-    /* data_off */
+        .size = MDS_32_BITS,
+        .repeat = 1,
 
-    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        PLAIN_COMMENT(__("Offset to the start of the data section"))
 
-    SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+    }
+
+};
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = description de l'exécutable à compléter.            *
+*                                                                             *
+*  Description : Charge tous les symboles de l'en-tête DEX.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool annotate_dex_header(GDexFormat *format)
+{
+    bool result;                            /* Bilan à retourner           */
+    vmpa2t pos;                             /* Tête de lecture des symboles*/
 
-    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the start of the data section"));
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos);
 
-    g_object_unref(G_OBJECT(content));
+    if (result)
+        result = parse_field_definitions(PARSING_DEFS(_dex_header), G_BIN_FORMAT(format), &pos, NULL);
 
-    return true;
+    return result;
 
 }
diff --git a/plugins/readdex/ids.c b/plugins/readdex/ids.c
index cb24e7d..2586eaf 100644
--- a/plugins/readdex/ids.c
+++ b/plugins/readdex/ids.c
@@ -33,9 +33,197 @@
 #include <arch/raw.h>
 #include <format/symbol.h>
 #include <format/dex/dex_def.h>
+#include <plugins/fmtp/parser.h>
 
 
 
+/* Définition des champs */
+
+
+/* Récupère la taille d'une chaîne de caractères. */
+static bool get_dex_string_length_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, uleb128_t *);
+
+
+static fmt_field_def _dex_string_ids_length[] = {
+
+    {
+        .name = "length",
+
+        .get_value = (get_fdef_value_cb)get_dex_string_length_value,
+
+        .is_uleb128 = true,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("String length"))
+
+    }
+
+};
+
+static fmt_field_def _dex_type_ids[] = {
+
+    {
+        .name = "descriptor_idx",
+
+        .size = MDS_32_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the descriptor string of this type"))
+
+    }
+
+};
+
+static fmt_field_def _dex_proto_ids[] = {
+
+    {
+        .name = "shorty_idx",
+
+        .size = MDS_32_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the short-form descriptor string of this prototype"))
+
+    },
+
+    {
+        .name = "return_type_idx",
+
+        .size = MDS_32_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the return type of this prototype"))
+
+    },
+
+    {
+        .name = "parameters_off",
+
+        .size = MDS_32_BITS,
+        .repeat = 1,
+
+        PLAIN_COMMENT(__("Offset to the list of parameter types for this prototype"))
+
+    }
+
+};
+
+static fmt_field_def _dex_field_ids[] = {
+
+    {
+        .name = "class_idx",
+
+        .size = MDS_16_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the definer of this field"))
+
+    },
+
+    {
+        .name = "type_idx",
+
+        .size = MDS_16_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the type of this field"))
+
+    },
+
+    {
+        .name = "name_idx",
+
+        .size = MDS_32_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the name of this field"))
+
+    }
+
+};
+
+static fmt_field_def _dex_method_ids[] = {
+
+    {
+        .name = "class_idx",
+
+        .size = MDS_16_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the definer of this field"))
+
+    },
+
+    {
+        .name = "proto_idx",
+
+        .size = MDS_16_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the prototype of this method"))
+
+    },
+
+    {
+        .name = "name_idx",
+
+        .size = MDS_32_BITS,
+        .repeat = 1,
+
+        DISPLAY_RULES(IOD_DEC),
+
+        PLAIN_COMMENT(__("Index for the name of this method"))
+
+    }
+
+};
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : def     = définition à l'origine de l'appel.                 *
+*                content = contenu binaire à venir lire.                      *
+*                pos     = position de la tête de lecture.                    *
+*                endian  = ordre des bits dans la source.                     *
+*                data    = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Récupère la taille d'une chaîne de caractères.               *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool get_dex_string_length_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, uleb128_t *length)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = g_binary_content_read_uleb128(content, pos, length);
+
+    return result;
+
+}
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format = description de l'exécutable à compléter.            *
@@ -51,78 +239,89 @@
 
 bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
 {
+    bool result;                            /* Bilan à retourner           */
     GBinContent *content;                   /* Contenu binaire à lire      */
     const dex_header *header;               /* En-tête principale          */
     SourceEndian endian;                    /* Boutisme utilisé            */
     vmpa2t pos;                             /* Tête de lecture des symboles*/
     activity_id_t msg;                      /* Message de progression      */
+    GBinFormat *bformat;                    /* Autre version du format     */
     uint32_t i;                             /* Boucle de parcours          */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
+    fmt_field_def field;                    /* Définition de position      */
+    comment_part parts[2];                  /* Mise en place des parties   */
     phys_t loc;                             /* Localisation physique       */
     vmpa2t item_pos;                        /* Position d'un élément       */
-    vmpa2t start;                           /* Sauvagarde d'une position   */
     uleb128_t length;                       /* Taille de la chaîne en cours*/
-    MemoryDataSize leb_size;                /* Taille de la taille         */
+    GArchInstruction *instr;                /* Instruction décodée         */
+    GBinSymbol *symbol;                     /* Symbole à intégrer          */
 
     content = g_binary_format_get_content(G_BIN_FORMAT(format));
 
     header = g_dex_format_get_header(format);
     endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
 
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->string_ids_off, &pos))
-        return false;
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->string_ids_off, &pos);
+
+    if (!result)
+        goto adsi_exit;
 
     msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex strings..."),
                                         header->string_ids_size);
 
-    for (i = 0; i < header->string_ids_size; i++)
+    bformat = G_BIN_FORMAT(format);
+
+    bool get_string_offset_value(const fmt_field_def *d, GBinContent *c, vmpa2t *p, SourceEndian e, phys_t *val)
     {
-        /* Saut vers la définition */
+        bool status;                        /* Bilan à retourner           */
+        uint32_t offset;                    /* Position trouvée            */
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+        status = g_binary_content_read_u32(c, p, e, &offset);
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+        if (status)
+            *val = offset;
 
-        asprintf(&text, _("Offset for string item #%u/%u"), i, header->string_ids_size - 1);
+        return status;
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+    }
 
-        free(text);
+    for (i = 0; i < header->string_ids_size && result; i++)
+    {
+        /* Saut vers la définition */
 
-        if (i == 0)
-            g_binary_symbol_define_as_block_start(symbol, true);
+        memset(&field, 0, sizeof(field));
 
-        /* Description de la chaîne : taille */
+        field.name = "p_flags";
 
-        operand = g_arch_instruction_get_operand(instr, 0);
+        field.get_value = (get_fdef_value_cb)get_string_offset_value;
 
-        if (!g_imm_operand_to_phys_t(G_IMM_OPERAND(operand), &loc))
-            continue;
+        field.size = MDS_32_BITS;
+        field.repeat = 1;
 
-        if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), loc, &item_pos))
-            continue;
+        parts[0].is_static = true;
+        parts[0].static_text = __("Offset for string item #");
 
-        copy_vmpa(&start, &item_pos);
+        parts[1].is_static = false;
+        asprintf(&parts[1].dynamic_text, "%u/%u", i, header->string_ids_size - 1);
 
-        if (!g_binary_content_read_uleb128(content, &item_pos, &length))
-            continue;
+        field.ctype = FCT_MULTI;
+        field.comment.parts = parts;
+        field.comment.pcount = ARRAY_SIZE(parts);
+
+        result = parse_field_definitions(&field, 1, bformat, &pos, &loc);
 
-        leb_size = MDS_FROM_BYTES(compute_vmpa_diff(&start, &item_pos));
-        assert(leb_size != MDS_UNDEFINED);
+        if (!result)
+            break;
 
-        instr = g_raw_instruction_new_from_value(&start, leb_size, (uint64_t)length);
+        /* Description de la chaîne : taille */
 
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+        if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), loc, &item_pos))
+            continue;
 
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("String length"));
+        result = parse_field_definitions(PARSING_DEFS(_dex_string_ids_length), bformat, &item_pos, &length);
 
         /* Description de la chaîne : contenu */
 
-        if (length > 0)
+        if (result && length > 0)
         {
             instr = g_raw_instruction_new_array(content, MDS_8_BITS, length, &item_pos, endian);
 
@@ -140,7 +339,9 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
 
     g_object_unref(G_OBJECT(content));
 
-    return true;
+ adsi_exit:
+
+    return result;
 
 }
 
@@ -160,43 +361,28 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
 
 bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
 {
-    GBinContent *content;                   /* Contenu binaire à lire      */
+    bool result;                            /* Bilan à retourner           */
     const dex_header *header;               /* En-tête principale          */
-    SourceEndian endian;                    /* Boutisme utilisé            */
     vmpa2t pos;                             /* Tête de lecture des symboles*/
     activity_id_t msg;                      /* Message de progression      */
+    GBinFormat *bformat;                    /* Autre version du format     */
     uint32_t i;                             /* Boucle de parcours          */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
 
     header = g_dex_format_get_header(format);
-    endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
 
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->type_ids_off, &pos))
-        return false;
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->type_ids_off, &pos);
+
+    if (!result)
+        goto adti_exit;
 
     msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex types..."),
                                         header->type_ids_size);
 
-    for (i = 0; i < header->type_ids_size; i++)
-    {
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+    bformat = G_BIN_FORMAT(format);
 
-        asprintf(&text, _("Index for the descriptor string of this type"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
-
-        if (i == 0)
-            g_binary_symbol_define_as_block_start(symbol, true);
+    for (i = 0; i < header->type_ids_size && result; i++)
+    {
+        result = parse_field_definitions(PARSING_DEFS(_dex_type_ids), bformat, &pos, NULL);
 
         gtk_status_stack_update_activity_value(status, msg, 1);
 
@@ -204,9 +390,9 @@ bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
 
     gtk_status_stack_remove_activity(status, msg);
 
-    g_object_unref(G_OBJECT(content));
+ adti_exit:
 
-    return true;
+    return result;
 
 }
 
@@ -226,69 +412,28 @@ bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
 
 bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
 {
-    GBinContent *content;                   /* Contenu binaire à lire      */
+    bool result;                            /* Bilan à retourner           */
     const dex_header *header;               /* En-tête principale          */
-    SourceEndian endian;                    /* Boutisme utilisé            */
     vmpa2t pos;                             /* Tête de lecture des symboles*/
     activity_id_t msg;                      /* Message de progression      */
+    GBinFormat *bformat;                    /* Autre version du format     */
     uint32_t i;                             /* Boucle de parcours          */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
 
     header = g_dex_format_get_header(format);
-    endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
 
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->proto_ids_off, &pos))
-        return false;
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->proto_ids_off, &pos);
+
+    if (!result)
+        goto adpi_exit;
 
     msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex prototypes..."),
                                         header->proto_ids_size);
 
-    for (i = 0; i < header->proto_ids_size; i++)
-    {
-        /* shorty_idx */
-
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Index for the short-form descriptor string of this prototype"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
-
-        if (i == 0)
-            g_binary_symbol_define_as_block_start(symbol, true);
-
-        /* return_type_idx */
+    bformat = G_BIN_FORMAT(format);
 
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Index for the return type of this prototype"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
-
-        /* parameters_off */
-
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Offset to the list of parameter types for this prototype"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
+    for (i = 0; i < header->proto_ids_size && result; i++)
+    {
+        result = parse_field_definitions(PARSING_DEFS(_dex_proto_ids), bformat, &pos, NULL);
 
         gtk_status_stack_update_activity_value(status, msg, 1);
 
@@ -296,9 +441,9 @@ bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
 
     gtk_status_stack_remove_activity(status, msg);
 
-    g_object_unref(G_OBJECT(content));
+ adpi_exit:
 
-    return true;
+    return result;
 
 }
 
@@ -318,69 +463,28 @@ bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
 
 bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
 {
-    GBinContent *content;                   /* Contenu binaire à lire      */
+    bool result;                            /* Bilan à retourner           */
     const dex_header *header;               /* En-tête principale          */
-    SourceEndian endian;                    /* Boutisme utilisé            */
     vmpa2t pos;                             /* Tête de lecture des symboles*/
     activity_id_t msg;                      /* Message de progression      */
+    GBinFormat *bformat;                    /* Autre version du format     */
     uint32_t i;                             /* Boucle de parcours          */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
 
     header = g_dex_format_get_header(format);
-    endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
 
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->field_ids_off, &pos))
-        return false;
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->field_ids_off, &pos);
+
+    if (!result)
+        goto adfi_exit;
 
     msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex fields..."),
                                         header->field_ids_size);
 
-    for (i = 0; i < header->field_ids_size; i++)
-    {
-        /* class_idx */
-
-        instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Index for the definer of this field"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
-
-        if (i == 0)
-            g_binary_symbol_define_as_block_start(symbol, true);
-
-        /* type_idx */
+    bformat = G_BIN_FORMAT(format);
 
-        instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Index for the type of this field"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
-
-        /* name_idx */
-
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Index for the name of this field"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
+    for (i = 0; i < header->field_ids_size && result; i++)
+    {
+        result = parse_field_definitions(PARSING_DEFS(_dex_field_ids), bformat, &pos, NULL);
 
         gtk_status_stack_update_activity_value(status, msg, 1);
 
@@ -388,9 +492,9 @@ bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
 
     gtk_status_stack_remove_activity(status, msg);
 
-    g_object_unref(G_OBJECT(content));
+ adfi_exit:
 
-    return true;
+    return result;
 
 }
 
@@ -410,69 +514,28 @@ bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
 
 bool annotate_dex_method_ids(const GDexFormat *format, GtkStatusStack *status)
 {
-    GBinContent *content;                   /* Contenu binaire à lire      */
+    bool result;                            /* Bilan à retourner           */
     const dex_header *header;               /* En-tête principale          */
-    SourceEndian endian;                    /* Boutisme utilisé            */
     vmpa2t pos;                             /* Tête de lecture des symboles*/
-    uint32_t i;                             /* Boucle de parcours          */
     activity_id_t msg;                      /* Message de progression      */
-    GArchInstruction *instr;                /* Instruction décodée         */
-    GArchOperand *operand;                  /* Opérande à venir modifier   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GBinSymbol *symbol;                     /* Symbole à intégrer          */
-    char *text;                             /* Texte constant à insérer    */
-
-    content = g_binary_format_get_content(G_BIN_FORMAT(format));
+    GBinFormat *bformat;                    /* Autre version du format     */
+    uint32_t i;                             /* Boucle de parcours          */
 
     header = g_dex_format_get_header(format);
-    endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
 
-    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->method_ids_off, &pos))
-        return false;
+    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->method_ids_off, &pos);
+
+    if (!result)
+        goto admi_exit;
 
     msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex methods..."),
                                         header->method_ids_size);
 
-    for (i = 0; i < header->method_ids_size; i++)
-    {
-        /* class_idx */
-
-        instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Index for the definer of this field"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
+    bformat = G_BIN_FORMAT(format);
 
-        if (i == 0)
-            g_binary_symbol_define_as_block_start(symbol, true);
-
-        /* proto_idx */
-
-        instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Index for the prototype of this method"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
-
-        /* name_idx */
-
-        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
-        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
-        asprintf(&text, _("Index for the name of this method"));
-
-        ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
-        free(text);
+    for (i = 0; i < header->method_ids_size && result; i++)
+    {
+        result = parse_field_definitions(PARSING_DEFS(_dex_method_ids), bformat, &pos, NULL);
 
         gtk_status_stack_update_activity_value(status, msg, 1);
 
@@ -480,8 +543,8 @@ bool annotate_dex_method_ids(const GDexFormat *format, GtkStatusStack *status)
 
     gtk_status_stack_remove_activity(status, msg);
 
-    g_object_unref(G_OBJECT(content));
+ admi_exit:
 
-    return true;
+    return result;
 
 }
diff --git a/plugins/readelf/header.c b/plugins/readelf/header.c
index 21884a3..4b3cdbc 100644
--- a/plugins/readelf/header.c
+++ b/plugins/readelf/header.c
@@ -471,17 +471,15 @@ bool annotate_elf_header(GBinFormat *format)
     result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos);
 
     if (result)
-        result = parse_field_definitions(_elf_header_base, ARRAY_SIZE(_elf_header_base), format, &pos);
+        result = parse_field_definitions(PARSING_DEFS(_elf_header_base), format, &pos, NULL);
 
     if (result)
     {
         if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS32)
-            result = parse_field_definitions(_elf_header_offset_32, ARRAY_SIZE(_elf_header_offset_32),
-                                             format, &pos);
+            result = parse_field_definitions(PARSING_DEFS(_elf_header_offset_32), format, &pos, NULL);
 
         else if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS64)
-            result = parse_field_definitions(_elf_header_offset_64, ARRAY_SIZE(_elf_header_offset_64),
-                                             format, &pos);
+            result = parse_field_definitions(PARSING_DEFS(_elf_header_offset_64), format, &pos, NULL);
 
         else
             result = false;
@@ -489,7 +487,7 @@ bool annotate_elf_header(GBinFormat *format)
     }
 
     if (result)
-        result = parse_field_definitions(_elf_header_ending, ARRAY_SIZE(_elf_header_ending), format, &pos);
+        result = parse_field_definitions(PARSING_DEFS(_elf_header_ending), format, &pos, NULL);
 
     return result;
 
diff --git a/plugins/readelf/program.c b/plugins/readelf/program.c
index ba47639..b1e253a 100644
--- a/plugins/readelf/program.c
+++ b/plugins/readelf/program.c
@@ -287,28 +287,28 @@ static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian,
 
     bformat = G_BIN_FORMAT(format);
 
-    result = parse_field_definitions(_elf_phdr_base, ARRAY_SIZE(_elf_phdr_base), bformat, pos);
+    result = parse_field_definitions(PARSING_DEFS(_elf_phdr_base), bformat, pos, NULL);
 
     if (format->is_32b)
     {
         if (result)
-            result = parse_field_definitions(_elf_phdr_32b_a, ARRAY_SIZE(_elf_phdr_32b_a), bformat, pos);
+            result = parse_field_definitions(PARSING_DEFS(_elf_phdr_32b_a), bformat, pos, NULL);
 
         if (result)
-            result = parse_field_definitions(&flags_field, 1, bformat, pos);
+            result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
 
         if (result)
-            result = parse_field_definitions(_elf_phdr_32b_b, ARRAY_SIZE(_elf_phdr_32b_b), bformat, pos);
+            result = parse_field_definitions(PARSING_DEFS(_elf_phdr_32b_b), bformat, pos, NULL);
 
     }
     else
     {
 
         if (result)
-            result = parse_field_definitions(&flags_field, 1, bformat, pos);
+            result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
 
         if (result)
-            result = parse_field_definitions(_elf_phdr_64b, ARRAY_SIZE(_elf_phdr_64b), bformat, pos);
+            result = parse_field_definitions(PARSING_DEFS(_elf_phdr_64b), bformat, pos, NULL);
 
     }
 
diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c
index e689aac..6161892 100644
--- a/plugins/readelf/section.c
+++ b/plugins/readelf/section.c
@@ -370,21 +370,21 @@ static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian,
 
     bformat = G_BIN_FORMAT(format);
 
-    result = parse_field_definitions(&name_field, 1, bformat, pos);
+    result = parse_field_definitions(&name_field, 1, bformat, pos, NULL);
 
     if (result)
-        result = parse_field_definitions(_elf_sh_type, ARRAY_SIZE(_elf_sh_type), bformat, pos);
+        result = parse_field_definitions(PARSING_DEFS(_elf_sh_type), bformat, pos, NULL);
 
     if (format->is_32b)
     {
         if (result)
         {
             flags_field.size = MDS_32_BITS;
-            result = parse_field_definitions(&flags_field, 1, bformat, pos);
+            result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
         }
 
         if (result)
-            result = parse_field_definitions(_elf_shdr_32b, ARRAY_SIZE(_elf_shdr_32b), bformat, pos);
+            result = parse_field_definitions(PARSING_DEFS(_elf_shdr_32b), bformat, pos, NULL);
 
     }
     else
@@ -392,11 +392,11 @@ static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian,
         if (result)
         {
             flags_field.size = MDS_64_BITS;
-            result = parse_field_definitions(&flags_field, 1, bformat, pos);
+            result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
         }
 
         if (result)
-            result = parse_field_definitions(_elf_shdr_64b, ARRAY_SIZE(_elf_shdr_64b), bformat, pos);
+            result = parse_field_definitions(PARSING_DEFS(_elf_shdr_64b), bformat, pos, NULL);
 
     }
 
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index b638b8a..e34318f 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -54,6 +54,9 @@ static void g_dex_format_dispose(GDexFormat *);
 /* Procède à la libération totale de la mémoire. */
 static void g_dex_format_finalize(GDexFormat *);
 
+/* Informe quant au boutisme utilisé. */
+static SourceEndian g_dex_format_get_endianness(const GDexFormat *);
+
 /* Indique le type d'architecture visée par le format. */
 static const char *g_dex_format_get_target_machine(const GDexFormat *);
 
@@ -148,6 +151,7 @@ G_DEFINE_TYPE(GDexFormat, g_dex_format, G_TYPE_EXE_FORMAT);
 static void g_dex_format_class_init(GDexFormatClass *klass)
 {
     GObjectClass *object;                   /* Autre version de la classe  */
+    GBinFormatClass *fmt;                   /* Version en format basique   */
     GExeFormatClass *exe;                   /* Version en exécutable       */
 
     object = G_OBJECT_CLASS(klass);
@@ -155,6 +159,10 @@ static void g_dex_format_class_init(GDexFormatClass *klass)
     object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_format_dispose;
     object->finalize = (GObjectFinalizeFunc)g_dex_format_finalize;
 
+    fmt = G_BIN_FORMAT_CLASS(klass);
+
+    fmt->get_endian = (format_get_endian_fc)g_dex_format_get_endianness;
+
     exe = G_EXE_FORMAT_CLASS(klass);
 
     exe->get_machine = (get_target_machine_fc)g_dex_format_get_target_machine;
@@ -297,6 +305,25 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus
 *                                                                             *
 *  Paramètres  : format = informations chargées à consulter.                  *
 *                                                                             *
+*  Description : Informe quant au boutisme utilisé.                           *
+*                                                                             *
+*  Retour      : Indicateur de boutisme.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static SourceEndian g_dex_format_get_endianness(const GDexFormat *format)
+{
+    return SRE_LITTLE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = informations chargées à consulter.                  *
+*                                                                             *
 *  Description : Indique le type d'architecture visée par le format.          *
 *                                                                             *
 *  Retour      : Identifiant de l'architecture ciblée par le format.          *
-- 
cgit v0.11.2-87-g4458