From 39116dce7d40dab310e929f92fdbfc865b5fac20 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 8 Dec 2017 21:50:56 +0100 Subject: Introduced the symbol visibility. --- ChangeLog | 20 ++++++++++++++ plugins/elf/symbols.c | 60 ++++++++++++++++++++++++---------------- plugins/pychrysa/format/symbol.c | 36 ++++++++++++++++++++++++ src/analysis/disass/output.c | 27 +++++++++++------- src/analysis/disass/routines.c | 7 +++++ src/format/format.c | 2 +- src/format/symbol-int.h | 1 + src/format/symbol.c | 41 +++++++++++++++++++++++++++ src/format/symbol.h | 18 ++++++++++++ src/gui/panels/symbols.c | 16 +++++++++-- src/panels/strings.c | 2 ++ 11 files changed, 192 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cc6a93..07987e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 17-12-08 Cyrille Bagard + * plugins/elf/symbols.c: + Load imported symbols. + + * plugins/pychrysa/format/symbol.c: + * src/analysis/disass/output.c: + * src/analysis/disass/routines.c: + * src/format/format.c: + Update code. + + * src/format/symbol-int.h: + * src/format/symbol.c: + * src/format/symbol.h: + Introduce the symbol visibility. + + * src/gui/panels/symbols.c: + * src/panels/strings.c: + Update code. + +17-12-08 Cyrille Bagard + * plugins/pychrysa/arch/vmpa.c: Update the comparison features for the Python bindings. diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c index 292913b..b5dc2b8 100644 --- a/plugins/elf/symbols.c +++ b/plugins/elf/symbols.c @@ -521,6 +521,8 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for { bool result; /* Bilan à retourner */ elf_sym sym; /* Symbole aux infos visées */ + SymbolStatus status; /* Visibilité du symbole */ + vmpa2t addr; /* Localisation d'un symbole */ virt_t virt; /* Adresse virtuelle */ const elf_shdr *section; /* Groupe de sections trouvées */ bool use_virt; /* Choix de construction de nom*/ @@ -529,7 +531,6 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for phys_t first; /* Position du premier élément */ const char *name; /* Nom du symbole trouvé */ GBinFormat *base; /* Version basique du format */ - vmpa2t addr; /* Localisation d'une routine */ GBinSymbol *symbol; /* Nouveau symbole construit */ char alt_name[6 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/ virt_t final_virt; /* Adresse virtuelle retenue */ @@ -539,23 +540,23 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for result = read_elf_symbol(format, iter, &sym); if (!result) goto geslp_done; - /* On rejette les symboles qui ne sont pas définis au sein du binaire */ - - if (ELF_SYM(format, sym, st_shndx) == 0) goto geslp_done; - - /* Résolution précise d'adresse */ - - virt = ELF_SYM(format, sym, st_value); - if (virt == 0) goto geslp_done; + /* Nature de la visibilité et adresse associée */ + if (ELF_SYM(format, sym, st_shndx) == 0) + { + status = SSS_IMPORTED; + init_vmpa(&addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); - /* TODO */ - - //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value)); + } + else + { + status = SSS_EXPORTED; - //init_mrange(&range, &addr, 0); + virt = ELF_SYM(format, sym, st_value); + if (virt == 0) goto geslp_done; + } /* Première ébauche de nom */ @@ -611,18 +612,25 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for /* Ajustement de la position */ - if (ELF_HDR(format, format->header, e_machine) == EM_ARM) - final_virt = virt & ~0x1; - else - final_virt = virt; + if (status == SSS_IMPORTED) + init_mrange(&range, &addr, 0); - if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr)) + else { - symbol = NULL; - break; - } + if (ELF_HDR(format, format->header, e_machine) == EM_ARM) + final_virt = virt & ~0x1; + else + final_virt = virt; + + if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr)) + { + symbol = NULL; + break; + } + + init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); - init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); + } /* Création d'un nom unique ? */ @@ -644,8 +652,6 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for routine = try_to_demangle_routine(name); symbol = G_BIN_SYMBOL(routine); - g_binary_symbol_set_range(symbol, &range); - /* Comptabilisation pour le désassemblage brut */ g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false); @@ -659,8 +665,14 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for } if (symbol != NULL) + { + g_binary_symbol_set_range(symbol, &range); + g_binary_symbol_set_status(symbol, status); + g_binary_format_add_symbol(base, symbol); + } + geslp_done: return result; diff --git a/plugins/pychrysa/format/symbol.c b/plugins/pychrysa/format/symbol.c index b9ac13c..736a8d2 100644 --- a/plugins/pychrysa/format/symbol.c +++ b/plugins/pychrysa/format/symbol.c @@ -57,6 +57,9 @@ static PyObject *py_binary_symbol_get_label(PyObject *, void *); /* Fournit l'emplacement où se situe un symbole. */ static PyObject *py_binary_symbol_get_range(PyObject *, void *); +/* Fournit la visibilité du symbole. */ +static PyObject *py_binary_symbol_get_status(PyObject *, void *); + /* Définit les constantes pour les symboles binaires. */ static bool py_binary_symbol_define_constants(PyTypeObject *); @@ -285,6 +288,35 @@ static PyObject *py_binary_symbol_get_range(PyObject *self, void *closure) /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la visibilité du symbole. * +* * +* Retour : Etat de la visibilité du symbole représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_symbol_get_status(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBinSymbol *symbol; /* Elément à consulter */ + SymbolStatus status; /* Visibilité du symbole fourni*/ + + symbol = G_BIN_SYMBOL(pygobject_get(self)); + status = g_binary_symbol_get_status(symbol); + + result = PyLong_FromLong(status); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : obj_type = type dont le dictionnaire est à compléter. * * * * Description : Définit les constantes pour les symboles binaires. * @@ -351,6 +383,10 @@ PyTypeObject *get_python_binary_symbol_type(void) "range", py_binary_symbol_get_range, NULL, "Range covered by the symbol.", NULL }, + { + "status", py_binary_symbol_get_status, NULL, + "Status of the symbol's visibility.", NULL + }, { NULL } }; diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 8e74d1c..f9656cf 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -81,6 +81,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, GBorderGenerator *border; /* Délimitation de routine */ const vmpa2t *paddr; /* Adresse de portion */ GLineGenerator *generator; /* Générateur de contenu ajouté*/ + SymbolStatus sym_status; /* Visibilité du symbole obtenu*/ const vmpa2t *saddr; /* Adresse de symbole */ int compared; /* Bilan d'une comparaison */ char *errmsg; /* Description d'une erreur */ @@ -210,13 +211,21 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, else { iaddr = get_mrange_addr(g_arch_instruction_get_range(instr)); - saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])); - /* On écarte les symboles qu'on ne sait pas réintroduire */ - for (compared = cmp_vmpa(iaddr, saddr); - compared > 0; - compared = cmp_vmpa(iaddr, saddr)) + for ( ; sym_index < sym_count; sym_index++) { + sym_status = g_binary_symbol_get_status(symbols[sym_index]); + + if (sym_status == SSS_IMPORTED) + continue; + + saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])); + + compared = cmp_vmpa(iaddr, saddr); + + if (compared <= 0) + break; + log_variadic_message(LMT_BAD_BINARY, _("Unable to find a proper location for symbol '%s' @ 0x%08x"), g_binary_symbol_get_label(symbols[sym_index]), get_phy_addr(saddr)); @@ -230,13 +239,11 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, _missing++; - if (++sym_index == sym_count) - goto no_more_symbol_finally; - - saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])); - } + if (sym_index == sym_count) + goto no_more_symbol_finally; + if (compared == 0) { /* Coupure pour une nouvelle routine */ diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c index 01a6e48..63a32cf 100644 --- a/src/analysis/disass/routines.c +++ b/src/analysis/disass/routines.c @@ -233,11 +233,18 @@ static void g_routines_study_process(GRoutinesStudy *study, GtkStatusStack *stat { size_t i; /* Boucle de parcours */ GBinSymbol *symbol; /* Commodité d'accès */ + SymbolStatus sym_status; /* Visibilité du symbole obtenu*/ SymbolType type; /* Type de symbole rencontré */ for (i = study->begin; i < study->end; i++) { symbol = study->symbols[i]; + + sym_status = g_binary_symbol_get_status(symbol); + + if (sym_status == SSS_IMPORTED) + continue; + type = g_binary_symbol_get_target_type(symbol); if (type == STP_ROUTINE || type == STP_ENTRY_POINT) diff --git a/src/format/format.c b/src/format/format.c index 8b1bf0a..ec8e5fb 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -407,7 +407,7 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol) range = g_binary_symbol_get_range(symbol); addr = get_mrange_addr(range); - assert(has_phys_addr(addr)); + assert(has_phys_addr(addr) || g_binary_symbol_get_status(symbol) == SSS_IMPORTED); #endif g_rw_lock_writer_lock(&format->syms_lock); diff --git a/src/format/symbol-int.h b/src/format/symbol-int.h index 49a0b97..a0460c2 100644 --- a/src/format/symbol-int.h +++ b/src/format/symbol-int.h @@ -41,6 +41,7 @@ struct _GBinSymbol mrange_t range; /* Couverture mémoire */ SymbolType type; /* Type du symbole */ + SymbolStatus status; /* Visibilité du symbole */ char *alt; /* Nom alternatif */ diff --git a/src/format/symbol.c b/src/format/symbol.c index 0b300bd..099b764 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -123,6 +123,8 @@ static void g_binary_symbol_init(GBinSymbol *symbol) { g_binary_symbol_set_target_type(symbol, STP_COUNT); + g_binary_symbol_set_status(symbol, SSS_INTERNAL); + } @@ -345,6 +347,45 @@ SymbolType g_binary_symbol_get_target_type(const GBinSymbol *symbol) /****************************************************************************** * * +* Paramètres : symbol = symbole à venir modifier. * +* status = état de la visibilité du symbole représenté. * +* * +* Description : Définit la visibilité du symbole. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_symbol_set_status(GBinSymbol *symbol, SymbolStatus status) +{ + symbol->status = status; + +} + + +/****************************************************************************** +* * +* Paramètres : symbol = symbole à venir consulter. * +* * +* Description : Fournit la visibilité du symbole. * +* * +* Retour : Etat de la visibilité du symbole représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +SymbolStatus g_binary_symbol_get_status(const GBinSymbol *symbol) +{ + return symbol->status; + +} + + +/****************************************************************************** +* * * Paramètres : symbol = symbole à venir consulter. * * * * Description : Fournit une étiquette pour viser un symbole. * diff --git a/src/format/symbol.h b/src/format/symbol.h index da51262..8aabfdf 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -51,6 +51,18 @@ typedef enum _SymbolType } SymbolType; +/* Visibilité du symbole */ +typedef enum _SymbolStatus +{ + SSS_INTERNAL, /* Visibilité nulle */ + SSS_EXPORTED, /* Disponibilité extérieure */ + SSS_IMPORTED, /* Besoin interne */ + + SSS_COUNT + +} SymbolStatus; + + #define G_TYPE_BIN_SYMBOL g_binary_symbol_get_type() #define G_BIN_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_symbol_get_type(), GBinSymbol)) #define G_IS_BIN_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_symbol_get_type())) @@ -90,6 +102,12 @@ void g_binary_symbol_set_target_type(GBinSymbol *, SymbolType); /* Fournit le type du symbole. */ SymbolType g_binary_symbol_get_target_type(const GBinSymbol *); +/* Définit la visibilité du symbole. */ +void g_binary_symbol_set_status(GBinSymbol *, SymbolStatus); + +/* Fournit la visibilité du symbole. */ +SymbolStatus g_binary_symbol_get_status(const GBinSymbol *); + /* Fournit une étiquette pour viser un symbole. */ const char *g_binary_symbol_get_label(GBinSymbol *); diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index 3b01f24..f64f087 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -1064,15 +1064,25 @@ static void do_filtering_on_symbols(GSymbolsPanel *panel) static bool is_symbol_matching(GSymbolsPanel *panel, const GBinSymbol *symbol, regmatch_t *match) { bool result; /* Bilan à retourner */ + SymbolStatus status; /* Visibilité du symbole obtenu*/ SymbolType type; /* Type associé au symbole */ - type = g_binary_symbol_get_target_type(symbol); + status = g_binary_symbol_get_status(symbol); - if (type != STP_ROUTINE && type != STP_ENTRY_POINT && type != STP_OBJECT) + if (status == SSS_IMPORTED) result = false; else - result = is_content_matching(panel->filter, g_binary_symbol_get_label(symbol), match); + { + type = g_binary_symbol_get_target_type(symbol); + + if (type != STP_ROUTINE && type != STP_ENTRY_POINT && type != STP_OBJECT) + result = false; + + else + result = is_content_matching(panel->filter, g_binary_symbol_get_label(symbol), match); + + } return result; diff --git a/src/panels/strings.c b/src/panels/strings.c index c7fd393..c60ef0a 100644 --- a/src/panels/strings.c +++ b/src/panels/strings.c @@ -135,6 +135,8 @@ void handle_new_exe_on_strings_panel(GtkWidget *panel, const GExeFormat *format) for (i = 0; i < count; i++) { + if (g_binary_symbol_get_status(symbols[i]) == SSS_IMPORTED) continue; + if (g_binary_symbol_get_target_type(symbols[i]) != STP_STRING) continue; range = g_binary_symbol_get_range(symbols[i]); -- cgit v0.11.2-87-g4458