diff --git a/src/conf.h b/src/conf.h index 93c8d44f..8484cc65 100644 --- a/src/conf.h +++ b/src/conf.h @@ -298,10 +298,15 @@ typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int); #define index upx_index #define outp upx_outp + // a dummy statement #define nop ((void)0) +#define COMPILE_TIME_ASSERT(expr) \ + { typedef int upx_compile_time_assert_fail[(expr) ? 1 : -1]; } + + /************************************************************************* // file io **************************************************************************/ diff --git a/src/main.cpp b/src/main.cpp index 60dbbc9f..c78f583a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -931,20 +931,20 @@ static void first_options(int argc, char **argv) void upx_sanity_check(void) { - assert(sizeof(char) == 1); - assert(sizeof(short) == 2); - assert(sizeof(int) == 4); - assert(sizeof(long) >= 4); - assert(sizeof(void *) >= 4); - assert(sizeof(long) >= sizeof(void *)); - assert(((size_t) -1) > 0); - assert(((ptrdiff_t) -1) < 0); - assert(((off_t) -1) < 0); + COMPILE_TIME_ASSERT(sizeof(char) == 1); + COMPILE_TIME_ASSERT(sizeof(short) == 2); + COMPILE_TIME_ASSERT(sizeof(int) == 4); + COMPILE_TIME_ASSERT(sizeof(long) >= 4); + COMPILE_TIME_ASSERT(sizeof(void *) >= 4); + COMPILE_TIME_ASSERT(sizeof(long) >= sizeof(void *)); + COMPILE_TIME_ASSERT(((size_t) -1) > 0); + COMPILE_TIME_ASSERT(((ptrdiff_t) -1) < 0); + COMPILE_TIME_ASSERT(((off_t) -1) < 0); - assert(sizeof(BE16) == 2); - assert(sizeof(BE32) == 4); - assert(sizeof(LE16) == 2); - assert(sizeof(LE32) == 4); + COMPILE_TIME_ASSERT(sizeof(BE16) == 2); + COMPILE_TIME_ASSERT(sizeof(BE32) == 4); + COMPILE_TIME_ASSERT(sizeof(LE16) == 2); + COMPILE_TIME_ASSERT(sizeof(LE32) == 4); struct align_assertion_1a_t { @@ -978,10 +978,10 @@ void upx_sanity_check(void) //printf("%d\n", (int) sizeof(align_assertion_1b_t)); //printf("%d\n", (int) sizeof(align_assertion_2a_t)); //printf("%d\n", (int) sizeof(align_assertion_2b_t)); - assert(sizeof(align_assertion_1a_t) == sizeof(align_assertion_1b_t)); - assert(sizeof(align_assertion_2a_t) == sizeof(align_assertion_2b_t)); - assert(sizeof(align_assertion_1a_t) == 3*9); - assert(sizeof(align_assertion_2a_t) == 3*17); + COMPILE_TIME_ASSERT(sizeof(align_assertion_1a_t) == sizeof(align_assertion_1b_t)); + COMPILE_TIME_ASSERT(sizeof(align_assertion_2a_t) == sizeof(align_assertion_2b_t)); + COMPILE_TIME_ASSERT(sizeof(align_assertion_1a_t) == 3*9); + COMPILE_TIME_ASSERT(sizeof(align_assertion_2a_t) == 3*17); } diff --git a/src/p_djgpp2.cpp b/src/p_djgpp2.cpp index 55fd21f2..a8483815 100644 --- a/src/p_djgpp2.cpp +++ b/src/p_djgpp2.cpp @@ -45,8 +45,8 @@ static const PackDjgpp2::PackDjgpp2(InputFile *f) : super(f), coff_offset(0) { - assert(sizeof(coff_hdr) == 0xa8); - assert(sizeof(stubify_stub) == 2048); + COMPILE_TIME_ASSERT(sizeof(coff_hdr) == 0xa8); + COMPILE_TIME_ASSERT(sizeof(stubify_stub) == 2048); } diff --git a/src/p_exe.cpp b/src/p_exe.cpp index 90f5b300..380f7d7b 100644 --- a/src/p_exe.cpp +++ b/src/p_exe.cpp @@ -47,7 +47,7 @@ static const PackExe::PackExe(InputFile *f) : super(f) { - assert(sizeof(exe_header_t) == 32); + COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32); ih_exesize = ih_imagesize = ih_overlay = 0; } diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index f9aaf1d9..a237794a 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -152,7 +152,7 @@ void PackLinuxI386elf::patchLoader() bool PackLinuxI386elf::canPack() { unsigned char buf[sizeof(Elf_LE32_Ehdr) + 14*sizeof(Elf_LE32_Phdr)]; - assert(sizeof(buf) <= 512); + COMPILE_TIME_ASSERT(sizeof(buf) <= 512); exetype = 0; diff --git a/src/p_tmt.cpp b/src/p_tmt.cpp index 79cc9aad..a4be8b56 100644 --- a/src/p_tmt.cpp +++ b/src/p_tmt.cpp @@ -41,6 +41,12 @@ static const // **************************************************************************/ +PackTmt::PackTmt(InputFile *f) : super(f) +{ + COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44); +} + + int PackTmt::getCompressionMethod() const { if (M_IS_NRV2B(opt->method)) diff --git a/src/p_tmt.h b/src/p_tmt.h index 7c5bb1a8..762d2198 100644 --- a/src/p_tmt.h +++ b/src/p_tmt.h @@ -38,7 +38,7 @@ class PackTmt : public Packer { typedef Packer super; public: - PackTmt(InputFile *f) : super(f) { assert(sizeof(tmt_header_t) == 44); } + PackTmt(InputFile *f); virtual int getVersion() const { return 11; } virtual int getFormat() const { return UPX_F_TMT_ADAM; } virtual const char *getName() const { return "tmt/adam"; } @@ -64,7 +64,7 @@ protected: LE32 entry; char ___[12]; // esp,numfixups,flags LE32 relocsize; - } ih,oh; + } ih, oh; }; diff --git a/src/p_tos.cpp b/src/p_tos.cpp index 2732b618..781e826b 100644 --- a/src/p_tos.cpp +++ b/src/p_tos.cpp @@ -53,7 +53,7 @@ static const PackTos::PackTos(InputFile *f) : super(f) { - assert(FH_SIZE == 28); + COMPILE_TIME_ASSERT(FH_SIZE == 28); } diff --git a/src/p_unix.cpp b/src/p_unix.cpp index d2376b58..b3e2bd2c 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -44,10 +44,10 @@ PackUnix::PackUnix(InputFile *f) : super(f), exetype(0), blocksize(0), overlay_offset(0), lsize(0) { - assert(sizeof(Elf_LE32_Ehdr) == 52); - assert(sizeof(Elf_LE32_Phdr) == 32); - assert(sizeof(l_info) == 12); - assert(sizeof(p_info) == 12); + COMPILE_TIME_ASSERT(sizeof(Elf_LE32_Ehdr) == 52); + COMPILE_TIME_ASSERT(sizeof(Elf_LE32_Phdr) == 32); + COMPILE_TIME_ASSERT(sizeof(l_info) == 12); + COMPILE_TIME_ASSERT(sizeof(p_info) == 12); } diff --git a/src/p_vmlinz.cpp b/src/p_vmlinz.cpp index 63632bc3..cde74a76 100644 --- a/src/p_vmlinz.cpp +++ b/src/p_vmlinz.cpp @@ -52,7 +52,7 @@ static const unsigned bzimage_offset = 0x100000; PackVmlinuzI386::PackVmlinuzI386(InputFile *f) : super(f) { - assert(sizeof(boot_sect_t) == 0x218); + COMPILE_TIME_ASSERT(sizeof(boot_sect_t) == 0x218); } @@ -88,9 +88,12 @@ int PackVmlinuzI386::readFileHeader() { boot_sect_t h; + setup_size = 0; + fi->readx(&h, sizeof(h)); if (h.boot_flag != 0xAA55) return 0; + const bool hdrs = (memcmp(h.hdrs, "HdrS", 4) == 0); setup_size = (1 + (h.setup_sects ? h.setup_sects : 4)) * 0x200; if (setup_size <= 0 || setup_size >= file_size) @@ -98,14 +101,21 @@ int PackVmlinuzI386::readFileHeader() int format = UPX_F_VMLINUZ_i386; unsigned sys_size = ALIGN_UP(file_size, 16) - setup_size; - if (memcmp(h.hdrs, "HdrS", 4) == 0 && (h.load_flags & 1) != 0) + + const unsigned char *p = (const unsigned char *) &h + 0x1e3; + + if (hdrs && memcmp(p, "\x0d\x0a\x07""ELKS", 7) == 0) + { + format = UPX_F_ELKS_8086; + } + else if (hdrs && (h.load_flags & 1) != 0) { format = UPX_F_BVMLINUZ_i386; - // account for 16-bit h.sys_size, wraparound at 20 bits + // account for 16-bit h.sys_size, wrap around at 20 bits sys_size &= (1 << 20) - 1; } - if (16 * h.sys_size != sys_size) + if (16u * h.sys_size != sys_size) return 0; // FIXME: add more checks for a valid kernel @@ -160,7 +170,7 @@ void PackVmlinuzI386::readKernel() if (klen <= 0) throwCantPack("kernel decompression failed"); if (klen >= (int) ibuf.getSize()) - throwCantPack("kernel decompression failed -- too big"); + throwCantPack("kernel decompression failed -- too big; send a bug report"); //OutputFile::dump("kernel.img", ibuf, klen); @@ -233,7 +243,7 @@ void PackVmlinuzI386::pack(OutputFile *fo) patch_le32(loader, lsize, "KEIP", kernel_entry); patch_le32(loader, lsize, "STAK", stack_during_uncompression); - boot_sect_t *bs = (boot_sect_t *) ((unsigned char *) setup_buf); + boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf); bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16) / 16; fo->write(setup_buf, setup_buf.getSize()); @@ -332,8 +342,8 @@ void PackBvmlinuzI386::pack(OutputFile *fo) patch_le32(loader, e_len, "KEIP", kernel_entry); patch_le32(loader, e_len, "STAK", stack_during_uncompression); - boot_sect_t *bs = (boot_sect_t *) ((unsigned char *) setup_buf); - bs->sys_size = ALIGN_UP(lsize + clen, 16) / 16; + boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf); + bs->sys_size = (ALIGN_UP(lsize + clen, 16) / 16) & 0xffff; fo->write(setup_buf, setup_buf.getSize()); fo->write(loader, e_len); diff --git a/src/p_w32pe.cpp b/src/p_w32pe.cpp index 7a52ee1c..b204281e 100644 --- a/src/p_w32pe.cpp +++ b/src/p_w32pe.cpp @@ -64,8 +64,8 @@ PackW32Pe::PackW32Pe(InputFile *f) : super(f) { //printf("pe_header_t %d\n", (int) sizeof(pe_header_t)); //printf("pe_section_t %d\n", (int) sizeof(pe_section_t)); - assert(sizeof(pe_header_t) == 248); - assert(sizeof(pe_section_t) == 40); + COMPILE_TIME_ASSERT(sizeof(pe_header_t) == 248); + COMPILE_TIME_ASSERT(sizeof(pe_section_t) == 40); isection = 0; oimport = 0; @@ -1204,8 +1204,9 @@ void Resource::clear(upx_byte *node,unsigned level,Interval *iv) else { const res_dir * const rd = (res_dir*) node; + const unsigned n = rd->identr + rd->namedentr; const res_dir_entry *rde = rd->entries; - for (unsigned ic = 0; ic < rd->identr + rd->namedentr; ic++, rde++) + for (unsigned ic = 0; ic < n; ic++, rde++) clear(newstart + (rde->child & 0x7fffffff),level + 1,iv); iv->add(rd,rd->Sizeof()); }