diff --git a/NEWS b/NEWS index 04b0548c..7b85712a 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,8 @@ User visible changes for UPX ================================================================== -Changes in 3.00 (08 Apr 2007): +Changes in 3.00 (27 Apr 2007): + * watcom/le & tmt/adam: fixed a problem when using certain filters Changes in 2.93 beta (08 Mar 2007): * new formats Mach/i386 and Mach/fat support Mac OS X i686 and diff --git a/src/conf.h b/src/conf.h index 119d5147..65e1cfb6 100644 --- a/src/conf.h +++ b/src/conf.h @@ -463,8 +463,9 @@ private: #define UPX_F_SOLARIS_SPARC 130 #define UPX_F_MACH_PPC32 131 #define UPX_F_LINUX_ELFPPC32 132 -#define UPX_F_LINUX_ELF32_ARMBE 133 +#define UPX_F_LINUX_ELF32_ARMEB 133 #define UPX_F_MACH_FAT 134 +#define UPX_F_VMLINUX_ARMEB 135 // compression methods diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index f446cddc..dbf45bd1 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -436,7 +436,7 @@ class PackLinuxElf32armBe : public PackLinuxElf32Be public: PackLinuxElf32armBe(InputFile *f); virtual ~PackLinuxElf32armBe(); - virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; } + virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEB; } virtual const char *getName() const { return "linux/armBE"; } virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; } virtual const int *getFilters() const; diff --git a/src/p_vmlinx.cpp b/src/p_vmlinx.cpp index 7470627d..8e13efe6 100644 --- a/src/p_vmlinx.cpp +++ b/src/p_vmlinx.cpp @@ -44,6 +44,8 @@ static const #include "stub/amd64-linux.kernel.vmlinux.h" static const #include "stub/arm-linux.kernel.vmlinux.h" +static const +#include "stub/armeb-linux.kernel.vmlinux.h" /************************************************************************* @@ -552,6 +554,11 @@ const int *PackVmlinuxARM::getCompressionMethods(int method, int level) const return Packer::getDefaultCompressionMethods_8(method, level); } +const int *PackVmlinuxARMEB::getCompressionMethods(int method, int level) const +{ + return Packer::getDefaultCompressionMethods_8(method, level); +} + const int *PackVmlinuxARM::getFilters() const { @@ -559,6 +566,12 @@ const int *PackVmlinuxARM::getFilters() const return f50; } +const int *PackVmlinuxARMEB::getFilters() const +{ + static const int f51[] = { 0x51, FT_END }; + return f51; +} + // // Examples as of 2004-07-16 [readelf --segments vmlinux # before fiddling]: // @@ -651,11 +664,21 @@ bool PackVmlinuxARM::is_valid_e_entry(Addr e_entry) return 0xc0008000==e_entry; } +bool PackVmlinuxARMEB::is_valid_e_entry(Addr e_entry) +{ + return 0xc0008000==e_entry; +} + Linker* PackVmlinuxARM::newLinker() const { return new ElfLinkerArmLE; } +Linker* PackVmlinuxARMEB::newLinker() const +{ + return new ElfLinkerArmBE; +} + void PackVmlinuxARM::buildLoader(const Filter *ft) { @@ -679,6 +702,28 @@ void PackVmlinuxARM::buildLoader(const Filter *ft) addLoader("IDENTSTR,UPX1HEAD", NULL); } +void PackVmlinuxARMEB::buildLoader(const Filter *ft) +{ + // prepare loader + initLoader(stub_armeb_linux_kernel_vmlinux, sizeof(stub_armeb_linux_kernel_vmlinux)); + addLoader("LINUX000", NULL); + if (ft->id) { + assert(ft->calls > 0); + addLoader("LINUX010", NULL); + } + addLoader("LINUX020", NULL); + if (ft->id) { + addFilter32(ft->id); + } + addLoader("LINUX030", NULL); + if (ph.method == M_NRV2E_8) addLoader("NRV2E", NULL); + else if (ph.method == M_NRV2B_8) addLoader("NRV2B", NULL); + else if (ph.method == M_NRV2D_8) addLoader("NRV2D", NULL); + else if (M_IS_LZMA(ph.method)) addLoader("LZMA_ELF00,LZMA_DEC10,LZMA_DEC30", NULL); + else throwBadLoader(); + addLoader("IDENTSTR,UPX1HEAD", NULL); +} + static const #include "stub/i386-linux.kernel.vmlinux-head.h" @@ -686,6 +731,8 @@ static const #include "stub/amd64-linux.kernel.vmlinux-head.h" static const #include "stub/arm-linux.kernel.vmlinux-head.h" +static const +#include "stub/armeb-linux.kernel.vmlinux-head.h" unsigned PackVmlinuxI386::write_vmlinux_head( OutputFile *const fo, @@ -727,6 +774,14 @@ void PackVmlinuxARM::defineDecompressorSymbols() linker->defineSymbol("METHOD", ph.method); } +void PackVmlinuxARMEB::defineDecompressorSymbols() +{ + super::defineDecompressorSymbols(); + linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len); + linker->defineSymbol("UNCOMPRESSED_LENGTH", ph.u_len); + linker->defineSymbol("METHOD", ph.method); +} + void PackVmlinuxI386::defineDecompressorSymbols() { super::defineDecompressorSymbols(); @@ -766,6 +821,28 @@ unsigned PackVmlinuxARM::write_vmlinux_head( return sizeof(stub_arm_linux_kernel_vmlinux_head); } +unsigned PackVmlinuxARMEB::write_vmlinux_head( + OutputFile *const fo, + Shdr *const stxt +) +{ + // First word from vmlinux-head.S + fo->write(&stub_armeb_linux_kernel_vmlinux_head[0], 4); + + // Second word + U32 tmp_u32; + unsigned const t = (0xff000000 & + BeLePolicy::get32(&stub_armeb_linux_kernel_vmlinux_head[4])) + | (0x00ffffff & (0u - 1 + ((3+ ph.c_len)>>2))); + tmp_u32 = t; + fo->write(&tmp_u32, 4); + + stxt->sh_addralign = 4; + stxt->sh_size += sizeof(stub_armeb_linux_kernel_vmlinux_head); + + return sizeof(stub_armeb_linux_kernel_vmlinux_head); +} + bool PackVmlinuxARM::has_valid_vmlinux_head() { @@ -781,6 +858,20 @@ bool PackVmlinuxARM::has_valid_vmlinux_head() return false; } +bool PackVmlinuxARMEB::has_valid_vmlinux_head() +{ + U32 buf[2]; + fi->seek(p_text->sh_offset + sizeof(stub_armeb_linux_kernel_vmlinux_head) -8, SEEK_SET); + fi->readx(buf, sizeof(buf)); + //unsigned const word0 = buf[0]; + unsigned const word1 = buf[1]; + if (0xeb==(word1>>24) + && (0x00ffffff& word1)==(0u - 1 + ((3+ ph.c_len)>>2))) { + return true; + } + return false; +} + bool PackVmlinuxI386::has_valid_vmlinux_head() { unsigned char buf[5]; @@ -1058,6 +1149,7 @@ Linker* PackVmlinuxAMD64::newLinker() const // instantiate instances template class PackVmlinuxBase; +template class PackVmlinuxBase; template class PackVmlinuxBase; diff --git a/src/p_vmlinx.h b/src/p_vmlinx.h index 04ad83b5..f9c28a4e 100644 --- a/src/p_vmlinx.h +++ b/src/p_vmlinx.h @@ -143,6 +143,30 @@ protected: ); }; +class PackVmlinuxARMEB : public PackVmlinuxBase +{ + typedef PackVmlinuxBase super; +public: + PackVmlinuxARMEB(InputFile *f) : super(f, Ehdr::EM_ARM, + Ehdr::ELFCLASS32, Ehdr::ELFDATA2MSB, "decompress_kernel") { } + virtual int getFormat() const { return UPX_F_VMLINUX_ARMEB; } + virtual const char *getName() const { return "vmlinux/ARMEB"; } + virtual const char *getFullName(const options_t *) const { return "armbe-linux.kernel.vmlinux"; } + virtual const int *getCompressionMethods(int method, int level) const; + virtual const int *getFilters() const; + +protected: + virtual void buildLoader(const Filter *ft); + virtual void defineDecompressorSymbols(); + virtual Linker* newLinker() const; + virtual bool is_valid_e_entry(Addr); + virtual bool has_valid_vmlinux_head(); + virtual unsigned write_vmlinux_head( + OutputFile *const fo, + Shdr *const stxt + ); +}; + class PackVmlinuxAMD64 : public PackVmlinuxBase { diff --git a/src/packer_c.cpp b/src/packer_c.cpp index 437089be..c14c8428 100644 --- a/src/packer_c.cpp +++ b/src/packer_c.cpp @@ -210,9 +210,10 @@ const char *Packer::getDecompressorSections() const || UPX_F_LINUX_ELF64_AMD ==ph.format || UPX_F_LINUX_ELF32_ARMLE==ph.format || UPX_F_LINUX_ELFPPC32 ==ph.format - || UPX_F_LINUX_ELF32_ARMBE==ph.format + || UPX_F_LINUX_ELF32_ARMEB==ph.format || UPX_F_BSD_ELF_i386 ==ph.format || UPX_F_VMLINUX_ARM ==ph.format + || UPX_F_VMLINUX_ARMEB ==ph.format || UPX_F_MACH_PPC32 ==ph.format || UPX_F_MACH_i386 ==ph.format ) { @@ -246,9 +247,10 @@ void Packer::defineDecompressorSymbols() || UPX_F_LINUX_ELF64_AMD ==ph.format || UPX_F_LINUX_ELF32_ARMLE==ph.format || UPX_F_LINUX_ELFPPC32 ==ph.format - || UPX_F_LINUX_ELF32_ARMBE==ph.format + || UPX_F_LINUX_ELF32_ARMEB==ph.format || UPX_F_BSD_ELF_i386 ==ph.format || UPX_F_VMLINUX_ARM ==ph.format + || UPX_F_VMLINUX_ARMEB ==ph.format || UPX_F_MACH_PPC32 ==ph.format || UPX_F_MACH_i386 ==ph.format ) { diff --git a/src/packmast.cpp b/src/packmast.cpp index 9144e14e..d77419b1 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -194,6 +194,8 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio // if ((p = func(new PackVmlinuxARM(f), user)) != NULL) return p; + if ((p = func(new PackVmlinuxARMEB(f), user)) != NULL) + return p; if ((p = func(new PackVmlinuxAMD64(f), user)) != NULL) return p; if ((p = func(new PackVmlinuxI386(f), user)) != NULL) diff --git a/src/stub/Makefile b/src/stub/Makefile index 992286d9..75ea26e2 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -56,6 +56,8 @@ STUBS += arm-linux.kernel.vmlinux.h STUBS += arm-linux.kernel.vmlinux-head.h STUBS += armeb-linux.elf-entry.h STUBS += armeb-linux.elf-fold.h +STUBS += armeb-linux.kernel.vmlinux.h +STUBS += armeb-linux.kernel.vmlinux-head.h STUBS += arm.v4a-wince.pe.h STUBS += arm.v4t-wince.pe.h STUBS += i086-dos16.com.h @@ -336,6 +338,28 @@ arm-linux.kernel.vmlinux-head.h : $(srcdir)/src/$$T.S $(call tc,bin2h) tmp/$T.bin $@ +# /*********************************************************************** +# // armeb-linux.kernel.vmlinux +# // armeb-linux.kernel.vmlinuz +# // armeb-linux.kernel.vmlinux-head +# ************************************************************************/ + +armeb-linux.kernel.vmlinu%.h : tc_list = armeb-linux.kernel default +armeb-linux.kernel.vmlinu%.h : tc_bfdname = elf32-bigarm + +tc.armeb-linux.kernel.gcc = $(tc.arm-linux.elf.gcc) -mbig-endian + +armeb-linux.kernel.vmlinu%.h : $(srcdir)/src/$$T.S + $(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.bin + $(call tc,f-embed_objinfo,tmp/$T.bin) + $(call tc,bin2h-c) tmp/$T.bin $@ + +armeb-linux.kernel.vmlinux-head.h : $(srcdir)/src/$$T.S + $(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.o + $(call tc,objcopy) --output-target binary --only-section .text tmp/$T.o tmp/$T.bin + $(call tc,bin2h) tmp/$T.bin $@ + + # /*********************************************************************** # // armeb-linux.elf # ************************************************************************/ diff --git a/src/version.h b/src/version.h index 52ed1618..96ef75d2 100644 --- a/src/version.h +++ b/src/version.h @@ -1,6 +1,6 @@ #define UPX_VERSION_HEX 0x030000 /* 03.00.00 */ #define UPX_VERSION_STRING "3.00" #define UPX_VERSION_STRING4 "3.00" -#define UPX_VERSION_DATE "Apr 8th 2007" -#define UPX_VERSION_DATE_ISO "2007-04-08" +#define UPX_VERSION_DATE "Apr 27th 2007" +#define UPX_VERSION_DATE_ISO "2007-04-27" #define UPX_VERSION_YEAR "2007"