From b8d5a539b1e6837f7395598a3fa25ef69650e885 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 29 Mar 2017 23:01:51 +0200 Subject: Handled areas which are not allocated in memory. --- ChangeLog | 38 ++++++++++++++++++++++++++++++++++++++ plugins/readelf/section.c | 3 ++- src/analysis/db/items/comment.c | 5 +---- src/analysis/db/items/move.c | 12 +++--------- src/analysis/db/items/switcher.c | 5 +---- src/analysis/disass/area.c | 19 ++++++++++++++----- src/arch/post.c | 2 +- src/arch/processor.c | 2 +- src/arch/target.c | 2 +- src/arch/vmpa.c | 29 +++++++++++++++++++++++++++++ src/arch/vmpa.h | 5 +++++ src/format/elf/elf.c | 3 --- src/format/executable-int.c | 20 +++++++++----------- src/format/executable.c | 7 ++++--- src/glibext/gbufferline.c | 21 ++++++++++++++------- 15 files changed, 123 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2c34438..4f92fe8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +17-03-29 Cyrille Bagard + + * plugins/readelf/section.c: + Delete a hardcoded virtual address and use usual translation instead. + + * src/analysis/db/items/comment.c: + * src/analysis/db/items/move.c: + * src/analysis/db/items/switcher.c: + Update code in order to not choose which part of locations to print here. + + * src/analysis/disass/area.c: + Handle areas which are not allocated in memory. + + * src/arch/post.c: + Update code in order to not choose which part of locations to print here. + + * src/arch/processor.c: + Update an assertion about virtual addresses. + + * src/arch/target.c: + Update code in order to not choose which part of locations to print here. + + * src/arch/vmpa.c: + * src/arch/vmpa.h: + Reset virtual addresses and output locations into strings when requested. + + * src/format/elf/elf.c: + Load ELF section which are not event allocated in memory. + + * src/format/executable-int.c: + Update code. + + * src/format/executable.c: + Mark the first part of binaries as not allocated. + + * src/glibext/gbufferline.c: + Update code. + 17-03-26 Cyrille Bagard * src/analysis/routine.c: diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c index 9410f69..89b13c4 100644 --- a/plugins/readelf/section.c +++ b/plugins/readelf/section.c @@ -414,7 +414,8 @@ bool annotate_elf_section_header_table(GElfFormat *format, GtkStatusStack *statu offset = ELF_HDR(format, *header, e_shoff); - init_vmpa(&pos, offset, 0x9900); + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos)) + return false; e_shnum = ELF_HDR(format, *header, e_shnum); diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index 50522d9..263f415 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -544,10 +544,7 @@ static void g_db_comment_build_label(GDbComment *comment) { VMPA_BUFFER(loc); /* Indication de position */ - if (has_virt_addr(&comment->addr)) - vmpa2_virt_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL); - else - vmpa2_phys_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL); + vmpa2_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL); if (is_rle_string_empty(&comment->text)) asprintf(&G_DB_ITEM(comment)->label, _("Delete comment at %s"), loc); diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c index f6e585d..4fd1667 100644 --- a/src/analysis/db/items/move.c +++ b/src/analysis/db/items/move.c @@ -388,15 +388,9 @@ static void g_db_move_build_label(GDbMove *move) VMPA_BUFFER(src_loc); /* Indication de position #1 */ VMPA_BUFFER(dest_loc); /* Indication de position #2 */ - if (has_virt_addr(&move->src)) - vmpa2_virt_to_string(&move->src, MDS_UNDEFINED, src_loc, NULL); - else - vmpa2_phys_to_string(&move->src, MDS_UNDEFINED, src_loc, NULL); - - if (has_virt_addr(&move->dest)) - vmpa2_virt_to_string(&move->dest, MDS_UNDEFINED, dest_loc, NULL); - else - vmpa2_phys_to_string(&move->dest, MDS_UNDEFINED, dest_loc, NULL); + vmpa2_to_string(&move->src, MDS_UNDEFINED, src_loc, NULL); + + vmpa2_to_string(&move->dest, MDS_UNDEFINED, dest_loc, NULL); asprintf(&G_DB_ITEM(move)->label, _("Move from %s to %s"), src_loc, dest_loc); diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index 9cd2a2e..b7957ff 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -449,10 +449,7 @@ static void g_db_switcher_build_label(GDbSwitcher *switcher) { VMPA_BUFFER(loc); /* Indication de position */ - if (has_virt_addr(&switcher->addr)) - vmpa2_virt_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL); - else - vmpa2_phys_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL); + vmpa2_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL); switch (switcher->display) { diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index bdfb1b2..5478fe3 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -947,6 +947,12 @@ void insert_extra_symbol_into_mem_areas(mem_area *areas, size_t count, const GBi } + /** + * Un symbole (au sens large) ne peut avoir une adresse virtuelle que s'il + * est compris dans une zone chargée en mémoire (en toute logique). + */ + assert(has_virt_addr(get_mrange_addr(&area->range)) == has_virt_addr(addr)); + /* L'instruction est-elle accueillie dans son intégralité ? */ start = compute_vmpa_diff(get_mrange_addr(&area->range), addr); @@ -1238,7 +1244,7 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac } - void fill_gap(vmpa2t *old, vmpa2t *new, bool exec) + void fill_gap(vmpa2t *old, vmpa2t *new, bool alloc, bool exec) { phys_t diff; /* Espace entre bordures */ mem_area *area; /* Zone avec valeurs à éditer */ @@ -1252,6 +1258,9 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac if (diff > 0) { + if (!alloc) + reset_virt_addr(old); + /* Zone tampon à constituer */ *list = (mem_area *)realloc(*list, ++(*count) * sizeof(mem_area)); @@ -1326,7 +1335,7 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac if (on_track) { rights = (parent != NULL ? g_binary_portion_get_rights(parent) : PAC_NONE); - fill_gap(&prev, &border, rights & PAC_EXEC); + fill_gap(&prev, &border, rights != PAC_NONE, rights & PAC_EXEC); } else copy_vmpa(&prev, &border); @@ -1342,12 +1351,12 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac if (on_track) { rights = (parent != NULL ? g_binary_portion_get_rights(parent) : PAC_NONE); - fill_gap(&prev, &border, rights & PAC_EXEC); + fill_gap(&prev, &border, rights != PAC_NONE, rights & PAC_EXEC); compute_mrange_end_addr(range, &border); rights = g_binary_portion_get_rights(portion); - fill_gap(&prev, &border, rights & PAC_EXEC); + fill_gap(&prev, &border, rights != PAC_NONE, rights & PAC_EXEC); } else @@ -1367,7 +1376,7 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac if (on_track) { rights = (parent != NULL ? g_binary_portion_get_rights(parent) : PAC_NONE); - fill_gap(&prev, &border, rights & PAC_EXEC); + fill_gap(&prev, &border, rights != PAC_NONE, rights & PAC_EXEC); } else copy_vmpa(&prev, &border); diff --git a/src/arch/post.c b/src/arch/post.c index 9973dd3..5c7ed13 100644 --- a/src/arch/post.c +++ b/src/arch/post.c @@ -79,7 +79,7 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro if (!g_target_operand_resolve(G_TARGET_OPERAND(new), bfmt, true)) { - vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL); + vmpa2_to_string(&target, MDS_UNDEFINED, loc, NULL); switch (type) { diff --git a/src/arch/processor.c b/src/arch/processor.c index 3a049b1..38c39e6 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -314,7 +314,7 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc GArchInstruction *result; /* Instruction à renvoyer */ vmpa2t back; /* Position sauvegardée */ - assert(has_phys_addr(pos) && has_virt_addr(pos)); + assert(has_phys_addr(pos)); copy_vmpa(&back, pos); diff --git a/src/arch/target.c b/src/arch/target.c index bce00a7..896b9f7 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -245,7 +245,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l } else { - vmpa2_virt_to_string(&operand->addr, operand->size, value, &len); + vmpa2_to_string(&operand->addr, operand->size, value, &len); g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand)); diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index f344101..dc1804c 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -530,6 +530,35 @@ char *vmpa2_virt_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer /****************************************************************************** * * +* Paramètres : addr = adresse virtuelle ou physique à traiter. * +* msize = taille de cette adresse, réelle ou désirée. * +* buffer = tampon de sortie utilisé à constituer. [OUT] * +* length = transmission de la taille du résultat ou NULL. [OUT]* +* * +* Description : Transforme une localisation en chaîne de caractères. * +* * +* Retour : Chaîne de caractères constituée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *vmpa2_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer[VMPA_MAX_LEN], size_t *length) +{ + char *result; /* Résultat à retourner */ + + if (has_virt_addr(addr)) + result = vmpa2_virt_to_string(addr, msize, buffer, length); + else + result = vmpa2_phys_to_string(addr, msize, buffer, length); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : buffer = chaîne de caractères à consulter. * * * * Description : Transforme une chaîne de caractères en position physique. * diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 3bfb40c..48f61a8 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -107,6 +107,8 @@ int cmp_vmpa(const vmpa2t *, const vmpa2t *); #define is_invalid_vmpa(a) (!has_phys_addr(a) && !has_virt_addr(a)) +#define reset_virt_addr(a) (a)->virtual = VMPA_NO_VIRTUAL + #define dup_vmpa(src) \ make_vmpa(get_phy_addr(src), get_virt_addr(src)) @@ -134,6 +136,9 @@ char *vmpa2_phys_to_string(const vmpa2t *, MemoryDataSize, char [VMPA_MAX_LEN], /* Transforme une adresse virtuelle en chaîne de caractères. */ char *vmpa2_virt_to_string(const vmpa2t *, MemoryDataSize, char [VMPA_MAX_LEN], size_t *); +/* Transforme une localisation en chaîne de caractères. */ +char *vmpa2_to_string(const vmpa2t *, MemoryDataSize, char [VMPA_MAX_LEN], size_t *); + /* Transforme une chaîne de caractères en position physique. */ vmpa2t *string_to_vmpa_phy(const char *); diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index e874c86..0ad90ff 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -490,9 +490,6 @@ static void g_elf_format_refine_portions(GElfFormat *format) sh_flags = ELF_SHDR(format, shdr, sh_flags); - if ((sh_flags & SHF_ALLOC) == 0) - continue; - if (sh_flags & SHF_EXECINSTR) background = BPC_CODE; else if (sh_flags & SHF_WRITE) background = BPC_DATA; else background = BPC_DATA_RO; diff --git a/src/format/executable-int.c b/src/format/executable-int.c index eff3d39..ebea16e 100644 --- a/src/format/executable-int.c +++ b/src/format/executable-int.c @@ -41,13 +41,7 @@ bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExeFormat *format, phys_t off, vmpa2t *pos) { - /** - * On ne peut pas initialiser la partie virtuelle à VMPA_NO_VIRTUAL - * car les manipulations au niveau des formats (par exemple, cf. la fonction - * g_binary_format_add_symbol()) attendent des définitions complètes. - */ - - init_vmpa(pos, off, off); + init_vmpa(pos, off, VMPA_NO_VIRTUAL); return true; @@ -71,12 +65,16 @@ bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExeFormat *form bool g_exe_format_without_virt_translate_address_into_vmpa(const GExeFormat *format, virt_t addr, vmpa2t *pos) { /** - * Comme les sauts dans le code sont considérés en mémoire virtuelle, - * on tolère la considération de champs virtuels même si l'architecture n'en - * a pas la définition. + * S'il n'y a pas de notion de mémoire virtuelle, positions physiques et + * adresses virtuelles se confondent. + * + * On reste néanmoins cohérent, et on n'utilise donc pas d'adresse virtuelle. + * + * Les sauts dans le code renvoient de façon transparente vers des positions + * physiques. */ - init_vmpa(pos, addr, addr); + init_vmpa(pos, addr, VMPA_NO_VIRTUAL); return true; diff --git a/src/format/executable.c b/src/format/executable.c index 0153f69..3d3847c 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -24,7 +24,6 @@ #include "executable.h" -#include #include #include @@ -267,8 +266,10 @@ bool g_executable_format_complete_loading(GExeFormat *format, GtkStatusStack *st if (result) { - result = g_exe_format_translate_offset_into_vmpa(format, 0, &addr); - assert(result); + /** + * Avant de lire l'entête du format, on ne sait pas où on se trouve ! + */ + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); length = g_binary_content_compute_size(base->content); diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index 8c8f4f6..d8ed7ed 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -352,16 +352,23 @@ void g_buffer_line_fill_virt(GBufferLine *line, MemoryDataSize size, const vmpa2 vmpa2_virt_to_string(addr, size, position, &len); - for (i = 2; i < len; i++) - if (position[i] != '0') break; + if (has_virt_addr(addr)) + { + for (i = 2; i < len; i++) + if (position[i] != '0') break; - if (i == len) - i = len - 1; + if (i == len) + i = len - 1; - if (i > 0) - g_buffer_line_append_text(line, BLC_VIRTUAL, position, i, RTT_PHYS_ADDR_PAD, NULL); + if (i > 0) + g_buffer_line_append_text(line, BLC_VIRTUAL, position, i, RTT_PHYS_ADDR_PAD, NULL); + + g_buffer_line_append_text(line, BLC_VIRTUAL, &position[i], len - i, RTT_PHYS_ADDR, NULL); - g_buffer_line_append_text(line, BLC_VIRTUAL, &position[i], len - i, RTT_PHYS_ADDR, NULL); + } + + else + g_buffer_line_append_text(line, BLC_VIRTUAL, position, len, RTT_PHYS_ADDR_PAD, NULL); } -- cgit v0.11.2-87-g4458