summaryrefslogtreecommitdiff
path: root/src/analysis/disass/limit.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-03-13 22:29:55 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-03-13 22:29:55 (GMT)
commit5c1636199a06965c549f748014d582dcb85ba7df (patch)
treee70aa1a094b5b6538b02a6aa1576d33b3c3f8c3e /src/analysis/disass/limit.c
parent3aa59dafae3c0d6f3f158db284b1b2af2246b173 (diff)
Updated and improved without testing the old process of computing limits for routines.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@490 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/disass/limit.c')
-rw-r--r--src/analysis/disass/limit.c133
1 files changed, 54 insertions, 79 deletions
diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c
index 6d5bc35..bb2c865 100644
--- a/src/analysis/disass/limit.c
+++ b/src/analysis/disass/limit.c
@@ -28,129 +28,104 @@
-/* Cherche l'adresse de fin d'une routine. */
-static vmpa_t find_best_ending_address_for_routine(GArchInstruction *, size_t, const vmpa_t *, const off_t *, size_t);
+/* Recherche la zone correspond à une adresse donnée. */
+static const mrange_t *find_x_range_for_addr(const mrange_t *, size_t, const vmpa2t *);
/******************************************************************************
* *
-* Paramètres : list = ensemble d'instructions désassemblées. *
-* routines = prototypes existants à insérer. *
-* count = quantité de ces prototypes. *
-* statusbar = barre de statut avec progression à mettre à jour.*
-* id = identifiant du message affiché à l'utilisateur. *
+* Paramètres : ranges = liste de zones offrant une exécution et disponibles.*
+* count = taille de cette liste. *
* *
-* Description : S'assure que toutes les routines ont une taille définie. *
+* Description : Recherche la zone correspond à une adresse donnée. *
* *
-* Retour : - *
+* Retour : Zone trouvée ou NULL si aucune ne correspond. *
* *
* Remarques : - *
* *
******************************************************************************/
-void limit_all_routines(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
+static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t count, const vmpa2t *addr)
{
+ const mrange_t *result; /* Zone à retourner */
size_t i; /* Boucle de parcours */
- vmpa_t *starts; /* Adresses de départ */
- off_t *lengths; /* Tailles des routines */
- GArchInstruction *instr; /* Instr. de départ / arrivée */
-
- if (count == 0) return;
-
- starts = (vmpa_t *)calloc(count, sizeof(vmpa_t));
- lengths = (off_t *)calloc(count, sizeof(off_t));
-
- for (i = 0; i < count; i++)
- {
- starts[i] = g_binary_routine_get_address(routines[i]);
- lengths[i] = g_binary_routine_get_size(routines[i]);
-
- gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / (count * 2));
-
- }
-
- for (i = 0; i < count; i++)
- {
- /* Instruction de départ */
-
- instr = g_arch_instruction_find_by_address(list, starts[i], true);
- g_binary_routine_set_instructions(routines[i], instr);
-
- if (lengths[i] > 0) goto lar_next;
-
- /* Si le symbole est hors du code analysé (routine de PLT par exemple) */
- if (instr == NULL) goto lar_next;
-
- /* Taille de la routine */
- lengths[i] = find_best_ending_address_for_routine(instr, i, starts, lengths, count);
- lengths[i] -= starts[i];
+ result = NULL;
- /////////g_binary_routine_set_size(routines[i], lengths[i]);
+ for (i = 0; i < count && result == NULL; i++)
+ if (mrange_contains_addr(&ranges[i], addr))
+ result = &ranges[i];
- lar_next:
-
- gtk_extended_status_bar_update_activity(statusbar, id, (i + 1 + count) * 1.0 / (count * 2));
-
- }
-
- free(starts);
- free(lengths);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : first = première instruction de la routine courante. *
-* index = indice de la routine traitée dans la liste. *
-* starts = adresse de départ des autres routines. *
-* lengths = taille des différentes routines, valides ou nulles.*
-* count = quantité de routines présentes. *
+* Paramètres : list = ensemble d'instructions désassemblées. *
+* routines = prototypes existants à insérer. *
+* count = quantité de ces prototypes. *
+* statusbar = barre de statut avec progression à mettre à jour.*
+* id = identifiant du message affiché à l'utilisateur. *
* *
-* Description : Cherche l'adresse de fin d'une routine. *
+* Description : S'assure que toutes les routines ont une taille définie. *
* *
-* Retour : Plus grande adresse de dernière instruction de routine. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static vmpa_t find_best_ending_address_for_routine(GArchInstruction *first, size_t index, const vmpa_t *starts, const off_t *lengths, size_t count)
+void limit_all_routines(GExeFormat *format, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
{
- vmpa_t result; /* Haute adresse à remonter */
- GArchInstruction *iter; /* Boucle de parcours #1 */
- vmpa_t candidate; /* Candidat potentiel */
- size_t i; /* Boucle de parcours #2 */
+ mrange_t *exe_ranges; /* Liste de zones exécutables */
+ size_t exe_count; /* Nombre de ces zones */
+ size_t i; /* Boucle de parcours */
+ const mrange_t *range; /* Emplacement courant */
+ vmpa2t addr; /* Adresse à conserver */
+ phys_t diff; /* Taille définie par déduction*/
+ mrange_t new; /* Nouvel emplacement taillé */
- result = starts[index];
+ exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
- for (iter = first;
- iter != NULL;
- iter = g_arch_instruction_get_next_iter(first, iter, VMPA_MAX))
+ for (i = 0; i < count; i++)
{
- g_arch_instruction_get_location(iter, NULL, NULL, &candidate);
+ //gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count);
+
+ range = g_binary_routine_get_range(routines[i]);
+ if (get_mrange_length(range) > 0) continue;
+
+ copy_vmpa(&addr, get_mrange_addr(range));
- /* Regarde si on n'empiète pas sur une autre routine */
+ /* Si on peut se raccrocher à la routine suivante... */
+ if ((i + 1) < count)
+ {
+ range = g_binary_routine_get_range(routines[i + 1]);
+
+ diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
- for (i = 0; i < count; i++)
+ }
+
+ /* Sinon on va jusqu'à la fin de la zone ! */
+ else
{
- if (i == index) continue;
+ range = find_x_range_for_addr(exe_ranges, exe_count, &addr);
+ if (range == NULL) continue;
- if (starts[i] <= candidate && candidate < (starts[i] + lengths[i]))
- break;
+ diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
+ diff = get_mrange_length(range) - diff;
}
- if (i != count) break;
- else result = candidate;
+ init_mrange(&new, &addr, diff);
- /* Retour de fonction ? */
- if (g_arch_instruction_is_return(iter)) break;
+ g_binary_routine_set_range(routines[i], &new);
}
- return result;
+ if (exe_ranges != NULL)
+ free(exe_ranges);
}