summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--src/analysis/disass/fetch.c40
-rw-r--r--src/format/elf/helper_arm.c14
-rw-r--r--src/format/elf/symbols.c74
-rw-r--r--src/format/format-int.h8
-rw-r--r--src/format/format.c45
-rw-r--r--src/format/format.h3
7 files changed, 133 insertions, 65 deletions
diff --git a/ChangeLog b/ChangeLog
index e36dd09..f594cba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+15-10-14 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/disass/fetch.c:
+ Update code.
+
+ * src/format/elf/helper_arm.c:
+ * src/format/elf/symbols.c:
+ Keep all information about real addresses for routine symbols (ARM vs Thumb).
+
+ * src/format/format.c:
+ * src/format/format.h:
+ * src/format/format-int.h:
+ Register all starting points for the disassembling process.
+
15-10-13 Cyrille Bagard <nocbos@gmail.com>
* src/analysis/binary.c:
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 9ebe231..67a6f3b 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -35,7 +35,7 @@
/* Suit un flot d'exécution pour désassembler du code. */
-static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *, virt_t);
+static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *);
/* S'assure que l'ensemble des aires est entièrement décodé. */
static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *);
@@ -50,7 +50,6 @@ static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoaded
* areas = liste de zones contenant des données à traiter. *
* count = nombre de ces aires à disposition. *
* info = informations liées à l'affichage de la progression. *
-* virt = adresse d'un point de départ d'un traitement. *
* *
* Description : Suit un flot d'exécution pour désassembler du code. *
* *
@@ -60,17 +59,13 @@ static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoaded
* *
******************************************************************************/
-static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info, virt_t virt)
+static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info)
{
+ virt_t virt; /* Adresse de départ dépilée */
vmpa2t addr; /* Conversion en pleine adresse*/
GExeFormat *format; /* Format du fichier binaire */
size_t index; /* Zone trouvée à traiter */
- printf("-- follow 0x%08x\n", (unsigned int)virt);
-
- if (virt == VMPA_NO_VIRTUAL)
- g_proc_context_push_drop_point(ctx, virt);
-
while (g_proc_context_has_drop_points(ctx))
{
virt = g_proc_context_pop_drop_point(ctx);
@@ -153,12 +148,6 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt
mem_area *areas; /* Zone de productions */
size_t count; /* Nombre de ces zones */
status_blob_info *info; /* Informations de progression */
- virt_t virt; /* Point d'accroche virtuelle */
- GBinSymbol **symbols; /* Symboles à représenter */
- size_t sym_count; /* Qté de symboles présents */
- size_t i; /* Boucle de parcours */
- const mrange_t *range; /* Couverture d'un symbole */
- const vmpa2t *addr; /* Point de départ du symbole */
double done; /* Portion de travail accompli */
format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
@@ -182,28 +171,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt
_("Disassembling following the execution flow..."),
0, length);
- /* Insertion des points de départ */
-
- follow_execution_flow(binary, ctx, &areas, &count, info, VMPA_NO_VIRTUAL);
-
- /* Symboles exécutables présents et passés à travers les mailles */
-
- symbols = g_binary_format_get_symbols(format, &sym_count);
-
- for (i = 0; i < sym_count; i++)
- {
- if (g_binary_symbol_get_target_type(symbols[i]) != STP_FUNCTION)
- continue;
-
- range = g_binary_symbol_get_range(symbols[i]);
- addr = get_mrange_addr(range);
- virt = get_virt_addr(addr);
-
- follow_execution_flow(binary, ctx, &areas, &count, info, virt);
-
- }
-
- printf(" ------------------------------------------- follow done\n");
+ follow_execution_flow(binary, ctx, &areas, &count, info);
done = get_current_progessive_status(info);
diff --git a/src/format/elf/helper_arm.c b/src/format/elf/helper_arm.c
index cd2d922..f47df5d 100644
--- a/src/format/elf/helper_arm.c
+++ b/src/format/elf/helper_arm.c
@@ -63,7 +63,9 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,
- virt_t virt; /* Adresse en mémoire virtuelle */
+ virt_t virt; /* Adresse en mémoire virtuelle*/
+ virt_t final_virt; /* Adresse virtuelle retenue */
+ bool status; /* Bilan d'une opération */
vmpa2t addr; /* Localisation d'une routine */
mrange_t range; /* Couverture mémoire associée */
GBinRoutine *routine; /* Nouvelle routine trouvée */
@@ -100,14 +102,14 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,
{
case R_ARM_JUMP_SLOT:
-
virt = ELF_SYM(format, sym, st_value);
-
-
if (virt == 0) continue;
+ final_virt = virt & ~0x1;
+
+ status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr);
+ if (!status) continue;
- init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
init_mrange(&range, &addr, 0);
routine = try_to_demangle_routine(name);
@@ -118,6 +120,8 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,
g_binary_symbol_attach_routine(symbol, routine);
g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+ /* Comptabilisation pour le désassemblage brut */
+ g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false);
/*
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index c3c2ecd..fa7cb8f 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -168,26 +168,25 @@ bool load_elf_symbols(GElfFormat *format)
static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t len, GBinRoutine *routine)
{
- GBinFormat *base; /* Version basique de l'instance */
- vmpa2t addr; /* Localisation d'une routine */
- mrange_t range; /* Couverture mémoire associée */
- GBinSymbol *symbol; /* Nouveau symbole construit */
-
- base = G_BIN_FORMAT(format);
+ GBinFormat *base; /* Version basique du format */
+ virt_t final_vaddr; /* Adresse virtuelle retenue */
+ bool status; /* Bilan d'une opération */
+ vmpa2t addr; /* Localisation d'une routine */
+ mrange_t range; /* Couverture mémoire associée */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
- /* Comptabilisation pour le désassemblage brut */
+ /* Localisation complète du symbole */
- base->entry_points = (virt_t *)realloc(base->entry_points, ++base->ep_count * sizeof(virt_t));
+ if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
+ final_vaddr = vaddr & ~0x1;
+ else
+ final_vaddr = vaddr;
- base->entry_points[base->ep_count - 1] = vaddr;
+ status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_vaddr, &addr);
+ if (!status) return;
/* Comptabilisation en tant que symbole */
- if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
- vaddr &= ~0x1;
-
- init_vmpa(&addr, VMPA_NO_PHYSICAL, vaddr);
-
if (g_binary_format_find_symbol_at(G_BIN_FORMAT(format), &addr, &symbol))
{
g_object_unref(G_OBJECT(routine));
@@ -200,6 +199,8 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
}
else
{
+ base = G_BIN_FORMAT(format);
+
init_mrange(&range, &addr, len);
g_binary_routine_set_range(routine, &range);
@@ -208,6 +209,9 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
g_binary_symbol_attach_routine(symbol, routine);
_g_binary_format_add_symbol(base, symbol, false);
+ /* Comptabilisation pour le désassemblage brut */
+ g_binary_format_register_code_point(base, vaddr, true);
+
}
}
@@ -513,6 +517,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
/* Charge tous les symboles définis dans une section */
bool add_all_symbols_from_section(GElfFormat *format, const elf_shdr *section, bool use_virt)
{
+ GBinFormat *base; /* Version basique du format */
elf_shdr strtab; /* Section .strtab trouvée */
bool has_strtab; /* Présence de cette section */
phys_t start; /* Début de la zone à traiter */
@@ -520,6 +525,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
phys_t iter; /* Boucle de parcours */
elf_sym sym; /* Symbole aux infos visées */
virt_t virt; /* Adresse virtuelle */
+ virt_t final_virt; /* Adresse virtuelle retenue */
vmpa2t addr; /* Localisation d'une routine */
mrange_t range; /* Couverture mémoire associée */
const char *name; /* Nom du symbole trouvé */
@@ -527,6 +533,8 @@ static bool load_elf_internal_symbols(GElfFormat *format)
GBinRoutine *routine; /* Nouvelle routine trouvée */
GBinSymbol *symbol; /* Nouveau symbole construit */
+ base = G_BIN_FORMAT(format);
+
has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, *section, sh_link), &strtab);
get_elf_section_content(format, section, &start, &size, NULL);
@@ -562,15 +570,6 @@ static bool load_elf_internal_symbols(GElfFormat *format)
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, 0);
@@ -586,6 +585,14 @@ static bool load_elf_internal_symbols(GElfFormat *format)
{
case STT_OBJECT:
+ /* Ajustement de la position */
+
+ if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
+ {
+ symbol = NULL;
+ break;
+ }
+
/* Création d'un nom unique ? */
if (name != NULL)
@@ -609,6 +616,21 @@ static bool load_elf_internal_symbols(GElfFormat *format)
case STT_FUNC:
+ /* Ajustement de la position */
+
+ 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));
+
/* Création d'un nom unique ? */
if (name != NULL)
@@ -635,6 +657,10 @@ static bool load_elf_internal_symbols(GElfFormat *format)
symbol = g_binary_symbol_new(STP_ROUTINE);
g_binary_symbol_attach_routine(symbol, routine);
+ /* Comptabilisation pour le désassemblage brut */
+
+ g_binary_format_register_code_point(base, virt, false);
+
break;
default:
@@ -644,7 +670,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
}
if (symbol != NULL)
- _g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol, false);
+ _g_binary_format_add_symbol(base, symbol, false);
}
diff --git a/src/format/format-int.h b/src/format/format-int.h
index 3e6ed9c..f97a4ad 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -36,6 +36,10 @@
typedef void (* format_decompile_fc) (const GBinFormat *, GCodeBuffer *, const char *);
+/* Rythme des allocations pour les entrées de code */
+#define EXTRA_POINT_BLOCK 100
+
+
/* Format binaire générique (instance) */
struct _GBinFormat
{
@@ -46,6 +50,10 @@ struct _GBinFormat
virt_t *entry_points; /* Points d'entrée du code */
size_t ep_count; /* Nombre de ces points */
+ virt_t *extra_points; /* Autres débuts de code */
+ size_t xp_allocated; /* Taille d'inscription allouée*/
+ size_t xp_count; /* Nombre de points enregistrés*/
+
GBinSymbol **symbols; /* Liste des symboles trouvés */
size_t symbols_count; /* Quantité de ces symboles */
GRWLock syms_lock; /* Accès à la liste de symboles*/
diff --git a/src/format/format.c b/src/format/format.c
index 6128c9a..9f03924 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -147,6 +147,48 @@ GBinContent *g_binary_format_get_content(const GBinFormat *format)
/******************************************************************************
* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* pt = point de l'espace mémoire à considérer. *
+* entry = nature du point fourni. *
+* *
+* Description : Enregistre une adresse comme début d'une zone de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool entry)
+{
+ if (entry)
+ {
+ format->entry_points = (virt_t *)realloc(format->entry_points,
+ ++format->ep_count * sizeof(virt_t));
+
+ format->entry_points[format->ep_count - 1] = pt;
+
+ }
+ else
+ {
+ if (format->xp_count == format->xp_allocated)
+ {
+ format->xp_allocated += EXTRA_POINT_BLOCK;
+
+ format->extra_points = (virt_t *)realloc(format->extra_points,
+ format->xp_allocated * sizeof(virt_t));
+
+ }
+
+ format->extra_points[format->xp_count++] = pt;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = description de l'exécutable à consulter. *
* ctx = contexte de désassemblage à préparer. *
* *
@@ -165,6 +207,9 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc
for (i = 0; i < format->ep_count; i++)
g_proc_context_push_drop_point(ctx, format->entry_points[i]);
+ for (i = 0; i < format->xp_count; i++)
+ g_proc_context_push_drop_point(ctx, format->extra_points[i]);
+
}
diff --git a/src/format/format.h b/src/format/format.h
index 8c06522..314306e 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -57,6 +57,9 @@ GType g_binary_format_get_type(void);
/* Fournit une référence vers le contenu binaire analysé. */
GBinContent *g_binary_format_get_content(const GBinFormat *);
+/* Enregistre une adresse comme début d'une zone de code. */
+void g_binary_format_register_code_point(GBinFormat *, virt_t, bool);
+
/* Fournit un contexte initialisé pour un désassemblage. */
void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContext *);