diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-03-13 22:29:55 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-03-13 22:29:55 (GMT) |
commit | 5c1636199a06965c549f748014d582dcb85ba7df (patch) | |
tree | e70aa1a094b5b6538b02a6aa1576d33b3c3f8c3e /src/analysis/disass | |
parent | 3aa59dafae3c0d6f3f158db284b1b2af2246b173 (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')
-rw-r--r-- | src/analysis/disass/area.c | 3 | ||||
-rw-r--r-- | src/analysis/disass/limit.c | 133 | ||||
-rw-r--r-- | src/analysis/disass/limit.h | 3 |
3 files changed, 58 insertions, 81 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index bd99402..916918e 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -1249,7 +1249,8 @@ mem_area *compute_memory_areas(GExeFormat *format, phys_t bin_length, size_t *co - //free + if (exe_ranges != NULL) + free(exe_ranges); //exit(0); 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); } diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h index d768765..92c7df4 100644 --- a/src/analysis/disass/limit.h +++ b/src/analysis/disass/limit.h @@ -26,12 +26,13 @@ #include "../routine.h" +#include "../../format/executable.h" #include "../../gtkext/gtkextstatusbar.h" /* S'assure que toutes les routines ont une taille définie. */ -void limit_all_routines(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); +void limit_all_routines(GExeFormat *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); |