From 0e2849345be5018152d60b5aa27eebb2de75e1df Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 24 May 2016 23:45:53 +0200
Subject: Attached priority levels with disassembly starting points.

---
 ChangeLog                    |  25 +++++++++
 src/analysis/disass/area.c   | 122 ++++++++++++++++++++++++++++++-------------
 src/analysis/disass/area.h   |   2 +-
 src/analysis/disass/fetch.c  |  16 +++---
 src/analysis/disass/output.c |  12 +++++
 src/arch/arm/v7/context.c    |   7 +--
 src/arch/arm/v7/fetch.c      |  19 ++++---
 src/arch/context-int.h       |   8 +--
 src/arch/context.c           |  62 ++++++++++++++--------
 src/arch/context.h           |  16 +++++-
 src/arch/dalvik/fetch.c      |   2 +-
 src/format/format.c          |   4 +-
 12 files changed, 211 insertions(+), 84 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 934e299..6895d32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+16-05-24  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/area.c:
+	* src/analysis/disass/area.h:
+	Ensure all starts of code begin with an instruction.
+
+	* src/analysis/disass/fetch.c:
+	Attach priority levels with disassembly starting points.
+
+	* src/analysis/disass/output.c:
+	Count the missing symbols (for debug information only).
+
+	* src/arch/arm/v7/context.c:
+	* src/arch/arm/v7/fetch.c:
+	Update code.
+
+	* src/arch/context-int.h:
+	* src/arch/context.c:
+	* src/arch/context.h:
+	Attach priority levels with disassembly starting points.
+
+	* src/arch/dalvik/fetch.c:
+	* src/format/format.c:
+	Update code.
+
 16-05-23  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/arm/v7/operands/maccess.c:
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 1abb402..b1d4bb1 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -75,6 +75,10 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *, GArchInstructi
 
 
 
+/* Crée une instruction issue d'un désassemblage brut. */
+static GArchInstruction *load_raw_instruction_from_mem_area_v2(mem_area_v2 *, phys_t, vmpa2t *, phys_t *);
+
+
 
 /* Procède au désassemblage d'un contenu binaire non exécutable. */
 static void load_data_from_mem_area_v2(mem_area_v2 *, GProcContext *, const vmpa2t *, GtkStatusStack *, activity_id_t);
@@ -264,6 +268,60 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstr
 
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : area   = aire représentant à contenu à parcourir.            *
+*                offset = point de départ au sein de l'aire en question.      *
+*                pos    = tête de lecture dans l'espace global.               *
+*                size   = taille de l'instruction mise en place. [OUT]        *
+*                                                                             *
+*  Description : Crée une instruction issue d'un désassemblage brut.          *
+*                                                                             *
+*  Retour      : Instruction mise en place ou NULL en cas d'échec.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GArchInstruction *load_raw_instruction_from_mem_area_v2(mem_area_v2 *area, phys_t offset, vmpa2t *pos, phys_t *size)
+{
+    GArchInstruction *result;               /* Instruction à retourner     */
+    GBinContent *content;                   /* Données binaires à lire     */
+    SourceEndian endianness;                /* Boutisme de cette machine   */
+    phys_t sz;                              /* Volume de données traité    */
+    vmpa2t prev;                            /* Boucle de parcours          */
+
+    result = NULL;
+
+    content = area->content;
+    endianness = area->endianness;
+
+    sz = area->packing_size;
+
+    if (get_virt_addr(pos) % sz == 0 && is_range_blank_in_mem_area_v2(area, offset, sz))
+    {
+        *size = sz;
+
+        copy_vmpa(&prev, pos);
+
+        result = g_raw_instruction_new_array(content, MDS_FROM_BYTES(sz), 1, pos, endianness);
+
+        if (result == NULL)
+            copy_vmpa(pos, &prev);
+
+    }
+
+    if (result == NULL)
+    {
+        *size = 1;
+
+        result = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, endianness);
+
+    }
+
+    return result;
+
+}
 
 
 
@@ -280,6 +338,7 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstr
 *                binary = représentation de binaire chargé.                   *
 *                ctx    = contexte offert en soutien à un désassemblage.      *
 *                start  = démarrage de l'exécution au sein de la zone.        *
+*                force  = force la création d'au moins une instruction.       *
 *                status = barre de statut à actualiser.                       *
 *                id     = identifiant du groupe de progression à l'affichage. *
 *                                                                             *
@@ -291,7 +350,7 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstr
 *                                                                             *
 ******************************************************************************/
 
