From 0c2263d0e9857b17d60111500f2506f0f29c6377 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sun, 22 Apr 2007 15:50:24 -0700 Subject: [PATCH 1/2] fix O_INP etc because cto8 is not pushed. This change should have paralleled 1382:367eb149f29c (Sun Aug 20 11:19:37 2006 -0700) --- src/stub/i386-bsd.elf-entry.h | 16 ++++++++-------- src/stub/src/i386-bsd.elf-entry.S | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/stub/i386-bsd.elf-entry.h b/src/stub/i386-bsd.elf-entry.h index 78569aaa..9a297fd2 100644 --- a/src/stub/i386-bsd.elf-entry.h +++ b/src/stub/i386-bsd.elf-entry.h @@ -29,15 +29,15 @@ #define STUB_I386_BSD_ELF_ENTRY_SIZE 37562 -#define STUB_I386_BSD_ELF_ENTRY_ADLER32 0xb6d5917d -#define STUB_I386_BSD_ELF_ENTRY_CRC32 0x57a02d3a +#define STUB_I386_BSD_ELF_ENTRY_ADLER32 0x0c31915d +#define STUB_I386_BSD_ELF_ENTRY_CRC32 0x68fd1b14 unsigned char stub_i386_bsd_elf_entry[37562] = { 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ 1, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 10 */ 116, 34, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 40, 0, /* 0x 20 */ -243, 0,240, 0,232,123, 0, 0, 0, 96,139,116, 36, 40,139,124, /* 0x 30 */ - 36, 48,131,205,255,235, 3,164,235, 3,138, 6, 70,136, 7, 71, /* 0x 40 */ +243, 0,240, 0,232,123, 0, 0, 0, 96,139,116, 36, 36,139,124, /* 0x 30 */ + 36, 44,131,205,255,235, 3,164,235, 3,138, 6, 70,136, 7, 71, /* 0x 40 */ 1,219,117, 7,139, 30,131,238,252, 17,219,114, 1, 49,192, 64, /* 0x 50 */ 138, 7,114,255,184, 1, 0, 0, 0, 1,219,117, 7,139, 30,131, /* 0x 60 */ 238,252, 17,219, 17,192, 1,219,117, 7,139, 30,131,238,252, 17, /* 0x 70 */ @@ -88,10 +88,10 @@ unsigned char stub_i386_bsd_elf_entry[37562] = { 4,119,241, 1,207,233,252,255,255,255,137,229,141,156, 36, 0, /* 0x 340 */ 0, 0, 0, 49,192, 80, 57,220,117,251, 70, 70, 83,104, 0, 0, /* 0x 350 */ 0, 0, 87,131,195, 4, 83,104, 0, 0, 0, 0, 86,131,195, 4, /* 0x 360 */ - 83, 80,199, 3, 0, 0, 0, 0,137,229,139, 85, 44,172, 74,136, /* 0x 370 */ + 83, 80,199, 3, 0, 0, 0, 0,137,229,139, 85, 40,172, 74,136, /* 0x 370 */ 193, 36, 7,192,233, 3,187, 0,253,255,255,211,227,141,164, 92, /* 0x 380 */ 144,241,255,255,131,228,224,106, 0,106, 0,137,227, 83,131,195, /* 0x 390 */ - 4,139, 77, 52,255, 49, 87, 83,131,195, 4,136, 67, 2,172, 74, /* 0x 3a0 */ + 4,139, 77, 48,255, 49, 87, 83,131,195, 4,136, 67, 2,172, 74, /* 0x 3a0 */ 136,193, 36, 15,136, 3,192,233, 4,136, 75, 1, 82, 86, 83, 80, /* 0x 3b0 */ 85, 87, 86, 83,131,236,124,139,148, 36,144, 0, 0, 0,199, 68, /* 0x 3c0 */ 36,116, 0, 0, 0, 0,198, 68, 36,115, 0,139,172, 36,156, 0, /* 0x 3d0 */ @@ -431,8 +431,8 @@ unsigned char stub_i386_bsd_elf_entry[37562] = { 148, 36,156, 0, 0, 0,139, 76, 36,116,137, 26,139,156, 36,168, /* 0x18b0 */ 0, 0, 0,137, 11,131,196,124, 91, 94, 95, 93, 3,115,252, 3, /* 0x18c0 */ 123,248, 49,192,141,140, 36, 0,255,255,255,137,236, 80, 57,204, /* 0x18d0 */ -117,251,137,236, 49,201,139, 84, 36, 40, 3, 84, 36, 44, 57,214, /* 0x18e0 */ -116, 1, 72, 43,124, 36, 48,139, 84, 36, 52,137, 58,137, 68, 36, /* 0x18f0 */ +117,251,137,236, 49,201,139, 84, 36, 36, 3, 84, 36, 40, 57,214, /* 0x18e0 */ +116, 1, 72, 43,124, 36, 44,139, 84, 36, 48,137, 58,137, 68, 36, /* 0x18f0 */ 28, 97,195,235, 4, 90, 88, 89,151, 96, 49,219,187, 0, 0, 0, /* 0x1900 */ 0,106, 15, 88,138,100, 36, 32,106, 15, 91,138,124, 36, 32,138, /* 0x1910 */ 84, 36, 32,233,252,255,255,255, 15,183, 47, 43,110, 12, 41,221, /* 0x1920 */ diff --git a/src/stub/src/i386-bsd.elf-entry.S b/src/stub/src/i386-bsd.elf-entry.S index 071f6def..5083a9d9 100644 --- a/src/stub/src/i386-bsd.elf-entry.S +++ b/src/stub/src/i386-bsd.elf-entry.S @@ -67,12 +67,12 @@ decompress: // // C callable decompressor // **************************************************************************/ -// /* Offsets to parameters, allowing for {push + pusha + call} */ -#define O_INP (4+ 8*4 +1*4) -#define O_INS (4+ 8*4 +2*4) -#define O_OUTP (4+ 8*4 +3*4) -#define O_OUTS (4+ 8*4 +4*4) -#define O_PARAM (4+ 8*4 +5*4) +// /* Offsets to parameters, allowing for {pusha + call} */ +#define O_INP (8*4 +1*4) +#define O_INS (8*4 +2*4) +#define O_OUTP (8*4 +3*4) +#define O_OUTS (8*4 +4*4) +#define O_PARAM (8*4 +5*4) #define INP dword ptr [esp+O_INP] #define INS dword ptr [esp+O_INS] From 9c564fd4c71e4fe7dc27a8ff9e75c28bb03dd6cd Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sun, 22 Apr 2007 16:09:18 -0700 Subject: [PATCH 2/2] Add file formst UPX_F_LINUX_ELF32_ARMEB and normalize spelling of ARMEL, ARMEB, armel, armeb. --- src/conf.h | 7 +-- src/p_lx_elf.h | 4 +- src/p_vmlinx.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++---- src/p_vmlinx.h | 32 ++++++++++++-- src/packer_c.cpp | 14 +++--- src/packmast.cpp | 4 +- src/stub/Makefile | 24 +++++++++++ 7 files changed, 169 insertions(+), 24 deletions(-) diff --git a/src/conf.h b/src/conf.h index 119d5147..7b9620f2 100644 --- a/src/conf.h +++ b/src/conf.h @@ -448,13 +448,13 @@ private: #define UPX_F_LINUX_ELFI_i386 20 #define UPX_F_WINCE_ARM_PE 21 #define UPX_F_LINUX_ELF64_AMD 22 -#define UPX_F_LINUX_ELF32_ARMLE 23 +#define UPX_F_LINUX_ELF32_ARMEL 23 #define UPX_F_BSD_i386 24 #define UPX_F_BSD_ELF_i386 25 #define UPX_F_BSD_SH_i386 26 #define UPX_F_VMLINUX_AMD64 27 -#define UPX_F_VMLINUX_ARM 28 +#define UPX_F_VMLINUX_ARMEL 28 #define UPX_F_MACH_i386 29 #define UPX_F_PLAIN_TEXT 127 @@ -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..fc8533d2 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -416,7 +416,7 @@ class PackLinuxElf32armLe : public PackLinuxElf32Le public: PackLinuxElf32armLe(InputFile *f); virtual ~PackLinuxElf32armLe(); - virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; } + virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEL; } virtual const char *getName() const { return "linux/armLE"; } virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; } virtual const int *getFilters() const; @@ -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..6b062d69 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" /************************************************************************* @@ -547,18 +549,29 @@ const int *PackVmlinuxI386::getFilters() const return filters; } -const int *PackVmlinuxARM::getCompressionMethods(int method, int level) const +const int *PackVmlinuxARMEL::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 +const int *PackVmlinuxARMEL::getFilters() const { static const int f50[] = { 0x50, FT_END }; 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]: // @@ -646,18 +659,28 @@ void PackVmlinuxAMD64::buildLoader(const Filter *ft) "LINUX992,IDENTSTR,UPX1HEAD", NULL); } -bool PackVmlinuxARM::is_valid_e_entry(Addr e_entry) +bool PackVmlinuxARMEL::is_valid_e_entry(Addr e_entry) { return 0xc0008000==e_entry; } -Linker* PackVmlinuxARM::newLinker() const +bool PackVmlinuxARMEB::is_valid_e_entry(Addr e_entry) +{ + return 0xc0008000==e_entry; +} + +Linker* PackVmlinuxARMEL::newLinker() const { return new ElfLinkerArmLE; } +Linker* PackVmlinuxARMEB::newLinker() const +{ + return new ElfLinkerArmBE; +} -void PackVmlinuxARM::buildLoader(const Filter *ft) + +void PackVmlinuxARMEL::buildLoader(const Filter *ft) { // prepare loader initLoader(stub_arm_linux_kernel_vmlinux, sizeof(stub_arm_linux_kernel_vmlinux)); @@ -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, @@ -719,7 +766,15 @@ printf("UnCompressed length=0x%x\n", ph.u_len); return sizeof(stub_amd64_linux_kernel_vmlinux_head); } -void PackVmlinuxARM::defineDecompressorSymbols() +void PackVmlinuxARMEL::defineDecompressorSymbols() +{ + super::defineDecompressorSymbols(); + linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len); + linker->defineSymbol("UNCOMPRESSED_LENGTH", ph.u_len); + linker->defineSymbol("METHOD", ph.method); +} + +void PackVmlinuxARMEB::defineDecompressorSymbols() { super::defineDecompressorSymbols(); linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len); @@ -744,7 +799,7 @@ void PackVmlinuxAMD64::defineDecompressorSymbols() linker->defineSymbol("PHYSICAL_START", phdri[0].p_paddr); } -unsigned PackVmlinuxARM::write_vmlinux_head( +unsigned PackVmlinuxARMEL::write_vmlinux_head( OutputFile *const fo, Shdr *const stxt ) @@ -766,8 +821,30 @@ 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); -bool PackVmlinuxARM::has_valid_vmlinux_head() + // 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 PackVmlinuxARMEL::has_valid_vmlinux_head() { U32 buf[2]; fi->seek(p_text->sh_offset + sizeof(stub_arm_linux_kernel_vmlinux_head) -8, SEEK_SET); @@ -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..0734a45f 100644 --- a/src/p_vmlinx.h +++ b/src/p_vmlinx.h @@ -119,14 +119,14 @@ protected: }; -class PackVmlinuxARM : public PackVmlinuxBase +class PackVmlinuxARMEL : public PackVmlinuxBase { typedef PackVmlinuxBase super; public: - PackVmlinuxARM(InputFile *f) : super(f, Ehdr::EM_ARM, + PackVmlinuxARMEL(InputFile *f) : super(f, Ehdr::EM_ARM, Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "decompress_kernel") { } - virtual int getFormat() const { return UPX_F_VMLINUX_ARM; } - virtual const char *getName() const { return "vmlinux/ARM"; } + virtual int getFormat() const { return UPX_F_VMLINUX_ARMEL; } + virtual const char *getName() const { return "vmlinux/armel"; } virtual const char *getFullName(const options_t *) const { return "arm-linux.kernel.vmlinux"; } virtual const int *getCompressionMethods(int method, int level) const; virtual const int *getFilters() const; @@ -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..1cd9b5ed 100644 --- a/src/packer_c.cpp +++ b/src/packer_c.cpp @@ -208,11 +208,12 @@ const char *Packer::getDecompressorSections() const if (UPX_F_LINUX_ELF_i386 ==ph.format || UPX_F_LINUX_ELFI_i386 ==ph.format || UPX_F_LINUX_ELF64_AMD ==ph.format - || UPX_F_LINUX_ELF32_ARMLE==ph.format + || UPX_F_LINUX_ELF32_ARMEL==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_ARMEL ==ph.format + || UPX_F_VMLINUX_ARMEB ==ph.format || UPX_F_MACH_PPC32 ==ph.format || UPX_F_MACH_i386 ==ph.format ) { @@ -244,11 +245,12 @@ void Packer::defineDecompressorSymbols() if (UPX_F_LINUX_ELF_i386 ==ph.format || UPX_F_LINUX_ELFI_i386 ==ph.format || UPX_F_LINUX_ELF64_AMD ==ph.format - || UPX_F_LINUX_ELF32_ARMLE==ph.format + || UPX_F_LINUX_ELF32_ARMEL==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_ARMEL ==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..efaa1194 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -192,7 +192,9 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio // // linux kernel // - if ((p = func(new PackVmlinuxARM(f), user)) != NULL) + if ((p = func(new PackVmlinuxARMEL(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; 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 # ************************************************************************/