From 6e4aeffc0ce3232bf5fbe4aee1a218aefe71f276 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Fri, 12 Mar 2010 10:20:18 -0800 Subject: [PATCH] Withdraw support for shared libraries (.dylib) on Darwin (Apple Mac OS X). --- NEWS | 2 ++ src/p_mach.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++--- src/p_mach.h | 2 +- src/p_mach_enum.h | 22 +++++++++++------ src/packmast.cpp | 16 +++++++----- 5 files changed, 86 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index 9b806d76..b42ebe91 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ User visible changes for UPX ================================================================== Changes in 3.05 (27 Apr 2010): + * Withdraw support for shared libraries on Darwin (Apple Mac OS X) + because upx does not understand enough about .dylib. * i386-linux and amd64-linux support shared libraries (DT_INIT must exist, all info needed by runtime loader must be first in .text, etc.) * Linux /proc/self/exe now is preserved by default, by leaving behind diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 67e5c228..c7a65762 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -598,9 +598,59 @@ void PackMachBase::pack4dylib( // append PackHeader for (unsigned j = 0; j < nsects; ++secp, ++j) { seccmdtmp = *secp; if (o_end_txt <= seccmdtmp.offset) { seccmdtmp.offset += slide; } - if (seccmdtmp.nreloc) { - if (o_end_txt <= seccmdtmp.reloff) { seccmdtmp.reloff += slide; } + if (o_end_txt <= seccmdtmp.reloff) { seccmdtmp.reloff += slide; } + if (0==strncmp(&seccmdtmp.sectname[0], "__mod_init_func", 1+ 15)) { + if (seccmdtmp.flags==9 // FIXME: S_MOD_INIT_FUNC_POINTERS + && seccmdtmp.nreloc==0 && seccmdtmp.size==sizeof(Addr) ) { + seccmdtmp.addr = seccmdtmp.offset = init_address -4*4 - 8; + } + else + infoWarning("unknown __mod_init_func section"); } +#if 0 /*{*/ +// 2010-03-12 Stop work because I don't understand what is going on, +// and I cannot find good documentation on the meaning of various parts +// of .dylib. amd64(x86_64) is almost certain to fail in the dynamic +// loader, before the upx stub gets control. For instance: +// +// Program received signal EXC_BAD_ACCESS, Could not access memory. +// Reason: KERN_INVALID_ADDRESS at address: 0x000000015f00329a +// 0x00007fff5fc10ce3 in __dyld__ZN16ImageLoaderMachO23setupLazyPointerHandlerERKN11ImageLoader11LinkContextE () +// (gdb) bt +// #0 0x00007fff5fc10ce3 in __dyld__ZN16ImageLoaderMachO23setupLazyPointerHandlerERKN11ImageLoader11LinkContextE () +// #1 0x00007fff5fc138c2 in __dyld__ZN16ImageLoaderMachO6doBindERKN11ImageLoader11LinkContextEb () +// #2 0x00007fff5fc0c0ab in __dyld__ZN11ImageLoader13recursiveBindERKNS_11LinkContextEb () +// #3 0x00007fff5fc0c08f in __dyld__ZN11ImageLoader13recursiveBindERKNS_11LinkContextEb () +// #4 0x00007fff5fc0f49e in __dyld__ZN11ImageLoader4linkERKNS_11LinkContextEbbRKNS_10RPathChainE () +// #5 0x00007fff5fc04c56 in __dyld__ZN4dyld4linkEP11ImageLoaderbRKNS0_10RPathChainE () +// #6 0x00007fff5fc06e04 in __dyld__ZN4dyld5_mainEPK11mach_headermiPPKcS5_S5_ () +// #7 0x00007fff5fc01695 in __dyld__ZN13dyldbootstrap5startEPK11mach_headeriPPKcl () +// #8 0x00007fff5fc0103a in __dyld__dyld_start () +// #9 0x0000000100000000 in ?? () +// #10 0x0000000000000001 in ?? () +// #11 0x00007fff5fbffbd0 in ?? () +// +// The various paragraphs below are experiments in "commenting out" pieces of +// the compressed .dylib, trying to isolate the bug(s). + // FIXME + unsigned const t = seccmdtmp.flags & 0xff; + if (t==6 // FIXME: S_NON_LAZY_SYMBOL_POINTERS + || t==7 // FIXME: S_LAZY_SYMBOL_POINTERS + || t==8 // FIXME: S_SYMBOL_STUBS + || t==11 // FIXME: S_COALESCED + ) { + seccmdtmp.flags = 0; // FIXME: S_REGULAR + strcpy(seccmdtmp.sectname, "__data"); + } + // FIXME + if (0==strncmp("__stub_helper", &seccmdtmp.sectname[0], 1+ 13)) { + strcpy(seccmdtmp.sectname, "__text"); + } + // FIXME + if (0==strncmp("__dyld", &seccmdtmp.sectname[0], 1+ 6)) { + strcpy(seccmdtmp.sectname, "__text"); + } +#endif /*}*/ fo->rewrite(&seccmdtmp, sizeof(seccmdtmp)); hdrpos += sizeof(seccmdtmp); } @@ -748,11 +798,15 @@ void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader void PackDylibAMD64::pack3(OutputFile *fo, Filter &ft) // append loader { TE32 disp; + TE64 disp64; unsigned const zero = 0; unsigned len = fo->getBytesWritten(); - fo->write(&zero, 3& (0u-len)); - len += (3& (0u-len)) + 4*sizeof(disp); + fo->write(&zero, 7& (0u-len)); + len += (7& (0u-len)) + sizeof(disp64) + 4*sizeof(disp); + disp64= len; + fo->write(&disp64, sizeof(disp64)); // __mod_init_func + disp = prev_init_address; fo->write(&disp, sizeof(disp)); // user .init_address diff --git a/src/p_mach.h b/src/p_mach.h index d5e584e1..f6478383 100644 --- a/src/p_mach.h +++ b/src/p_mach.h @@ -571,7 +571,7 @@ protected: Mach_segment_command *rawmseg; // as input, with sections Mach_segment_command *msegcmd; // LC_SEGMENT first, without sections unsigned o_routines_cmd; // file offset to LC_ROUINTES - unsigned prev_init_address; + acc_uint64l_t prev_init_address; Mach_header mhdri; Mach_header mhdro; diff --git a/src/p_mach_enum.h b/src/p_mach_enum.h index c4faba95..b536f0c3 100644 --- a/src/p_mach_enum.h +++ b/src/p_mach_enum.h @@ -90,24 +90,32 @@ #ifdef WANT_MACH_SECTION_ENUM /*{*/ #undef WANT_MACH_SECTION_ENUM - enum { // section flags + enum { // section type (low byte only) S_REGULAR = 0, S_ZEROFILL, S_CSTRING_LITERALS, S_4BYTE_LITERALS, S_8BYTE_LITERALS, S_LITERAL_POINTERS, - S_NON_LAZY_SYMBOL_POINTERS, - S_LAZY_SYMBOL_POINTERS, + S_NON_LAZY_SYMBOL_POINTERS, // sectname __nl_symbol_ptr + S_LAZY_SYMBOL_POINTERS, // sectname __la_symbol_ptr S_SYMBOL_STUBS, - S_MOD_INIT_FUNC_POINTERS, - S_MOD_TERM_FNC_POINTERS, - S_COALESCED + S_MOD_INIT_FUNC_POINTERS, // sectname __mod_init_func + S_MOD_TERM_FUNC_POINTERS, + S_COALESCED, + S_GB_ZEROFILL, + S_INTERPOSING, + S_16BYTE_LITERALS, + S_DTRACE_DOF }; - enum { + enum { // section flags (high 24 bits) S_ATTR_PURE_INSTRUCTIONS = 0x80000000, S_ATTR_NO_TOC = 0x40000000, S_ATTR_STRIP_STATIC_SYMS = 0x20000000, + S_ATTR_NO_DEAD_STRIP = 0x10000000, + S_ATTR_LIVE_SUPPORT = 0x08000000, + S_ATTR_SELF_MODIFYING_CODE = 0x04000000, + S_ATTR_DEBUG = 0x02000000, S_ATTR_SOME_INSTRUCTIONS = 0x00000400, S_ATTR_EXT_RELOC = 0x00000200, S_ATTR_LOC_RELOC = 0x00000100 diff --git a/src/packmast.cpp b/src/packmast.cpp index 04b9a31b..a1142830 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -281,12 +281,16 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio return p; if ((p = func(new PackMachARMEL(f), user)) != NULL) return p; - if ((p = func(new PackDylibI386(f), user)) != NULL) - return p; - if ((p = func(new PackDylibPPC32(f), user)) != NULL) - return p; - if ((p = func(new PackDylibAMD64(f), user)) != NULL) - return p; + + // 2010-03-12 omit these because PackMachBase::pack4dylib (p_mach.cpp) + // does not understand what the Darwin (Apple Mac OS X) dynamic loader + // assumes about .dylib file structure. + //if ((p = func(new PackDylibI386(f), user)) != NULL) + // return p; + //if ((p = func(new PackDylibPPC32(f), user)) != NULL) + // return p; + //if ((p = func(new PackDylibAMD64(f), user)) != NULL) + // return p; return NULL; }