-void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count, GProcContext *ctx, const vmpa2t *start, GtkStatusStack *status, activity_id_t id)
+void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count, GProcContext *ctx, const vmpa2t *start, bool force, GtkStatusStack *status, activity_id_t id)
 {
 
 
@@ -300,9 +359,11 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
     GArchProcessor *proc;                   /* Architecture du binaire     */
     GBinContent *content;                   /* Données binaires à lire     */
 
-    phys_t diff;                            /* Volume de données traité    */
+    phys_t init_diff;                       /* Position initiale de lecture*/
     phys_t alen;                            /* Taille de l'aire utilisée   */
 
+    bool forced_once;                       /* Préfigure une sortie rapide */
+
     phys_t i;                               /* Boucle de parcours          */
 
 
@@ -310,6 +371,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
     vmpa2t prev;                            /* Boucle de parcours          */
 
     GArchInstruction *instr;                /* Instruction décodée         */
+    phys_t diff;                            /* Volume de données traité    */
 
 
 
@@ -326,15 +388,13 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
 
 
 
-
-
     /* Récupération des informations de base */
 
     format = area->format;
     proc = area->proc;
     content = area->content;
 
-    diff = compute_vmpa_diff(get_mrange_addr(&area->range), start);
+    init_diff = compute_vmpa_diff(get_mrange_addr(&area->range), start);
     alen = get_mrange_length(&area->range);
 
     copy_vmpa(&pos, start);
@@ -343,7 +403,9 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
 
     printf("=== processing @ 0x%08x\n", (unsigned int)start->virtual);
 
-    for (i = diff; i < alen; i += diff)
+    forced_once = false;
+
+    for (i = init_diff; i < alen; i += diff)
     {
         /**
          * On réalise un premier test informel (car non atomique) peu coûteux
@@ -362,11 +424,24 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
         copy_vmpa(&prev, &pos);
 
         instr = g_arch_processor_disassemble(proc, ctx, content, &pos, G_EXE_FORMAT(format));
-        if (instr == NULL) break;
 
-        /* Enregistrement des positions et adresses */
+        if (instr != NULL)
+            diff = compute_vmpa_diff(&prev, &pos);
 
-        diff = compute_vmpa_diff(&prev, &pos);
+        else
+        {
+            if (i == init_diff && force)
+            {
+                instr = load_raw_instruction_from_mem_area_v2(area, i, &pos, &diff);
+                forced_once = true;
+            }
+
+            if (instr == NULL)
+                break;
+
+        }
+
+        /* Enregistrement des positions et adresses */
 
         init_mrange(&range, &prev, diff);
 
@@ -409,7 +484,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
         }
 
         /* Rupture du flot d'exécution ? */
-        if (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
+        if (forced_once || g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
             break;
 
     }
@@ -435,8 +510,6 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
 
 static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, const vmpa2t *start, GtkStatusStack *status, activity_id_t id)
 {
-    GBinContent *content;                   /* Données binaires à lire     */
-    SourceEndian endianness;                /* Boutisme de cette machine   */
     phys_t diff;                            /* Volume de données traité    */
     phys_t alen;                            /* Taille de l'aire utilisée   */
     vmpa2t pos;                             /* Boucle de parcours          */
@@ -448,9 +521,6 @@ static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, con
 
     /* Récupération des informations de base */
 
-    content = area->content;
-    endianness = area->endianness;
-
     diff = compute_vmpa_diff(get_mrange_addr(&area->range), start);
     alen = get_mrange_length(&area->range);
 
@@ -471,25 +541,7 @@ static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, con
 
         /* Décodage d'une nouvelle instruction, sur mesure puis minimale */
 
-        if (get_virt_addr(&pos) % area->packing_size == 0
-            && is_range_blank_in_mem_area_v2(area, i, area->packing_size))
-        {
-            diff = area->packing_size;
-
-            instr = g_raw_instruction_new_array(content, MDS_FROM_BYTES(diff), 1, &pos, endianness);
-
-            if (instr == NULL)
-                copy_vmpa(&pos, &prev);
-
-        }
-
-        if (instr == NULL)
-        {
-            diff = 1;
-
-            instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endianness);
-
-        }
+        instr = load_raw_instruction_from_mem_area_v2(area, i, &pos, &diff);
 
         /* On rencontre ici un morceau déjà traité. */
 
@@ -562,7 +614,7 @@ static void fill_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count,
             advance_vmpa(&start, i);
 
             if (area->is_exec && get_virt_addr(&start) % area->packing_size == 0)
-                load_code_from_mem_area_v2(area, list, count, ctx, &start, status, id);
+                load_code_from_mem_area_v2(area, list, count, ctx, &start, false, status, id);
 
             if (is_range_blank_in_mem_area_v2(area, i, 1))
                 load_data_from_mem_area_v2(area, ctx, &start, status, id);
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index 3ffdbc5..abfa509 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -40,7 +40,7 @@ typedef struct _mem_area_v2 mem_area_v2;
 
 
 /* Procède au désassemblage d'un contenu binaire exécutable. */
-void load_code_from_mem_area_v2(mem_area_v2 *, mem_area_v2 *, size_t, GProcContext *, const vmpa2t *, GtkStatusStack *, activity_id_t);
+void load_code_from_mem_area_v2(mem_area_v2 *, mem_area_v2 *, size_t, GProcContext *, const vmpa2t *, bool, GtkStatusStack *, activity_id_t);
 
 
 
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 373b8dc..4b162e8 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -68,6 +68,7 @@ typedef struct _GDelayedFetching
     GtkStatusStack *status;                 /* Barre de statut             */
     activity_id_t id;                       /* Groupe de progression       */
 
+    DisassPriorityLevel level;              /* Niveau d'importance du point*/
     virt_t virt;                            /* Adresse de départ dépilée   */
 
 } GDelayedFetching;
