summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-10-13 23:30:30 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-10-13 23:30:30 (GMT)
commit18beadb4192144b00c06769645befb17ae1ce98e (patch)
tree9d29be95f3343bf8126ca99c42907242ceb57714 /src/format
parent7800159c1dd6538f0ee9d026cf3f121a488dd647 (diff)
Kept all information about real addresses for routine symbols (ARM vs Thumb).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@593 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format')
-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
5 files changed, 115 insertions, 29 deletions
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 *);