From ed763539951307353042c04af5c2278db0d05298 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 16 Aug 2017 23:52:02 +0200 Subject: Ensured all registered binary portions are fully included in the file. --- ChangeLog | 14 +++++++++++++ plugins/mobicore/mclf.c | 40 ++++++++++++++++++++++++++++-------- src/format/dex/dex-int.c | 2 ++ src/format/dex/dex_def.h | 2 ++ src/format/dex/method.c | 2 +- src/format/elf/elf.c | 12 +++++++++-- src/format/executable.c | 52 ++++++++++++++++++++++++++++++++++++++--------- src/format/executable.h | 2 +- src/glibext/gbinportion.c | 15 +++++--------- 9 files changed, 109 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index dad8776..f4fddab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +17-08-16 Cyrille Bagard + + * plugins/mobicore/mclf.c: + * src/format/dex/dex-int.c: + * src/format/dex/dex_def.h: + * src/format/dex/method.c: + * src/format/elf/elf.c: + Update code. + + * src/format/executable.c: + * src/format/executable.h: + * src/glibext/gbinportion.c: + Ensure all registered binary portions are fully included in the file. + 17-08-15 Cyrille Bagard * src/analysis/contents/file.c: diff --git a/plugins/mobicore/mclf.c b/plugins/mobicore/mclf.c index 740e7b1..7697d15 100644 --- a/plugins/mobicore/mclf.c +++ b/plugins/mobicore/mclf.c @@ -270,6 +270,8 @@ static const char *g_mclf_format_get_target_machine(const GMCLFFormat *format) static void g_mclf_format_refine_portions(GMCLFFormat *format) { GExeFormat *exe_format; /* Autre version du format */ + phys_t offset; /* Position physique */ + vmpa2t origin; /* Origine d'une définition */ vmpa2t addr; /* Emplacement dans le binaire */ GBinPortion *new; /* Nouvelle portion définie */ char desc[MAX_PORTION_DESC]; /* Description d'une portion */ @@ -279,6 +281,18 @@ static void g_mclf_format_refine_portions(GMCLFFormat *format) /* Segment de code */ + offset = sizeof(uint32_t) /* magic */ \ + + sizeof(uint32_t) /* version */ \ + + sizeof(uint32_t) /* flags */ \ + + sizeof(uint32_t) /* mem_type */ \ + + sizeof(uint32_t) /* service_type */ \ + + sizeof(uint32_t) /* num_instances */ \ + + 16 /* uuid */ \ + + sizeof(uint32_t) /* driver_id */ \ + + sizeof(uint32_t); /* num_threads */ + + init_vmpa(&origin, offset, VMPA_NO_VIRTUAL); + init_vmpa(&addr, 0, format->header.v1.text.start); new = g_binary_portion_new(BPC_CODE, &addr, format->header.v1.text.len); @@ -288,10 +302,15 @@ static void g_mclf_format_refine_portions(GMCLFFormat *format) g_binary_portion_set_rights(new, PAC_WRITE | PAC_EXEC); - g_exe_format_include_portion(exe_format, new); + g_exe_format_include_portion(exe_format, new, &origin); /* Segment de données */ + offset += sizeof(uint32_t) /* start */ \ + + sizeof(uint32_t); /* len */ + + init_vmpa(&origin, offset, VMPA_NO_VIRTUAL); + init_vmpa(&addr, format->header.v1.text.len, format->header.v1.data.start); new = g_binary_portion_new(BPC_DATA, &addr, format->header.v1.data.len); @@ -301,20 +320,25 @@ static void g_mclf_format_refine_portions(GMCLFFormat *format) g_binary_portion_set_rights(new, PAC_READ | PAC_WRITE); - g_exe_format_include_portion(exe_format, new); + g_exe_format_include_portion(exe_format, new, &origin); /* Signature finale */ length = g_binary_content_compute_size(G_BIN_FORMAT(format)->content); - init_vmpa(&addr, length - 521, VMPA_NO_VIRTUAL); /* FIXME */ - new = g_binary_portion_new(BPC_DATA, &addr, 521); + if (length > 521) + { + init_vmpa(&addr, length - 521, VMPA_NO_VIRTUAL); + + new = g_binary_portion_new(BPC_DATA, &addr, 521); - sprintf(desc, "%s \"%s\"", _("Segment"), "sig"); - g_binary_portion_set_desc(new, desc); + sprintf(desc, "%s \"%s\"", _("Segment"), "sig"); + g_binary_portion_set_desc(new, desc); - g_binary_portion_set_rights(new, PAC_READ | PAC_WRITE); + g_binary_portion_set_rights(new, PAC_READ | PAC_WRITE); - g_exe_format_include_portion(exe_format, new); + g_exe_format_include_portion(exe_format, new, NULL); + + } } diff --git a/src/format/dex/dex-int.c b/src/format/dex/dex-int.c index 1626dde..c49445d 100644 --- a/src/format/dex/dex-int.c +++ b/src/format/dex/dex-int.c @@ -376,6 +376,8 @@ bool read_dex_encoded_method(const GDexFormat *format, vmpa2t *pos, encoded_meth content = G_BIN_FORMAT(format)->content; + copy_vmpa(&method->origin, pos); + result &= g_binary_content_read_uleb128(content, pos, &method->method_idx_diff); result &= g_binary_content_read_uleb128(content, pos, &method->access_flags); result &= g_binary_content_read_uleb128(content, pos, &method->code_off); diff --git a/src/format/dex/dex_def.h b/src/format/dex/dex_def.h index 8ddcf30..e1521e8 100755 --- a/src/format/dex/dex_def.h +++ b/src/format/dex/dex_def.h @@ -191,6 +191,8 @@ typedef struct _encoded_method uleb128_t access_flags; /* Conditions d'accès */ uleb128_t code_off; /* Position du code associé */ + vmpa2t origin; /* Rajout pour suivi interne */ + } encoded_method; /* Type quelconque */ diff --git a/src/format/dex/method.c b/src/format/dex/method.c index f487c0a..ec12119 100644 --- a/src/format/dex/method.c +++ b/src/format/dex/method.c @@ -387,7 +387,7 @@ void g_dex_method_include_as_portion(const GDexMethod *method, GExeFormat *forma g_binary_portion_set_rights(new, PAC_READ | PAC_EXEC); - g_exe_format_include_portion(format, new); + g_exe_format_include_portion(format, new, &method->info.origin); } diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 1ca81be..2ca3b8c 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -468,6 +468,7 @@ static void g_elf_format_refine_portions(GElfFormat *format) uint16_t max; /* Décompte d'éléments traités */ uint16_t i; /* Boucle de parcours */ off_t offset; /* Début de part de programme */ + vmpa2t origin; /* Origine d'une définition */ elf_phdr phdr; /* En-tête de programme ELF */ uint32_t p_flags; /* Droits associés à une partie*/ const char *background; /* Fond signigicatif */ @@ -506,6 +507,8 @@ static void g_elf_format_refine_portions(GElfFormat *format) offset = ELF_HDR(format, format->header, e_phoff) + ELF_HDR(format, format->header, e_phentsize) * i; + init_vmpa(&origin, offset, VMPA_NO_VIRTUAL); + if (!read_elf_program_header(format, offset, &phdr)) continue; @@ -535,7 +538,7 @@ static void g_elf_format_refine_portions(GElfFormat *format) g_binary_portion_set_rights(new, rights); - g_exe_format_include_portion(exe_format, new); + g_exe_format_include_portion(exe_format, new, &origin); } @@ -586,7 +589,12 @@ static void g_elf_format_refine_portions(GElfFormat *format) g_binary_portion_set_rights(new, rights); - g_exe_format_include_portion(exe_format, new); + offset = ELF_HDR(format, format->header, e_shoff) + + ELF_HDR(format, format->header, e_shentsize) * i; + + init_vmpa(&origin, offset, VMPA_NO_VIRTUAL); + + g_exe_format_include_portion(exe_format, new, &origin); } diff --git a/src/format/executable.c b/src/format/executable.c index f121f5b..ac67d62 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -24,7 +24,9 @@ #include "executable.h" +#include #include +#include #include @@ -330,6 +332,7 @@ bool g_executable_format_complete_loading(GExeFormat *format, GtkStatusStack *st * * * Paramètres : format = description de l'exécutable à modifier. * * portion = portion à inclure dans les définitions du format. * +* origin = source de définition de la portion fournie. * * * * Description : Procède à l'enregistrement d'une portion dans un format. * * * @@ -339,24 +342,53 @@ bool g_executable_format_complete_loading(GExeFormat *format, GtkStatusStack *st * * ******************************************************************************/ -void g_exe_format_include_portion(GExeFormat *format, GBinPortion *portion) +void g_exe_format_include_portion(GExeFormat *format, GBinPortion *portion, const vmpa2t *origin) { - phys_t max; /* Position hors limite */ + phys_t available; /* Taille totale du bianire */ + const mrange_t *range; /* Emplacement de la portion */ + phys_t start; /* Début de zone de la portion */ + char *msg; /* Description d'une erreur */ + phys_t remaining; /* Taille maximale envisageable*/ bool truncated; /* Modification faite ? */ - max = g_binary_content_compute_size(G_BIN_FORMAT(format)->content); + available = g_binary_content_compute_size(G_BIN_FORMAT(format)->content); - truncated = g_binary_portion_limit_range(portion, max); + range = g_binary_portion_get_range(portion); - if (truncated) - log_variadic_message(LMT_BAD_BINARY, _("Truncated binary portion '%s' to fit the binary content size!"), - g_binary_portion_get_desc(portion)); + start = get_phy_addr(get_mrange_addr(range)); - g_mutex_lock(&format->mutex); + if (start >= available) + { + assert(origin != NULL); - g_binary_portion_include(format->portions, portion); + asprintf(&msg, _("Defined binary portion '%s' is out of the file scope... Discarding!"), + g_binary_portion_get_desc(portion)); - g_mutex_unlock(&format->mutex); + g_binary_format_add_error(G_BIN_FORMAT(format), BFE_STRUCTURE, origin, msg); + + free(msg); + + g_object_unref(G_OBJECT(portion)); + + } + + else + { + remaining = available - start; + + truncated = g_binary_portion_limit_range(portion, remaining); + + if (truncated) + log_variadic_message(LMT_BAD_BINARY, _("Truncated binary portion '%s' to fit the binary content size!"), + g_binary_portion_get_desc(portion)); + + g_mutex_lock(&format->mutex); + + g_binary_portion_include(format->portions, portion); + + g_mutex_unlock(&format->mutex); + + } } diff --git a/src/format/executable.h b/src/format/executable.h index 985efb2..81e5e6c 100644 --- a/src/format/executable.h +++ b/src/format/executable.h @@ -68,7 +68,7 @@ const char *g_exe_format_get_target_machine(const GExeFormat *); bool g_exe_format_get_main_address(GExeFormat *, vmpa2t *); /* Procède à l'enregistrement d'une portion dans un format. */ -void g_exe_format_include_portion(GExeFormat *, GBinPortion *); +void g_exe_format_include_portion(GExeFormat *, GBinPortion *, const vmpa2t *); /* Fournit la première couche des portions composent le binaire. */ GBinPortion *g_exe_format_get_portions(GExeFormat *); diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c index 731cd08..c0e14fa 100644 --- a/src/glibext/gbinportion.c +++ b/src/glibext/gbinportion.c @@ -488,7 +488,7 @@ const mrange_t *g_binary_portion_get_range(const GBinPortion *portion) /****************************************************************************** * * * Paramètres : portion = description de partie à mettre à jour. * -* max = première position physique hors limite. * +* max = taille maximale accordée à la portion. * * * * Description : Assure qu'une portion ne dépasse pas une position donnée. * * * @@ -501,19 +501,14 @@ const mrange_t *g_binary_portion_get_range(const GBinPortion *portion) bool g_binary_portion_limit_range(GBinPortion *portion, phys_t max) { bool result; /* Bilan à retourner */ - vmpa2t end; /* Limite actuelle de portion */ - const vmpa2t *start; /* Position de départ */ + phys_t current; /* Taille courante */ - compute_mrange_end_addr(&portion->range, &end); + current = get_mrange_length(&portion->range); - result = get_phy_addr(&end) > max; + result = (current > max); if (result) - { - start = get_mrange_addr(&portion->range); - set_mrange_length(&portion->range, max - get_phy_addr(start)); - - } + set_mrange_length(&portion->range, max); return result; -- cgit v0.11.2-87-g4458