From 198c7874ccb79ce14c338b4e5d9f7b8b6ccb9f04 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 8 Apr 2021 23:31:24 +0200 Subject: Fortify access to the PE directories. --- plugins/pe/format.c | 21 ++++++++++++++++----- plugins/pe/pe-int.c | 20 ++++++++++++++++---- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/plugins/pe/format.c b/plugins/pe/format.c index f5bdac1..3839063 100644 --- a/plugins/pe/format.c +++ b/plugins/pe/format.c @@ -722,14 +722,23 @@ const image_data_directory *g_pe_format_get_directories(const GPeFormat *format, { const image_data_directory *result; /* Liste à retourner */ - if (count != NULL) - *count = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; - if (g_pe_format_get_is_32b(format)) + { result = format->nt_headers.optional_header.header_32.data_directory; + + if (count != NULL) + *count = format->nt_headers.optional_header.header_32.number_of_rva_and_sizes; + + } else + { result = format->nt_headers.optional_header.header_64.data_directory; + if (count != NULL) + *count = format->nt_headers.optional_header.header_64.number_of_rva_and_sizes; + + } + return result; } @@ -751,6 +760,7 @@ const image_data_directory *g_pe_format_get_directories(const GPeFormat *format, void *g_pe_format_get_directory(const GPeFormat *format, size_t index) { void *result; /* Données à retourner */ + size_t max; /* Quantité de répertoires */ const image_data_directory *dir; /* Localisation du répertoire */ vmpa2t pos; /* Tête de lecture */ bool status; /* Bilan d'un traitement */ @@ -760,10 +770,11 @@ void *g_pe_format_get_directory(const GPeFormat *format, size_t index) result = NULL; - if (index >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES) + dir = g_pe_format_get_directories(format, &max); + + if (index >= max) goto exit; - dir = g_pe_format_get_directories(format, NULL); dir += index; status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), dir->virtual_address, &pos); diff --git a/plugins/pe/pe-int.c b/plugins/pe/pe-int.c index db09c15..4104ce1 100644 --- a/plugins/pe/pe-int.c +++ b/plugins/pe/pe-int.c @@ -27,7 +27,9 @@ #include #include +#include #include +#include @@ -145,7 +147,7 @@ bool read_pe_optional_header(const GPeFormat *format, vmpa2t *pos, image_optiona image_optional_header_32 *hdr32; /* Version 32 bits */ image_optional_header_64 *hdr64; /* Version 64 bits */ image_data_directory *directories; /* Répertoires à charger */ - uint32_t number_of_rva_and_sizes; /* Quantité de ces répertoires */ + uint32_t *number_of_rva_and_sizes; /* Quantité de ces répertoires */ uint32_t i; /* Boucle de parcours */ content = G_KNOWN_FORMAT(format)->content; @@ -194,7 +196,7 @@ bool read_pe_optional_header(const GPeFormat *format, vmpa2t *pos, image_optiona if (result) result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &hdr32->number_of_rva_and_sizes); directories = hdr32->data_directory; - number_of_rva_and_sizes = hdr32->number_of_rva_and_sizes; + number_of_rva_and_sizes = &hdr32->number_of_rva_and_sizes; } else @@ -235,11 +237,21 @@ bool read_pe_optional_header(const GPeFormat *format, vmpa2t *pos, image_optiona if (result) result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &hdr64->number_of_rva_and_sizes); directories = hdr64->data_directory; - number_of_rva_and_sizes = hdr64->number_of_rva_and_sizes; + number_of_rva_and_sizes = &hdr64->number_of_rva_and_sizes; } - for (i = 0; i < number_of_rva_and_sizes && result; i++) + if (result && *number_of_rva_and_sizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES) + { + log_variadic_message(LMT_BAD_BINARY, + _("Corrupted number of directories (%u); fixed!"), + *number_of_rva_and_sizes); + + *number_of_rva_and_sizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + + } + + for (i = 0; i < *number_of_rva_and_sizes && result; i++) { result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &directories[i].virtual_address); if (result) result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &directories[i].size); -- cgit v0.11.2-87-g4458