@@ -96,7 +97,7 @@ static void g_delayed_fetching_dispose(GDelayedFetching *);
 static void g_delayed_fetching_finalize(GDelayedFetching *);
 
 /* Crée une tâche de récupération d'instructions différée. */
-static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *, virt_t);
+static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *, unsigned int, virt_t);
 
 /* Assure la récupération d'instructions en différé. */
 static void g_delayed_fetching_process(GDelayedFetching *, GtkExtStatusBar *);
@@ -236,6 +237,7 @@ static void g_delayed_fetching_finalize(GDelayedFetching *fetching)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : template = modèle dont les informations sont à copier.       *
+*                level    = indication de priorité et d'origine de l'adresse. *
 *                virt     = point départ dépilé et personnalisant l'instance. *
 *                                                                             *
 *  Description : Crée une tâche de récupération d'instructions différée.      *
@@ -246,7 +248,7 @@ static void g_delayed_fetching_finalize(GDelayedFetching *fetching)
 *                                                                             *
 ******************************************************************************/
 
-static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template, virt_t virt)
+static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template, DisassPriorityLevel level, virt_t virt)
 {
     GDelayedFetching *result;            /* Tâche à retourner           */
 
@@ -268,9 +270,9 @@ static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template
 
     result->id = template->id;
 
+    result->level = level;
     result->virt = virt;
 
-
     return result;
 
 }
@@ -301,7 +303,8 @@ static void g_delayed_fetching_process(GDelayedFetching *fetching, GtkExtStatusB
 
     if (area != NULL)
         load_code_from_mem_area_v2(area, fetching->areas, fetching->count,
-                                   fetching->ctx, &addr, fetching->status, fetching->id);
+                                   fetching->ctx, &addr, fetching->level < 2,
+                                   fetching->status, fetching->id);
 
 }
 
