summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/disass/area.c6
-rw-r--r--src/analysis/disass/links.c19
-rw-r--r--src/arch/arm/v7/post.c10
-rw-r--r--src/arch/dalvik/link.c24
-rw-r--r--src/arch/link.c21
-rw-r--r--src/arch/post.c2
-rw-r--r--src/arch/target.c37
-rw-r--r--src/arch/target.h4
-rw-r--r--src/format/elf/symbols.c2
-rw-r--r--src/format/format.c50
-rw-r--r--src/gui/menus/edition.c27
11 files changed, 122 insertions, 80 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 7eacc29..389dd75 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -484,6 +484,9 @@ static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr)
}
+ if (found)
+ g_object_unref(G_OBJECT(symbol));
+
}
@@ -632,7 +635,10 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
has_new_sym = g_binary_format_find_symbol_at(format, &sym_addr, &symbol);
if (has_new_sym)
+ {
insert_extra_symbol_into_mem_areas(list, count, symbol);
+ g_object_unref(G_OBJECT(symbol));
+ }
}
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 77ec2af..d3434cb 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -139,6 +139,7 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index,
GImmOperand *imm; /* Version native de l'opérande*/
virt_t addr; /* Adresse visée par le saut */
MemoryDataSize msize; /* Taille de l'opérande */
+ vmpa2t target; /* Défination finale précise */
GArchOperand *new; /* Instruction de ciblage */
op = g_arch_instruction_get_operand(instr, index);
@@ -152,12 +153,16 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index,
{
msize = g_imm_operand_get_size(imm);
- new = g_target_operand_new(msize, addr);
+ if (g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target))
+ {
+ new = g_target_operand_new(msize, &target);
+
+ if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format, false))
+ g_object_unref(G_OBJECT(new));
+ else
+ g_arch_instruction_replace_operand(instr, new, op);
- if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format, false))
- g_object_unref(G_OBJECT(new));
- else
- g_arch_instruction_replace_operand(instr, new, op);
+ }
}
@@ -184,7 +189,6 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format
size_t count; /* Nombre d'opérandes présents */
size_t i; /* Boucle de parcours */
GArchOperand *op; /* Opérande numérique en place */
- virt_t virt; /* Adresse liée à une cible */
vmpa2t addr; /* Localisation plus complète */
GArchInstruction *target; /* Instruction visée au final */
@@ -203,8 +207,7 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format
op = g_arch_instruction_get_operand(instr, i);
if (!G_IS_TARGET_OPERAND(op)) continue;
- virt = g_target_operand_get_addr(G_TARGET_OPERAND(op));
- init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+ g_target_operand_get_addr(G_TARGET_OPERAND(op), &addr);
target = g_arch_processor_find_instr_by_address(proc, &addr);
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index 4037c05..5ac3c62 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -49,10 +49,10 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
uint32_t addr; /* Adresse visée par le saut */
GBinFormat *bfmt; /* Version basique du format */
GArchOperand *new; /* Instruction de ciblage */
- vmpa2t target;
+ vmpa2t target; /* Défination finale précise */
mrange_t trange; /* Etendue du symbole à créer */
- VMPA_BUFFER(loc);
- char name[5 + VMPA_MAX_LEN];
+ VMPA_BUFFER(loc); /* Espace pour une conversion */
+ char name[5 + VMPA_MAX_LEN]; /* Etiquette à constituer */
GBinRoutine *routine; /* Nouvelle routine trouvée */
GBinSymbol *symbol; /* Nouveau symbole construit */
@@ -67,7 +67,7 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
{
bfmt = G_BIN_FORMAT(format);
- new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
+ new = g_target_operand_new(MDS_32_BITS_UNSIGNED, &target);
if (!g_target_operand_resolve(G_TARGET_OPERAND(new), bfmt, true))
{
@@ -88,8 +88,6 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
g_binary_symbol_attach_routine(symbol, routine);
g_binary_format_add_symbol(bfmt, symbol);
-
-
g_target_operand_resolve(G_TARGET_OPERAND(new), bfmt, true);
}
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c
index 3295c76..f92541b 100644
--- a/src/arch/dalvik/link.c
+++ b/src/arch/dalvik/link.c
@@ -80,8 +80,9 @@ typedef struct _case_comment
void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GExeFormat *format)
{
GArchOperand *op; /* Opérande numérique en place */
- virt_t virt; /* Adresse virtuelle */
+ bool defined; /* Adresse définie ? */
vmpa2t addr; /* Adresse de destination */
+ virt_t virt; /* Adresse virtuelle */
GArchInstruction *switch_ins; /* Instruction de branchements */
const mrange_t *range; /* Zone d'occupation */
const vmpa2t *start_addr; /* Adresse de référentiel */
@@ -104,24 +105,25 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
op = g_arch_instruction_get_operand(instr, 1);
- virt = VMPA_NO_VIRTUAL;
+ defined = false;
if (G_IS_TARGET_OPERAND(op))
- virt = g_target_operand_get_addr(G_TARGET_OPERAND(op));
+ {
+ g_target_operand_get_addr(G_TARGET_OPERAND(op), &addr);
+ defined = true;
+ }
else if (G_IS_IMM_OPERAND(op))
{
- if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
- virt = VMPA_NO_VIRTUAL;
+ if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+ {
+ init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+ defined = true;
+ }
}
- if (virt != VMPA_NO_VIRTUAL)
+ if (defined)
{
- /* TODO : utiliser format pour contruire une adresse avec une position physique,
- * ce qui accélèrerait les recherches.
- */
- init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
-
switch_ins = g_arch_processor_find_instr_by_address(proc, &addr);
if (G_IS_DALVIK_SWITCH_INSTR(switch_ins))
diff --git a/src/arch/link.c b/src/arch/link.c
index 8b02aa8..0e11521 100644
--- a/src/arch/link.c
+++ b/src/arch/link.c
@@ -95,8 +95,9 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GExeFormat *format, size_t index)
{
GArchOperand *op; /* Opérande numérique en place */
- virt_t virt; /* Adresse virtuelle */
+ bool defined; /* Adresse définie ? */
vmpa2t addr; /* Adresse de destination */
+ virt_t virt; /* Adresse virtuelle */
instr_iter_t *iter; /* Parcours d'instructions */
GArchInstruction *target; /* Ligne visée par la référence*/
@@ -104,21 +105,25 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
op = g_arch_instruction_get_operand(instr, index);
- virt = VMPA_NO_VIRTUAL;
+ defined = false;
if (G_IS_TARGET_OPERAND(op))
- virt = g_target_operand_get_addr(G_TARGET_OPERAND(op));
+ {
+ g_target_operand_get_addr(G_TARGET_OPERAND(op), &addr);
+ defined = true;
+ }
else if (G_IS_IMM_OPERAND(op))
{
- if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
- virt = VMPA_NO_VIRTUAL;
+ if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+ {
+ init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+ defined = true;
+ }
}
- if (virt != VMPA_NO_VIRTUAL)
+ if (defined)
{
- init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
-
iter = g_arch_processor_get_iter_from_address(proc, &addr);
if (iter != NULL)
diff --git a/src/arch/post.c b/src/arch/post.c
index 9a296d4..59ed40e 100644
--- a/src/arch/post.c
+++ b/src/arch/post.c
@@ -73,7 +73,7 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro
ptr_size = g_arch_processor_get_memory_size(proc);
- new = g_target_operand_new(ptr_size, addr);
+ new = g_target_operand_new(ptr_size, &target);
if (!g_target_operand_resolve(G_TARGET_OPERAND(new), bfmt, true))
{
diff --git a/src/arch/target.c b/src/arch/target.c
index 4655351..63ae295 100644
--- a/src/arch/target.c
+++ b/src/arch/target.c
@@ -43,7 +43,7 @@ struct _GTargetOperand
GArchOperand parent; /* Instance parente */
MemoryDataSize size; /* Taille de l'opérande */
- virt_t addr; /* Adresse de l'élément visé */
+ vmpa2t addr; /* Adresse de l'élément visé */
GBinSymbol *symbol; /* Eventuel symbole associé */
phys_t diff; /* Position dans le symbole */
@@ -171,7 +171,7 @@ static void g_target_operand_finalize(GTargetOperand *operand)
/******************************************************************************
* *
* Paramètres : size = taille des adresse mémoire virtuelles. *
-* addr = adresse virtuelle d'un élément à retrouver. *
+* addr = localisation d'un élément à retrouver. *
* *
* Description : Crée un opérande réprésentant une valeur numérique. *
* *
@@ -181,14 +181,14 @@ static void g_target_operand_finalize(GTargetOperand *operand)
* *
******************************************************************************/
-GArchOperand *g_target_operand_new(MemoryDataSize size, virt_t addr)
+GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)
{
GTargetOperand *result; /* Opérande à retourner */
result = g_object_new(G_TYPE_TARGET_OPERAND, NULL);
result->size = size;
- result->addr = addr;
+ copy_vmpa(&result->addr, addr);
return G_ARCH_OPERAND(result);
@@ -240,8 +240,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
}
else
{
- init_vmpa(&tmp, VMPA_NO_PHYSICAL, operand->addr);
- vmpa2_virt_to_string(&tmp, operand->size, value, &len);
+ vmpa2_virt_to_string(&operand->addr, operand->size, value, &len);
g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand));
@@ -271,19 +270,20 @@ MemoryDataSize g_target_operand_get_size(const GTargetOperand *operand)
/******************************************************************************
* *
-* Paramètres : operand = structure dont le contenu est à définir. *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* addr = localisation à renseigner. [OUT] *
* *
* Description : Fournit l'adresse en mémoire de l'élément visé. *
* *
-* Retour : Adresse en mémoire virtuelle associée. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-virt_t g_target_operand_get_addr(const GTargetOperand *operand)
+void g_target_operand_get_addr(const GTargetOperand *operand, vmpa2t *addr)
{
- return operand->addr;
+ copy_vmpa(addr, &operand->addr);
}
@@ -305,17 +305,11 @@ virt_t g_target_operand_get_addr(const GTargetOperand *operand)
bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool strict)
{
bool result; /* Bilan à retourner */
- vmpa2t addr; /* Adresse de recherche */
if (operand->symbol != NULL)
g_object_unref(G_OBJECT(operand->symbol));
- operand->symbol = NULL;
- operand->diff = 0;
-
- init_vmpa(&addr, VMPA_NO_PHYSICAL, operand->addr);
-
- result = g_binary_format_resolve_symbol(format, &addr, strict, &operand->symbol, &operand->diff);
+ result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff);
return result;
@@ -337,9 +331,16 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool
GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *diff)
{
+ GBinSymbol *result; /* Symbole associé à retourner */
+
if (diff != NULL)
*diff = operand->diff;
- return operand->symbol;
+ result = operand->symbol;
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ return result;
}
diff --git a/src/arch/target.h b/src/arch/target.h
index e1ea173..529dba8 100644
--- a/src/arch/target.h
+++ b/src/arch/target.h
@@ -55,13 +55,13 @@ typedef struct _GTargetOperandClass GTargetOperandClass;
GType g_target_operand_get_type(void);
/* Crée un opérande réprésentant une valeur numérique. */
-GArchOperand *g_target_operand_new(MemoryDataSize, virt_t);
+GArchOperand *g_target_operand_new(MemoryDataSize, const vmpa2t *);
/* Renseigne la taille de la valeur indiquée à la construction. */
MemoryDataSize g_target_operand_get_size(const GTargetOperand *);
/* Fournit l'adresse en mémoire de l'élément visé. */
-virt_t g_target_operand_get_addr(const GTargetOperand *);
+void g_target_operand_get_addr(const GTargetOperand *, vmpa2t *);
/* Tente une résolution de symbole. */
bool g_target_operand_resolve(GTargetOperand *, GBinFormat *, bool);
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index b936a47..8451911 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -215,6 +215,8 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
_g_binary_symbol_attach_routine(symbol, routine, STP_ENTRY_POINT);
+ g_object_unref(G_OBJECT(symbol));
+
}
else
{
diff --git a/src/format/format.c b/src/format/format.c
index 550e816..327b28e 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -297,21 +297,29 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
GBinRoutine *routine; /* Nouvelle routine à insérer */
/**
- * Lorsque les fonctions de recherche type g_binary_format_find_symbol_at()
- * sont appelées avec une localisation, cette dernière peut reposer soit sur
- * une position physique soit une adresse virtuelle uniquement.
+ * Pour que les fonctions de recherche basées sur _g_binary_format_find_symbol()
+ * fassent bien leur office, il faut que les symboles soient triés.
*
- * Pour que les comparaisons de positions puissent se réaliser, il faut donc
- * pouvoir satisfaire les deux aspects : physiques et virtuels.
+ * Cependant, les localisations à satisfaire lors d'une recherche recontrent
+ * un problème si les positions physiques ne sont pas renseignées. En effet
+ * les adresses virtuelles en sont potentiellement décorrélées (c'est le cas
+ * avec le format ELF par exemple, où les zones en mémoire ne suivent pas le
+ * même ordre que les segments du binaire).
*
- * On corrige donc le tir si besoin est ici.
+ * Comme les comparaisons entre localisations se réalisent sur les éléments
+ * renseignés communs, à commencer par la position physique si c'est possible,
+ * une localisation s'appuyant uniquement sur une adresse virtuelle va être
+ * analysée suivant une liste non triée d'adresses virtuelles.
+ *
+ * On corrige donc le tir si besoin est en forçant la comparaison via les
+ * positions physiques.
*/
#ifndef NDEBUG
range = g_binary_symbol_get_range(symbol);
addr = get_mrange_addr(range);
- assert(!is_invalid_vmpa(addr));
+ assert(has_phys_addr(addr));
#endif
g_rw_lock_writer_lock(&format->syms_lock);
@@ -684,9 +692,12 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t
bool result; /* Bilan à retourner */
void *found; /* Résultat de recherches */
- result = false;
+ /**
+ * Pour ce qui est des justifications quant à la vérification suivante,
+ * se référer aux commentaires placés dans g_binary_format_add_symbol().
+ */
- *symbol = NULL; /* TODO : vérifier les doublons côtés appelants */
+ assert(has_phys_addr(addr));
found = bsearch(addr, format->symbols, format->symbols_count, sizeof(GBinSymbol *), fn);
@@ -695,13 +706,22 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t
if (index != NULL)
*index = (GBinSymbol **)found - format->symbols;
- *symbol = *(GBinSymbol **)found;
+ if (symbol != NULL)
+ {
+ *symbol = *(GBinSymbol **)found;
+ g_object_ref(G_OBJECT(*symbol));
+ }
- g_object_ref(G_OBJECT(*symbol));
result = true;
}
+ else
+ {
+ *symbol = NULL;
+ result = false;
+ }
+
return result;
}
@@ -816,7 +836,7 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *format, const vmpa2t *addr,
g_rw_lock_reader_lock(&format->syms_lock);
- result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, &index, symbol);
+ result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, &index, NULL);
if (result && (index + 1) < format->symbols_count)
{
@@ -826,7 +846,10 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *format, const vmpa2t *addr,
}
else
+ {
+ *symbol = NULL;
result = false;
+ }
g_rw_lock_reader_unlock(&format->syms_lock);
@@ -870,6 +893,9 @@ bool g_binary_format_resolve_symbol(GBinFormat *format, const vmpa2t *addr, bool
}
+ else
+ *diff = 0;
+
return result;
}
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index 9c01a6b..31fbc0d 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -434,8 +434,9 @@ static void mcb_edition_follow_ref(GtkMenuItem *menuitem, GMenuBar *bar)
GtkDisplayPanel *panel; /* Afficheur effectif de code */
GBufferLine *line; /* Ligne de position courante */
GObject *creator; /* Créateur à l'orgine du seg. */
- virt_t virt; /* Adresse virtuelle */
+ bool defined; /* Adresse définie ? */
vmpa2t addr; /* Adresse de destination */
+ virt_t virt; /* Adresse virtuelle */
panel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar));
@@ -443,27 +444,25 @@ static void mcb_edition_follow_ref(GtkMenuItem *menuitem, GMenuBar *bar)
{
assert(creator != NULL);
- /**
- * On fait le pari de reposer uniquement sur des adresses virtuelles !
- * A changer dans un futur ?
- */
-
- virt = VMPA_NO_VIRTUAL;
+ defined = false;
if (G_IS_TARGET_OPERAND(creator))
- virt = g_target_operand_get_addr(G_TARGET_OPERAND(creator));
+ {
+ g_target_operand_get_addr(G_TARGET_OPERAND(creator), &addr);
+ defined = true;
+ }
else if (G_IS_IMM_OPERAND(creator))
{
- if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(creator), &virt))
- virt = VMPA_NO_VIRTUAL;
+ if (g_imm_operand_to_virt_t(G_IMM_OPERAND(creator), &virt))
+ {
+ init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+ defined = true;
+ }
}
- if (virt != VMPA_NO_VIRTUAL)
- {
- init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+ if (defined)
gtk_display_panel_request_move(panel, &addr);
- }
g_object_unref(creator);
g_object_unref(G_OBJECT(line));