summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--src/analysis/disass/output.c5
-rw-r--r--src/format/elf/symbols.c103
-rw-r--r--src/format/format.c140
-rw-r--r--src/format/format.h6
-rw-r--r--src/gui/panels/symbols.c4
6 files changed, 225 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 479f470..17dce96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,19 @@
-15-04-25 Cyrille Bagard <nocbos@gmail.com>
+115-04-26 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/disass/output.c:
+ Give more information about not found symbols.
+
+ * src/format/elf/symbols.c:
+ Load internal smybols ; create entry points only when needed.
+
+ * src/format/format.c:
+ * src/format/format.h:
+ Allow to remove symbols and/or routines.
+
+ * src/gui/panels/symbols.c
+ Display entry points as symbols too.
+
+115-04-25 Cyrille Bagard <nocbos@gmail.com>
* src/analysis/disass/macro.c:
Use an uniq coverage memory for all visited branches.
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index f2c49bb..324975b 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -188,8 +188,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
compared > 0;
compared = cmp_vmpa(iaddr, saddr))
{
- log_variadic_message(LMT_BAD_BINARY, _("Unable to find a proper location for symbol '%s'"),
- g_binary_symbol_to_string(symbols[sym_index]));
+ 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_virt_addr(saddr));
if (++sym_index == sym_count)
goto no_more_symbol_finally;
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index b57c601..4c1811f 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -93,7 +93,7 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *);
-#include <stdlib.h>
+
/******************************************************************************
* *
@@ -116,18 +116,10 @@ bool load_elf_symbols(GElfFormat *format)
result = true;
+ /* Symboles internes */
+ result &= load_elf_internal_symbols(format);
- result &= load_all_elf_basic_entry_points(format);
-
-
-
-
-
- /* Symboles internes */
-#if 0
- result = load_elf_internal_symbols(format);
-#endif
@@ -149,34 +141,9 @@ bool load_elf_symbols(GElfFormat *format)
- qsort(G_BIN_FORMAT(format)->symbols, G_BIN_FORMAT(format)->symbols_count,
- sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp);
+ /* Symboles d'entrée, si encore besoin */
-#if 0
-
- const vmpa2t *saddr; /* Adresse de symbole */
- size_t i; /* Boucle de parcours #2 */
- GBinSymbol **symbols; /* Symboles à représenter */
-
- symbols = G_BIN_FORMAT(format)->symbols;
-
- for (i = 0; i < G_BIN_FORMAT(format)->symbols_count; i++)
- {
- saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[i]));
- if (saddr == NULL) continue;
-
- //if (g_binary_symbol_to_string(symbols[i]) == NULL) continue;
-
- printf(" <symbol % 2zu> '% 22s'-> 0x%08lx 0x%08lx\n",
- i,
- g_binary_symbol_to_string(symbols[i]),
- saddr->physical,
- saddr->virtual);
-
- }
-
- //exit(0);
-#endif
+ result &= load_all_elf_basic_entry_points(format);
return result;
@@ -220,13 +187,31 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
init_vmpa(&addr, VMPA_NO_PHYSICAL, vaddr);
- init_mrange(&range, &addr, len);
+ if (g_binary_format_find_symbol_at(format, &addr, &symbol))
+ {
+ g_object_unref(G_OBJECT(routine));
+
+ routine = g_binary_symbol_get_routine(symbol);
+ g_object_ref(G_OBJECT(routine));
+
+ printf(" -- SYM CHANGE @ 0x%08x\n", vaddr);
- g_binary_routine_set_range(routine, &range);
+ _g_binary_symbol_attach_routine(symbol, routine, STP_ENTRY_POINT);
+
+ }
+ else
+ {
+ printf(" -- SYM ENTRY @ 0x%08x\n", vaddr);
- symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0);
- g_binary_symbol_attach_routine(symbol, routine);
- g_binary_format_add_symbol(base, symbol);
+ init_mrange(&range, &addr, len);
+
+ g_binary_routine_set_range(routine, &range);
+
+ symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0);
+ g_binary_symbol_attach_routine(symbol, routine);
+ g_binary_format_add_symbol(base, symbol);
+
+ }
}
@@ -530,6 +515,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
off_t size; /* Taille de cette même zone */
off_t iter; /* Boucle de parcours */
elf_sym sym; /* Symbole aux infos visées */
+ virt_t virt; /* Adresse virtuelle */
vmpa2t addr; /* Localisation d'une routine */
mrange_t range; /* Couverture mémoire associée */
const char *name; /* Nom du symbole trouvé */
@@ -546,6 +532,21 @@ static bool load_elf_internal_symbols(GElfFormat *format)
result = read_elf_symbol(format, &iter, &sym);
if (!result) break;
+ /* On rejette les symboles qui ne sont pas définis au sein du binaire */
+ if (ELF_SYM(format, sym, st_shndx) == 0) continue;
+
+#if 0
+
+ Elf64_Word st_name; /* Symbol name (string tbl index) */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* Symbol visibility */
+ Elf64_Section st_shndx; /* Section index */
+ Elf64_Addr st_value; /* Symbol value */
+ Elf64_Xword st_size; /* Symbol size */
+
+#endif
+
+
if (ELF_SYM(format, sym, st_value) == 0) continue;
/* Résolution précise d'adresse */
@@ -553,10 +554,20 @@ static bool load_elf_internal_symbols(GElfFormat *format)
/* TODO */
- init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL);
+ //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value));
+
+ virt = ELF_SYM(format, sym, st_value);
+
+ if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
+ virt &= ~0x1;
+
+ if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
+ continue;
+
- init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
+ //init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
+ init_mrange(&range, &addr, 0);
/* Première ébauche de nom */
@@ -609,7 +620,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
/* Routine */
- printf("ADDING>> '%s'\n", name);
+ printf("SYM ADDING>> '%s'\n", name);
routine = try_to_demangle_routine(name);
diff --git a/src/format/format.c b/src/format/format.c
index 5478d3c..2256160 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -49,6 +49,9 @@ static void g_binary_format_class_init(GBinFormatClass *);
/* Initialise une instance de format binaire générique. */
static void g_binary_format_init(GBinFormat *);
+/* Retire un symbole de la collection du format binaire. */
+static void _g_binary_format_remove_symbol(GBinFormat *, size_t);
+
/* Indique le type défini pour un format binaire générique. */
@@ -222,6 +225,96 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
/******************************************************************************
* *
+* Paramètres : format = informations chargées à compléter. *
+* index = indice du symbole à retirer de la liste. *
+* *
+* Description : Retire un symbole de la collection du format binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void _g_binary_format_remove_symbol(GBinFormat *format, size_t index)
+{
+ GBinSymbol *symbol; /* Symbole visé par l'opération*/
+ GBinRoutine *routine; /* Eventuelle routine associée */
+ size_t i; /* Boucle de parcours */
+
+ /**
+ * TODO : envoyer un signal pour avertir les opérandes concernées.
+ */
+
+ symbol = format->symbols[index];
+
+ switch (g_binary_symbol_get_target_type(symbol))
+ {
+ case STP_ROUTINE:
+ case STP_ENTRY_POINT:
+
+ routine = g_binary_symbol_get_routine(symbol);
+
+ for (i = 0; i < format->routines_count; i++)
+ if (format->routines[i] == routine)
+ break;
+
+ assert(i < format->routines_count);
+
+ if ((i + 1) < format->routines_count)
+ memmove(&format->routines[i], &format->routines[i + 1],
+ (format->routines_count - i - 1) * sizeof(GBinRoutine *));
+
+ format->routines = (GBinRoutine **)realloc(format->routines,
+ --format->routines_count * sizeof(GBinRoutine *));
+
+ break;
+
+ default:
+ break;
+
+ }
+
+ assert(index < format->symbols_count);
+
+ if ((index + 1) < format->symbols_count)
+ memmove(&format->symbols[index], &format->symbols[index + 1],
+ (format->symbols_count - index - 1) * sizeof(GBinSymbol *));
+
+ format->symbols = (GBinSymbol **)realloc(format->symbols,
+ --format->symbols_count * sizeof(GBinSymbol *));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à compléter. *
+* symbol = symbole à retirer de la liste. *
+* *
+* Description : Retire un symbole de la collection du format binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < format->symbols_count; i++)
+ if (format->symbols[i] == symbol)
+ break;
+
+ _g_binary_format_remove_symbol(format, i);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = informations chargées à consulter. *
* count = taille du tableau créé. [OUT] *
* *
@@ -480,6 +573,53 @@ void g_binary_format_add_routine(GBinFormat *format, GBinRoutine *routine)
/******************************************************************************
* *
+* Paramètres : format = informations chargées à compléter. *
+* routine = routine à ajouter à la liste. *
+* *
+* Description : Retire une routine de la collection du format binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_format_remove_routine(GBinFormat *format, GBinRoutine *routine)
+{
+ size_t index; /* Indice trouvé à utiliser */
+ size_t i; /* Boucle de parcours */
+ GBinSymbol *symbol; /* Symbole en cours d'analyse */
+
+ index = format->symbols_count;
+
+ for (i = 0; i < format->symbols_count && index == format->symbols_count; i++)
+ {
+ symbol = format->symbols[i];
+
+ switch (g_binary_symbol_get_target_type(symbol))
+ {
+ case STP_ROUTINE:
+ case STP_ENTRY_POINT:
+
+ if (g_binary_symbol_get_routine(symbol) == routine)
+ index = i;
+
+ break;
+
+ default:
+ break;
+
+ }
+
+ }
+
+ _g_binary_format_remove_symbol(format, index);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = informations chargées à consulter. *
* count = taille du tableau créé. [OUT] *
* *
diff --git a/src/format/format.h b/src/format/format.h
index 38418b3..66f014b 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -67,6 +67,9 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContex
/* Ajoute un symbole à la collection du format binaire. */
void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
+/* Retire un symbole de la collection du format binaire. */
+void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *);
+
/* Fournit la liste de tous les symboles détectés. */
GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *);
@@ -85,6 +88,9 @@ bool g_binary_format_resolve_symbol(const GBinFormat *, const vmpa2t *, GBinSymb
/* Ajoute une routine à la collection du format binaire. */
void g_binary_format_add_routine(GBinFormat *, GBinRoutine *) __attribute__ ((deprecated));
+/* Retire une routine de la collection du format binaire. */
+void g_binary_format_remove_routine(GBinFormat *, GBinRoutine *);
+
/* Fournit le prototype de toutes les routines détectées. */
GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *);
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index b523cd2..42098c8 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -662,6 +662,7 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
switch (g_binary_symbol_get_target_type(symbols[i]))
{
case STP_ROUTINE:
+ case STP_ENTRY_POINT:
icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img;
break;
case STP_OBJECT:
@@ -843,6 +844,7 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
switch (g_binary_symbol_get_target_type(symbols[i]))
{
case STP_ROUTINE:
+ case STP_ENTRY_POINT:
icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img;
break;
case STP_OBJECT:
@@ -1044,7 +1046,7 @@ static bool is_symbol_filtered(GSymbolsPanel *panel, const GBinSymbol *symbol)
type = g_binary_symbol_get_target_type(symbol);
- if (type != STP_ROUTINE && type != STP_OBJECT)
+ if (type != STP_ROUTINE && type != STP_ENTRY_POINT && type != STP_OBJECT)
return true;
if (panel->filter == NULL)