@@ -341,6 +344,7 @@ static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching *
 {
     GWorkQueue *queue;                      /* Gestionnaire de différés    */
     gint *remaining_counter;                /* Compteur à considérer       */
+    DisassPriorityLevel level;              /* Niveau d'importance du point*/
     virt_t virt;                            /* Adresse de départ dépilée   */
     GDelayedFetching *fetching;             /* Récupération à mener        */
 
@@ -348,9 +352,9 @@ static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching *
 
     remaining_counter = (gint *)g_object_get_data(G_OBJECT(ctx), "remaining_counter");
 
-    while (g_proc_context_pop_drop_point(ctx, &virt))
+    while (g_proc_context_pop_drop_point(ctx, &level, &virt))
     {
-        fetching = g_delayed_fetching_new(template, virt);
+        fetching = g_delayed_fetching_new(template, level, virt);
 
         /**
          * Pas très élégant : l'identifiant du groupe de travail ne sert qu'ici ;
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index 0ff6148..78aba82 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -101,6 +101,12 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
     char *prefixed;
 
 
+
+    unsigned int _missing = 0;
+
+
+
+
     output = g_asm_output_new();
 
     layer = g_exe_format_get_main_layer(format);
@@ -202,6 +208,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
                                      _("Unable to find a proper location for symbol '%s' @ 0x%08x"),
                                      g_binary_symbol_get_label(symbols[sym_index]), get_virt_addr(saddr));
 
+                _missing++;
+
                 if (++sym_index == sym_count)
                     goto no_more_symbol_finally;
 
@@ -342,4 +350,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
 
     g_object_unref(G_OBJECT(output));
 
+
+    fprintf(stderr, "MISSING :: %u symbols\n", _missing);
+
+
 }
diff --git a/src/arch/arm/v7/context.c b/src/arch/arm/v7/context.c
index 446a972..659fdd1 100644
--- a/src/arch/arm/v7/context.c
+++ b/src/arch/arm/v7/context.c
@@ -63,7 +63,7 @@ static void g_armv7_context_dispose(GArmV7Context *);
 static void g_armv7_context_finalize(GArmV7Context *);
 
 /* Ajoute une adresse virtuelle comme point de départ de code. */
-static void g_armv7_context_push_drop_point(GArmV7Context *, unsigned int, virt_t, va_list);
+static void g_armv7_context_push_drop_point(GArmV7Context *, DisassPriorityLevel, virt_t, va_list);
 
 
 
@@ -209,13 +209,14 @@ GArmV7Context *g_armv7_context_new(void)
 *                                                                             *
 ******************************************************************************/
 
-static void g_armv7_context_push_drop_point(GArmV7Context *ctx, unsigned int level, virt_t addr, va_list ap)
+static void g_armv7_context_push_drop_point(GArmV7Context *ctx, DisassPriorityLevel level, virt_t addr, va_list ap)
 {
     ArmV7InstrSet marker;                   /* Type de jeu d'instructions  */
 
     switch (level)
     {
-        case 0:
+        case DPL_ENTRY_POINT:
+        case DPL_SYMBOL:
 
             if (addr & 0x1)
             {
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
index 206e6e6..67129b2 100644
--- a/src/arch/arm/v7/fetch.c
+++ b/src/arch/arm/v7/fetch.c
@@ -99,7 +99,7 @@ void help_fetching_with_instruction_b_with_orig(GArchInstruction *instr, GArchPr
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
-    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target, iset);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, target, iset);
 
 }
 
@@ -168,7 +168,7 @@ void help_fetching_with_instruction_bl_with_orig(GArchInstruction *instr, GArchP
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
-    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target, iset);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, target, iset);
 
 }
 
@@ -227,7 +227,7 @@ void help_fetching_with_instruction_blx_with_dest(GArchInstruction *instr, GArch
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
-    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target, iset);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, target, iset);
 
 }
 
@@ -280,12 +280,12 @@ void help_fetching_with_instruction_bx_with_orig(GArchInstruction *instr, GArchP
         case AV7IS_ARM:
             pc += 8;
             //g_armv7_context_define_encoding(context, 
-            g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, pc, AV7IS_THUMB);
+            g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, pc, AV7IS_THUMB);
             break;
         case AV7IS_THUMB:
             pc += 4;
             //g_armv7_context_define_encoding(context, 
-            g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, pc, AV7IS_ARM);
+            g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, pc, AV7IS_ARM);
             break;
         default:
             assert(0);
@@ -342,7 +342,7 @@ void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcess
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
-    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target, AV7IS_THUMB);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, target, AV7IS_THUMB);
 
 }
 
@@ -518,8 +518,13 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
     //target = pc + offset;
 
 
+    if (target & 0x1)
+        iset = AV7IS_THUMB;
+    //else
+    //    iset = AV7IS_ARM;
+
     //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
-    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 0/*FIXME*/, target);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, target, iset);
 
 
     //exit(0);
diff --git a/src/arch/context-int.h b/src/arch/context-int.h
index 59a06bb..1ea8b6c 100644
--- a/src/arch/context-int.h
+++ b/src/arch/context-int.h
@@ -37,7 +37,7 @@
 
 
 /* Ajoute une adresse virtuelle comme point de départ de code. */
-typedef void (* push_drop_point_fc) (GProcContext *, unsigned int, virt_t, va_list);
+typedef void (* push_drop_point_fc) (GProcContext *, DisassPriorityLevel, virt_t, va_list);
 
 
 /* Définition d'un contexte pour processeur (instance) */
