summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2019-08-05 16:25:06 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2019-08-05 16:25:06 +0200
commit0ae3da416103e2d47bb944bcaaa33e2bf736d96c (patch)
treef460a283824eb6589cba0c091974b6fd046dcd43 /src
parent94fa96ce3f72d03dd4e113eadc2043872bc07664 (diff)
PhotoRec: avoid potential integer overflow while parsing exe files
Diffstat (limited to 'src')
-rw-r--r--src/file_exe.c171
1 files changed, 86 insertions, 85 deletions
diff --git a/src/file_exe.c b/src/file_exe.c
index 1348db5..12f1400 100644
--- a/src/file_exe.c
+++ b/src/file_exe.c
@@ -37,7 +37,6 @@
#include "log.h"
static void register_header_check_exe(file_stat_t *file_stat);
-static int header_check_exe(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new);
static void file_rename_pe_exe(file_recovery_t *file_recovery);
const file_hint_t file_hint_exe= {
@@ -51,122 +50,119 @@ const file_hint_t file_hint_exe= {
static const unsigned char exe_header[2] = {'M','Z'};
-static void register_header_check_exe(file_stat_t *file_stat)
-{
- register_header_check(0, exe_header,sizeof(exe_header), &header_check_exe, file_stat);
-}
-
static int header_check_exe(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
{
const struct dos_image_file_hdr *dos_hdr=(const struct dos_image_file_hdr*)buffer;
- const struct pe_image_file_hdr *pe_hdr;
if(memcmp(buffer,exe_header,sizeof(exe_header))!=0)
return 0;
- pe_hdr=(const struct pe_image_file_hdr *)(buffer+le32(dos_hdr->e_lfanew));
if(le32(dos_hdr->e_lfanew)>0 &&
- le32(dos_hdr->e_lfanew) <= buffer_size-sizeof(struct pe_image_file_hdr) &&
- (le32(pe_hdr->Magic) & 0xffff) == IMAGE_WIN16_SIGNATURE)
+ le32(dos_hdr->e_lfanew) <= buffer_size-sizeof(struct pe_image_file_hdr))
{
- /* NE Win16 */
- reset_file_recovery(file_recovery_new);
- file_recovery_new->extension=file_hint_exe.extension;
- return 1;
- }
- if(le32(dos_hdr->e_lfanew)>0 &&
- le32(dos_hdr->e_lfanew) <= buffer_size-sizeof(struct pe_image_file_hdr) &&
- (le32(pe_hdr->Magic) & 0xffff) == IMAGE_NT_SIGNATURE)
- {
- /* Windows PE */
- if(le16(pe_hdr->Characteristics) & 0x2000)
- {
- /* Dynamic Link Library */
- reset_file_recovery(file_recovery_new);
- file_recovery_new->extension="dll";
- }
- else if(le16(pe_hdr->Characteristics) & 0x02)
+ const struct pe_image_file_hdr *pe_hdr=(const struct pe_image_file_hdr *)(buffer+le32(dos_hdr->e_lfanew));
+ if((le32(pe_hdr->Magic) & 0xffff) == IMAGE_WIN16_SIGNATURE)
{
+ /* NE Win16 */
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_exe.extension;
+ return 1;
}
- else
+ if((le32(pe_hdr->Magic) & 0xffff) == IMAGE_NT_SIGNATURE)
{
+ /* Windows PE */
+ if(le16(pe_hdr->Characteristics) & 0x2000)
+ {
+ /* Dynamic Link Library */
+ reset_file_recovery(file_recovery_new);
+ file_recovery_new->extension="dll";
+ }
+ else if(le16(pe_hdr->Characteristics) & 0x02)
+ {
+ reset_file_recovery(file_recovery_new);
+ file_recovery_new->extension=file_hint_exe.extension;
+ }
+ else
+ {
#ifdef DEBUG_EXE
- log_warning("EXE rejected, bad characteristics %02x\n", le16(pe_hdr->Characteristics));
+ log_warning("EXE rejected, bad characteristics %02x\n", le16(pe_hdr->Characteristics));
#endif
- return 0;
- }
- file_recovery_new->time=le32(pe_hdr->TimeDateStamp);
-#ifdef DEBUG_EXE
- {
- const struct pe_image_optional_hdr32 *pe_image_optional32=(const struct pe_image_optional_hdr32 *)
- (((const unsigned char*)pe_hdr + sizeof(struct pe_image_file_hdr)));
- if(le16(pe_image_optional32->Magic)==IMAGE_NT_OPTIONAL_HDR_MAGIC)
- {
- log_debug("SizeOfCode %lx\n", (long unsigned)le32(pe_image_optional32->SizeOfCode));
- log_debug("SizeOfImage %lx\n", (long unsigned)le32(pe_image_optional32->SizeOfImage));
+ return 0;
}
- else if(le16(pe_image_optional32->Magic)==IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+ file_recovery_new->time=le32(pe_hdr->TimeDateStamp);
+#ifdef DEBUG_EXE
{
- const struct pe_image_optional_hdr64 *pe_image_optional64=(const struct pe_image_optional_hdr64 *)
+ const struct pe_image_optional_hdr32 *pe_image_optional32=(const struct pe_image_optional_hdr32 *)
(((const unsigned char*)pe_hdr + sizeof(struct pe_image_file_hdr)));
+ if(le16(pe_image_optional32->Magic)==IMAGE_NT_OPTIONAL_HDR_MAGIC)
+ {
+ log_debug("SizeOfCode %lx\n", (long unsigned)le32(pe_image_optional32->SizeOfCode));
+ log_debug("SizeOfImage %lx\n", (long unsigned)le32(pe_image_optional32->SizeOfImage));
+ }
+ else if(le16(pe_image_optional32->Magic)==IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+ {
+ const struct pe_image_optional_hdr64 *pe_image_optional64=(const struct pe_image_optional_hdr64 *)
+ (((const unsigned char*)pe_hdr + sizeof(struct pe_image_file_hdr)));
+ }
+ log_debug("PE image opt 0x%lx-0x%lx\n", (long unsigned)sizeof(struct pe_image_file_hdr),
+ (long unsigned)(sizeof(struct pe_image_file_hdr) + le16(pe_hdr->SizeOfOptionalHeader) - 1));
}
- log_debug("PE image opt 0x%lx-0x%lx\n", (long unsigned)sizeof(struct pe_image_file_hdr),
- (long unsigned)(sizeof(struct pe_image_file_hdr) + le16(pe_hdr->SizeOfOptionalHeader) - 1));
- }
#endif
- {
- unsigned int i;
- uint64_t sum=0;
- const struct pe_image_section_hdr *pe_image_section=(const struct pe_image_section_hdr*)
- ((const unsigned char*)pe_hdr + sizeof(struct pe_image_file_hdr) + le16(pe_hdr->SizeOfOptionalHeader));
- for(i=0;
- i<le16(pe_hdr->NumberOfSections) &&
- (const unsigned char*)(pe_image_section+1) <= buffer+buffer_size;
- i++,pe_image_section++)
{
- if(le32(pe_image_section->SizeOfRawData)>0)
+ unsigned int i;
+ uint64_t sum=0;
+ const struct pe_image_section_hdr *pe_image_section=(const struct pe_image_section_hdr*)
+ ((const unsigned char*)pe_hdr + sizeof(struct pe_image_file_hdr) + le16(pe_hdr->SizeOfOptionalHeader));
+ for(i=0;
+ i<le16(pe_hdr->NumberOfSections) &&
+ (const unsigned char*)(pe_image_section+1) <= buffer+buffer_size;
+ i++,pe_image_section++)
{
+ if(le32(pe_image_section->SizeOfRawData)>0)
+ {
+ const uint64_t tmp=(uint64_t)le32(pe_image_section->PointerToRawData) + le32(pe_image_section->SizeOfRawData);
#ifdef DEBUG_EXE
- log_debug("%s 0x%lx-0x%lx\n", pe_image_section->Name,
- (unsigned long)le32(pe_image_section->PointerToRawData),
- (unsigned long)le32(pe_image_section->PointerToRawData)+le32(pe_image_section->SizeOfRawData)-1);
+ log_debug("%s 0x%lx-0x%lx\n", pe_image_section->Name,
+ (unsigned long)le32(pe_image_section->PointerToRawData),
+ (unsigned long)(tmp-1));
#endif
- if(le32(pe_image_section->SizeOfRawData)%32==0)
- {
- if(sum < le32(pe_image_section->PointerToRawData) + le32(pe_image_section->SizeOfRawData))
- sum=le32(pe_image_section->PointerToRawData) + le32(pe_image_section->SizeOfRawData);
+ if(le32(pe_image_section->SizeOfRawData)%32==0)
+ {
+ if(sum < tmp)
+ sum=tmp;
+ }
}
- }
- if(le16(pe_image_section->NumberOfRelocations)>0)
- {
+ if(le16(pe_image_section->NumberOfRelocations)>0)
+ {
+ const uint64_t tmp=(uint64_t)le32(pe_image_section->PointerToRelocations)+ 1*le16(pe_image_section->NumberOfRelocations);
#ifdef DEBUG_EXE
- log_debug("relocations 0x%lx-0x%lx\n",
- (unsigned long)le32(pe_image_section->PointerToRelocations),
- (unsigned long)le32(pe_image_section->PointerToRelocations)+1*le16(pe_image_section->NumberOfRelocations)-1);
+ log_debug("relocations 0x%lx-0x%lx\n",
+ (unsigned long)le32(pe_image_section->PointerToRelocations),
+ (unsigned long)(tmp-1));
#endif
- if(sum < le32(pe_image_section->PointerToRelocations)+ 1*le16(pe_image_section->NumberOfRelocations))
- sum = le32(pe_image_section->PointerToRelocations)+ 1*le16(pe_image_section->NumberOfRelocations);
+ if(sum < tmp)
+ sum = tmp;
+ }
}
- }
- if(le32(pe_hdr->NumberOfSymbols)>0)
- {
+ if(le32(pe_hdr->NumberOfSymbols)>0)
+ {
+ const uint64_t tmp=(uint64_t)le32(pe_hdr->PointerToSymbolTable)+ IMAGE_SIZEOF_SYMBOL*(uint64_t)le32(pe_hdr->NumberOfSymbols);
#ifdef DEBUG_EXE
- log_debug("Symboles 0x%lx-0x%lx\n", (long unsigned)le32(pe_hdr->PointerToSymbolTable),
- (long unsigned)(le32(pe_hdr->PointerToSymbolTable)+ IMAGE_SIZEOF_SYMBOL*le32(pe_hdr->NumberOfSymbols))-1);
+ log_debug("Symboles 0x%lx-0x%lx\n", (long unsigned)le32(pe_hdr->PointerToSymbolTable),
+ (long unsigned)(tmp-1));
#endif
- if(le32(pe_hdr->NumberOfSymbols)<0x10000)
- {
- if(sum < le32(pe_hdr->PointerToSymbolTable)+ IMAGE_SIZEOF_SYMBOL*le32(pe_hdr->NumberOfSymbols))
- sum = le32(pe_hdr->PointerToSymbolTable)+ IMAGE_SIZEOF_SYMBOL*le32(pe_hdr->NumberOfSymbols);
+ if(le32(pe_hdr->NumberOfSymbols)<0x10000)
+ {
+ if(sum < tmp)
+ sum = tmp;
+ }
}
+ /* It's not perfect, EXE overlay are not recovered */
+ file_recovery_new->calculated_file_size=sum;
}
- /* It's not perfect, EXE overlay are not recovered */
- file_recovery_new->calculated_file_size=sum;
+ file_recovery_new->data_check=&data_check_size;
+ file_recovery_new->file_check=&file_check_size;
+ file_recovery_new->file_rename=&file_rename_pe_exe;
+ return 1;
}
- file_recovery_new->data_check=&data_check_size;
- file_recovery_new->file_check=&file_check_size;
- file_recovery_new->file_rename=&file_rename_pe_exe;
- return 1;
}
if(le16(dos_hdr->bytes_in_last_block) <= 512 &&
le16(dos_hdr->blocks_in_file) > 0 &&
@@ -520,3 +516,8 @@ static void file_rename_pe_exe(file_recovery_t *file_recovery)
}
fclose(file);
}
+
+static void register_header_check_exe(file_stat_t *file_stat)
+{
+ register_header_check(0, exe_header,sizeof(exe_header), &header_check_exe, file_stat);
+}