From c117491549d04d312078976ef60f61fdcf89d806 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Mon, 12 Jun 2006 11:05:52 -0700 Subject: [PATCH 01/10] arm-9tdmi-linux-gnu-gcc is gcc-3.4.5-glibc-2.3.6; old was gcc-3.4.1-glibc-2.3.3 --- src/stub/fold_elf32arm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stub/fold_elf32arm.h b/src/stub/fold_elf32arm.h index 826efc8a..788054da 100644 --- a/src/stub/fold_elf32arm.h +++ b/src/stub/fold_elf32arm.h @@ -28,8 +28,8 @@ #define LINUX_ELF32ARM_FOLD_SIZE 2080 -#define LINUX_ELF32ARM_FOLD_ADLER32 0xbb4d53cf -#define LINUX_ELF32ARM_FOLD_CRC32 0x44605956 +#define LINUX_ELF32ARM_FOLD_ADLER32 0x885d5313 +#define LINUX_ELF32ARM_FOLD_CRC32 0x744eec3f unsigned char linux_elf32arm_fold[2080] = { 127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ @@ -114,7 +114,7 @@ unsigned char linux_elf32arm_fold[2080] = { 12,192,100,224, 8, 32,130,225, 5, 0,160,225, 10, 16,160,225, /* 0x 4f0 */ 0,224,141,229, 4,192,141,229, 25,255,255,235, 0, 0, 85,225, /* 0x 500 */ 62, 0, 0, 26, 0, 0, 91,227, 6, 0, 0, 10, 16, 32,157,229, /* 0x 510 */ - 40, 49,176,225, 2, 48,160, 17, 28, 16,141,226, 11, 0,160,225, /* 0x 520 */ + 4, 48, 24,226, 2, 48,160, 17, 28, 16,141,226, 11, 0,160,225, /* 0x 520 */ 24, 32,157,229, 45,255,255,235, 0, 48,106,226, 3, 74,160,225, /* 0x 530 */ 2, 0, 24,227, 36, 74,160,225, 7, 0, 0, 10, 0, 0, 84,227, /* 0x 540 */ 10, 16,133,224, 4, 32,160,225, 3, 0, 0, 10, 0, 48,160,227, /* 0x 550 */ From 1af5820db0557e842412fdfa2415000739ed9b31 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 08:24:38 -0700 Subject: [PATCH 02/10] hack printf() --- src/stub/l_lx_elf.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/stub/l_lx_elf.c b/src/stub/l_lx_elf.c index d8622058..f86e3661 100644 --- a/src/stub/l_lx_elf.c +++ b/src/stub/l_lx_elf.c @@ -102,20 +102,24 @@ dprintf(char const *fmt, ...) char buf[20]; va_list va; va_start(va, fmt); ptr= &buf[0]; - while (0!=(c= *fmt++)) if ('%'!=c) n+= write(2, fmt-1, 1); + while (0!=(c= *fmt++)) if ('%'!=c) goto literal; else switch (c= *fmt++) { default: { +literal: n+= write(2, fmt-1, 1); } break; case 0: goto done; /* early */ + case 'u': { + n+= write(2, buf, unsimal(va_arg(va, unsigned), buf, 0)); + } break; case 'd': { n+= write(2, buf, decimal(va_arg(va, int), buf, 0)); } break; - case 'p': { - n+= write(2, STR_0x(), 2); - } /* fall through into 'x' */ + case 'p': /* same as 'x'; relies on sizeof(int)==sizeof(void *) */ case 'x': { - n+= write(2, buf, heximal(va_arg(va, int), buf, 0)); + buf[0] = '0'; + buf[1] = 'x'; + n+= write(2, buf, heximal(va_arg(va, int), buf, 2)); } break; } done: From 0a72f00175e82148db79459494bf9ac12c3c6622 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 08:25:30 -0700 Subject: [PATCH 03/10] Elf_BE32_* --- src/p_elf.h | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/p_elf.h b/src/p_elf.h index dfad9c3b..c98ab396 100644 --- a/src/p_elf.h +++ b/src/p_elf.h @@ -313,29 +313,41 @@ __attribute_packed; // now for the actual types **************************************************************************/ -typedef TT_Elf ::Ehdr Elf_LE32_Ehdr; -typedef TT_Elf32::Phdr Elf_LE32_Phdr; -typedef TT_Elf32::Shdr Elf_LE32_Shdr; -typedef TT_Elf ::Dyn Elf_LE32_Dyn; -typedef TT_Elf32::Sym Elf_LE32_Sym; - typedef TT_Elf ::Ehdr Elf32_Ehdr; typedef TT_Elf32::Phdr Elf32_Phdr; typedef TT_Elf32::Shdr Elf32_Shdr; typedef TT_Elf ::Dyn Elf32_Dyn; typedef TT_Elf32::Sym Elf32_Sym; +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16) + +typedef TT_Elf ::Ehdr Elf_LE32_Ehdr; +typedef TT_Elf32::Phdr Elf_LE32_Phdr; +typedef TT_Elf32::Shdr Elf_LE32_Shdr; +typedef TT_Elf ::Dyn Elf_LE32_Dyn; +typedef TT_Elf32::Sym Elf_LE32_Sym; + ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16) -ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52) -ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32) -ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40) -ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8) -ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16) +typedef TT_Elf ::Ehdr Elf_BE32_Ehdr; +typedef TT_Elf32::Phdr Elf_BE32_Phdr; +typedef TT_Elf32::Shdr Elf_BE32_Shdr; +typedef TT_Elf ::Dyn Elf_BE32_Dyn; +typedef TT_Elf32::Sym Elf_BE32_Sym; + +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Shdr) == 40) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Dyn) == 8) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Sym) == 16) typedef TT_Elf ::Ehdr Elf_LE64_Ehdr; From 49c1da79c8615a7c57f8f15d77932bdb33d402e4 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 08:27:14 -0700 Subject: [PATCH 04/10] PackLinuxElf32arm ==> PackLinuxElf32armLe --- src/p_lx_elf.cpp | 16 ++++++++-------- src/p_lx_elf.h | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index d284f165..cc4f524e 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -208,7 +208,7 @@ PackLinuxElf64amd::getCompressionMethods(int method, int level) const } int const * -PackLinuxElf32arm::getCompressionMethods(int /*method*/, int /*level*/) const +PackLinuxElf32armLe::getCompressionMethods(int /*method*/, int /*level*/) const { static const int m_nrv2e[] = { M_NRV2E_8, -1 }; @@ -553,7 +553,7 @@ static const #include "stub/fold_elf32arm.h" int -PackLinuxElf32arm::buildLoader(const Filter *ft) +PackLinuxElf32armLe::buildLoader(const Filter *ft) { return buildLinuxLoader( linux_elf32arm_loader, sizeof(linux_elf32arm_loader), @@ -872,7 +872,7 @@ void PackLinuxElf32x86::pack1(OutputFile *fo, Filter &ft) generateElfHdr(fo, linux_i386elf_fold, getbrk(phdri, ehdri.e_phnum) ); } -void PackLinuxElf32arm::pack1(OutputFile *fo, Filter &ft) +void PackLinuxElf32armLe::pack1(OutputFile *fo, Filter &ft) { super::pack1(fo, ft); generateElfHdr(fo, linux_elf32arm_fold, getbrk(phdri, ehdri.e_phnum) ); @@ -1191,7 +1191,7 @@ void PackLinuxElf64amd::pack3(OutputFile *fo, Filter &ft) super::pack3(fo, ft); } -void PackLinuxElf32arm::pack3(OutputFile *fo, Filter &ft) +void PackLinuxElf32armLe::pack3(OutputFile *fo, Filter &ft) { unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info); unsigned const len0 = fo->getBytesWritten(); @@ -1675,22 +1675,22 @@ bool PackLinuxElf32x86::canPack() return true; } -PackLinuxElf32arm::PackLinuxElf32arm(InputFile *f) : super(f) +PackLinuxElf32armLe::PackLinuxElf32armLe(InputFile *f) : super(f) { } -PackLinuxElf32arm::~PackLinuxElf32arm() +PackLinuxElf32armLe::~PackLinuxElf32armLe() { } const int * -PackLinuxElf32arm::getFilters() const +PackLinuxElf32armLe::getFilters() const { static const int filters[] = { 0x50, -1 }; return filters; } -bool PackLinuxElf32arm::canPack() +bool PackLinuxElf32armLe::canPack() { unsigned char buf[sizeof(Elf32_Ehdr) + 14*sizeof(Elf32_Phdr)]; COMPILE_TIME_ASSERT(sizeof(buf) <= 512); diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index 157b2b42..cd74d688 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -330,12 +330,12 @@ protected: // linux/elfarm **************************************************************************/ -class PackLinuxElf32arm : public PackLinuxElf32Le +class PackLinuxElf32armLe : public PackLinuxElf32Le { typedef PackLinuxElf32Le super; public: - PackLinuxElf32arm(InputFile *f); - virtual ~PackLinuxElf32arm(); + PackLinuxElf32armLe(InputFile *f); + virtual ~PackLinuxElf32armLe(); virtual int getVersion() const { return 13; } virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARM; } virtual const char *getName() const { return "linux/arm"; } From d89e561a8535d0b4aac76e5c2116490db564c302 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 08:51:02 -0700 Subject: [PATCH 05/10] PackLinuxElf32armLe, PackLinuxElf32armBe --- src/conf.h | 3 ++- src/p_lx_elf.cpp | 66 ++++++++++++++++++++++++++++++++++++++---------- src/p_lx_elf.h | 24 +++++++++++++++--- 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/conf.h b/src/conf.h index e3f6023a..ba76c6c2 100644 --- a/src/conf.h +++ b/src/conf.h @@ -459,7 +459,7 @@ inline void operator delete[](void *p) #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_ARM 23 +#define UPX_F_LINUX_ELF32_ARMLE 23 #define UPX_F_PLAIN_TEXT 127 @@ -467,6 +467,7 @@ inline void operator delete[](void *p) #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_MAGIC_LE32 0x21585055 /* "UPX!" */ diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index cc4f524e..8d8b31d0 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -215,6 +215,14 @@ PackLinuxElf32armLe::getCompressionMethods(int /*method*/, int /*level*/) const return m_nrv2e; } +int const * +PackLinuxElf32armBe::getCompressionMethods(int /*method*/, int /*level*/) const +{ + static const int m_nrv2e[] = { M_NRV2E_8, -1 }; + + return m_nrv2e; +} + int const * PackLinuxElf32ppc::getFilters() const { @@ -560,6 +568,14 @@ PackLinuxElf32armLe::buildLoader(const Filter *ft) linux_elf32arm_fold, sizeof(linux_elf32arm_fold), ft ); } +int +PackLinuxElf32armBe::buildLoader(const Filter *ft) // FIXME +{ + return buildLinuxLoader( + linux_elf32arm_loader, sizeof(linux_elf32arm_loader), + linux_elf32arm_fold, sizeof(linux_elf32arm_fold), ft ); +} + static const #include "stub/l_lx_elfppc32.h" static const @@ -878,6 +894,12 @@ void PackLinuxElf32armLe::pack1(OutputFile *fo, Filter &ft) generateElfHdr(fo, linux_elf32arm_fold, getbrk(phdri, ehdri.e_phnum) ); } +void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft) // FIXME +{ + super::pack1(fo, ft); + generateElfHdr(fo, linux_elf32arm_fold, getbrk(phdri, ehdri.e_phnum) ); +} + void PackLinuxElf32ppc::pack1(OutputFile *fo, Filter &ft) { super::pack1(fo, ft); @@ -1205,7 +1227,7 @@ void PackLinuxElf32armLe::pack3(OutputFile *fo, Filter &ft) upx_byte *const p = const_cast(getLoader()); lsize = getLoaderSize(); unsigned const lo_va_user = 0x8000; // XXX - unsigned lo_va_stub = elfout.phdr[0].p_vaddr; + unsigned lo_va_stub = get_native32(&elfout.phdr[0].p_vaddr); unsigned adrc; unsigned adrm; unsigned adrx; @@ -1216,11 +1238,11 @@ void PackLinuxElf32armLe::pack3(OutputFile *fo, Filter &ft) bool const is_big = true; if (is_big) { elfout.ehdr.e_entry += lo_va_user - lo_va_stub; - elfout.phdr[0].p_vaddr = lo_va_user; - elfout.phdr[0].p_paddr = lo_va_user; - lo_va_stub = lo_va_user; + set_native32(&elfout.phdr[0].p_vaddr, lo_va_user); + set_native32(&elfout.phdr[0].p_paddr, lo_va_user); + lo_va_stub = lo_va_user; adrc = lo_va_stub; - adrm = getbrk(phdri, ehdri.e_phnum); + adrm = getbrk(phdri, get_native16(&ehdri.e_phnum)); adrx = hlen + (PAGE_MASK & (~PAGE_MASK + adrm)); // round up to page boundary lenm = PAGE_SIZE + len; cntc = len >> 5; @@ -1683,6 +1705,14 @@ PackLinuxElf32armLe::~PackLinuxElf32armLe() { } +PackLinuxElf32armBe::PackLinuxElf32armBe(InputFile *f) : super(f) +{ +} + +PackLinuxElf32armBe::~PackLinuxElf32armBe() +{ +} + const int * PackLinuxElf32armLe::getFilters() const { @@ -1690,6 +1720,13 @@ PackLinuxElf32armLe::getFilters() const return filters; } +const int * +PackLinuxElf32armBe::getFilters() const +{ + static const int filters[] = { 0x50, -1 }; + return filters; +} + bool PackLinuxElf32armLe::canPack() { unsigned char buf[sizeof(Elf32_Ehdr) + 14*sizeof(Elf32_Phdr)]; @@ -1707,18 +1744,19 @@ bool PackLinuxElf32armLe::canPack() return false; // additional requirements for linux/elfarm - if (ehdr->e_ehsize != sizeof(*ehdr)) { + if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) { throwCantPack("invalid Ehdr e_ehsize; try `--force-execve'"); return false; } - if (ehdr->e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr + if (get_native32(&ehdr->e_phoff) != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr throwCantPack("non-contiguous Ehdr/Phdr; try `--force-execve'"); return false; } // The first PT_LOAD32 must cover the beginning of the file (0==p_offset). - Elf32_Phdr const *phdr = (Elf32_Phdr const *)(buf + ehdr->e_phoff); - for (unsigned j=0; j < ehdr->e_phnum; ++phdr, ++j) { + Elf32_Phdr const *phdr = (Elf32_Phdr const *)(buf + get_native32(&ehdr->e_phoff)); + unsigned const e_phnum = get_native16(&ehdr->e_phnum); + for (unsigned j=0; j < e_phnum; ++phdr, ++j) { if (j >= 14) // 512 bytes holds Elf32_Ehdr + Elf32_Phdr[0..13] return false; if (phdr->PT_LOAD32 == get_native32(&phdr->p_type)) { @@ -1753,13 +1791,13 @@ bool PackLinuxElf32armLe::canPack() // Otherwise (no __libc_start_main as global undefined): skip it. // Also allow __uClibc_main and __uClibc_start_main . - if (Elf32_Ehdr::ET_DYN==ehdr->e_type) { + if (Elf32_Ehdr::ET_DYN==get_native16(&ehdr->e_type)) { // The DT_STRTAB has no designated length. Read the whole file. file_image = new char[file_size]; fi->seek(0, SEEK_SET); fi->readx(file_image, file_size); ehdri= *ehdr; - phdri= (Elf32_Phdr *)(ehdr->e_phoff + file_image); // do not free() !! + phdri= (Elf32_Phdr *)(get_native32(&ehdr->e_phoff) + file_image); // do not free() !! int j= ehdr->e_phnum; phdr= phdri; @@ -1778,9 +1816,9 @@ bool PackLinuxElf32armLe::canPack() for (j=0; j<3; ++j) { // elf_lookup() returns 0 if any required table is missing. Elf32_Sym const *const lsm = elf_lookup(run_start[j]); - if (lsm && lsm->st_shndx==Elf32_Sym::SHN_UNDEF - && lsm->st_info==lsm->Elf32_Sym::St_info(Elf32_Sym::STB_GLOBAL, Elf32_Sym::STT_FUNC) - && lsm->st_other==Elf32_Sym::STV_DEFAULT ) { + if (lsm && get_native16(&lsm->st_shndx)==Elf32_Sym::SHN_UNDEF + && get_native16(&lsm->st_info)==lsm->Elf32_Sym::St_info(Elf32_Sym::STB_GLOBAL, Elf32_Sym::STT_FUNC) + && get_native16(&lsm->st_other)==Elf32_Sym::STV_DEFAULT ) { break; } } diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index cd74d688..84fc4431 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -305,7 +305,6 @@ class PackLinuxElf32x86 : public PackLinuxElf32Le public: PackLinuxElf32x86(InputFile *f); virtual ~PackLinuxElf32x86(); - virtual int getVersion() const { return 13; } virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; } virtual const char *getName() const { return "linux/elf386"; } virtual const int *getFilters() const; @@ -336,9 +335,26 @@ class PackLinuxElf32armLe : public PackLinuxElf32Le public: PackLinuxElf32armLe(InputFile *f); virtual ~PackLinuxElf32armLe(); - virtual int getVersion() const { return 13; } - virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARM; } - virtual const char *getName() const { return "linux/arm"; } + virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; } + virtual const char *getName() const { return "linux/ElfArmLE"; } + virtual const int *getFilters() const; + virtual int const *getCompressionMethods(int method, int level) const; + + virtual bool canPack(); +protected: + virtual void pack1(OutputFile *, Filter &); // generate executable header + virtual void pack3(OutputFile *, Filter &); // append loader + virtual int buildLoader(const Filter *); +}; + +class PackLinuxElf32armBe : public PackLinuxElf32Be +{ + typedef PackLinuxElf32Be super; +public: + PackLinuxElf32armBe(InputFile *f); + virtual ~PackLinuxElf32armBe(); + virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; } + virtual const char *getName() const { return "linux/ElfArmBL"; } virtual const int *getFilters() const; virtual int const *getCompressionMethods(int method, int level) const; From 112b10c19d52fd4e5c8a252b40aed1b07ca523f8 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 08:53:41 -0700 Subject: [PATCH 06/10] avoid randomness for progid in Elf --- src/p_lx_elf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 8d8b31d0..7960d07b 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -879,7 +879,7 @@ void PackLinuxElf32::pack1(OutputFile */*fo*/, Filter &/*ft*/) fi->seek(e_phoff, SEEK_SET); fi->readx(phdri, sz_phdrs); - progid = getRandomId(); + progid = 0; // getRandomId(); not useful, so do not clutter } void PackLinuxElf32x86::pack1(OutputFile *fo, Filter &ft) @@ -919,7 +919,7 @@ void PackLinuxElf64::pack1(OutputFile */*fo*/, Filter &/*ft*/) fi->seek(e_phoff, SEEK_SET); fi->readx(phdri, sz_phdrs); - progid = getRandomId(); + progid = 0; // getRandomId(); not useful, so do not clutter } void PackLinuxElf64amd::pack1(OutputFile *fo, Filter &ft) From bd8acbde9796318f0c84b0a1830ce2f07d77b4cd Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 11:48:54 -0700 Subject: [PATCH 07/10] PackLinuxElf32armBe (Linux ARM big-endian) --- src/p_lx_elf.cpp | 230 +++++++++++++++++++++++++++++++++++++++++++++-- src/p_lx_elf.h | 4 +- src/packmast.cpp | 4 +- 3 files changed, 230 insertions(+), 8 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 7960d07b..2728a28d 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -560,6 +560,8 @@ static const static const #include "stub/fold_elf32arm.h" +#include "mem.h" + int PackLinuxElf32armLe::buildLoader(const Filter *ft) { @@ -568,12 +570,52 @@ PackLinuxElf32armLe::buildLoader(const Filter *ft) linux_elf32arm_fold, sizeof(linux_elf32arm_fold), ft ); } +static void brev( + unsigned char *const dst, + unsigned char const *const src, + unsigned len +) +{ + assert(0==(3 & len)); + assert(!((src -4)<=dst && dst < (len + src))); + for (unsigned j = 0; j < len; j += 4) { + dst[0+ j] = src[3+ j]; + dst[1+ j] = src[2+ j]; + dst[2+ j] = src[1+ j]; + dst[3+ j] = src[0+ j]; + } +} + +static void +ehdr_bele(Elf_BE32_Ehdr *const ehdr_be, Elf_LE32_Ehdr const *const ehdr_le) +{ + memcpy(&ehdr_be->e_ident, &ehdr_le->e_ident, sizeof(ehdr_be->e_ident)); + ehdr_be->e_type = ehdr_le->e_type; + ehdr_be->e_machine = ehdr_le->e_machine; + ehdr_be->e_version = ehdr_le->e_version; + ehdr_be->e_entry = ehdr_le->e_entry; + ehdr_be->e_phoff = ehdr_le->e_phoff; + ehdr_be->e_shoff = ehdr_le->e_shoff; + ehdr_be->e_flags = ehdr_le->e_flags; + ehdr_be->e_ehsize = ehdr_le->e_ehsize; + ehdr_be->e_phentsize = ehdr_le->e_phentsize; + ehdr_be->e_phnum = ehdr_le->e_phnum; + ehdr_be->e_shentsize = ehdr_le->e_shentsize; + ehdr_be->e_shnum = ehdr_le->e_shnum; + ehdr_be->e_shstrndx = ehdr_le->e_shstrndx; +} + int PackLinuxElf32armBe::buildLoader(const Filter *ft) // FIXME { - return buildLinuxLoader( - linux_elf32arm_loader, sizeof(linux_elf32arm_loader), - linux_elf32arm_fold, sizeof(linux_elf32arm_fold), ft ); + unsigned const sz_loader = sizeof(linux_elf32arm_loader); + unsigned const sz_fold = sizeof(linux_elf32arm_fold); + MemBuffer brev_loader(sz_loader); + MemBuffer brev_fold (sz_fold); + brev(brev_loader, linux_elf32arm_loader, sz_loader); + brev(brev_fold, linux_elf32arm_fold, sz_fold); + ehdr_bele((Elf_BE32_Ehdr *)&brev_fold, (Elf_LE32_Ehdr const *)linux_elf32arm_fold); + return buildLinuxLoader(brev_loader, sz_loader, brev_fold, sz_fold, ft); } static const @@ -897,7 +939,14 @@ void PackLinuxElf32armLe::pack1(OutputFile *fo, Filter &ft) void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft) // FIXME { super::pack1(fo, ft); - generateElfHdr(fo, linux_elf32arm_fold, getbrk(phdri, ehdri.e_phnum) ); + + cprElfHdr3 h3; + ehdr_bele((Elf_BE32_Ehdr *)&h3.ehdr, (Elf_LE32_Ehdr const *)linux_elf32arm_fold); + brev((unsigned char *)&h3.phdr[0], + (unsigned char const *)(sizeof(Elf32_Ehdr) + &linux_elf32arm_fold), + 3*sizeof(Elf32_Phdr) ); + + generateElfHdr(fo, &h3, getbrk(phdri, ehdri.e_phnum) ); } void PackLinuxElf32ppc::pack1(OutputFile *fo, Filter &ft) @@ -1237,7 +1286,8 @@ void PackLinuxElf32armLe::pack3(OutputFile *fo, Filter &ft) len += lsize; bool const is_big = true; if (is_big) { - elfout.ehdr.e_entry += lo_va_user - lo_va_stub; + set_native32( &elfout.ehdr.e_entry, + get_native32(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub); set_native32(&elfout.phdr[0].p_vaddr, lo_va_user); set_native32(&elfout.phdr[0].p_paddr, lo_va_user); lo_va_stub = lo_va_user; @@ -1273,6 +1323,67 @@ void PackLinuxElf32armLe::pack3(OutputFile *fo, Filter &ft) super::pack3(fo, ft); } +void PackLinuxElf32armBe::pack3(OutputFile *fo, Filter &ft) +{ + unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info); + unsigned const len0 = fo->getBytesWritten(); + unsigned len = len0; + unsigned const zero = 0; + fo->write(&zero, 3& -len); // align to 0 mod 4 + len += (3& -len); + +#define PAGE_MASK (~0u<<12) +#define PAGE_SIZE (-PAGE_MASK) + upx_byte *const p = const_cast(getLoader()); + lsize = getLoaderSize(); + unsigned const lo_va_user = 0x8000; // XXX + unsigned lo_va_stub = get_native32(&elfout.phdr[0].p_vaddr); + unsigned adrc; + unsigned adrm; + unsigned adrx; + unsigned cntc; + unsigned lenm; + + len += lsize; + bool const is_big = true; + if (is_big) { + set_native32( &elfout.ehdr.e_entry, + get_native32(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub); + set_native32(&elfout.phdr[0].p_vaddr, lo_va_user); + set_native32(&elfout.phdr[0].p_paddr, lo_va_user); + lo_va_stub = lo_va_user; + adrc = lo_va_stub; + adrm = getbrk(phdri, get_native16(&ehdri.e_phnum)); + adrx = hlen + (PAGE_MASK & (~PAGE_MASK + adrm)); // round up to page boundary + lenm = PAGE_SIZE + len; + cntc = len >> 5; + } + else { + adrm = lo_va_stub + len; + adrc = adrm; + adrx = lo_va_stub + hlen; + lenm = PAGE_SIZE; + cntc = 0; + } + adrm = PAGE_MASK & (~PAGE_MASK + adrm); // round up to page boundary + adrc = PAGE_MASK & (~PAGE_MASK + adrc); // round up to page boundary + + // patch in order of descending address + patch_be32(p,lsize,"ADRX", adrx); // compressed input for eXpansion + patch_be32(p,lsize,"LENX", len0 - hlen); + + patch_be32(p,lsize,"CNTC", cntc); // count for copy + patch_be32(p,lsize,"ADRC", adrc); // addr for copy + + patch_be32(p,lsize,"LENM", lenm); // len for map + patch_be32(p,lsize,"ADRM", adrm); // addr for map + +#undef PAGE_SIZE +#undef PAGE_MASK + + super::pack3(fo, ft); +} + void PackLinuxElf::pack4(OutputFile *fo, Filter &ft) { super::pack4(fo, ft); @@ -1836,6 +1947,115 @@ bool PackLinuxElf32armLe::canPack() return true; } +bool PackLinuxElf32armBe::canPack() +{ + unsigned char buf[sizeof(Elf32_Ehdr) + 14*sizeof(Elf32_Phdr)]; + COMPILE_TIME_ASSERT(sizeof(buf) <= 512); + + exetype = 0; + + fi->readx(buf, sizeof(buf)); + fi->seek(0, SEEK_SET); + Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; + + // now check the ELF header + if (checkEhdr(ehdr, Elf32_Ehdr::EM_ARM, + Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2MSB) != 0) + return false; + + // additional requirements for linux/elfarm + if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) { + throwCantPack("invalid Ehdr e_ehsize; try `--force-execve'"); + return false; + } + if (get_native32(&ehdr->e_phoff) != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr + throwCantPack("non-contiguous Ehdr/Phdr; try `--force-execve'"); + return false; + } + + // The first PT_LOAD32 must cover the beginning of the file (0==p_offset). + Elf32_Phdr const *phdr = (Elf32_Phdr const *)(buf + get_native32(&ehdr->e_phoff)); + unsigned const e_phnum = get_native16(&ehdr->e_phnum); + for (unsigned j=0; j < e_phnum; ++phdr, ++j) { + if (j >= 14) // 512 bytes holds Elf32_Ehdr + Elf32_Phdr[0..13] + return false; + if (phdr->PT_LOAD32 == get_native32(&phdr->p_type)) { + if (phdr->p_offset != 0) { + throwCantPack("invalid Phdr p_offset; try `--force-execve'"); + return false; + } + + // detect possible conflict upon invocation + //if (ehdr->e_type!=Elf32_Ehdr::ET_DYN + //&& (phdr->p_vaddr < (unsigned)(0x4000 + file_size) + // || phdr->p_paddr < (unsigned)(0x4000 + file_size) ) ) { + // throwAlreadyPackedByUPX(); // not necessarily, but mostly true + // return false; + //} + exetype = 1; + break; + } + } + + // We want to compress position-independent executable (gcc -pie) + // main programs, but compressing a shared library must be avoided + // because the result is no longer usable. In theory, there is no way + // to tell them apart: both are just ET_DYN. Also in theory, + // neither the presence nor the absence of any particular symbol name + // can be used to tell them apart; there are counterexamples. + // However, we will use the following heuristic suggested by + // Peter S. Mazinger September 2005: + // If a ET_DYN has __libc_start_main as a global undefined symbol, + // then the file is a position-independent executable main program + // (that depends on libc.so.6) and is eligible to be compressed. + // Otherwise (no __libc_start_main as global undefined): skip it. + // Also allow __uClibc_main and __uClibc_start_main . + + if (Elf32_Ehdr::ET_DYN==get_native16(&ehdr->e_type)) { + // The DT_STRTAB has no designated length. Read the whole file. + file_image = new char[file_size]; + fi->seek(0, SEEK_SET); + fi->readx(file_image, file_size); + ehdri= *ehdr; + phdri= (Elf32_Phdr *)(get_native32(&ehdr->e_phoff) + file_image); // do not free() !! + + int j= ehdr->e_phnum; + phdr= phdri; + for (; --j>=0; ++phdr) if (Elf32_Phdr::PT_DYNAMIC==get_native32(&phdr->p_type)) { + dynseg= (Elf32_Dyn const *)(get_native32(&phdr->p_offset) + file_image); + break; + } + // elf_find_dynamic() returns 0 if 0==dynseg. + hashtab= (unsigned int const *)elf_find_dynamic(Elf32_Dyn::DT_HASH); + dynstr= (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB); + dynsym= (Elf32_Sym const *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB); + + char const *const run_start[]= { + "__libc_start_main", "__uClibc_main", "__uClibc_start_main", + }; + for (j=0; j<3; ++j) { + // elf_lookup() returns 0 if any required table is missing. + Elf32_Sym const *const lsm = elf_lookup(run_start[j]); + if (lsm && get_native16(&lsm->st_shndx)==Elf32_Sym::SHN_UNDEF + && get_native16(&lsm->st_info)==lsm->Elf32_Sym::St_info(Elf32_Sym::STB_GLOBAL, Elf32_Sym::STT_FUNC) + && get_native16(&lsm->st_other)==Elf32_Sym::STV_DEFAULT ) { + break; + } + } + phdri = 0; // done "borrowing" this member + if (3<=j) { + return false; + } + } + if (!super::canPack()) + return false; + assert(exetype == 1); + + // set options + opt->o_unix.blocksize = blocksize = file_size; + return true; +} + unsigned PackLinuxElf32::elf_get_offset_from_address(unsigned const addr) const { diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index 84fc4431..cef0963d 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -336,7 +336,7 @@ public: PackLinuxElf32armLe(InputFile *f); virtual ~PackLinuxElf32armLe(); virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; } - virtual const char *getName() const { return "linux/ElfArmLE"; } + virtual const char *getName() const { return "linux/armLE"; } virtual const int *getFilters() const; virtual int const *getCompressionMethods(int method, int level) const; @@ -354,7 +354,7 @@ public: PackLinuxElf32armBe(InputFile *f); virtual ~PackLinuxElf32armBe(); virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; } - virtual const char *getName() const { return "linux/ElfArmBL"; } + virtual const char *getName() const { return "linux/armBE"; } virtual const int *getFilters() const; virtual int const *getCompressionMethods(int method, int level) const; diff --git a/src/packmast.cpp b/src/packmast.cpp index e19e4e75..47965a22 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -219,7 +219,9 @@ static Packer* try_packers(InputFile *f, try_function func) return p; if ((p = func(new PackLinuxElf64amd(f),f)) != NULL) return p; - if ((p = func(new PackLinuxElf32arm(f),f)) != NULL) + if ((p = func(new PackLinuxElf32armLe(f),f)) != NULL) + return p; + if ((p = func(new PackLinuxElf32armBe(f),f)) != NULL) return p; if ((p = func(new PackLinuxElf32ppc(f),f)) != NULL) return p; From dcc704a357767850d7201d649d2924079cb78f01 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 15:51:29 -0700 Subject: [PATCH 08/10] debug PackLinuxElf32armBe. Also unify subroutines. --- src/p_elf.h | 4 +-- src/p_lx_elf.cpp | 75 +++++++++++++++++++++++++----------------------- src/p_lx_elf.h | 22 ++++++-------- 3 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/p_elf.h b/src/p_elf.h index c98ab396..50d48b59 100644 --- a/src/p_elf.h +++ b/src/p_elf.h @@ -337,11 +337,11 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16) -typedef TT_Elf ::Ehdr Elf_BE32_Ehdr; +typedef TT_Elf ::Ehdr Elf_BE32_Ehdr; typedef TT_Elf32::Phdr Elf_BE32_Phdr; typedef TT_Elf32::Shdr Elf_BE32_Shdr; typedef TT_Elf ::Dyn Elf_BE32_Dyn; -typedef TT_Elf32::Sym Elf_BE32_Sym; +typedef TT_Elf32::Sym Elf_BE32_Sym; ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 2728a28d..b29fc3e8 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -46,12 +46,7 @@ int -PackLinuxElf32::checkEhdr( - Elf32_Ehdr const *ehdr, - unsigned char e_machine, - unsigned char ei_class, - unsigned char ei_data -) const +PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const { const unsigned char * const buf = ehdr->e_ident; @@ -94,12 +89,7 @@ PackLinuxElf32::checkEhdr( } int -PackLinuxElf64::checkEhdr( - Elf64_Ehdr const *ehdr, - unsigned char e_machine, - unsigned char ei_class, - unsigned char ei_data -) const +PackLinuxElf64::checkEhdr(Elf64_Ehdr const *ehdr) const { const unsigned char * const buf = ehdr->e_ident; @@ -141,7 +131,9 @@ PackLinuxElf64::checkEhdr( } PackLinuxElf::PackLinuxElf(InputFile *f) - : super(f) + : super(f), file_image(NULL), dynstr(NULL), + sz_phdrs(0), sz_elf_hdrs(0), + e_machine(0), ei_class(0), ei_data(0) { } @@ -151,7 +143,7 @@ PackLinuxElf::~PackLinuxElf() PackLinuxElf32::PackLinuxElf32(InputFile *f) : super(f), phdri(NULL), - file_image(NULL), dynseg(NULL), hashtab(NULL), dynstr(NULL), dynsym(NULL) + dynseg(NULL), hashtab(NULL), dynsym(NULL) { } @@ -264,6 +256,9 @@ void PackLinuxElf64::updateLoader(OutputFile *fo) PackLinuxElf32ppc::PackLinuxElf32ppc(InputFile *f) : super(f) { + e_machine = Elf32_Ehdr::EM_PPC; + ei_class = Elf32_Ehdr::ELFCLASS32; + ei_data = Elf32_Ehdr::ELFDATA2MSB; } PackLinuxElf32ppc::~PackLinuxElf32ppc() @@ -273,6 +268,9 @@ PackLinuxElf32ppc::~PackLinuxElf32ppc() PackLinuxElf64amd::PackLinuxElf64amd(InputFile *f) : super(f) { + e_machine = Elf64_Ehdr::EM_X86_64; + ei_class = Elf64_Ehdr::ELFCLASS64; + ei_data = Elf64_Ehdr::ELFDATA2LSB; } PackLinuxElf64amd::~PackLinuxElf64amd() @@ -590,6 +588,7 @@ static void ehdr_bele(Elf_BE32_Ehdr *const ehdr_be, Elf_LE32_Ehdr const *const ehdr_le) { memcpy(&ehdr_be->e_ident, &ehdr_le->e_ident, sizeof(ehdr_be->e_ident)); + ehdr_be->e_ident[Elf32_Ehdr::EI_DATA] = Elf32_Ehdr::ELFDATA2MSB; ehdr_be->e_type = ehdr_le->e_type; ehdr_be->e_machine = ehdr_le->e_machine; ehdr_be->e_version = ehdr_le->e_version; @@ -614,7 +613,7 @@ PackLinuxElf32armBe::buildLoader(const Filter *ft) // FIXME MemBuffer brev_fold (sz_fold); brev(brev_loader, linux_elf32arm_loader, sz_loader); brev(brev_fold, linux_elf32arm_fold, sz_fold); - ehdr_bele((Elf_BE32_Ehdr *)&brev_fold, (Elf_LE32_Ehdr const *)linux_elf32arm_fold); + ehdr_bele((Elf_BE32_Ehdr *)brev_fold.getVoidPtr(), (Elf_LE32_Ehdr const *)linux_elf32arm_fold); return buildLinuxLoader(brev_loader, sz_loader, brev_fold, sz_fold, ft); } @@ -657,8 +656,7 @@ PackLinuxElf32ppc::canPack() Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; // now check the ELF header - if (checkEhdr(ehdr, Elf32_Ehdr::EM_PPC, - Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2MSB) != 0) + if (checkEhdr(ehdr) != 0) return false; // additional requirements for linux/elf386 @@ -719,8 +717,7 @@ PackLinuxElf64amd::canPack() Elf64_Ehdr const *const ehdr = (Elf64_Ehdr const *)buf; // now check the ELF header - if (checkEhdr(ehdr, Elf64_Ehdr::EM_X86_64, - Elf64_Ehdr::ELFCLASS64, Elf64_Ehdr::ELFDATA2LSB) != 0) + if (checkEhdr(ehdr) != 0) return false; // additional requirements for linux/elf386 @@ -943,7 +940,7 @@ void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft) // FIXME cprElfHdr3 h3; ehdr_bele((Elf_BE32_Ehdr *)&h3.ehdr, (Elf_LE32_Ehdr const *)linux_elf32arm_fold); brev((unsigned char *)&h3.phdr[0], - (unsigned char const *)(sizeof(Elf32_Ehdr) + &linux_elf32arm_fold), + (unsigned char const *)(sizeof(Elf32_Ehdr) + (char const *)&linux_elf32arm_fold), 3*sizeof(Elf32_Phdr) ); generateElfHdr(fo, &h3, getbrk(phdri, ehdri.e_phnum) ); @@ -1369,14 +1366,14 @@ void PackLinuxElf32armBe::pack3(OutputFile *fo, Filter &ft) adrc = PAGE_MASK & (~PAGE_MASK + adrc); // round up to page boundary // patch in order of descending address - patch_be32(p,lsize,"ADRX", adrx); // compressed input for eXpansion - patch_be32(p,lsize,"LENX", len0 - hlen); + patch_be32(p,lsize,"XRDA", adrx); // compressed input for eXpansion + patch_be32(p,lsize,"XNEL", len0 - hlen); - patch_be32(p,lsize,"CNTC", cntc); // count for copy - patch_be32(p,lsize,"ADRC", adrc); // addr for copy + patch_be32(p,lsize,"CTNC", cntc); // count for copy + patch_be32(p,lsize,"CRDA", adrc); // addr for copy - patch_be32(p,lsize,"LENM", lenm); // len for map - patch_be32(p,lsize,"ADRM", adrm); // addr for map + patch_be32(p,lsize,"MNEL", lenm); // len for map + patch_be32(p,lsize,"MRDA", adrm); // addr for map #undef PAGE_SIZE #undef PAGE_MASK @@ -1671,6 +1668,9 @@ void PackLinuxElf64::unpack(OutputFile *fo) PackLinuxElf32x86::PackLinuxElf32x86(InputFile *f) : super(f) { + e_machine = Elf32_Ehdr::EM_386; + ei_class = Elf32_Ehdr::ELFCLASS32; + ei_data = Elf32_Ehdr::ELFDATA2LSB; } PackLinuxElf32x86::~PackLinuxElf32x86() @@ -1712,8 +1712,7 @@ bool PackLinuxElf32x86::canPack() Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; // now check the ELF header - if (checkEhdr(ehdr, Elf32_Ehdr::EM_386, - Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2LSB) != 0) + if (checkEhdr(ehdr) != 0) return false; // additional requirements for linux/elf386 @@ -1810,6 +1809,9 @@ bool PackLinuxElf32x86::canPack() PackLinuxElf32armLe::PackLinuxElf32armLe(InputFile *f) : super(f) { + e_machine = Elf32_Ehdr::EM_ARM; + ei_class = Elf32_Ehdr::ELFCLASS32; + ei_data = Elf32_Ehdr::ELFDATA2LSB; } PackLinuxElf32armLe::~PackLinuxElf32armLe() @@ -1818,6 +1820,9 @@ PackLinuxElf32armLe::~PackLinuxElf32armLe() PackLinuxElf32armBe::PackLinuxElf32armBe(InputFile *f) : super(f) { + e_machine = Elf32_Ehdr::EM_ARM; + ei_class = Elf32_Ehdr::ELFCLASS32; + ei_data = Elf32_Ehdr::ELFDATA2MSB; } PackLinuxElf32armBe::~PackLinuxElf32armBe() @@ -1850,8 +1855,7 @@ bool PackLinuxElf32armLe::canPack() Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; // now check the ELF header - if (checkEhdr(ehdr, Elf32_Ehdr::EM_ARM, - Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2LSB) != 0) + if (checkEhdr(ehdr) != 0) return false; // additional requirements for linux/elfarm @@ -1959,8 +1963,7 @@ bool PackLinuxElf32armBe::canPack() Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; // now check the ELF header - if (checkEhdr(ehdr, Elf32_Ehdr::EM_ARM, - Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2MSB) != 0) + if (checkEhdr(ehdr) != 0) return false; // additional requirements for linux/elfarm @@ -2075,8 +2078,8 @@ PackLinuxElf32::elf_find_dynamic(unsigned int const key) const { Elf32_Dyn const *dynp= dynseg; if (dynp) - for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (dynp->d_tag == key) { - unsigned const t= elf_get_offset_from_address(dynp->d_val); + for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_native32(&dynp->d_tag)==key) { + unsigned const t= elf_get_offset_from_address(get_native32(&dynp->d_val)); if (t) { return t + file_image; } @@ -2102,12 +2105,12 @@ unsigned PackLinuxElf32::elf_hash(char const *p) Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const { if (hashtab && dynsym && dynstr) { - unsigned const nbucket = hashtab[0]; + unsigned const nbucket = get_native32(&hashtab[0]); unsigned const *const buckets = &hashtab[2]; unsigned const *const chains = &buckets[nbucket]; unsigned const m = elf_hash(name) % nbucket; unsigned si; - for (si= buckets[m]; 0!=si; si= chains[si]) { + for (si= get_native32(&buckets[m]); 0!=si; si= get_native32(&chains[si])) { char const *const p= dynsym[si].st_name + dynstr; if (0==strcmp(name, p)) { return &dynsym[si]; diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index cef0963d..2fea5886 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -62,8 +62,15 @@ protected: virtual void unpack(OutputFile *fo) = 0; protected: + char *file_image; // if ET_DYN investigation + char const *dynstr; // from DT_STRTAB + unsigned sz_phdrs; // sizeof Phdr[] unsigned sz_elf_hdrs; // all Elf headers + + unsigned short e_machine; + unsigned char ei_class; + unsigned char ei_data; }; class PackLinuxElf32 : public PackLinuxElf @@ -73,11 +80,7 @@ public: PackLinuxElf32(InputFile *f); virtual ~PackLinuxElf32(); protected: - virtual int checkEhdr( - Elf32_Ehdr const *ehdr, - unsigned char e_machine, - unsigned char ei_class, - unsigned char ei_data) const; + virtual int checkEhdr(Elf32_Ehdr const *ehdr) const; virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack2(OutputFile *, Filter &); // append compressed data @@ -112,12 +115,9 @@ protected: protected: Elf32_Ehdr ehdri; // from input file Elf32_Phdr *phdri; // for input file - unsigned sz_phdrs; // sizeof Phdr[] - char *file_image; // if ET_DYN investigation Elf32_Dyn const *dynseg; // from PT_DYNAMIC unsigned int const *hashtab; // from DT_HASH - char const *dynstr; // from DT_STRTAB Elf32_Sym const *dynsym; // from DT_SYMTAB struct cprElfHdr1 { @@ -154,11 +154,7 @@ public: /*virtual int buildLoader(const Filter *);*/ protected: - virtual int checkEhdr( - Elf64_Ehdr const *ehdr, - unsigned char e_machine, - unsigned char ei_class, - unsigned char ei_data) const; + virtual int checkEhdr(Elf64_Ehdr const *ehdr) const; virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack2(OutputFile *, Filter &); // append compressed data From 4fc0a32572cd6d74037bc8318e12fd1e69df9683 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 18:55:26 -0700 Subject: [PATCH 09/10] Do not brev() strings in stub for PackLinuxEl32armBe. --- src/Makefile | 3 ++- src/p_lx_elf.cpp | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index e992e6ba..6d746c2e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,7 +18,8 @@ ifeq ($(CXX),) CXX = g++ endif ifeq ($(CXX),g++) -CXXFLAGS += -O2 -MMD +#CXXFLAGS += -O2 -MMD +CXXFLAGS += -g -MMD CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror endif CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index b29fc3e8..3fa33076 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -611,7 +611,24 @@ PackLinuxElf32armBe::buildLoader(const Filter *ft) // FIXME unsigned const sz_fold = sizeof(linux_elf32arm_fold); MemBuffer brev_loader(sz_loader); MemBuffer brev_fold (sz_fold); - brev(brev_loader, linux_elf32arm_loader, sz_loader); + + // linux_elf32arm_loader[] is all instructions, except for two strings + // at the end: the copyright message, and the SELinux message. + // The copyright message begins and ends with '\n', and the SELinux + // message ends with '\n'. So copy back to the third '\n' from the end, + // and apply brev() only before that point. + int nl = 0; + int j; + for (j= sz_loader; --j>=0; ) { + unsigned char const c = linux_elf32arm_loader[j]; + brev_loader[j] = c; + if ('\n'==c) { + if (3==++nl) { + break; + } + } + } + brev(brev_loader, linux_elf32arm_loader, j); brev(brev_fold, linux_elf32arm_fold, sz_fold); ehdr_bele((Elf_BE32_Ehdr *)brev_fold.getVoidPtr(), (Elf_LE32_Ehdr const *)linux_elf32arm_fold); return buildLinuxLoader(brev_loader, sz_loader, brev_fold, sz_fold, ft); From 3fc6535012c5b888b085dc9c7cd31b708860aee2 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 13 Jun 2006 19:02:21 -0700 Subject: [PATCH 10/10] un-debug Makefile --- src/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 6d746c2e..e992e6ba 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,8 +18,7 @@ ifeq ($(CXX),) CXX = g++ endif ifeq ($(CXX),g++) -#CXXFLAGS += -O2 -MMD -CXXFLAGS += -g -MMD +CXXFLAGS += -O2 -MMD CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror endif CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)