diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-10-11 20:50:03 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-10-11 20:50:03 (GMT) |
commit | ffc49de3b424d3daf08b5fdeefd4a3ede6defd02 (patch) | |
tree | cf1a96860e922715bcab55126f8095b7f562d2a1 | |
parent | a5e162d47a574f334b172dfee3128a40e8d52fb3 (diff) |
Improved the disassembling process using memory ranges.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@411 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | src/analysis/disass/fetch.c | 547 | ||||
-rw-r--r-- | src/arch/instruction.c | 20 | ||||
-rw-r--r-- | src/arch/instruction.h | 3 | ||||
-rw-r--r-- | src/format/elf/symbols.c | 2 | ||||
-rw-r--r-- | src/format/executable.c | 59 | ||||
-rw-r--r-- | src/format/executable.h | 5 | ||||
-rw-r--r-- | src/glibext/gbinportion.c | 55 | ||||
-rw-r--r-- | src/glibext/gbinportion.h | 12 |
9 files changed, 462 insertions, 262 deletions
@@ -1,3 +1,24 @@ +14-10-11 Cyrille Bagard <nocbos@gmail.com> + + * src/analysis/disass/fetch.c: + Improve the disassembling process using memory ranges. + + * src/arch/instruction.c: + * src/arch/instruction.h: + Provide a way to merge two lists of instructions. + + * src/format/elf/symbols.c: + Remove the arbitrary length of ELF symbols. + + * src/format/executable.c: + * src/format/executable.h: + Compute ranges of executable binary areas. + + * src/glibext/gbinportion.c: + * src/glibext/gbinportion.h: + Combine a memory range with each binary portion. Add a design pattern to + visit portions. + 14-10-08 Cyrille Bagard <nocbos@gmail.com> * configure.ac: diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index eee2eb6..f10178a 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -24,18 +24,33 @@ #include "fetch.h" -#include "../../arch/artificial.h" +#include <assert.h> +#include "../../arch/raw.h" +#include "../../arch/instruction.h" -#include "../../arch/raw.h" -#include "../../arch/instruction-int.h" +/* Zone mémoire bien bornée */ +typedef struct _mem_area +{ + mrange_t range; /* Couverture de la zone */ + bool has_sym; /* Représentation via symbole ?*/ + + union + { + bool exec; /* Zone exécutable ? */ + GBinSymbol *symbol; /* Symbole associé à la zone */ + }; +} mem_area; +/* Détermine une liste de zones contigües à traiter. */ +static mem_area *compute_memory_areas(const GExeFormat *, phys_t, size_t *); + /* Procède au désassemblage basique d'un contenu binaire. */ static GArchInstruction *load_raw_binary(const GLoadedBinary *, const vmpa2t *, off_t, GtkExtStatusBar *, bstatus_id_t); @@ -44,6 +59,241 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *, const vmpa2t *, +/****************************************************************************** +* * +* Paramètres : format = format d'un exécutable à consulter. * +* bin_length = quantité d'octets à traiter au total. * +* count = nombre de zones mises en place. [OUT] * +* * +* Description : Détermine une liste de zones contigües à traiter. * +* * +* Retour : Liste de zones mémoire à libérer après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static mem_area *compute_memory_areas(const GExeFormat *format, phys_t bin_length, size_t *count) +{ + mem_area *result; /* Liste à renvoyer */ + mrange_t *exe_ranges; /* Liste de zones exécutables */ + size_t exe_count; /* Nombre de ces zones */ + GBinSymbol **symbols; /* Symboles à représenter */ + size_t sym_count; /* Qté de symboles présents */ + vmpa2t *last; /* Dernière bordure rencontrée */ + size_t i; /* Boucle de parcours #1 */ + vmpa2t *border; /* Nouvelle bordure rencontrée */ + mem_area *area; /* Zone avec valeurs à éditer */ + vmpa2t tmp; /* Stockage temporaire */ + size_t j; /* Boucle de parcours #2 */ + const mrange_t *range; /* Couverture d'un symbole */ + const vmpa2t *start; /* Point de départ du symbole */ + phys_t length; /* Taille de ce même symbole */ + bool included; /* Inclusion dans une zone ? */ + mem_area orig; /* Copie de la zone réduite */ + phys_t old_length; /* Taille de zone originelle */ + phys_t new_length; /* Nouvelle taille déterminée */ + size_t next; /* Indice de zone suivante */ + + result = NULL; + *count = 0; + + /** + * Le parcours n'est valide que si les listes, symboles et zones exécutables, + * sont triées ! + */ + + exe_ranges = g_exe_format_get_x_ranges(format, &exe_count); + + symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count); + + /* Première étape : on comble les trous ! */ + + last = make_vmpa(0, VMPA_NO_VIRTUAL); + + for (i = 0; i < exe_count; i++) + { + border = get_mrange_addr(&exe_ranges[i]); + + /* Zone tampon à constituer */ + + if (cmp_vmpa_by_phy(last, border) < 0) + { + result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); + + area = &result[*count - 1]; + + init_mrange(&area->range, last, compute_vmpa_diff(last, border)); + area->has_sym = false; + area->exec = false; + + } + + /* Insertion d'une zone exécutable déjà définie */ + + result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); + + area = &result[*count - 1]; + + copy_mrange(&area->range, &exe_ranges[i]); + area->has_sym = false; + area->exec = true; + + /* Avancée du curseur */ + + copy_vmpa(last, border); + + advance_vmpa(last, get_mrange_length(&exe_ranges[i])); + + } + + delete_vmpa(last); + + /* Extension finale complémentaire ? */ + + area = &result[*count - 1]; + + copy_vmpa(&tmp, get_mrange_addr(&area->range)); + advance_vmpa(&tmp, get_mrange_length(&area->range)); + + if (get_phy_addr(&tmp) < bin_length) + { + result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); + + area = &result[*count - 1]; + + init_mrange(&area->range, &tmp, bin_length - get_phy_addr(&tmp)); + area->has_sym = false; + area->exec = false; + + } + + /* Seconde étape : on insère les symboles existants */ + + j = 0; + +#define SKIP_EMPTY_SYMBOLS \ + for (; j < sym_count; j++) \ + { \ + range = g_binary_symbol_get_range(symbols[j]); \ + \ + length = get_mrange_length(range); \ + if (length > 0) break; \ + \ + } \ + + SKIP_EMPTY_SYMBOLS + + for (i = 0; i < *count && j < sym_count; i++) + { + range = g_binary_symbol_get_range(symbols[j]); + + start = get_mrange_addr(range); + length = get_mrange_length(range); + + /* Si un découpage s'impose... */ + + if (mrange_contains_addr(&result[i].range, start)) + { + copy_vmpa(&tmp, start); + advance_vmpa(&tmp, length); + + included = mrange_contains_addr(&result[i].range, &tmp); + + memcpy(&orig, &result[i], sizeof(mem_area)); + + /* Réduction de la zone de départ */ + + copy_vmpa(&tmp, get_mrange_addr(&result[i].range)); + old_length = get_mrange_length(&result[i].range); + + new_length = compute_vmpa_diff(get_mrange_addr(&result[i].range), start); + + if (new_length == 0) + { + memmove(&result[i], &result[i + 1], (*count - i - 1) * sizeof(mem_area)); + + (*count)--; + next = i; + + } + else + { + init_mrange(&result[i].range, &tmp, new_length); + next = i + 1; + } + + /* Insertion de la zone du symbole */ + + result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); + + memmove(&result[next + 1], &result[next], (*count - next - 1) * sizeof(mem_area)); + + area = &result[next]; + + copy_mrange(&area->range, range); + + area->has_sym = true; + area->symbol = symbols[j]; + + /* Jointure finale... */ + + if (included) + { + /* Simple extension pour rattraper la fin originelle */ + + if ((old_length - new_length - length) > 0) + { + result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); + + memmove(&result[next + 2], &result[next + 1], (*count - next - 2) * sizeof(mem_area)); + + area = &result[next + 1]; + + copy_vmpa(&tmp, start); + advance_vmpa(&tmp, length); + + memcpy(area, &orig, sizeof(mem_area)); + + init_mrange(&area->range, &tmp, old_length - new_length - length); + + } + + i = next; + + } + else + { + /* Suppression des éventuelles zones totalement recouvertes */ + + + + /* Réduction de la zone d'arrivée */ + + + } + + + + + + j++; + + SKIP_EMPTY_SYMBOLS + + } + + } + + + + //free + + //exit(0); + + return result; + +} /****************************************************************************** @@ -159,7 +409,7 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp { instr = g_arch_processor_disassemble(proc, NULL, bin_data, &pos, end); - if (!G_IS_RAW_INSTRUCTION(instr)) printf("GOT %p\n", instr); + //if (!G_IS_RAW_INSTRUCTION(instr)) printf("GOT %p\n", instr); if (instr == NULL) instr = g_raw_instruction_new_array(bin_data, MDS_32_BITS, 1, &pos, end, @@ -187,12 +437,6 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp } - - - - - - /****************************************************************************** * * * Paramètres : binary = représentation de binaire chargé. * @@ -209,277 +453,66 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExtStatusBar *statusbar, bstatus_id_t id) { - GArchInstruction *result; /* Instruction désassemblées */ - - - GBinFormat *format; /* Format du fichier binaire */ - - - - vmpa2t *last; /* Dernière bordure rencontrée */ - - - - GBinSymbol **symbols; /* Symboles à représenter */ - size_t sym_count; /* Qté de symboles présents */ - - + GExeFormat *format; /* Format du fichier binaire */ + off_t length; /* Taille des données à lire */ + mem_area *areas; /* Zone de productions */ + size_t count; /* Nombre de ces zones */ size_t i; /* Boucle de parcours */ - - - const mrange_t *range; /* Couverture d'un symbole */ - const vmpa2t *border; /* Nouvelle bordure rencontrée */ - off_t length; /* Taille d'une partie traitée */ - - - GArchInstruction *instr; /* Instruction à insérer */ - - - - GArchInstruction *joint; /* Jointure entre deux lots */ - - - - off_t max_length; /* Taille des données à lire */ - - - - - result = NULL; - - - - format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); - - last = make_vmpa(0, VMPA_NO_VIRTUAL); - - symbols = g_binary_format_get_symbols(format, &sym_count); - - - //sym_count = 0; - - - for (i = 0; i < sym_count; i++) - { - - - - - range = g_binary_symbol_get_range(symbols[i]); - - border = get_mrange_addr(range); - length = get_mrange_length(range); - - - - - switch (g_binary_symbol_get_target_type(symbols[i])) - { - case STP_DATA: - instr = g_binary_symbol_get_instruction(symbols[i]); - g_object_ref(G_OBJECT(instr)); - break; - - case STP_ROUTINE: - instr = load_code_binary(binary, border, - get_phy_addr(border) + length, - statusbar, id); - break; - - default: - printf("BADDD !\n"); - exit(0); - break; - - } - - /* Traiter la diff */ - - if (0 && cmp_vmpa_by_phy(last, border) < 0) - { - joint = load_raw_binary(binary, last, - get_phy_addr(last) + compute_vmpa_diff(border, last), - statusbar, id); - - ainstr_list_merge(&result, &joint); - - } - - /* Ajout des instructions déjà établies */ - - ainstr_list_merge(&result, &instr); - - /* Marquage de la nouvelle dernière bordure */ - - copy_vmpa(last, border); - - advance_vmpa(last, length); - - } - - /* Raccord final ? */ - - g_loaded_binary_get_data(binary, &max_length); - - if (get_phy_addr(last) < max_length) - { - joint = load_raw_binary(binary, last, max_length, statusbar, id); - ainstr_list_merge(&result, &joint); - } - - - - - printf("COUNT :: %zu\n", sym_count); - - //exit(0); - - - return result; - - - -} - - - - - - - - - - - - - - - -#ifdef DEBUG -# include "../../arch/artificial.h" -#endif - - - -/****************************************************************************** -* * -* Paramètres : binary = représentation de binaire chargé. * -* parts = parties binaires à désassembler. * -* count = nombre de parties à traiter. * -* statusbar = barre de statut avec progression à mettre à jour.* -* id = identifiant du message affiché à l'utilisateur. * -* * -* Description : Procède au désassemblage basique d'un contenu binaire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *disassemble_binary_parts(const GLoadedBinary *binary, GBinPart **parts, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) -{ - GArchInstruction *result; /* Liste d'instr. à renvoyer */ - GBinFormat *format; /* Format du fichier binaire */ - GArchProcessor *proc; /* Architecture du binaire */ - off_t bin_length; /* Taille des données à lire */ - bin_t *bin_data; /* Données binaires à lire */ - size_t i; /* Boucle de parcours #1 */ - off_t sum; /* Somme de toutes les tailles */ - off_t done; /* Quantité déjà traitée */ -#ifdef DEBUG - unsigned int valid; /* Instructions traduites */ - unsigned int db; /* Instructions non décodées */ -#endif - off_t pos; /* Début d'une zone binaire */ - off_t len; /* Taille de cette même zone */ - vmpa_t base; /* Adresse de la zone binaire */ - off_t start; /* Conservation du pt de départ*/ - GProcContext *context; /* Contexte pour le décodage */ - vmpa_t addr; /* Adresse d'une instruction */ - GArchInstruction *instr; /* Instruction décodée */ + mem_area *iter; /* Zone parcourue */ + GArchInstruction *instr; /* Instruction(s) à insérer */ + const vmpa2t *start; /* Début d'une zone traitée */ + phys_t end; /* Fin d'une zone traitée */ result = NULL; - format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); - proc = get_arch_processor_from_format(G_EXE_FORMAT(format)); - bin_data = g_loaded_binary_get_data(binary, &bin_length); - - /* Préparation du suivi de la progression */ + format = g_loaded_binary_get_format(binary); + g_loaded_binary_get_data(binary, &length); - sum = 0; + areas = compute_memory_areas(format, length, &count); for (i = 0; i < count; i++) { - g_binary_part_get_values(parts[i], NULL, &len, NULL); - if (len > bin_length) continue; - sum += len; - } - - done = 0; + iter = &areas[i]; - for (i = 0; i < count; i++) - { - g_binary_part_get_values(parts[i], &pos, &len, &base); + start = get_mrange_addr(&iter->range); + end = get_phy_addr(start) + get_mrange_length(&iter->range); - if (len > bin_length) continue; + assert(get_mrange_length(&iter->range) > 0); - context = g_arch_processor_get_context(proc); + if (iter->has_sym) + switch (g_binary_symbol_get_target_type(iter->symbol)) + { + case STP_DATA: + instr = g_binary_symbol_get_instruction(iter->symbol); + g_object_ref(G_OBJECT(instr)); + break; - /* Décodage des instructions */ + case STP_ROUTINE: + instr = load_code_binary(binary, start, end, statusbar, id); + break; -#ifdef DEBUG - valid = 0; - db = 0; -#endif + default: + assert(false); + break; - start = pos; - len += start; + } - while (pos < len) + else { - addr = base + (pos - start); - - instr = g_arch_processor_decode_instruction(proc, context, bin_data, - &pos, len, addr, format); - g_arch_instruction_add_to_list(&result, instr); - -#ifdef DEBUG - if (G_IS_DB_INSTRUCTION(instr) && !g_db_instruction_is_skipped(G_DB_INSTRUCTION(instr))) - db++; + if (iter->exec) + instr = load_code_binary(binary, start, end, statusbar, id); else - valid++; -#endif - - if (pos < len) - gtk_extended_status_bar_update_activity(statusbar, id, (done + pos - start) * 1.0 / sum); + instr = load_raw_binary(binary, start, end, statusbar, id); } - if (context != NULL) - g_object_unref(context); - -#ifdef DEBUG - g_binary_part_set_checkup(parts[i], valid, db); -#endif - - done += (len - start); - gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / sum); + g_arch_instruction_merge_lists(&result, &instr); } + free(areas); + return result; } - - - - - - - - - - - diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 402b0f5..8312bf6 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -829,6 +829,26 @@ void g_arch_instruction_add_to_list(GArchInstruction **list, GArchInstruction *i /****************************************************************************** * * +* Paramètres : list1 = première liste à traiter. * +* list2 = seconde liste à traiter. * +* * +* Description : Fusionne deux listes d'instructions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_arch_instruction_merge_lists(GArchInstruction **list1, GArchInstruction **list2) +{ + ainstr_list_merge(list1, list2); + +} + + +/****************************************************************************** +* * * Paramètres : list = liste d'instructions à consulter. * * : iter = position actuelle dans la liste. * * * diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 4fe0569..eadac8b 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -168,6 +168,9 @@ GArchInstruction *g_arch_instruction_find_last(const GArchInstruction *); /* Ajoute une instruction à un ensemble existant. */ void g_arch_instruction_add_to_list(GArchInstruction **, GArchInstruction *); +/* Fusionne deux listes d'instructions. */ +void g_arch_instruction_merge_lists(GArchInstruction **, GArchInstruction **); + /* Fournit l'élement suivant un autre pour un parcours. */ GArchInstruction *g_arch_instruction_get_prev_iter(const GArchInstruction *, const GArchInstruction *); diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index 84bf9b7..15c3a6b 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -1321,7 +1321,7 @@ static bool load_elf_internal_symbols(GElfFormat *format) init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL); - init_mrange(&range, &addr, 4/*ELF_SYM(format, sym, st_size) FIXME !!! */); + init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); /* Première ébauche de nom */ diff --git a/src/format/executable.c b/src/format/executable.c index 6b39ac8..ea1b398 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -28,6 +28,9 @@ #include "format.h" +#include <malloc.h> + + /* Initialise la classe des formats d'exécutables génériques. */ static void g_executable_format_class_init(GExeFormatClass *); @@ -162,6 +165,62 @@ GBinPortion *g_exe_format_get_portions(GExeFormat *format) * Paramètres : format = informations chargées à consulter. * * count = quantité de zones listées. [OUT] * * * +* Description : Fournit les espaces mémoires des portions exécutables. * +* * +* Retour : Liste de zones binaires exécutables à libérer après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count) +{ + mrange_t *result; /* Liste à retourner */ + + typedef struct _x_ranges + { + mrange_t *list; + size_t length; + + } x_ranges; + + x_ranges tmp; /* Sauvegarde de la liste */ + + bool visit_for_x(GBinPortion *portion, x_ranges *ranges) + { + const mrange_t *range; + + if (g_binary_portion_get_rights(portion) & PAC_EXEC) + { + range = g_binary_portion_get_range(portion); + + ranges->list = (mrange_t *)realloc(ranges->list, ++ranges->length * sizeof(mrange_t)); + copy_mrange(&ranges->list[ranges->length - 1], range); + + } + + return true; + + } + + tmp.list = NULL; + tmp.length = 0; + + g_binary_portion_visit(g_exe_format_get_portions(format), (visit_portion_fc)visit_for_x, &tmp); + + result = tmp.list; + *count = tmp.length; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = quantité de zones listées. [OUT] * +* * * Description : Fournit les références aux zones binaires à analyser. * * * * Retour : Zones binaires à analyser. * diff --git a/src/format/executable.h b/src/format/executable.h index b43a9f5..10bff42 100644 --- a/src/format/executable.h +++ b/src/format/executable.h @@ -78,8 +78,11 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *); /* Décrit les différentes portions qui composent le binaire. */ GBinPortion *g_exe_format_get_portions(GExeFormat *); +/* Fournit les espaces mémoires des portions exécutables. */ +mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count); + /* Fournit les références aux zones binaires à analyser. */ -GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *); +GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *) __attribute__ ((deprecated)); /* Fournit la position correspondant à une adresse virtuelle. */ bool g_exe_format_translate_address_into_offset(const GExeFormat *, vmpa_t, off_t *); diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c index 76926ca..94a04cc 100644 --- a/src/glibext/gbinportion.c +++ b/src/glibext/gbinportion.c @@ -50,6 +50,7 @@ struct _GBinPortion char *desc; /* Désignation humaine */ + mrange_t range; /* Emplacement dans le code */ vmpa2t addr; /* Emplacement dans le code */ off_t size; /* Taille de la partie */ @@ -265,7 +266,7 @@ const char *g_binary_portion_get_desc(const GBinPortion *portion) * addr = emplacement de la section à conserver. * * size = taille de la section à conserver. * * * -* Description : Définit les valeurs utiles d'une partie de code. * +* Description : Définit les valeurs utiles d'une partie de code binaire. * * * * Retour : - * * * @@ -273,11 +274,32 @@ const char *g_binary_portion_get_desc(const GBinPortion *portion) * * ******************************************************************************/ -void g_binary_portion_set_values(GBinPortion *portion, const vmpa2t *addr, off_t size) +void g_binary_portion_set_values(GBinPortion *portion, const vmpa2t *addr, phys_t size) { copy_vmpa(&portion->addr, addr); portion->size = size; + init_mrange(&portion->range, addr, size); + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* * +* Description : Fournit l'emplacement d'une partie de code binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +const mrange_t *g_binary_portion_get_range(const GBinPortion *portion) +{ + return &portion->range; + } @@ -376,6 +398,35 @@ static bool g_binary_portion_compute_sub_area(GBinPortion *portion, GBinPortion /****************************************************************************** * * +* Paramètres : portion = première portion amorçant la visite. * +* visitor = fonction à appeler à chaque étape de la descente. * +* data = adresse pointant vers des données de l'utilisateur.* +* * +* Description : Parcours un ensemble de portions binaires. * +* * +* Retour : true si la visite a été jusqu'à son terme, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void *data) +{ + bool result; /* Etat à retourner */ + size_t i; /* Boucle de parcours */ + + result = visitor(portion, data); + + for (i = 0; i < portion->sub_count && result; i++) + result = g_binary_portion_visit(portion->sub_portions[i], visitor, data); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : portion = description de partie à mettre à jour. * * x = abscisse du point de recherche. * * y = ordonnée du point de recherche. * diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h index fb32496..ac6b4fd 100644 --- a/src/glibext/gbinportion.h +++ b/src/glibext/gbinportion.h @@ -72,6 +72,10 @@ typedef enum _PortionAccessRights } PortionAccessRights; +/* Fonction appelée à chaque visite de portion.*/ +typedef bool (* visit_portion_fc) (GBinPortion *, void *); + + /* Indique le type défini par la GLib pour les blocs de données. */ GType g_binary_portion_get_type(void); @@ -85,7 +89,10 @@ void g_binary_portion_set_desc(GBinPortion *, const char *); const char *g_binary_portion_get_desc(const GBinPortion *); /* Définit les valeurs utiles d'une partie de code. */ -void g_binary_portion_set_values(GBinPortion *, const vmpa2t *, off_t); +void g_binary_portion_set_values(GBinPortion *, const vmpa2t *, phys_t); + +/* Fournit l'emplacement d'une partie de code binaire. */ +const mrange_t *g_binary_portion_get_range(const GBinPortion *); /* Définit les droits associés à une partie de code. */ void g_binary_portion_set_rights(GBinPortion *, PortionAccessRights); @@ -96,6 +103,9 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *); /* Procède à l'inclusion d'une portion dans une autre. */ void g_binary_portion_include(GBinPortion *, GBinPortion *); +/* Parcours un ensemble de portions binaires. */ +bool g_binary_portion_visit(GBinPortion *, visit_portion_fc, void *); + /* Recherche la portion présente à un point donné. */ GBinPortion *g_binary_portion_find_at_pos(GBinPortion *, gint, GdkRectangle *); |