@@ -45,9 +45,9 @@ struct _GProcContext
 {
     GObject parent;                         /* A laisser en premier        */
 
-    virt_t *drop_points;                    /* Liste de points de départ   */
-    size_t dp_allocated;                    /* Taille de liste allouée     */
-    size_t dp_count;                        /* Quantité utile de la liste  */
+    virt_t *drop_points[DPL_COUNT];         /* Liste de points de départ   */
+    size_t dp_allocated[DPL_COUNT];         /* Taille de liste allouée     */
+    size_t dp_count[DPL_COUNT];             /* Quantité utile de la liste  */
     GMutex dp_access;                       /* Accès à la liste FIFO       */
 
     vmpa2t *extra_symbols;                  /* Adresses de symboles        */
diff --git a/src/arch/context.c b/src/arch/context.c
index 98eebb2..979a403 100644
--- a/src/arch/context.c
+++ b/src/arch/context.c
@@ -40,7 +40,7 @@ static void g_proc_context_class_init(GProcContextClass *);
 static void g_proc_context_init(GProcContext *);
 
 /* Ajoute une adresse virtuelle comme point de départ de code. */
-static void _g_proc_context_push_drop_point(GProcContext *, unsigned int, virt_t, va_list);
+static void _g_proc_context_push_drop_point(GProcContext *, DisassPriorityLevel, virt_t, va_list);
 
 
 
@@ -90,9 +90,15 @@ static void g_proc_context_class_init(GProcContextClass *klass)
 
 static void g_proc_context_init(GProcContext *ctx)
 {
-    ctx->drop_points = NULL;
-    ctx->dp_allocated = 0;
-    ctx->dp_count = 0;
+    DisassPriorityLevel i;                   /* Boucle de parcours          */
+
+    for (i = 0; i < DPL_COUNT; i++)
+    {
+        ctx->drop_points[i] = NULL;
+        ctx->dp_allocated[i] = 0;
+        ctx->dp_count[i] = 0;
+    }
+
     g_mutex_init(&ctx->dp_access);
 
     ctx->extra_symbols = NULL;
@@ -137,17 +143,22 @@ void g_proc_context_attach_counter(GProcContext *ctx, gint *counter)
 *                                                                             *
 ******************************************************************************/
 
-static void _g_proc_context_push_drop_point(GProcContext *ctx, unsigned int level, virt_t addr, va_list ap)
+static void _g_proc_context_push_drop_point(GProcContext *ctx, DisassPriorityLevel level, virt_t addr, va_list ap)
 {
-    if (ctx->dp_count >= ctx->dp_allocated)
+    assert(level < DPL_COUNT);
+
+    if (ctx->dp_count[level] >= ctx->dp_allocated[level])
     {
-        ctx->dp_allocated += DP_ALLOC_BLOCK;
+        ctx->dp_allocated[level] += DP_ALLOC_BLOCK;
 
-        ctx->drop_points = (virt_t *)realloc(ctx->drop_points, ctx->dp_allocated * sizeof(virt_t));
+        ctx->drop_points[level] = (virt_t *)realloc(ctx->drop_points[level],
+                                                    ctx->dp_allocated[level] * sizeof(virt_t));
 
     }
 
-    ctx->drop_points[ctx->dp_count++] = addr;
+    ctx->drop_points[level][ctx->dp_count[level]] = addr;
+
+    ctx->dp_count[level]++;
 
 }
 
@@ -167,7 +178,7 @@ static void _g_proc_context_push_drop_point(GProcContext *ctx, unsigned int leve
 *                                                                             *
 ******************************************************************************/
 
-void g_proc_context_push_drop_point(GProcContext *ctx, unsigned int level, virt_t addr, ...)
+void g_proc_context_push_drop_point(GProcContext *ctx, DisassPriorityLevel level, virt_t addr, ...)
 {
     va_list ap;                             /* Arguments complémentaires ? */
 
@@ -191,8 +202,9 @@ void g_proc_context_push_drop_point(GProcContext *ctx, unsigned int level, virt_
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : ctx  = contexte de désassemblage à compléter.                *
-*                virt = adresse d'un point de départ de code à traiter.       *
+*  Paramètres  : ctx   = contexte de désassemblage à compléter.               *
+*                level = degré d'importance de l'adresse retournée. [OUT]     *
+*                virt  = adresse d'un point de départ de code à traiter. [OUT]*
 *                                                                             *
 *  Description : Fournit une adresse virtuelle comme point de départ de code. *
 *                                                                             *
@@ -202,26 +214,30 @@ void g_proc_context_push_drop_point(GProcContext *ctx, unsigned int level, virt_
 *                                                                             *
 ******************************************************************************/
 
-bool g_proc_context_pop_drop_point(GProcContext *ctx, virt_t *virt)
+bool g_proc_context_pop_drop_point(GProcContext *ctx, DisassPriorityLevel *level, virt_t *virt)
 {
     bool result;                            /* Bilan d'accès à retourner   */
+    DisassPriorityLevel i;                  /* Boucle de parcours          */
+
+    result = false;
 
     g_mutex_lock(&ctx->dp_access);
 
-    if (ctx->dp_count > 0)
-    {
-        result = true;
+    for (i = 0; i < DPL_COUNT && !result; i++)
+        if (ctx->dp_count[i] > 0)
+        {
+            result = true;
 
-        *virt = ctx->drop_points[0];
+            *level = i;
+            *virt = ctx->drop_points[i][0];
 
-        if (ctx->dp_count > 1)
-            memmove(&ctx->drop_points[0], &ctx->drop_points[1], (ctx->dp_count - 1) * sizeof(virt_t));
+            if (ctx->dp_count[i] > 1)
+                memmove(&ctx->drop_points[i][0], &ctx->drop_points[i][1],
+                        (ctx->dp_count[i] - 1) * sizeof(virt_t));
 
-        ctx->dp_count--;
+            ctx->dp_count[i]--;
 
-    }
-    else
-        result = false;
+        }
 
     g_mutex_unlock(&ctx->dp_access);
 
diff --git a/src/arch/context.h b/src/arch/context.h
index 334eaf1..d8b5793 100644
--- a/src/arch/context.h
+++ b/src/arch/context.h
@@ -48,6 +48,18 @@ typedef struct _GProcContext GProcContext;
 typedef struct _GProcContextClass GProcContextClass;
 
 
+/* Degré de priorité des points à désassembler */
+typedef enum _DisassPriorityLevel
+{
+    DPL_ENTRY_POINT,                        /* Validité indiscutable       */
+    DPL_SYMBOL,                             /* Symboles utilisés           */
+    DPL_OTHER,                              /* Injections complémentaires  */
+
+    DPL_COUNT
+
+} DisassPriorityLevel;
+
+
 /* Indique le type définit par la GLib pour le contexte de processeur. */
 GType g_proc_context_get_type(void);
 
@@ -55,10 +67,10 @@ GType g_proc_context_get_type(void);
 void g_proc_context_attach_counter(GProcContext *, gint *);
 
 /* Ajoute une adresse virtuelle comme point de départ de code. */
-void g_proc_context_push_drop_point(GProcContext *, unsigned int, virt_t, ...);
+void g_proc_context_push_drop_point(GProcContext *, DisassPriorityLevel, virt_t, ...);
 
 /* Fournit une adresse virtuelle comme point de départ de code. */
-bool g_proc_context_pop_drop_point(GProcContext *, virt_t *);
+bool g_proc_context_pop_drop_point(GProcContext *, DisassPriorityLevel *, virt_t *);
 
 /* Empile une adresse de nouveau symbole à prendre en compte. */
 void g_proc_context_push_new_symbol_at(GProcContext *, const vmpa2t *);
diff --git a/src/arch/dalvik/fetch.c b/src/arch/dalvik/fetch.c
index a557601..d9bbf9b 100644
--- a/src/arch/dalvik/fetch.c
+++ b/src/arch/dalvik/fetch.c
@@ -57,6 +57,6 @@ void help_fetching_with_dalvik_instruction(GArchInstruction *instr, GArchProcess
     assert(status);
 
     if (status)
-        g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target);
+        g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, target);
 
 }
diff --git a/src/format/format.c b/src/format/format.c
index ea67d2d..5b44156 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -264,10 +264,10 @@ void g_binary_format_setup_disassembling_context(GBinFormat *format, GProcContex
     g_rw_lock_reader_lock(&format->pt_lock);
 
     for (i = 0; i < format->ep_count; i++)
-        g_proc_context_push_drop_point(ctx, 0, format->entry_points[i]);
+        g_proc_context_push_drop_point(ctx, DPL_ENTRY_POINT, format->entry_points[i]);
 
     for (i = 0; i < format->xp_count; i++)
-        g_proc_context_push_drop_point(ctx, 0, format->extra_points[i]);
+        g_proc_context_push_drop_point(ctx, DPL_SYMBOL, format->extra_points[i]);
 
     g_rw_lock_reader_unlock(&format->pt_lock);
 
-- 
cgit v0.11.2-87-g4458