From c4231094c9c77c685371d726d28e65c0459486de Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 11 Mar 2009 22:59:46 +0000 Subject: Inserted comments into disassembled code. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@53 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 25 +++++ src/analysis/line.c | 226 ++++++++++++++++++++++++++++++++++++++++++-- src/analysis/line.h | 31 ++++-- src/analysis/prototype.c | 46 +++++++++ src/analysis/prototype.h | 9 ++ src/binary.c | 40 ++++++-- src/common/dllist.c | 4 +- src/common/dllist.h | 12 +++ src/format/elf/e_elf.c | 36 +++++++ src/format/elf/e_elf.h | 2 + src/format/exe_format-int.h | 3 + src/format/exe_format.c | 45 +++++++++ src/format/exe_format.h | 9 ++ 13 files changed, 461 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3603eed..420ecf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2009-03-11 Cyrille Bagard + + * src/analysis/line.c: + * src/analysis/line.h: + Attach an offset to lines and create comment lines. Provide disassembly + options for lines rendering (this part needs to be rewritten). + + * src/analysis/prototype.c: + * src/analysis/prototype.h: + Add an offset to routines information. + + * src/binary.c: + Insert comments into disassembled code. + + * src/common/dllist.c: + * src/common/dllist.h: + Add a macro for inserting items. + + * src/format/elf/e_elf.c: + * src/format/elf/e_elf.h: + * src/format/exe_format.c: + * src/format/exe_format.h: + * src/format/exe_format-int.h: + Load all routine prototypes. Enable binary parts sorting. + 2009-03-04 Cyrille Bagard * configure.ac: diff --git a/src/analysis/line.c b/src/analysis/line.c index 052adea..f5f3d9c 100644 --- a/src/analysis/line.c +++ b/src/analysis/line.c @@ -55,6 +55,8 @@ struct _rendering_line { DL_LIST_ITEM; + uint64_t offset; /* Position en mémoire/physique*/ + RenderingLineType type; /* Type de représentation */ PangoLayout *layout; /* Moteur de rendu du code/txt */ @@ -75,7 +77,6 @@ void init_rendering_line(rendering_line *); - /* ------------------------- LIGNE EN TETE DE DESASSEMBLAGE ------------------------- */ @@ -94,6 +95,25 @@ void refresh_prologue_markup(prologue_line *); +/* ----------------------- COMMENTAIRES SUR UNE LIGNE ENTIERE ----------------------- */ + + +/* Ligne de commantaires entière */ +typedef struct _comment_line +{ + rendering_line basic; /* A laisser en premier */ + + char *comment; /* Texte à afficher */ + const disass_options *options; /* Options de représentation */ + +} comment_line; + + +/* Met à jour la ligne de représentation de commentaires. */ +void refresh_comment_markup(comment_line *); + + + /* ------------------------ LIGNE DE CODE EN LANGAGE MACHINE ------------------------ */ @@ -162,7 +182,7 @@ void init_rendering_line(rendering_line *line) * * * Retour : - * * * -* Remarques : - * +* Remarques : La ligne est considérée comme étant insérée au bon endroit. * * * ******************************************************************************/ @@ -173,6 +193,48 @@ void add_line_to_rendering_lines(rendering_line **lines, rendering_line *line) } +/****************************************************************************** +* * +* Paramètres : lines = liste de lignes à compléter, ou NULL. * +* line = nouvelle ligne à intégrer à l'ensemble. * +* first = position de la ligne en cas d'adresse partagée. * +* * +* Description : Insère une ligne dans un ensemble existant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void insert_line_into_rendering_lines(rendering_line **lines, rendering_line *line, bool first) +{ + rendering_line *iter; /* Boucle de parcours */ + rendering_line *next; /* Prochaine ligne parcourue */ + + dl_list_for_each_safe(iter, DLL_HCAST(lines), next, rendering_line *) + { + if (first && iter->offset >= line->offset) break; + else if (!first) + { + /* TODO */; + } + + } + + if (iter == NULL) + dl_list_add_tail(line, DLL_HCAST(lines)); + + else + { + if (first) + dl_list_insert_before(line, iter, DLL_HCAST(lines)); + else + /* TODO */; + } + +} + @@ -295,6 +357,8 @@ rendering_line *create_prologue_line(const char *comment) init_rendering_line(RENDERING_LINE(result)); + RENDERING_LINE(result)->offset = 0; + RENDERING_LINE(result)->type = RLT_PROLOGUE; RENDERING_LINE(result)->refresh_markup = (refresh_markup_fc)refresh_prologue_markup; @@ -340,6 +404,154 @@ void refresh_prologue_markup(prologue_line *line) /* ---------------------------------------------------------------------------------- */ +/* COMMENTAIRES SUR UNE LIGNE ENTIERE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : offset = position dans la mémoire ou le fichier. * +* type = type du commentaire. * +* comment = texte à afficher au final. * +* options = paramétrage du rendu. * +* * +* Description : Crée une ligne de commentaires entière. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +rendering_line *create_comment_line(uint64_t offset, RenderingLineType type, const char *comment, const disass_options *options) +{ + comment_line *result; /* Structure à retourner */ + + result = (prologue_line *)calloc(1, sizeof(prologue_line)); + + init_rendering_line(RENDERING_LINE(result)); + + RENDERING_LINE(result)->offset = offset; + + RENDERING_LINE(result)->type = type; + + RENDERING_LINE(result)->refresh_markup = (refresh_markup_fc)refresh_comment_markup; + + result->comment = strdup(comment); + result->options = options; + + return RENDERING_LINE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : line = ligne de représentation à actualiser. * +* * +* Description : Met à jour la ligne de représentation de commentaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void refresh_comment_markup(comment_line *line) +{ + size_t len; /* Taille du contenu */ + char *content; /* Contenu réellement imprimé */ + char buffer[CODE_BUFFER_LEN]; /* Zone tampon à utiliser */ + size_t clen; /* Taille du commentaire */ + + len = strlen("") + 1; + content = (char *)calloc(len, sizeof(char)); + strcpy(content, ""); + + /* Eventuelle adresse virtuelle */ + + if (line->options->show_address) + { + switch (ADM_32BITS /* FIXME */) + { + case ADM_32BITS: + snprintf(buffer, CODE_BUFFER_LEN, + "0x%08llx", + RENDERING_LINE(line)->offset); + break; + + case ADM_64BITS: + snprintf(buffer, CODE_BUFFER_LEN, + "0x%16llx", + RENDERING_LINE(line)->offset); + break; + + } + + len += strlen(buffer); + content = (char *)realloc(content, len * sizeof(char)); + strcat(content, buffer); + + } + + /* Eventuel code brut (sauté) */ + + if (line->options->show_code) + { + clen = (line->options->show_address ? strlen("\t") : 0); + clen += RENDERING_LINE(line)->max_bin_len; + + content = (char *)realloc(content, (len + clen) * sizeof(char)); + + if (line->options->show_address) + { + strcat(content, "\t"); + len += strlen("\t"); + } + + memset(&content[len - 1], RENDERING_LINE(line)->type == RLT_PROTOTYPE ? '-' : ' ', + RENDERING_LINE(line)->max_bin_len); + len += RENDERING_LINE(line)->max_bin_len; + + content[len] = '\0'; + + } + + /* Commentaire proprement dit */ + + clen = (line->options->show_address || line->options->show_code ? strlen("\t") : 0); + clen += strlen(""); + clen += strlen("; ") + strlen(line->comment); + clen += strlen(""); + + content = (char *)realloc(content, (len + clen) * sizeof(char)); + + if (line->options->show_address || line->options->show_code) + { + strcat(content, "\t"); + len += strlen("\t"); + clen -= strlen("\t"); + } + + snprintf(&content[len - 1], clen + 1, "; %s", line->comment); + + len += clen; + + /* Finalisation */ + + len += strlen(""); + content = (char *)realloc(content, len * sizeof(char)); + strcat(content, ""); + + pango_layout_set_markup(RENDERING_LINE(line)->layout, content, len - 1); + + free(content); + +} + + + +/* ---------------------------------------------------------------------------------- */ /* LIGNE DE CODE EN LANGAGE MACHINE */ /* ---------------------------------------------------------------------------------- */ @@ -357,7 +569,7 @@ void refresh_prologue_markup(prologue_line *line) * * ******************************************************************************/ -rendering_line *create_code_line(asm_instr *instr, const disass_options *options) +rendering_line *create_code_line(asm_instr *instr, uint64_t offset, const disass_options *options) { code_line *result; /* Structure à retourner */ @@ -365,6 +577,8 @@ rendering_line *create_code_line(asm_instr *instr, const disass_options *options init_rendering_line(RENDERING_LINE(result)); + RENDERING_LINE(result)->offset = offset; + RENDERING_LINE(result)->type = RLT_CODE; RENDERING_LINE(result)->get_bin_len = (get_bin_len_fc)get_code_binary_len; @@ -430,7 +644,7 @@ void refresh_code_markup(code_line *line) content = (char *)calloc(len, sizeof(char)); strcpy(content, ""); - if (line->options->show_address || line->options->show_code) + if (line->options->show_code) get_asm_instr_offset_and_length(line->instr, &bin_offset, &bin_len); /* Eventuelle adresse virtuelle */ @@ -442,13 +656,13 @@ void refresh_code_markup(code_line *line) case ADM_32BITS: snprintf(buffer, CODE_BUFFER_LEN, "0x%08llx", - bin_offset); + RENDERING_LINE(line)->offset); break; case ADM_64BITS: snprintf(buffer, CODE_BUFFER_LEN, "0x%16llx", - bin_offset); + RENDERING_LINE(line)->offset); break; } diff --git a/src/analysis/line.h b/src/analysis/line.h index cd2ec71..b0635bf 100644 --- a/src/analysis/line.h +++ b/src/analysis/line.h @@ -25,6 +25,7 @@ #define _ANALYSIS_LINE_H +#include #include @@ -37,10 +38,21 @@ typedef enum _RenderingLineType { RLT_PROLOGUE, /* Description de l'analyse */ + RLT_PROTOTYPE, /* Prototype de fonction */ RLT_CODE /* Code en langage machine */ } RenderingLineType; +/* Passage de paramètres compact */ +typedef struct _disass_options +{ + bool show_address; /* Affichage de l'adresse ? */ + bool show_code; /* Affichage du code brut ? */ + + exe_format *format; /* Format du contenu bianire */ + asm_processor *proc; /* Architecture utilisée */ + +} disass_options; @@ -52,6 +64,9 @@ typedef struct _rendering_line rendering_line; /* Ajoute une ligne à un ensemble existant. */ void add_line_to_rendering_lines(rendering_line **, rendering_line *); +/* Insère une ligne dans un ensemble existant. */ +void insert_line_into_rendering_lines(rendering_line **, rendering_line *, bool); + /* Met à jour la nombre d'octets maximale par instruction. */ @@ -76,23 +91,19 @@ rendering_line *create_prologue_line(const char *); -/* ------------------------ LIGNE DE CODE EN LANGAGE MACHINE ------------------------ */ +/* ----------------------- COMMENTAIRES SUR UNE LIGNE ENTIERE ----------------------- */ -/* Passage de paramètres compact */ -typedef struct _disass_options -{ - bool show_address; /* Affichage de l'adresse ? */ - bool show_code; /* Affichage du code brut ? */ +/* Crée une ligne de commentaires entière. */ +rendering_line *create_comment_line(uint64_t, RenderingLineType, const char *, const disass_options *); - exe_format *format; /* Format du contenu bianire */ - asm_processor *proc; /* Architecture utilisée */ -} disass_options; + +/* ------------------------ LIGNE DE CODE EN LANGAGE MACHINE ------------------------ */ /* Crée une ligne de représentation de code binaire. */ -rendering_line *create_code_line(asm_instr *, const disass_options *); +rendering_line *create_code_line(asm_instr *, uint64_t, const disass_options *); diff --git a/src/analysis/prototype.c b/src/analysis/prototype.c index aa3ca2f..0d2ebf5 100644 --- a/src/analysis/prototype.c +++ b/src/analysis/prototype.c @@ -25,6 +25,7 @@ #include +#include #include "../common/extstr.h" @@ -34,6 +35,12 @@ /* Variable représentant un prototype de routine */ struct _bin_routine { + + uint64_t offset; /* Position physique/mémoire */ + + + + RoutineType type; /* Type de routine */ variable *ret_type; /* Type retourné */ @@ -103,6 +110,45 @@ void delete_binary_routine(bin_routine *routine) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * +* offset = position mémoire ou physique déclarée. * +* * +* Description : Définit la position physique / en mémoire d'une routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_binary_routine_offset(bin_routine *routine, uint64_t offset) +{ + routine->offset = offset; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* * +* Description : Fournit la position physique / en mémoire d'une routine. * +* * +* Retour : Position mémoire ou physique déclarée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint64_t get_binary_routine_offset(const bin_routine *routine) +{ + return routine->offset; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * * type = type de routine spécifié. * * * * Description : Définit le type d'une routine. * diff --git a/src/analysis/prototype.h b/src/analysis/prototype.h index f86d541..891f294 100644 --- a/src/analysis/prototype.h +++ b/src/analysis/prototype.h @@ -25,6 +25,9 @@ #define _ANALYSIS_PROTOTYPE_H +#include + + #include "variable.h" @@ -49,6 +52,12 @@ bin_routine *create_binary_routine(void); /* Supprime une représentation de routine de la mémoire. */ void delete_binary_routine(bin_routine *); +/* Définit la position physique / en mémoire d'une routine. */ +void set_binary_routine_offset(bin_routine *, uint64_t); + +/* Fournit la position physique / en mémoire d'une routine. */ +uint64_t get_binary_routine_offset(const bin_routine *); + /* Définit le type d'une routine. */ void set_binary_routine_type(bin_routine *, RoutineType); diff --git a/src/binary.c b/src/binary.c index 427ad4e..5093335 100644 --- a/src/binary.c +++ b/src/binary.c @@ -35,7 +35,7 @@ #include - +#include "analysis/prototype.h" #include "arch/processor.h" @@ -435,6 +435,9 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) asm_processor *proc; asm_instr *instr; + bin_routine **routines; /* Liste des routines trouvées */ + size_t routines_count; /* Nombre de ces routines */ + bin_part **parts; size_t parts_count; @@ -464,6 +467,10 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) size_t k; + uint64_t routine_offset; /* Point de départ de routine */ + char *routine_desc; /* Prototype d'une routine */ + + disass_options options; proc = create_x86_processor(); @@ -497,21 +504,27 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) + options.show_address = true; options.show_code = true; options.format = format; options.proc = proc; + routines = get_all_exe_routines(format, &routines_count); + parts = get_elf_default_code_parts(format, &parts_count); + qsort(parts, parts_count, sizeof(bin_part *), compare_bin_parts); + + for (i = 0; i < parts_count; i++) { get_bin_part_values(parts[i], &pos, &len, &base); - + /* Décodage des instructions */ start = pos; pos = 0; @@ -524,19 +537,27 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) instr = decode_instruction(proc, &bin_data[start], &pos, len, start, offset); - line = create_code_line(instr, &options); + line = create_code_line(instr, offset, &options); add_line_to_rendering_lines(&lines, line); } + /* Ajout des prototypes de fonctions */ - /**** - ret = munmap(bin_data, length); - ****/ + for (k = 0; k < routines_count; k++) + { + routine_offset = get_binary_routine_offset(routines[k]); - /* - gtk_snippet_build_content(snippet); - */ + if (!(base <= routine_offset && routine_offset < (base + len))) continue; + + routine_desc = routine_to_string(routines[k]); + + line = create_comment_line(routine_offset, RLT_PROTOTYPE, routine_desc, &options); + insert_line_into_rendering_lines(&lines, line, true); + + free(routine_desc); + + } } @@ -547,6 +568,7 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) + gtk_snippet_set_rendering_lines(snippet, lines); handle_new_exe_on_symbols_panel(panel, format); diff --git a/src/common/dllist.c b/src/common/dllist.c index 10f73e1..7e56bf4 100644 --- a/src/common/dllist.c +++ b/src/common/dllist.c @@ -45,11 +45,11 @@ void __dl_list_add(dl_list_item *new, dl_list_head *head, dl_list_item *prev, dl_list_item *next) { - if (prev != NULL) prev->next = new; + prev->next = new; new->prev = prev; new->next = next; - if (next != NULL) next->prev = new; + next->prev = new; if (*head == NULL) *head = new; diff --git a/src/common/dllist.h b/src/common/dllist.h index 970edf9..670d3b9 100644 --- a/src/common/dllist.h +++ b/src/common/dllist.h @@ -44,6 +44,7 @@ typedef dl_list_item *dl_list_head; #define DL_LIST_ITEM dl_list_item dummy #define DLL_CAST(item) ((dl_list_item *)item) +#define DLL_HCAST(item) ((dl_list_item **)item) #define DL_LIST_HEAD_INIT(head) \ *(head) = NULL @@ -87,6 +88,17 @@ unsigned int count_dl_list_items(dl_list_head); #define dl_list_add_tail(new, head) \ __dl_list_add(DLL_CAST(new), (head), (dl_list_empty(*(head)) ? DLL_CAST(new) : (*(head))->prev), (dl_list_empty(*(head)) ? DLL_CAST(new) : *(head))) +#define dl_list_insert_before(new, target, head) \ + do \ + { \ + DLL_CAST(new)->prev = DLL_CAST(target)->prev; \ + DLL_CAST(target)->prev->next = DLL_CAST(new); \ + DLL_CAST(new)->next = DLL_CAST(target); \ + DLL_CAST(target)->prev = DLL_CAST(new); \ + if (DLL_CAST(target) == *head) *head = DLL_CAST(target); \ + \ + } while (0) + #define dl_list_del(item, head) \ do \ { \ diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c index a69be68..91e0403 100644 --- a/src/format/elf/e_elf.c +++ b/src/format/elf/e_elf.c @@ -106,6 +106,7 @@ elf_format *load_elf(const uint8_t *content, off_t length) EXE_FORMAT(result)->get_symbols = (get_symbols_fc)get_elf_symbols; EXE_FORMAT(result)->get_resolved = (get_resolved_fc)get_elf_resolved_items; EXE_FORMAT(result)->resolve_symbol = (resolve_symbol_fc)resolve_elf_symbol; + EXE_FORMAT(result)->get_all_routines = (get_all_routines_fc)get_all_elf_routines; memcpy(&result->header, content, sizeof(Elf32_Ehdr)); @@ -394,3 +395,38 @@ bool resolve_elf_symbol(const elf_format *format, char **label, SymbolType *type return result; } + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = taille du tableau créé. [OUT] * +* * +* Description : Fournit le prototype de toutes les routines détectées. * +* * +* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bin_routine **get_all_elf_routines(const elf_format *format, size_t *count) +{ + bin_routine **result; /* Tableau à retourner */ + size_t i; /* Boucle de parcours */ + + result = (bin_routine **)calloc(format->sym_count, sizeof(bin_routine *)); + *count = format->sym_count; + + for (i = 0; i < format->sym_count; i++) + { + result[i] = create_binary_routine(); + + set_binary_routine_offset(result[i], format->symbols[i].address); + set_binary_routine_name(result[i], strdup(format->symbols[i].name)); + + } + + return result; + +} diff --git a/src/format/elf/e_elf.h b/src/format/elf/e_elf.h index fffeff2..f0c2c12 100644 --- a/src/format/elf/e_elf.h +++ b/src/format/elf/e_elf.h @@ -55,6 +55,8 @@ size_t get_elf_symbols(const elf_format *, char ***, SymbolType **, uint64_t **) /* Recherche le symbole correspondant à une adresse. */ bool resolve_elf_symbol(const elf_format *, char **, SymbolType *, uint64_t *); +/* Fournit le prototype de toutes les routines détectées. */ +bin_routine **get_all_elf_routines(const elf_format *, size_t *); diff --git a/src/format/exe_format-int.h b/src/format/exe_format-int.h index 2fdb673..a882891 100644 --- a/src/format/exe_format-int.h +++ b/src/format/exe_format-int.h @@ -63,6 +63,8 @@ typedef size_t (* get_resolved_fc) (const exe_format *, char ***, ResolvedType * /* Recherche le symbole correspondant à une adresse. */ typedef bool (* resolve_symbol_fc) (const exe_format *, char **, SymbolType *, uint64_t *); +/* Fournit le prototype de toutes les routines détectées. */ +typedef bin_routine ** (* get_all_routines_fc) (const exe_format *, size_t *); /* Support générique d'un format d'exécutable */ @@ -76,6 +78,7 @@ struct _exe_format get_symbols_fc get_symbols; /* Liste des symboles présents */ get_resolved_fc get_resolved; /* Liste des éléments présents */ resolve_symbol_fc resolve_symbol; /* Recherche de symboles */ + get_all_routines_fc get_all_routines; /* Liste de routines détectées */ }; diff --git a/src/format/exe_format.c b/src/format/exe_format.c index 8a03243..be0e1f1 100644 --- a/src/format/exe_format.c +++ b/src/format/exe_format.c @@ -178,6 +178,31 @@ void delete_bin_part(bin_part *part) } +/****************************************************************************** +* * +* Paramètres : a = premières informations à consulter. * +* b = secondes informations à consulter. * +* * +* Description : Etablit la comparaison entre deux blocs binaires. * +* * +* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int compare_bin_parts(const bin_part **a, const bin_part **b) +{ + int result; /* Bilan à renvoyer */ + + if ((*a)->offset < (*b)->offset) result = -1; + else if((*a)->offset > (*b)->offset) result = 1; + else result = 0; + + return result; + +} + @@ -378,3 +403,23 @@ bool resolve_exe_symbol(const exe_format *format, char **label, SymbolType *type return format->resolve_symbol(format, label, type, offset); } + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = taille du tableau créé. [OUT] * +* * +* Description : Fournit le prototype de toutes les routines détectées. * +* * +* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bin_routine **get_all_exe_routines(const exe_format *format, size_t *count) +{ + return format->get_all_routines(format, count); + +} diff --git a/src/format/exe_format.h b/src/format/exe_format.h index 4fedf13..48cb989 100644 --- a/src/format/exe_format.h +++ b/src/format/exe_format.h @@ -30,6 +30,9 @@ #include +#include "../analysis/prototype.h" + + /* ------------------------ MANIPULATION DES PARTIES DE CODE ------------------------ */ @@ -53,6 +56,9 @@ void get_bin_part_values(const bin_part *, off_t *, off_t *, uint64_t *); /* Supprime de la mémoire une description de partie de code. */ void delete_bin_part(bin_part *); +/* Etablit la comparaison entre deux blocs binaires. */ +int compare_bin_parts(const bin_part **, const bin_part **); + @@ -117,6 +123,9 @@ size_t get_exe_resolved_items(const exe_format *, char ***, ResolvedType **, uin /* Recherche le symbole correspondant à une adresse. */ bool resolve_exe_symbol(const exe_format *, char **, SymbolType *, uint64_t *); +/* Fournit le prototype de toutes les routines détectées. */ +bin_routine **get_all_exe_routines(const exe_format *, size_t *); + #endif /* _FORMAT_EXE_FORMAT_H */ -- cgit v0.11.2-87-g4458