From 5d9dcb634b96cbab3753ee52ffdb60e990175b3c Mon Sep 17 00:00:00 2001 From: John Reiser Date: Wed, 8 Nov 2017 11:07:46 -0800 Subject: [PATCH] PeFile: Defend against bad crafted import descriptors https://github.com/upx/upx/issues/143 modified: pefile.cpp modified: pefile.h --- src/pefile.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++------ src/pefile.h | 15 +++++++++++---- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/pefile.cpp b/src/pefile.cpp index c764cab8..57ba4de0 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -547,12 +547,49 @@ void PeFile64::processRelocs() // pass1 // import handling **************************************************************************/ -__packed_struct(import_desc) - LE32 oft; // orig first thunk - char _[8]; - LE32 dllname; - LE32 iat; // import address table -__packed_struct_end() +//__packed_struct(import_desc) +// LE32 oft; // orig first thunk +// char _[8]; +// LE32 dllname; +// LE32 iat; // import address table +//__packed_struct_end() + +LE32& PeFile::IDSIZE(unsigned x) { + if ((file_size - sizeof(import_desc)) < iddirs[x].size) { + char buf[52]; + snprintf(buf,sizeof(buf),"bad import[%d].size %#x", + (unsigned)x, (unsigned)iddirs[x].size); + throwCantPack(buf); + } + return iddirs[x].size; +} +LE32& PeFile::IDADDR(unsigned x) { + if ((file_size - sizeof(import_desc)) < iddirs[x].vaddr) { + char buf[52]; + snprintf(buf,sizeof(buf),"bad import[%d].vaddr %#x", + (unsigned)x, (unsigned)iddirs[x].vaddr); + throwCantPack(buf); + } + return iddirs[x].vaddr; +} +LE32& PeFile::ODSIZE(unsigned x) { + if ((file_size - sizeof(import_desc)) < oddirs[x].size) { + char buf[52]; + snprintf(buf,sizeof(buf),"bad export[%d].size %#x", + (unsigned)x, (unsigned)oddirs[x].size); + throwCantPack(buf); + } + return oddirs[x].size; +} +LE32& PeFile::ODADDR(unsigned x) { + if ((file_size - sizeof(import_desc)) < oddirs[x].vaddr) { + char buf[52]; + snprintf(buf,sizeof(buf),"bad export[%d].vaddr %#x", + (unsigned)x, (unsigned)oddirs[x].vaddr); + throwCantPack(buf); + } + return oddirs[x].vaddr; +} /* ImportLinker: 32 and 64 bit import table building. diff --git a/src/pefile.h b/src/pefile.h index ec2fdd74..77dc4dc5 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -178,10 +178,17 @@ protected: ddirs_t *iddirs; ddirs_t *oddirs; - LE32 &IDSIZE(unsigned x) { return iddirs[x].size; } - LE32 &IDADDR(unsigned x) { return iddirs[x].vaddr; } - LE32 &ODSIZE(unsigned x) { return oddirs[x].size; } - LE32 &ODADDR(unsigned x) { return oddirs[x].vaddr; } + __packed_struct(import_desc) + LE32 oft; // orig first thunk + char _[8]; + LE32 dllname; + LE32 iat; // import address table + __packed_struct_end() + + LE32 &IDSIZE(unsigned x); + LE32 &IDADDR(unsigned x); + LE32 &ODSIZE(unsigned x); + LE32 &ODADDR(unsigned x); __packed_struct(pe_section_t) char name[8];