summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/pe/format.c21
-rw-r--r--plugins/pe/pe-int.c20
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 <malloc.h>
#include <string.h>
+#include <i18n.h>
#include <common/endianness.h>
+#include <core/logs.h>
@@ -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);