diff --git a/NEWS b/NEWS index 19667cd5..92ce1356 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ User visible changes for UPX ================================================================== Changes in 3.05 (01 XXX 2009): + * new format Mach/AMD64 supports 64-bit programs on Apple Macintosh. * new formats Dylib/i386 and Dylib/ppc32 support shared libraries [such as browser plugins] on Darwin (Apple Macintosh). An existing -init function (LC_ROUTINES command) is required. diff --git a/src/conf.h b/src/conf.h index a7886def..514dc10b 100644 --- a/src/conf.h +++ b/src/conf.h @@ -475,6 +475,8 @@ private: #define UPX_F_MACH_ARMEL 32 #define UPX_F_DYLIB_i386 33 +#define UPX_F_MACH_AMD64 34 +#define UPX_F_DYLIB_AMD64 35 #define UPX_F_PLAIN_TEXT 127 diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 381fa374..e2c3a01e 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -44,6 +44,11 @@ static const static const #include "stub/i386-darwin.macho-fold.h" +static const +#include "stub/amd64-darwin.macho-entry.h" +static const +#include "stub/amd64-darwin.macho-fold.h" + static const #include "stub/arm-darwin.macho-entry.h" static const @@ -66,6 +71,8 @@ static const static const #include "stub/powerpc-darwin.dylib-entry.h" +static unsigned lc_segment[2]; + template PackMachBase::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype, unsigned flavor, unsigned count, unsigned size) : @@ -76,6 +83,8 @@ PackMachBase::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype, { MachClass::compileTimeAssertions(); bele = N_BELE_CTP::getRTP((const BeLePolicy*) NULL); + lc_segment[0] = Mach_segment_command::LC_SEGMENT; + lc_segment[1] = Mach_segment_command::LC_SEGMENT_64; } template @@ -120,6 +129,12 @@ int const *PackMachI386::getFilters() const return filters; } +int const *PackMachAMD64::getFilters() const +{ + static const int filters[] = { 0x49, FT_END }; + return filters; +} + int const *PackMachARMEL::getFilters() const { static const int filters[] = { 0x50, FT_END }; @@ -136,6 +151,11 @@ Linker *PackMachI386::newLinker() const return new ElfLinkerX86; } +Linker *PackMachAMD64::newLinker() const +{ + return new ElfLinkerAMD64; +} + Linker *PackMachARMEL::newLinker() const { return new ElfLinkerArmLE; @@ -220,6 +240,21 @@ void PackMachI386::addStubEntrySections(Filter const *ft) addLoader("FOLDEXEC", NULL); } +void PackMachAMD64::addStubEntrySections(Filter const */*ft*/) +{ + addLoader("MACHMAINX", NULL); + //addLoader(getDecompressorSections(), NULL); + addLoader( + ( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL" + : M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL" + : M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL" + : M_IS_LZMA(ph.method) ? "LZMA_ELF00,+80C,LZMA_DEC20,LZMA_DEC30" + : NULL), NULL); + if (hasLoaderSection("CFLUSH")) + addLoader("CFLUSH"); + addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL); +} + void PackMachARMEL::addStubEntrySections(Filter const */*ft*/) { addLoader("MACHMAINX", NULL); @@ -305,6 +340,14 @@ PackMachI386::buildLoader(const Filter *ft) stub_i386_darwin_macho_fold, sizeof(stub_i386_darwin_macho_fold), ft ); } +void +PackMachAMD64::buildLoader(const Filter *ft) +{ + buildMachLoader( + stub_amd64_darwin_macho_entry, sizeof(stub_amd64_darwin_macho_entry), + stub_amd64_darwin_macho_fold, sizeof(stub_amd64_darwin_macho_fold), ft ); +} + void PackMachARMEL::buildLoader(const Filter *ft) { @@ -356,8 +399,9 @@ PackMachBase::compare_segment_command(void const *const aa, void const *const { Mach_segment_command const *const a = (Mach_segment_command const *)aa; Mach_segment_command const *const b = (Mach_segment_command const *)bb; - unsigned const xa = a->cmd - Mach_segment_command::LC_SEGMENT; - unsigned const xb = b->cmd - Mach_segment_command::LC_SEGMENT; + unsigned const lc_seg = lc_segment[sizeof(Addr)>>3]; + unsigned const xa = a->cmd - lc_seg; + unsigned const xb = b->cmd - lc_seg; if (xa < xb) return -1; // LC_SEGMENT first if (xa > xb) return 1; if (a->vmaddr < b->vmaddr) return -1; // ascending by .vmaddr @@ -393,6 +437,20 @@ void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader fo->rewrite(&linfo, sizeof(linfo)); } +void PackMachAMD64::pack4(OutputFile *fo, Filter &ft) // append PackHeader +{ + // offset of p_info in compressed file + overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo); + + super::pack4(fo, ft); + segcmdo.filesize = fo->getBytesWritten(); + segcmdo.vmsize += segcmdo.filesize; + fo->seek(sizeof(mhdro), SEEK_SET); + fo->rewrite(&segcmdo, sizeof(segcmdo)); + fo->rewrite(&threado, sizeof(threado)); + fo->rewrite(&linfo, sizeof(linfo)); +} + void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader { // offset of p_info in compressed file @@ -412,6 +470,11 @@ void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader #define PAGE_MASK (~0u<<12) #define PAGE_SIZE -PAGE_MASK +#undef PAGE_MASK64 +#undef PAGE_SIZE64 +#define PAGE_MASK64 (~(uint64_t)0<<12) +#define PAGE_SIZE64 -PAGE_MASK64 + template void PackMachBase::pack4dylib( // append PackHeader OutputFile *const fo, @@ -583,6 +646,20 @@ void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader super::pack3(fo, ft); } +void PackMachAMD64::pack3(OutputFile *fo, Filter &ft) // append loader +{ + TE32 disp; + unsigned const zero = 0; + unsigned len = fo->getBytesWritten(); + fo->write(&zero, 3& (0u-len)); + len += (3& (0u-len)); + disp = len - sz_mach_headers; + fo->write(&disp, sizeof(disp)); + + threado.state.rip = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */ + super::pack3(fo, ft); +} + void PackMachARMEL::pack3(OutputFile *fo, Filter &ft) // append loader { TE32 disp; @@ -652,7 +729,8 @@ unsigned PackMachBase::find_SEGMENT_gap( unsigned const k ) { - if (Mach_segment_command::LC_SEGMENT!=msegcmd[k].cmd + unsigned const lc_seg = lc_segment[sizeof(Addr)>>3]; + if (lc_seg!=msegcmd[k].cmd || 0==msegcmd[k].filesize ) { return 0; } @@ -667,7 +745,7 @@ unsigned PackMachBase::find_SEGMENT_gap( if (k==j) { break; } - if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd + if (lc_seg==msegcmd[j].cmd && 0!=msegcmd[j].filesize ) { unsigned const t = msegcmd[j].fileoff; if ((t - hi) < (lo - hi)) { @@ -696,13 +774,14 @@ void PackMachBase::pack3(OutputFile *fo, Filter &ft) template void PackMachBase::pack2(OutputFile *fo, Filter &ft) // append compressed body { + unsigned const lc_seg = lc_segment[sizeof(Addr)>>3]; Extent x; unsigned k; // count passes, set ptload vars uip->ui_total_passes = 0; for (k = 0; k < n_segment; ++k) { - if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd + if (lc_seg==msegcmd[k].cmd && 0!=msegcmd[k].filesize ) { uip->ui_total_passes++; if (my_filetype==Mach_header::MH_DYLIB) { @@ -728,7 +807,7 @@ void PackMachBase::pack2(OutputFile *fo, Filter &ft) // append compressed bo // instructions. So filter only the largest executable segment. unsigned exe_filesize_max = 0; for (k = 0; k < n_segment; ++k) - if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd + if (lc_seg==msegcmd[k].cmd && 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot) && exe_filesize_max < msegcmd[k].filesize) { exe_filesize_max = msegcmd[k].filesize; @@ -736,7 +815,7 @@ void PackMachBase::pack2(OutputFile *fo, Filter &ft) // append compressed bo int nx = 0; for (k = 0; k < n_segment; ++k) - if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd + if (lc_seg==msegcmd[k].cmd && 0!=msegcmd[k].filesize ) { x.offset = msegcmd[k].fileoff; x.size = msegcmd[k].filesize; @@ -793,6 +872,16 @@ void PackMachI386::pack1_setup_threado(OutputFile *const fo) fo->write(&threado, sizeof(threado)); } +void PackMachAMD64::pack1_setup_threado(OutputFile *const fo) +{ + threado.cmd = Mach_segment_command::LC_UNIXTHREAD; + threado.cmdsize = sizeof(threado); + threado.flavor = my_thread_flavor; + threado.count = my_thread_state_word_count; + memset(&threado.state, 0, sizeof(threado.state)); + fo->write(&threado, sizeof(threado)); +} + void PackMachARMEL::pack1_setup_threado(OutputFile *const fo) { threado.cmd = Mach_segment_command::LC_UNIXTHREAD; @@ -806,6 +895,7 @@ void PackMachARMEL::pack1_setup_threado(OutputFile *const fo) template void PackMachBase::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header { + unsigned const lc_seg = lc_segment[sizeof(Addr)>>3]; mhdro = mhdri; if (my_filetype==Mach_header::MH_EXECUTE) { mhdro.ncmds = 2; @@ -814,11 +904,11 @@ void PackMachBase::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e } fo->write(&mhdro, sizeof(mhdro)); - segcmdo.cmd = Mach_segment_command::LC_SEGMENT; + segcmdo.cmd = lc_seg; segcmdo.cmdsize = sizeof(segcmdo); strncpy((char *)segcmdo.segname, "__TEXT", sizeof(segcmdo.segname)); if (my_filetype==Mach_header::MH_EXECUTE) { - segcmdo.vmaddr = PAGE_MASK & (~PAGE_MASK + + segcmdo.vmaddr = PAGE_MASK64 & (~PAGE_MASK64 + msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr ); } if (my_filetype==Mach_header::MH_DYLIB) { @@ -851,6 +941,7 @@ void PackMachBase::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e template void PackMachBase::unpack(OutputFile *fo) { + unsigned const lc_seg = lc_segment[sizeof(Addr)>>3]; fi->seek(0, SEEK_SET); fi->readx(&mhdri, sizeof(mhdri)); rawmseg = (Mach_segment_command *)new char[(unsigned) mhdri.sizeofcmds]; @@ -890,7 +981,7 @@ void PackMachBase::unpack(OutputFile *fo) qsort(msegcmd, ncmds, sizeof(*msegcmd), compare_segment_command); n_segment = 0; for (unsigned j= 0; j < ncmds; ++j) { - n_segment += (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd); + n_segment += (lc_seg==msegcmd[j].cmd); } unsigned total_in = 0; @@ -906,7 +997,7 @@ void PackMachBase::unpack(OutputFile *fo) k < ncmds; (++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc)) ) { - if (Mach_segment_command::LC_SEGMENT==sc->cmd + if (lc_seg==sc->cmd && 0!=sc->filesize ) { unsigned filesize = sc->filesize; unpackExtent(filesize, fo, total_in, total_out, @@ -926,7 +1017,7 @@ void PackMachBase::unpack(OutputFile *fo) (++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc)), (rc = (Mach_segment_command const *)(rc->cmdsize + (char const *)rc)) ) { - if (Mach_segment_command::LC_SEGMENT==rc->cmd + if (lc_seg==rc->cmd && 0!=rc->filesize ) { fi->seek(rc->fileoff, SEEK_SET); fo->seek(sc->fileoff, SEEK_SET); @@ -955,21 +1046,23 @@ void PackMachBase::unpack(OutputFile *fo) template bool PackMachBase::canPack() { + unsigned const lc_seg = lc_segment[sizeof(Addr)>>3]; fi->seek(0, SEEK_SET); fi->readx(&mhdri, sizeof(mhdri)); - if (Mach_header::MH_MAGIC !=mhdri.magic - || my_cputype !=mhdri.cputype - || my_filetype !=mhdri.filetype + if ((Mach_header::MH_MAGIC + (sizeof(Addr)>>3)) !=mhdri.magic + || my_cputype !=mhdri.cputype + || my_filetype !=mhdri.filetype ) return false; rawmseg = (Mach_segment_command *)new char[(unsigned) mhdri.sizeofcmds]; fi->readx(rawmseg, mhdri.sizeofcmds); - msegcmd = new Mach_segment_command[(unsigned) mhdri.ncmds]; + unsigned const ncmds = mhdri.ncmds; + msegcmd = new Mach_segment_command[ncmds]; unsigned char const *ptr = (unsigned char const *)rawmseg; - for (unsigned j= 0; j < mhdri.ncmds; ++j) { + for (unsigned j= 0; j < ncmds; ++j) { msegcmd[j] = *(Mach_segment_command const *)ptr; if (((Mach_segment_command const *)ptr)->cmd == Mach_segment_command::LC_ROUTINES) { @@ -984,11 +1077,11 @@ bool PackMachBase::canPack() } // Put LC_SEGMENT together at the beginning, ascending by .vmaddr. - qsort(msegcmd, mhdri.ncmds, sizeof(*msegcmd), compare_segment_command); + qsort(msegcmd, ncmds, sizeof(*msegcmd), compare_segment_command); // Check that LC_SEGMENTs form one contiguous chunk of the file. - for (unsigned j= 0; j < mhdri.ncmds; ++j) { - if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd) { + for (unsigned j= 0; j < ncmds; ++j) { + if (lc_seg==msegcmd[j].cmd) { if (~PAGE_MASK & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) { return false; } @@ -1017,6 +1110,7 @@ bool PackMachBase::canPack() template class PackMachBase; template class PackMachBase; +template class PackMachBase; PackMachFat::PackMachFat(InputFile *f) : super(f) diff --git a/src/p_mach.h b/src/p_mach.h index f7e304be..d406cff6 100644 --- a/src/p_mach.h +++ b/src/p_mach.h @@ -256,6 +256,18 @@ __packed_struct(Mach_i386_thread_state) Word ds, es, fs, gs; __packed_struct_end() +template +__packed_struct(Mach_AMD64_thread_state) + typedef typename TMachITypes::Xword Xword; + + Xword rax, rbx, rcx, rdx; + Xword rdi, rsi, rbp, rsp; + Xword r8, r9, r10, r11; + Xword r12, r13, r14, r15; + Xword rip, rflags; + Xword cs, fs, gs; +__packed_struct_end() + template __packed_struct(Mach_i386_new_thread_state) typedef typename TMachITypes::Word Word; @@ -357,6 +369,7 @@ struct MachClass_32 typedef N_Mach::Mach_twolevel_hints_command Mach_twolevel_hints_command; typedef N_Mach::Mach_ppc_thread_state Mach_ppc_thread_state; typedef N_Mach::Mach_i386_thread_state Mach_i386_thread_state; + typedef N_Mach::Mach_AMD64_thread_state Mach_AMD64_thread_state; typedef N_Mach::Mach_ARM_thread_state Mach_ARM_thread_state; static void compileTimeAssertions() { @@ -375,6 +388,7 @@ struct MachClass_64 typedef typename TP::U32 TE32; typedef typename TP::U64 TE64; typedef N_Mach::MachITypes MachITypes; + typedef typename MachITypes::Addr Addr; // Mach types typedef N_Mach::Mach_header64 Mach_header; @@ -451,6 +465,7 @@ typedef MachClass_LE64::Mach_twolevel_hints_command MachLE64_twolevel_hints_co typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state; typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state; +typedef MachClass_LE32::Mach_AMD64_thread_state Mach_AMD64_thread_state; // FIXME LE32 vs AMD64 typedef MachClass_LE32::Mach_ARM_thread_state Mach_ARM_thread_state; #include "p_unix.h" @@ -626,7 +641,7 @@ class PackMachI386 : public PackMachBase public: PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386, - Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::i386_THREAD_STATE, + Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::x86_THREAD_STATE32, sizeof(Mach_i386_thread_state)>>2, sizeof(threado)) { } virtual int getFormat() const { return UPX_F_MACH_i386; } @@ -671,6 +686,41 @@ protected: virtual void buildLoader(const Filter *ft); }; +class PackMachAMD64 : public PackMachBase +{ + typedef PackMachBase super; + +public: + PackMachAMD64(InputFile *f) : super(f, Mach_header::CPU_TYPE_X86_64, + Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::x86_THREAD_STATE64, + sizeof(Mach_AMD64_thread_state)>>2, sizeof(threado)) { } + + virtual int getFormat() const { return UPX_F_MACH_AMD64; } + virtual const char *getName() const { return "Mach/AMD64"; } + virtual const char *getFullName(const options_t *) const { return "AMD64-darwin.macho"; } +protected: + virtual const int *getFilters() const; + + virtual void pack1_setup_threado(OutputFile *const fo); + virtual void pack3(OutputFile *, Filter &); // append loader + virtual void pack4(OutputFile *, Filter &); // append PackHeader + virtual Linker* newLinker() const; + virtual void buildLoader(const Filter *ft); + virtual void addStubEntrySections(Filter const *); + + __packed_struct(Mach_thread_command) + LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */ + LE32 cmdsize; /* total size of this command */ + LE32 flavor; + LE32 count; /* sizeof(following_thread_state)/4 */ + Mach_AMD64_thread_state state; + #define WANT_MACH_THREAD_ENUM + #include "p_mach_enum.h" + __packed_struct_end() + + Mach_thread_command threado; +}; + class PackMachARMEL : public PackMachBase { typedef PackMachBase super; diff --git a/src/p_mach_enum.h b/src/p_mach_enum.h index e36c8d03..b8316637 100644 --- a/src/p_mach_enum.h +++ b/src/p_mach_enum.h @@ -40,6 +40,7 @@ }; enum { // cputype CPU_TYPE_I386 = 7, + CPU_TYPE_X86_64 = 0x01000007, CPU_TYPE_ARM = 12, CPU_TYPE_POWERPC = 0x00000012, CPU_TYPE_POWERPC64 = 0x01000012 @@ -117,7 +118,9 @@ #undef WANT_MACH_THREAD_ENUM enum { // thread flavor PPC_THREAD_STATE = 1, - i386_THREAD_STATE = 1, + PPC_THREAD_STATE64 = 5, + x86_THREAD_STATE32 = 1, + x86_THREAD_STATE64 = 4, i386_OLD_THREAD_STATE = -1, ARM_THREAD_STATE = 1 }; diff --git a/src/packmast.cpp b/src/packmast.cpp index 90925316..b9e47137 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -277,6 +277,8 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio return p; if ((p = func(new PackMachI386(f), user)) != NULL) return p; + if ((p = func(new PackMachAMD64(f), user)) != NULL) + return p; if ((p = func(new PackMachARMEL(f), user)) != NULL) return p; if ((p = func(new PackDylibI386(f), user)) != NULL) diff --git a/src/stub/Makefile b/src/stub/Makefile index bd8e72cb..8776e44a 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -48,6 +48,8 @@ endif # ************************************************************************/ ifndef STUBS +STUBS += amd64-darwin.macho-entry.h +STUBS += amd64-darwin.macho-fold.h STUBS += amd64-linux.elf-entry.h STUBS += amd64-linux.elf-fold.h STUBS += amd64-linux.kernel.vmlinux.h @@ -248,6 +250,34 @@ tc.arch-i386.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT tc.arch-i386.djasm = djasm +# /*********************************************************************** +# // amd64-darwin.macho +# ************************************************************************/ + +# info: we use the tc settings from amd64-linux.elf +amd64-darwin.macho%.h : tc_list = amd64-linux.elf default +amd64-darwin.macho%.h : tc_bfdname = elf64-x86-64 + +amd64-darwin.macho-entry.h : $(srcdir)/src/$$T.S + $(call tc,gcc) -c $< -o tmp/$T.bin + $(call tc,f-embed_objinfo,tmp/$T.bin) + $(call tc,bin2h) tmp/$T.bin $@ + +amd64-darwin.macho-fold.h : tmp/$$T.o tmp/amd64-darwin.macho-main.o + $(call tc,ld) --no-warn-mismatch --strip-all --oformat binary -Map tmp/$T.map $(filter %.o,$^) -o tmp/$T.bin + chmod a-x tmp/$T.bin + $(call tc,bin2h) tmp/$T.bin $@ + +tmp/amd64-darwin.macho-fold.o : $(srcdir)/src/$$T.S + $(call tc,gcc) -c $< -o $@ + $(call tc,f-objstrip,$@) + +tmp/amd64-darwin.macho-main.o : $(srcdir)/src/$$T.c + $(call tc,gcc) -c -Os $< -o $@ + $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm + + # /*********************************************************************** # // amd64-linux.elf # ************************************************************************/ diff --git a/src/stub/amd64-darwin.macho-entry.h b/src/stub/amd64-darwin.macho-entry.h new file mode 100644 index 00000000..a660d018 --- /dev/null +++ b/src/stub/amd64-darwin.macho-entry.h @@ -0,0 +1,605 @@ +/* amd64-darwin.macho-entry.h + created from amd64-darwin.macho-entry.bin, 9044 (0x2354) bytes + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2009 Laszlo Molnar + Copyright (C) 2000-2009 John F. Reiser + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + + John F. Reiser + + */ + + +#define STUB_AMD64_DARWIN_MACHO_ENTRY_SIZE 9044 +#define STUB_AMD64_DARWIN_MACHO_ENTRY_ADLER32 0x393d27d0 +#define STUB_AMD64_DARWIN_MACHO_ENTRY_CRC32 0xdd898da3 + +unsigned char stub_amd64_darwin_macho_entry[9044] = { +/* 0x0000 */ 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x0010 */ 1, 0, 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x0020 */ 0, 0, 0, 0, 0, 0, 0, 0,224, 23, 0, 0, 0, 0, 0, 0, +/* 0x0030 */ 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 64, 0, 21, 0, 18, 0, +/* 0x0040 */ 232, 0, 0, 0, 0, 85, 83, 81, 82, 72, 1,254, 86, 72,137,254, +/* 0x0050 */ 72,137,215, 49,219, 49,201, 72,131,205,255,232, 80, 0, 0, 0, +/* 0x0060 */ 1,219,116, 2,243,195,139, 30, 72,131,238,252, 17,219,138, 22, +/* 0x0070 */ 243,195, 72,141, 4, 47,131,249, 5,138, 16,118, 33, 72,131,253, +/* 0x0080 */ 252,119, 27,131,233, 4,139, 16, 72,131,192, 4,131,233, 4,137, +/* 0x0090 */ 23, 72,141,127, 4,115,239,131,193, 4,138, 16,116, 16, 72,255, +/* 0x00a0 */ 192,136, 23,131,233, 1,138, 16, 72,141,127, 1,117,240,243,195, +/* 0x00b0 */ 252, 65, 91, 65,128,248, 8,116, 13,233,172, 0, 0, 0, 72,255, +/* 0x00c0 */ 198,136, 23, 72,255,199,138, 22, 1,219,117, 10,139, 30, 72,131, +/* 0x00d0 */ 238,252, 17,219,138, 22,114,230,141, 65, 1,235, 7,255,200, 65, +/* 0x00e0 */ 255,211, 17,192, 65,255,211, 17,192, 1,219,117, 10,139, 30, 72, +/* 0x00f0 */ 131,238,252, 17,219,138, 22,115,228,131,232, 3,114, 29,193,224, +/* 0x0100 */ 8, 15,182,210, 9,208, 72,255,198,131,240,255, 15,132, 0, 0, +/* 0x0110 */ 0, 0,209,248, 72, 99,232,114, 56,235, 14, 1,219,117, 8,139, +/* 0x0120 */ 30, 72,131,238,252, 17,219,114, 40,255,193, 1,219,117, 8,139, +/* 0x0130 */ 30, 72,131,238,252, 17,219,114, 24, 65,255,211, 17,201, 1,219, +/* 0x0140 */ 117, 8,139, 30, 72,131,238,252, 17,219,115,237,131,193, 2,235, +/* 0x0150 */ 5, 65,255,211, 17,201, 72,129,253, 0,251,255,255,131,209, 2, +/* 0x0160 */ 232, 0, 0, 0, 0,233, 92,255,255,255, 65,128,248, 5,116, 13, +/* 0x0170 */ 233,147, 0, 0, 0, 72,255,198,136, 23, 72,255,199,138, 22, 1, +/* 0x0180 */ 219,117, 10,139, 30, 72,131,238,252, 17,219,138, 22,114,230,141, +/* 0x0190 */ 65, 1,235, 7,255,200, 65,255,211, 17,192, 65,255,211, 17,192, +/* 0x01a0 */ 1,219,117, 10,139, 30, 72,131,238,252, 17,219,138, 22,115,228, +/* 0x01b0 */ 131,232, 3,114, 27,193,224, 8, 15,182,210, 9,208, 72,255,198, +/* 0x01c0 */ 131,240,255, 15,132, 0, 0, 0, 0,209,248, 72, 99,232,235, 3, +/* 0x01d0 */ 65,255,211, 17,201, 65,255,211, 17,201,117, 24,255,193, 65,255, +/* 0x01e0 */ 211, 17,201, 1,219,117, 8,139, 30, 72,131,238,252, 17,219,115, +/* 0x01f0 */ 237,131,193, 2, 72,129,253, 0,251,255,255,131,209, 1,232, 0, +/* 0x0200 */ 0, 0, 0,233,117,255,255,255, 65,128,248, 2,116, 13,233,133, +/* 0x0210 */ 0, 0, 0, 72,255,198,136, 23, 72,255,199,138, 22, 1,219,117, +/* 0x0220 */ 10,139, 30, 72,131,238,252, 17,219,138, 22,114,230,141, 65, 1, +/* 0x0230 */ 65,255,211, 17,192, 1,219,117, 10,139, 30, 72,131,238,252, 17, +/* 0x0240 */ 219,138, 22,115,235,131,232, 3,114, 23,193,224, 8, 15,182,210, +/* 0x0250 */ 9,208, 72,255,198,131,240,255, 15,132, 0, 0, 0, 0, 72, 99, +/* 0x0260 */ 232,141, 65, 1, 65,255,211, 17,201, 65,255,211, 17,201,117, 24, +/* 0x0270 */ 137,193,131,192, 2, 65,255,211, 17,201, 1,219,117, 8,139, 30, +/* 0x0280 */ 72,131,238,252, 17,219,115,237, 72,129,253, 0,243,255,255, 17, +/* 0x0290 */ 193,232, 0, 0, 0, 0,235,131, 65,128,248, 14, 15,133, 0, 0, +/* 0x02a0 */ 0, 0, 85, 72,137,229, 68,139, 9, 73,137,208, 72,137,242, 72, +/* 0x02b0 */ 141,119, 2, 86,138, 7,255,202,136,193, 36, 7,192,233, 3, 72, +/* 0x02c0 */ 199,195, 0,253,255,255, 72,211,227,136,193, 72,141,156, 92,136, +/* 0x02d0 */ 241,255,255, 72,131,227,192,106, 0, 72, 57,220,117,249, 83, 72, +/* 0x02e0 */ 141,123, 8,138, 78,255,255,202,136, 71, 2,136,200,192,233, 4, +/* 0x02f0 */ 136, 79, 1, 36, 15,136, 7, 72,141, 79,252, 80, 65, 87, 72,141, +/* 0x0300 */ 71, 4, 69, 49,255, 65, 86, 65,190, 1, 0, 0, 0, 65, 85, 69, +/* 0x0310 */ 49,237, 65, 84, 85, 83, 72,137, 76, 36,240, 72,137, 68, 36,216, +/* 0x0320 */ 184, 1, 0, 0, 0, 72,137,116, 36,248, 76,137, 68, 36,232,137, +/* 0x0330 */ 195, 68,137, 76, 36,228, 15,182, 79, 2,211,227,137,217, 72,139, +/* 0x0340 */ 92, 36, 56,255,201,137, 76, 36,212, 15,182, 79, 1,211,224, 72, +/* 0x0350 */ 139, 76, 36,240,255,200,137, 68, 36,208, 15,182, 7,199, 1, 0, +/* 0x0360 */ 0, 0, 0,199, 68, 36,200, 0, 0, 0, 0,199, 68, 36,196, 1, +/* 0x0370 */ 0, 0, 0,199, 68, 36,192, 1, 0, 0, 0,199, 68, 36,188, 1, +/* 0x0380 */ 0, 0, 0,199, 3, 0, 0, 0, 0,137, 68, 36,204, 15,182, 79, +/* 0x0390 */ 1, 1,193,184, 0, 3, 0, 0,211,224, 49,201,141,184, 54, 7, +/* 0x03a0 */ 0, 0, 65, 57,255,115, 19, 72,139, 92, 36,216,137,200,255,193, +/* 0x03b0 */ 57,249,102,199, 4, 67, 0, 4,235,235, 72,139,124, 36,248,137, +/* 0x03c0 */ 208, 69, 49,210, 65,131,203,255, 49,210, 73,137,252, 73, 1,196, +/* 0x03d0 */ 76, 57,231, 15,132,239, 8, 0, 0, 15,182, 7, 65,193,226, 8, +/* 0x03e0 */ 255,194, 72,255,199, 65, 9,194,131,250, 4,126,227, 68, 59,124, +/* 0x03f0 */ 36,228, 15,131,218, 8, 0, 0,139, 68, 36,212, 72, 99, 92, 36, +/* 0x0400 */ 200, 72,139, 84, 36,216, 68, 33,248,137, 68, 36,184, 72, 99,108, +/* 0x0410 */ 36,184, 72,137,216, 72,193,224, 4, 72, 1,232, 65,129,251,255, +/* 0x0420 */ 255,255, 0, 76,141, 12, 66,119, 26, 76, 57,231, 15,132,150, 8, +/* 0x0430 */ 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, +/* 0x0440 */ 65, 9,194, 65, 15,183, 17, 68,137,216,193,232, 11, 15,183,202, +/* 0x0450 */ 15,175,193, 65, 57,194, 15,131,197, 1, 0, 0, 65,137,195,184, +/* 0x0460 */ 0, 8, 0, 0, 72,139, 92, 36,216, 41,200, 15,182, 76, 36,204, +/* 0x0470 */ 190, 1, 0, 0, 0,193,248, 5,141, 4, 2, 65, 15,182,213,102, +/* 0x0480 */ 65,137, 1,139, 68, 36,208, 68, 33,248,211,224,185, 8, 0, 0, +/* 0x0490 */ 0, 43, 76, 36,204,211,250, 1,208,105,192, 0, 3, 0, 0,131, +/* 0x04a0 */ 124, 36,200, 6,137,192, 76,141,140, 67,108, 14, 0, 0, 15,142, +/* 0x04b0 */ 184, 0, 0, 0, 72,139, 84, 36,232, 68,137,248, 68, 41,240, 15, +/* 0x04c0 */ 182, 44, 2, 1,237, 72, 99,214,137,235,129,227, 0, 1, 0, 0, +/* 0x04d0 */ 65,129,251,255,255,255, 0, 72, 99,195, 73,141, 4, 65, 76,141, +/* 0x04e0 */ 4, 80,119, 26, 76, 57,231, 15,132,219, 7, 0, 0, 15,182, 7, +/* 0x04f0 */ 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, 15, +/* 0x0500 */ 183,144, 0, 2, 0, 0, 68,137,216,193,232, 11, 15,183,202, 15, +/* 0x0510 */ 175,193, 65, 57,194,115, 32, 65,137,195,184, 0, 8, 0, 0, 1, +/* 0x0520 */ 246, 41,200,193,248, 5,133,219,141, 4, 2,102, 65,137,128, 0, +/* 0x0530 */ 2, 0, 0,116, 33,235, 45, 65, 41,195, 65, 41,194,137,208,102, +/* 0x0540 */ 193,232, 5,141,116, 54, 1,102, 41,194,133,219,102, 65,137,144, +/* 0x0550 */ 0, 2, 0, 0,116, 14,129,254,255, 0, 0, 0, 15,142, 97,255, +/* 0x0560 */ 255,255,235,120,129,254,255, 0, 0, 0,127,112, 72, 99,198, 65, +/* 0x0570 */ 129,251,255,255,255, 0, 77,141, 4, 65,119, 26, 76, 57,231, 15, +/* 0x0580 */ 132, 67, 7, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, +/* 0x0590 */ 72,255,199, 65, 9,194, 65, 15,183, 16, 68,137,216,193,232, 11, +/* 0x05a0 */ 15,183,202, 15,175,193, 65, 57,194,115, 24, 65,137,195,184, 0, +/* 0x05b0 */ 8, 0, 0, 1,246, 41,200,193,248, 5,141, 4, 2,102, 65,137, +/* 0x05c0 */ 0,235,161, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,141, +/* 0x05d0 */ 116, 54, 1,102, 41,194,102, 65,137, 16,235,136, 72,139, 76, 36, +/* 0x05e0 */ 232, 68,137,248, 65,255,199, 65,137,245, 64,136, 52, 1,131,124, +/* 0x05f0 */ 36,200, 3,127, 13,199, 68, 36,200, 0, 0, 0, 0,233,166, 6, +/* 0x0600 */ 0, 0,139, 84, 36,200,139, 68, 36,200,131,234, 3,131,232, 6, +/* 0x0610 */ 131,124, 36,200, 9, 15, 79,208,137, 84, 36,200,233,135, 6, 0, +/* 0x0620 */ 0, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41,194, +/* 0x0630 */ 72,139, 68, 36,216, 65,129,251,255,255,255, 0,102, 65,137, 17, +/* 0x0640 */ 72,141, 52, 88,119, 26, 76, 57,231, 15,132,121, 6, 0, 0, 15, +/* 0x0650 */ 182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, +/* 0x0660 */ 15,183,150,128, 1, 0, 0, 68,137,216,193,232, 11, 15,183,202, +/* 0x0670 */ 15,175,193, 65, 57,194,115, 78, 65,137,195,184, 0, 8, 0, 0, +/* 0x0680 */ 76,139, 76, 36,216, 41,200,139, 76, 36,196, 68,137,116, 36,196, +/* 0x0690 */ 193,248, 5,141, 4, 2,139, 84, 36,192,137, 76, 36,192,102,137, +/* 0x06a0 */ 134,128, 1, 0, 0, 49,192,131,124, 36,200, 6,137, 84, 36,188, +/* 0x06b0 */ 15,159,192, 73,129,193,100, 6, 0, 0,141, 4, 64,137, 68, 36, +/* 0x06c0 */ 200,233, 84, 2, 0, 0, 65, 41,195, 65, 41,194,137,208,102,193, +/* 0x06d0 */ 232, 5,102, 41,194, 65,129,251,255,255,255, 0,102,137,150,128, +/* 0x06e0 */ 1, 0, 0,119, 26, 76, 57,231, 15,132,218, 5, 0, 0, 15,182, +/* 0x06f0 */ 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 15, +/* 0x0700 */ 183,150,152, 1, 0, 0, 68,137,216,193,232, 11, 15,183,202, 15, +/* 0x0710 */ 175,193, 65, 57,194, 15,131,208, 0, 0, 0, 65,184, 0, 8, 0, +/* 0x0720 */ 0, 65,137,195, 72,193,227, 5, 68,137,192, 41,200,193,248, 5, +/* 0x0730 */ 141, 4, 2,102,137,134,152, 1, 0, 0, 72,139, 68, 36,216, 72, +/* 0x0740 */ 1,216, 65,129,251,255,255,255, 0, 72,141, 52,104,119, 26, 76, +/* 0x0750 */ 57,231, 15,132,112, 5, 0, 0, 15,182, 7, 65,193,226, 8, 65, +/* 0x0760 */ 193,227, 8, 72,255,199, 65, 9,194, 15,183,150,224, 1, 0, 0, +/* 0x0770 */ 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194,115, +/* 0x0780 */ 79, 65, 41,200, 65,137,195, 65,193,248, 5, 69,133,255, 66,141, +/* 0x0790 */ 4, 2,102,137,134,224, 1, 0, 0, 15,132, 41, 5, 0, 0, 49, +/* 0x07a0 */ 192,131,124, 36,200, 6, 72,139, 92, 36,232, 15,159,192,141, 68, +/* 0x07b0 */ 0, 9,137, 68, 36,200, 68,137,248, 68, 41,240, 68, 15,182, 44, +/* 0x07c0 */ 3, 68,137,248, 65,255,199, 68,136, 44, 3,233,216, 4, 0, 0, +/* 0x07d0 */ 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41,194,102, +/* 0x07e0 */ 137,150,224, 1, 0, 0,233, 17, 1, 0, 0, 65, 41,195, 65, 41, +/* 0x07f0 */ 194,137,208,102,193,232, 5,102, 41,194, 65,129,251,255,255,255, +/* 0x0800 */ 0,102,137,150,152, 1, 0, 0,119, 26, 76, 57,231, 15,132,181, +/* 0x0810 */ 4, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255, +/* 0x0820 */ 199, 65, 9,194, 15,183,150,176, 1, 0, 0, 68,137,216,193,232, +/* 0x0830 */ 11, 15,183,202, 15,175,193, 65, 57,194,115, 32, 65,137,195,184, +/* 0x0840 */ 0, 8, 0, 0, 41,200,193,248, 5,141, 4, 2,102,137,134,176, +/* 0x0850 */ 1, 0, 0,139, 68, 36,196,233,152, 0, 0, 0, 65, 41,195, 65, +/* 0x0860 */ 41,194,137,208,102,193,232, 5,102, 41,194, 65,129,251,255,255, +/* 0x0870 */ 255, 0,102,137,150,176, 1, 0, 0,119, 26, 76, 57,231, 15,132, +/* 0x0880 */ 68, 4, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72, +/* 0x0890 */ 255,199, 65, 9,194, 15,183,150,200, 1, 0, 0, 68,137,216,193, +/* 0x08a0 */ 232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 29, 65,137,195, +/* 0x08b0 */ 184, 0, 8, 0, 0, 41,200,193,248, 5,141, 4, 2,102,137,134, +/* 0x08c0 */ 200, 1, 0, 0,139, 68, 36,192,235, 34, 65, 41,195, 65, 41,194, +/* 0x08d0 */ 137,208,102,193,232, 5,102, 41,194,139, 68, 36,188,102,137,150, +/* 0x08e0 */ 200, 1, 0, 0,139, 84, 36,192,137, 84, 36,188,139, 76, 36,196, +/* 0x08f0 */ 137, 76, 36,192, 68,137,116, 36,196, 65,137,198, 49,192,131,124, +/* 0x0900 */ 36,200, 6, 76,139, 76, 36,216, 15,159,192, 73,129,193,104, 10, +/* 0x0910 */ 0, 0,141, 68, 64, 8,137, 68, 36,200, 65,129,251,255,255,255, +/* 0x0920 */ 0,119, 26, 76, 57,231, 15,132,156, 3, 0, 0, 15,182, 7, 65, +/* 0x0930 */ 193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, 15,183, +/* 0x0940 */ 17, 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194, +/* 0x0950 */ 115, 39, 65,137,195,184, 0, 8, 0, 0, 69, 49,237, 41,200,193, +/* 0x0960 */ 248, 5,141, 4, 2,102, 65,137, 1, 72, 99, 68, 36,184, 72,193, +/* 0x0970 */ 224, 4, 77,141, 68, 1, 4,235,120, 65, 41,195, 65, 41,194,137, +/* 0x0980 */ 208,102,193,232, 5,102, 41,194, 65,129,251,255,255,255, 0,102, +/* 0x0990 */ 65,137, 17,119, 26, 76, 57,231, 15,132, 42, 3, 0, 0, 15,182, +/* 0x09a0 */ 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, +/* 0x09b0 */ 15,183, 81, 2, 68,137,216,193,232, 11, 15,183,202, 15,175,193, +/* 0x09c0 */ 65, 57,194,115, 52, 65,137,195,184, 0, 8, 0, 0, 65,189, 8, +/* 0x09d0 */ 0, 0, 0, 41,200,193,248, 5,141, 4, 2,102, 65,137, 65, 2, +/* 0x09e0 */ 72, 99, 68, 36,184, 72,193,224, 4, 77,141,132, 1, 4, 1, 0, +/* 0x09f0 */ 0, 65,185, 3, 0, 0, 0,235, 39, 65, 41,195, 65, 41,194,137, +/* 0x0a00 */ 208,102,193,232, 5, 77,141,129, 4, 2, 0, 0, 65,189, 16, 0, +/* 0x0a10 */ 0, 0,102, 41,194,102, 65,137, 81, 2, 65,185, 8, 0, 0, 0, +/* 0x0a20 */ 68,137,203,189, 1, 0, 0, 0, 72, 99,197, 65,129,251,255,255, +/* 0x0a30 */ 255, 0, 73,141, 52, 64,119, 26, 76, 57,231, 15,132,135, 2, 0, +/* 0x0a40 */ 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, +/* 0x0a50 */ 9,194, 15,183, 14, 68,137,216,193,232, 11, 15,183,209, 15,175, +/* 0x0a60 */ 194, 65, 57,194,115, 23, 65,137,195,184, 0, 8, 0, 0, 1,237, +/* 0x0a70 */ 41,208,193,248, 5,141, 4, 1,102,137, 6,235, 22, 65, 41,195, +/* 0x0a80 */ 65, 41,194,137,200,102,193,232, 5,141,108, 45, 1,102, 41,193, +/* 0x0a90 */ 102,137, 14,255,203,117,145,184, 1, 0, 0, 0, 68,137,201,211, +/* 0x0aa0 */ 224, 41,197, 68, 1,237,131,124, 36,200, 3, 15,143,194, 1, 0, +/* 0x0ab0 */ 0,131, 68, 36,200, 7,184, 3, 0, 0, 0,131,253, 4, 15, 76, +/* 0x0ac0 */ 197, 72,139, 92, 36,216, 65,184, 1, 0, 0, 0, 72,152, 72,193, +/* 0x0ad0 */ 224, 7, 76,141,140, 3, 96, 3, 0, 0,187, 6, 0, 0, 0, 73, +/* 0x0ae0 */ 99,192, 65,129,251,255,255,255, 0, 73,141, 52, 65,119, 26, 76, +/* 0x0af0 */ 57,231, 15,132,208, 1, 0, 0, 15,182, 7, 65,193,226, 8, 65, +/* 0x0b00 */ 193,227, 8, 72,255,199, 65, 9,194, 15,183, 22, 68,137,216,193, +/* 0x0b10 */ 232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 24, 65,137,195, +/* 0x0b20 */ 184, 0, 8, 0, 0, 69, 1,192, 41,200,193,248, 5,141, 4, 2, +/* 0x0b30 */ 102,137, 6,235, 23, 65, 41,195, 65, 41,194,137,208,102,193,232, +/* 0x0b40 */ 5, 71,141, 68, 0, 1,102, 41,194,102,137, 22,255,203,117,143, +/* 0x0b50 */ 65,131,232, 64, 65,131,248, 3, 69,137,198, 15,142, 13, 1, 0, +/* 0x0b60 */ 0, 65,131,230, 1, 68,137,192,209,248, 65,131,206, 2, 65,131, +/* 0x0b70 */ 248, 13,141,112,255,127, 35,137,241, 72,139, 92, 36,216, 73, 99, +/* 0x0b80 */ 192, 65,211,230, 72, 1,192, 68,137,242, 72,141, 20, 83, 72, 41, +/* 0x0b90 */ 194, 76,141,138, 94, 5, 0, 0,235, 81,141,112,251, 65,129,251, +/* 0x0ba0 */ 255,255,255, 0,119, 26, 76, 57,231, 15,132, 25, 1, 0, 0, 15, +/* 0x0bb0 */ 182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, +/* 0x0bc0 */ 65,209,235, 69, 1,246, 69, 57,218,114, 7, 69, 41,218, 65,131, +/* 0x0bd0 */ 206, 1,255,206,117,199, 76,139, 76, 36,216, 65,193,230, 4,190, +/* 0x0be0 */ 4, 0, 0, 0, 73,129,193, 68, 6, 0, 0, 65,189, 1, 0, 0, +/* 0x0bf0 */ 0,187, 1, 0, 0, 0, 72, 99,195, 65,129,251,255,255,255, 0, +/* 0x0c00 */ 77,141, 4, 65,119, 26, 76, 57,231, 15,132,185, 0, 0, 0, 15, +/* 0x0c10 */ 182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, +/* 0x0c20 */ 65, 15,183, 16, 68,137,216,193,232, 11, 15,183,202, 15,175,193, +/* 0x0c30 */ 65, 57,194,115, 24, 65,137,195,184, 0, 8, 0, 0, 1,219, 41, +/* 0x0c40 */ 200,193,248, 5,141, 4, 2,102, 65,137, 0,235, 26, 65, 41,195, +/* 0x0c50 */ 65, 41,194,137,208,102,193,232, 5,141, 92, 27, 1, 69, 9,238, +/* 0x0c60 */ 102, 41,194,102, 65,137, 16, 69, 1,237,255,206,117,136, 65,255, +/* 0x0c70 */ 198,116, 64,131,197, 2, 69, 57,254,119, 77, 72,139, 84, 36,232, +/* 0x0c80 */ 68,137,248, 68, 41,240, 68, 15,182, 44, 2, 68,137,248, 65,255, +/* 0x0c90 */ 199,255,205, 68,136, 44, 2, 15,149,194, 49,192, 68, 59,124, 36, +/* 0x0ca0 */ 228, 15,146,192,133,194,117,211, 68, 59,124, 36,228, 15,130, 69, +/* 0x0cb0 */ 247,255,255, 65,129,251,255,255,255, 0,119, 22, 76, 57,231,184, +/* 0x0cc0 */ 1, 0, 0, 0,116, 35,235, 7,184, 1, 0, 0, 0,235, 26, 72, +/* 0x0cd0 */ 255,199,137,248, 43, 68, 36,248, 72,139, 76, 36,240, 72,139, 92, +/* 0x0ce0 */ 36, 56,137, 1, 68,137, 59, 49,192, 91, 93, 65, 92, 65, 93, 65, +/* 0x0cf0 */ 94, 65, 95, 65, 87, 72,141, 71, 4, 69, 49,255, 65, 86, 65,190, +/* 0x0d00 */ 1, 0, 0, 0, 65, 85, 69, 49,237, 65, 84, 85, 83, 72,137, 76, +/* 0x0d10 */ 36,240, 72,137, 68, 36,216,184, 1, 0, 0, 0, 72,137,116, 36, +/* 0x0d20 */ 248, 76,137, 68, 36,232,137,195, 68,137, 76, 36,228, 15,182, 79, +/* 0x0d30 */ 2,211,227,137,217, 72,139, 92, 36, 56,255,201,137, 76, 36,212, +/* 0x0d40 */ 15,182, 79, 1,211,224, 72,139, 76, 36,240,255,200,137, 68, 36, +/* 0x0d50 */ 208, 15,182, 7,199, 1, 0, 0, 0, 0,199, 68, 36,200, 0, 0, +/* 0x0d60 */ 0, 0,199, 68, 36,196, 1, 0, 0, 0,199, 68, 36,192, 1, 0, +/* 0x0d70 */ 0, 0,199, 68, 36,188, 1, 0, 0, 0,199, 3, 0, 0, 0, 0, +/* 0x0d80 */ 137, 68, 36,204, 15,182, 79, 1, 1,193,184, 0, 3, 0, 0,211, +/* 0x0d90 */ 224, 49,201,141,184, 54, 7, 0, 0, 65, 57,255,115, 19, 72,139, +/* 0x0da0 */ 92, 36,216,137,200,255,193, 57,249,102,199, 4, 67, 0, 4,235, +/* 0x0db0 */ 235, 72,139,124, 36,248,137,208, 69, 49,210, 65,131,203,255, 49, +/* 0x0dc0 */ 210, 73,137,252, 73, 1,196, 76, 57,231, 15,132,239, 8, 0, 0, +/* 0x0dd0 */ 15,182, 7, 65,193,226, 8,255,194, 72,255,199, 65, 9,194,131, +/* 0x0de0 */ 250, 4,126,227, 68, 59,124, 36,228, 15,131,218, 8, 0, 0,139, +/* 0x0df0 */ 68, 36,212, 72, 99, 92, 36,200, 72,139, 84, 36,216, 68, 33,248, +/* 0x0e00 */ 137, 68, 36,184, 72, 99,108, 36,184, 72,137,216, 72,193,224, 4, +/* 0x0e10 */ 72, 1,232, 65,129,251,255,255,255, 0, 76,141, 12, 66,119, 26, +/* 0x0e20 */ 76, 57,231, 15,132,150, 8, 0, 0, 15,182, 7, 65,193,226, 8, +/* 0x0e30 */ 65,193,227, 8, 72,255,199, 65, 9,194, 65, 15,183, 17, 68,137, +/* 0x0e40 */ 216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194, 15,131,197, +/* 0x0e50 */ 1, 0, 0, 65,137,195,184, 0, 8, 0, 0, 72,139, 92, 36,216, +/* 0x0e60 */ 41,200, 15,182, 76, 36,204,190, 1, 0, 0, 0,193,248, 5,141, +/* 0x0e70 */ 4, 2, 65, 15,182,213,102, 65,137, 1,139, 68, 36,208, 68, 33, +/* 0x0e80 */ 248,211,224,185, 8, 0, 0, 0, 43, 76, 36,204,211,250, 1,208, +/* 0x0e90 */ 105,192, 0, 3, 0, 0,131,124, 36,200, 6,137,192, 76,141,140, +/* 0x0ea0 */ 67,108, 14, 0, 0, 15,142,184, 0, 0, 0, 72,139, 84, 36,232, +/* 0x0eb0 */ 68,137,248, 68, 41,240, 15,182, 44, 2, 1,237, 72, 99,214,137, +/* 0x0ec0 */ 235,129,227, 0, 1, 0, 0, 65,129,251,255,255,255, 0, 72, 99, +/* 0x0ed0 */ 195, 73,141, 4, 65, 76,141, 4, 80,119, 26, 76, 57,231, 15,132, +/* 0x0ee0 */ 219, 7, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72, +/* 0x0ef0 */ 255,199, 65, 9,194, 65, 15,183,144, 0, 2, 0, 0, 68,137,216, +/* 0x0f00 */ 193,232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 32, 65,137, +/* 0x0f10 */ 195,184, 0, 8, 0, 0, 1,246, 41,200,193,248, 5,133,219,141, +/* 0x0f20 */ 4, 2,102, 65,137,128, 0, 2, 0, 0,116, 33,235, 45, 65, 41, +/* 0x0f30 */ 195, 65, 41,194,137,208,102,193,232, 5,141,116, 54, 1,102, 41, +/* 0x0f40 */ 194,133,219,102, 65,137,144, 0, 2, 0, 0,116, 14,129,254,255, +/* 0x0f50 */ 0, 0, 0, 15,142, 97,255,255,255,235,120,129,254,255, 0, 0, +/* 0x0f60 */ 0,127,112, 72, 99,198, 65,129,251,255,255,255, 0, 77,141, 4, +/* 0x0f70 */ 65,119, 26, 76, 57,231, 15,132, 67, 7, 0, 0, 15,182, 7, 65, +/* 0x0f80 */ 193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, 15,183, +/* 0x0f90 */ 16, 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194, +/* 0x0fa0 */ 115, 24, 65,137,195,184, 0, 8, 0, 0, 1,246, 41,200,193,248, +/* 0x0fb0 */ 5,141, 4, 2,102, 65,137, 0,235,161, 65, 41,195, 65, 41,194, +/* 0x0fc0 */ 137,208,102,193,232, 5,141,116, 54, 1,102, 41,194,102, 65,137, +/* 0x0fd0 */ 16,235,136, 72,139, 76, 36,232, 68,137,248, 65,255,199, 65,137, +/* 0x0fe0 */ 245, 64,136, 52, 1,131,124, 36,200, 3,127, 13,199, 68, 36,200, +/* 0x0ff0 */ 0, 0, 0, 0,233,166, 6, 0, 0,139, 84, 36,200,139, 68, 36, +/* 0x1000 */ 200,131,234, 3,131,232, 6,131,124, 36,200, 9, 15, 79,208,137, +/* 0x1010 */ 84, 36,200,233,135, 6, 0, 0, 65, 41,195, 65, 41,194,137,208, +/* 0x1020 */ 102,193,232, 5,102, 41,194, 72,139, 68, 36,216, 65,129,251,255, +/* 0x1030 */ 255,255, 0,102, 65,137, 17, 72,141, 52, 88,119, 26, 76, 57,231, +/* 0x1040 */ 15,132,121, 6, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, +/* 0x1050 */ 8, 72,255,199, 65, 9,194, 15,183,150,128, 1, 0, 0, 68,137, +/* 0x1060 */ 216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 78, 65, +/* 0x1070 */ 137,195,184, 0, 8, 0, 0, 76,139, 76, 36,216, 41,200,139, 76, +/* 0x1080 */ 36,196, 68,137,116, 36,196,193,248, 5,141, 4, 2,139, 84, 36, +/* 0x1090 */ 192,137, 76, 36,192,102,137,134,128, 1, 0, 0, 49,192,131,124, +/* 0x10a0 */ 36,200, 6,137, 84, 36,188, 15,159,192, 73,129,193,100, 6, 0, +/* 0x10b0 */ 0,141, 4, 64,137, 68, 36,200,233, 84, 2, 0, 0, 65, 41,195, +/* 0x10c0 */ 65, 41,194,137,208,102,193,232, 5,102, 41,194, 65,129,251,255, +/* 0x10d0 */ 255,255, 0,102,137,150,128, 1, 0, 0,119, 26, 76, 57,231, 15, +/* 0x10e0 */ 132,218, 5, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, +/* 0x10f0 */ 72,255,199, 65, 9,194, 15,183,150,152, 1, 0, 0, 68,137,216, +/* 0x1100 */ 193,232, 11, 15,183,202, 15,175,193, 65, 57,194, 15,131,208, 0, +/* 0x1110 */ 0, 0, 65,184, 0, 8, 0, 0, 65,137,195, 72,193,227, 5, 68, +/* 0x1120 */ 137,192, 41,200,193,248, 5,141, 4, 2,102,137,134,152, 1, 0, +/* 0x1130 */ 0, 72,139, 68, 36,216, 72, 1,216, 65,129,251,255,255,255, 0, +/* 0x1140 */ 72,141, 52,104,119, 26, 76, 57,231, 15,132,112, 5, 0, 0, 15, +/* 0x1150 */ 182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, +/* 0x1160 */ 15,183,150,224, 1, 0, 0, 68,137,216,193,232, 11, 15,183,202, +/* 0x1170 */ 15,175,193, 65, 57,194,115, 79, 65, 41,200, 65,137,195, 65,193, +/* 0x1180 */ 248, 5, 69,133,255, 66,141, 4, 2,102,137,134,224, 1, 0, 0, +/* 0x1190 */ 15,132, 41, 5, 0, 0, 49,192,131,124, 36,200, 6, 72,139, 92, +/* 0x11a0 */ 36,232, 15,159,192,141, 68, 0, 9,137, 68, 36,200, 68,137,248, +/* 0x11b0 */ 68, 41,240, 68, 15,182, 44, 3, 68,137,248, 65,255,199, 68,136, +/* 0x11c0 */ 44, 3,233,216, 4, 0, 0, 65, 41,195, 65, 41,194,137,208,102, +/* 0x11d0 */ 193,232, 5,102, 41,194,102,137,150,224, 1, 0, 0,233, 17, 1, +/* 0x11e0 */ 0, 0, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41, +/* 0x11f0 */ 194, 65,129,251,255,255,255, 0,102,137,150,152, 1, 0, 0,119, +/* 0x1200 */ 26, 76, 57,231, 15,132,181, 4, 0, 0, 15,182, 7, 65,193,226, +/* 0x1210 */ 8, 65,193,227, 8, 72,255,199, 65, 9,194, 15,183,150,176, 1, +/* 0x1220 */ 0, 0, 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57, +/* 0x1230 */ 194,115, 32, 65,137,195,184, 0, 8, 0, 0, 41,200,193,248, 5, +/* 0x1240 */ 141, 4, 2,102,137,134,176, 1, 0, 0,139, 68, 36,196,233,152, +/* 0x1250 */ 0, 0, 0, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, +/* 0x1260 */ 41,194, 65,129,251,255,255,255, 0,102,137,150,176, 1, 0, 0, +/* 0x1270 */ 119, 26, 76, 57,231, 15,132, 68, 4, 0, 0, 15,182, 7, 65,193, +/* 0x1280 */ 226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 15,183,150,200, +/* 0x1290 */ 1, 0, 0, 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, +/* 0x12a0 */ 57,194,115, 29, 65,137,195,184, 0, 8, 0, 0, 41,200,193,248, +/* 0x12b0 */ 5,141, 4, 2,102,137,134,200, 1, 0, 0,139, 68, 36,192,235, +/* 0x12c0 */ 34, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41,194, +/* 0x12d0 */ 139, 68, 36,188,102,137,150,200, 1, 0, 0,139, 84, 36,192,137, +/* 0x12e0 */ 84, 36,188,139, 76, 36,196,137, 76, 36,192, 68,137,116, 36,196, +/* 0x12f0 */ 65,137,198, 49,192,131,124, 36,200, 6, 76,139, 76, 36,216, 15, +/* 0x1300 */ 159,192, 73,129,193,104, 10, 0, 0,141, 68, 64, 8,137, 68, 36, +/* 0x1310 */ 200, 65,129,251,255,255,255, 0,119, 26, 76, 57,231, 15,132,156, +/* 0x1320 */ 3, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255, +/* 0x1330 */ 199, 65, 9,194, 65, 15,183, 17, 68,137,216,193,232, 11, 15,183, +/* 0x1340 */ 202, 15,175,193, 65, 57,194,115, 39, 65,137,195,184, 0, 8, 0, +/* 0x1350 */ 0, 69, 49,237, 41,200,193,248, 5,141, 4, 2,102, 65,137, 1, +/* 0x1360 */ 72, 99, 68, 36,184, 72,193,224, 4, 77,141, 68, 1, 4,235,120, +/* 0x1370 */ 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41,194, 65, +/* 0x1380 */ 129,251,255,255,255, 0,102, 65,137, 17,119, 26, 76, 57,231, 15, +/* 0x1390 */ 132, 42, 3, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, +/* 0x13a0 */ 72,255,199, 65, 9,194, 65, 15,183, 81, 2, 68,137,216,193,232, +/* 0x13b0 */ 11, 15,183,202, 15,175,193, 65, 57,194,115, 52, 65,137,195,184, +/* 0x13c0 */ 0, 8, 0, 0, 65,189, 8, 0, 0, 0, 41,200,193,248, 5,141, +/* 0x13d0 */ 4, 2,102, 65,137, 65, 2, 72, 99, 68, 36,184, 72,193,224, 4, +/* 0x13e0 */ 77,141,132, 1, 4, 1, 0, 0, 65,185, 3, 0, 0, 0,235, 39, +/* 0x13f0 */ 65, 41,195, 65, 41,194,137,208,102,193,232, 5, 77,141,129, 4, +/* 0x1400 */ 2, 0, 0, 65,189, 16, 0, 0, 0,102, 41,194,102, 65,137, 81, +/* 0x1410 */ 2, 65,185, 8, 0, 0, 0, 68,137,203,189, 1, 0, 0, 0, 72, +/* 0x1420 */ 99,197, 65,129,251,255,255,255, 0, 73,141, 52, 64,119, 26, 76, +/* 0x1430 */ 57,231, 15,132,135, 2, 0, 0, 15,182, 7, 65,193,226, 8, 65, +/* 0x1440 */ 193,227, 8, 72,255,199, 65, 9,194, 15,183, 14, 68,137,216,193, +/* 0x1450 */ 232, 11, 15,183,209, 15,175,194, 65, 57,194,115, 23, 65,137,195, +/* 0x1460 */ 184, 0, 8, 0, 0, 1,237, 41,208,193,248, 5,141, 4, 1,102, +/* 0x1470 */ 137, 6,235, 22, 65, 41,195, 65, 41,194,137,200,102,193,232, 5, +/* 0x1480 */ 141,108, 45, 1,102, 41,193,102,137, 14,255,203,117,145,184, 1, +/* 0x1490 */ 0, 0, 0, 68,137,201,211,224, 41,197, 68, 1,237,131,124, 36, +/* 0x14a0 */ 200, 3, 15,143,194, 1, 0, 0,131, 68, 36,200, 7,184, 3, 0, +/* 0x14b0 */ 0, 0,131,253, 4, 15, 76,197, 72,139, 92, 36,216, 65,184, 1, +/* 0x14c0 */ 0, 0, 0, 72,152, 72,193,224, 7, 76,141,140, 3, 96, 3, 0, +/* 0x14d0 */ 0,187, 6, 0, 0, 0, 73, 99,192, 65,129,251,255,255,255, 0, +/* 0x14e0 */ 73,141, 52, 65,119, 26, 76, 57,231, 15,132,208, 1, 0, 0, 15, +/* 0x14f0 */ 182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, +/* 0x1500 */ 15,183, 22, 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, +/* 0x1510 */ 57,194,115, 24, 65,137,195,184, 0, 8, 0, 0, 69, 1,192, 41, +/* 0x1520 */ 200,193,248, 5,141, 4, 2,102,137, 6,235, 23, 65, 41,195, 65, +/* 0x1530 */ 41,194,137,208,102,193,232, 5, 71,141, 68, 0, 1,102, 41,194, +/* 0x1540 */ 102,137, 22,255,203,117,143, 65,131,232, 64, 65,131,248, 3, 69, +/* 0x1550 */ 137,198, 15,142, 13, 1, 0, 0, 65,131,230, 1, 68,137,192,209, +/* 0x1560 */ 248, 65,131,206, 2, 65,131,248, 13,141,112,255,127, 35,137,241, +/* 0x1570 */ 72,139, 92, 36,216, 73, 99,192, 65,211,230, 72, 1,192, 68,137, +/* 0x1580 */ 242, 72,141, 20, 83, 72, 41,194, 76,141,138, 94, 5, 0, 0,235, +/* 0x1590 */ 81,141,112,251, 65,129,251,255,255,255, 0,119, 26, 76, 57,231, +/* 0x15a0 */ 15,132, 25, 1, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, +/* 0x15b0 */ 8, 72,255,199, 65, 9,194, 65,209,235, 69, 1,246, 69, 57,218, +/* 0x15c0 */ 114, 7, 69, 41,218, 65,131,206, 1,255,206,117,199, 76,139, 76, +/* 0x15d0 */ 36,216, 65,193,230, 4,190, 4, 0, 0, 0, 73,129,193, 68, 6, +/* 0x15e0 */ 0, 0, 65,189, 1, 0, 0, 0,187, 1, 0, 0, 0, 72, 99,195, +/* 0x15f0 */ 65,129,251,255,255,255, 0, 77,141, 4, 65,119, 26, 76, 57,231, +/* 0x1600 */ 15,132,185, 0, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, +/* 0x1610 */ 8, 72,255,199, 65, 9,194, 65, 15,183, 16, 68,137,216,193,232, +/* 0x1620 */ 11, 15,183,202, 15,175,193, 65, 57,194,115, 24, 65,137,195,184, +/* 0x1630 */ 0, 8, 0, 0, 1,219, 41,200,193,248, 5,141, 4, 2,102, 65, +/* 0x1640 */ 137, 0,235, 26, 65, 41,195, 65, 41,194,137,208,102,193,232, 5, +/* 0x1650 */ 141, 92, 27, 1, 69, 9,238,102, 41,194,102, 65,137, 16, 69, 1, +/* 0x1660 */ 237,255,206,117,136, 65,255,198,116, 64,131,197, 2, 69, 57,254, +/* 0x1670 */ 119, 77, 72,139, 84, 36,232, 68,137,248, 68, 41,240, 68, 15,182, +/* 0x1680 */ 44, 2, 68,137,248, 65,255,199,255,205, 68,136, 44, 2, 15,149, +/* 0x1690 */ 194, 49,192, 68, 59,124, 36,228, 15,146,192,133,194,117,211, 68, +/* 0x16a0 */ 59,124, 36,228, 15,130, 69,247,255,255, 65,129,251,255,255,255, +/* 0x16b0 */ 0,119, 22, 76, 57,231,184, 1, 0, 0, 0,116, 35,235, 7,184, +/* 0x16c0 */ 1, 0, 0, 0,235, 26, 72,255,199,137,248, 43, 68, 36,248, 72, +/* 0x16d0 */ 139, 76, 36,240, 72,139, 92, 36, 56,137, 1, 68,137, 59, 49,192, +/* 0x16e0 */ 91, 93, 65, 92, 65, 93, 65, 94, 65, 95, 72,139,117,248, 72,139, +/* 0x16f0 */ 125, 16,139, 75, 4, 72, 1,206,139, 19, 72, 1,215,201, 89, 72, +/* 0x1700 */ 137,240, 72, 41,200, 90, 72, 41,215, 89,137, 57, 91, 93,195, 94, +/* 0x1710 */ 139, 70, 4, 72,141, 68, 6, 12, 80, 72,137,194,252,173, 80, 72, +/* 0x1720 */ 137,225,173,151,173, 68, 15,182,192, 72,135,254,255,213, 89,195, +/* 0x1730 */ 93, 72,141, 93,247,232,213,255,255,255,102,105,108,101, 32,102, +/* 0x1740 */ 111,114,109, 97,116, 32,101,108,102, 54, 52, 45,120, 56, 54, 45, +/* 0x1750 */ 54, 52, 10, 10, 83,101, 99,116,105,111,110,115, 58, 10, 73,100, +/* 0x1760 */ 120, 32, 78, 97,109,101, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x1770 */ 83,105,122,101, 32, 32, 32, 32, 32, 32, 86, 77, 65, 32, 32, 32, +/* 0x1780 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 76, 77, 65, 32, +/* 0x1790 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 70,105, +/* 0x17a0 */ 108,101, 32,111,102,102, 32, 32, 65,108,103,110, 32, 32, 70,108, +/* 0x17b0 */ 97,103,115, 10, 32, 32, 48, 32, 77, 65, 67, 72, 77, 65, 73, 78, +/* 0x17c0 */ 88, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, 48,100, 32, 32, +/* 0x17d0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x17e0 */ 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x17f0 */ 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 52, 48, 32, 32, 50, 42, +/* 0x1800 */ 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, +/* 0x1810 */ 76, 79, 67, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, +/* 0x1820 */ 49, 32, 78, 82, 86, 95, 72, 69, 65, 68, 32, 32, 32, 32, 32, 32, +/* 0x1830 */ 48, 48, 48, 48, 48, 48, 54, 54, 32, 32, 48, 48, 48, 48, 48, 48, +/* 0x1840 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, +/* 0x1850 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, +/* 0x1860 */ 48, 48, 48, 48, 52,100, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, +/* 0x1870 */ 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, +/* 0x1880 */ 10, 32, 32, 50, 32, 78, 82, 86, 50, 69, 32, 32, 32, 32, 32, 32, +/* 0x1890 */ 32, 32, 32, 48, 48, 48, 48, 48, 48, 98, 55, 32, 32, 48, 48, 48, +/* 0x18a0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x18b0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, +/* 0x18c0 */ 32, 48, 48, 48, 48, 48, 48, 98, 51, 32, 32, 50, 42, 42, 48, 32, +/* 0x18d0 */ 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 76, 79, 67, +/* 0x18e0 */ 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 51, 32, 78, +/* 0x18f0 */ 82, 86, 50, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 48, 48, 48, +/* 0x1900 */ 48, 48, 48, 57,101, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1910 */ 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, +/* 0x1920 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, +/* 0x1930 */ 49, 54, 97, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, +/* 0x1940 */ 78, 84, 83, 44, 32, 82, 69, 76, 79, 67, 44, 32, 82, 69, 65, 68, +/* 0x1950 */ 79, 78, 76, 89, 10, 32, 32, 52, 32, 78, 82, 86, 50, 66, 32, 32, +/* 0x1960 */ 32, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, 57, 48, 32, +/* 0x1970 */ 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1980 */ 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1990 */ 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 50, 48, 56, 32, 32, 50, +/* 0x19a0 */ 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, +/* 0x19b0 */ 69, 76, 79, 67, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, +/* 0x19c0 */ 32, 53, 32, 76, 90, 77, 65, 95, 69, 76, 70, 48, 48, 32, 32, 32, +/* 0x19d0 */ 32, 48, 48, 48, 48, 48, 48, 54, 52, 32, 32, 48, 48, 48, 48, 48, +/* 0x19e0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, +/* 0x19f0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x1a00 */ 48, 48, 48, 48, 50, 57, 56, 32, 32, 50, 42, 42, 48, 32, 32, 67, +/* 0x1a10 */ 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 76, 79, 67, 44, 32, +/* 0x1a20 */ 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 54, 32, 76, 90, 77, +/* 0x1a30 */ 65, 95, 68, 69, 67, 49, 48, 32, 32, 32, 32, 48, 48, 48, 48, 48, +/* 0x1a40 */ 57,102, 55, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1a50 */ 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1a60 */ 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 50,102, +/* 0x1a70 */ 99, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, +/* 0x1a80 */ 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 55, 32, +/* 0x1a90 */ 76, 90, 77, 65, 95, 68, 69, 67, 50, 48, 32, 32, 32, 32, 48, 48, +/* 0x1aa0 */ 48, 48, 48, 57,102, 55, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1ab0 */ 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, +/* 0x1ac0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, +/* 0x1ad0 */ 48, 99,102, 51, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, +/* 0x1ae0 */ 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, +/* 0x1af0 */ 32, 56, 32, 76, 90, 77, 65, 95, 68, 69, 67, 51, 48, 32, 32, 32, +/* 0x1b00 */ 32, 48, 48, 48, 48, 48, 48, 49, 52, 32, 32, 48, 48, 48, 48, 48, +/* 0x1b10 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, +/* 0x1b20 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x1b30 */ 48, 48, 48, 49, 54,101, 97, 32, 32, 50, 42, 42, 48, 32, 32, 67, +/* 0x1b40 */ 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, +/* 0x1b50 */ 89, 10, 32, 32, 57, 32, 78, 82, 86, 95, 84, 65, 73, 76, 32, 32, +/* 0x1b60 */ 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, +/* 0x1b70 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, +/* 0x1b80 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1b90 */ 32, 32, 48, 48, 48, 48, 49, 54,102,101, 32, 32, 50, 42, 42, 48, +/* 0x1ba0 */ 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, +/* 0x1bb0 */ 79, 78, 76, 89, 10, 32, 49, 48, 32, 77, 65, 67, 72, 77, 65, 73, +/* 0x1bc0 */ 78, 89, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, 49, 49, 32, +/* 0x1bd0 */ 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1be0 */ 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1bf0 */ 48, 48, 48, 32, 32, 48, 48, 48, 48, 49, 54,102,101, 32, 32, 50, +/* 0x1c00 */ 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, +/* 0x1c10 */ 69, 65, 68, 79, 78, 76, 89, 10, 32, 49, 49, 32, 77, 65, 67, 72, +/* 0x1c20 */ 77, 65, 73, 78, 90, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, +/* 0x1c30 */ 50, 98, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1c40 */ 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1c50 */ 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 49, 55, 48,102, +/* 0x1c60 */ 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, +/* 0x1c70 */ 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 83, 89, 77, 66, 79, +/* 0x1c80 */ 76, 32, 84, 65, 66, 76, 69, 58, 10, 48, 48, 48, 48, 48, 48, 48, +/* 0x1c90 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, +/* 0x1ca0 */ 32, 32, 78, 82, 86, 95, 72, 69, 65, 68, 9, 48, 48, 48, 48, 48, +/* 0x1cb0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 78, 82, 86, 95, +/* 0x1cc0 */ 72, 69, 65, 68, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1cd0 */ 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 76, 90, +/* 0x1ce0 */ 77, 65, 95, 68, 69, 67, 51, 48, 9, 48, 48, 48, 48, 48, 48, 48, +/* 0x1cf0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 76, 90, 77, 65, 95, 68, +/* 0x1d00 */ 69, 67, 51, 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1d10 */ 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 77, 65, +/* 0x1d20 */ 67, 72, 77, 65, 73, 78, 89, 9, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1d30 */ 48, 48, 48, 48, 48, 48, 48, 48, 32, 77, 65, 67, 72, 77, 65, 73, +/* 0x1d40 */ 78, 89, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1d50 */ 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 77, 65, 67, 72, +/* 0x1d60 */ 77, 65, 73, 78, 90, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1d70 */ 48, 48, 48, 48, 48, 48, 32, 77, 65, 67, 72, 77, 65, 73, 78, 90, +/* 0x1d80 */ 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1d90 */ 48, 32,108, 32, 32, 32, 32,100, 32, 32, 77, 65, 67, 72, 77, 65, +/* 0x1da0 */ 73, 78, 88, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1db0 */ 48, 48, 48, 48, 32, 77, 65, 67, 72, 77, 65, 73, 78, 88, 10, 48, +/* 0x1dc0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, +/* 0x1dd0 */ 108, 32, 32, 32, 32,100, 32, 32, 78, 82, 86, 50, 69, 9, 48, 48, +/* 0x1de0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 78, +/* 0x1df0 */ 82, 86, 50, 69, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1e00 */ 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 78, 82, +/* 0x1e10 */ 86, 50, 68, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1e20 */ 48, 48, 48, 48, 32, 78, 82, 86, 50, 68, 10, 48, 48, 48, 48, 48, +/* 0x1e30 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, 32, +/* 0x1e40 */ 32,100, 32, 32, 78, 82, 86, 50, 66, 9, 48, 48, 48, 48, 48, 48, +/* 0x1e50 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 78, 82, 86, 50, 66, +/* 0x1e60 */ 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1e70 */ 48, 32,108, 32, 32, 32, 32,100, 32, 32, 76, 90, 77, 65, 95, 69, +/* 0x1e80 */ 76, 70, 48, 48, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1e90 */ 48, 48, 48, 48, 48, 32, 76, 90, 77, 65, 95, 69, 76, 70, 48, 48, +/* 0x1ea0 */ 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1eb0 */ 48, 32,108, 32, 32, 32, 32,100, 32, 32, 76, 90, 77, 65, 95, 68, +/* 0x1ec0 */ 69, 67, 49, 48, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1ed0 */ 48, 48, 48, 48, 48, 32, 76, 90, 77, 65, 95, 68, 69, 67, 49, 48, +/* 0x1ee0 */ 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1ef0 */ 48, 32,108, 32, 32, 32, 32,100, 32, 32, 76, 90, 77, 65, 95, 68, +/* 0x1f00 */ 69, 67, 50, 48, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1f10 */ 48, 48, 48, 48, 48, 32, 76, 90, 77, 65, 95, 68, 69, 67, 50, 48, +/* 0x1f20 */ 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1f30 */ 48, 32,108, 32, 32, 32, 32,100, 32, 32, 78, 82, 86, 95, 84, 65, +/* 0x1f40 */ 73, 76, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1f50 */ 48, 48, 48, 32, 78, 82, 86, 95, 84, 65, 73, 76, 10, 48, 48, 48, +/* 0x1f60 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,103, 32, +/* 0x1f70 */ 32, 32, 32, 32, 32, 32, 77, 65, 67, 72, 77, 65, 73, 78, 88, 9, +/* 0x1f80 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1f90 */ 32, 95,115,116, 97,114,116, 10, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1fa0 */ 48, 48, 48, 48, 48, 48, 49, 49, 32,103, 32, 32, 32, 32, 32, 32, +/* 0x1fb0 */ 32, 77, 65, 67, 72, 77, 65, 73, 78, 89, 9, 48, 48, 48, 48, 48, +/* 0x1fc0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,101,110,100, 95, +/* 0x1fd0 */ 100,101, 99,111,109,112,114,101,115,115, 10, 10, 82, 69, 76, 79, +/* 0x1fe0 */ 67, 65, 84, 73, 79, 78, 32, 82, 69, 67, 79, 82, 68, 83, 32, 70, +/* 0x1ff0 */ 79, 82, 32, 91, 77, 65, 67, 72, 77, 65, 73, 78, 88, 93, 58, 10, +/* 0x2000 */ 79, 70, 70, 83, 69, 84, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x2010 */ 32, 84, 89, 80, 69, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x2020 */ 32, 32, 32, 86, 65, 76, 85, 69, 10, 48, 48, 48, 48, 48, 48, 48, +/* 0x2030 */ 48, 48, 48, 48, 48, 48, 48, 48, 49, 32, 82, 95, 88, 56, 54, 95, +/* 0x2040 */ 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, 32, 77, 65, 67, 72, +/* 0x2050 */ 77, 65, 73, 78, 90, 43, 48,120, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2060 */ 48, 48, 48, 48, 48, 48, 49,100, 10, 10, 82, 69, 76, 79, 67, 65, +/* 0x2070 */ 84, 73, 79, 78, 32, 82, 69, 67, 79, 82, 68, 83, 32, 70, 79, 82, +/* 0x2080 */ 32, 91, 78, 82, 86, 50, 69, 93, 58, 10, 79, 70, 70, 83, 69, 84, +/* 0x2090 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 84, 89, 80, 69, 32, +/* 0x20a0 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, +/* 0x20b0 */ 85, 69, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x20c0 */ 48, 97,101, 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 80, 67, 51, +/* 0x20d0 */ 50, 32, 32, 32, 32, 32, 78, 82, 86, 95, 72, 69, 65, 68, 43, 48, +/* 0x20e0 */ 120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, +/* 0x20f0 */ 49, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2100 */ 53, 98, 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 80, 67, 51, 50, +/* 0x2110 */ 32, 32, 32, 32, 32, 77, 65, 67, 72, 77, 65, 73, 78, 89, 43, 48, +/* 0x2120 */ 120,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +/* 0x2130 */ 99, 10, 10, 82, 69, 76, 79, 67, 65, 84, 73, 79, 78, 32, 82, 69, +/* 0x2140 */ 67, 79, 82, 68, 83, 32, 70, 79, 82, 32, 91, 78, 82, 86, 50, 68, +/* 0x2150 */ 93, 58, 10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 32, 32, 32, 32, +/* 0x2160 */ 32, 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x2170 */ 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, 10, 48, 48, 48, 48, +/* 0x2180 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 57, 53, 32, 82, 95, 88, +/* 0x2190 */ 56, 54, 95, 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, 32, 78, +/* 0x21a0 */ 82, 86, 95, 72, 69, 65, 68, 43, 48,120, 48, 48, 48, 48, 48, 48, +/* 0x21b0 */ 48, 48, 48, 48, 48, 48, 48, 48, 50, 49, 10, 48, 48, 48, 48, 48, +/* 0x21c0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 98, 32, 82, 95, 88, 56, +/* 0x21d0 */ 54, 95, 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, 32, 77, 65, +/* 0x21e0 */ 67, 72, 77, 65, 73, 78, 89, 43, 48,120,102,102,102,102,102,102, +/* 0x21f0 */ 102,102,102,102,102,102,102,102,102, 99, 10, 10, 82, 69, 76, 79, +/* 0x2200 */ 67, 65, 84, 73, 79, 78, 32, 82, 69, 67, 79, 82, 68, 83, 32, 70, +/* 0x2210 */ 79, 82, 32, 91, 78, 82, 86, 50, 66, 93, 58, 10, 79, 70, 70, 83, +/* 0x2220 */ 69, 84, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 84, 89, 80, +/* 0x2230 */ 69, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, +/* 0x2240 */ 65, 76, 85, 69, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2250 */ 48, 48, 48, 56, 97, 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 80, +/* 0x2260 */ 67, 51, 50, 32, 32, 32, 32, 32, 78, 82, 86, 95, 72, 69, 65, 68, +/* 0x2270 */ 43, 48,120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2280 */ 48, 50, 49, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2290 */ 48, 48, 53, 50, 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 80, 67, +/* 0x22a0 */ 51, 50, 32, 32, 32, 32, 32, 77, 65, 67, 72, 77, 65, 73, 78, 89, +/* 0x22b0 */ 43, 48,120,102,102,102,102,102,102,102,102,102,102,102,102,102, +/* 0x22c0 */ 102,102, 99, 10, 10, 82, 69, 76, 79, 67, 65, 84, 73, 79, 78, 32, +/* 0x22d0 */ 82, 69, 67, 79, 82, 68, 83, 32, 70, 79, 82, 32, 91, 76, 90, 77, +/* 0x22e0 */ 65, 95, 69, 76, 70, 48, 48, 93, 58, 10, 79, 70, 70, 83, 69, 84, +/* 0x22f0 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 84, 89, 80, 69, 32, +/* 0x2300 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, +/* 0x2310 */ 85, 69, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2320 */ 48, 48, 54, 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 80, 67, 51, +/* 0x2330 */ 50, 32, 32, 32, 32, 32, 76, 90, 77, 65, 95, 68, 69, 67, 51, 48, +/* 0x2340 */ 43, 48,120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2350 */ 48, 49, 48, 10 +}; diff --git a/src/stub/amd64-darwin.macho-fold.h b/src/stub/amd64-darwin.macho-fold.h new file mode 100644 index 00000000..8c4a7efe --- /dev/null +++ b/src/stub/amd64-darwin.macho-fold.h @@ -0,0 +1,124 @@ +/* amd64-darwin.macho-fold.h + created from amd64-darwin.macho-fold.bin, 1354 (0x54a) bytes + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2009 Laszlo Molnar + Copyright (C) 2000-2009 John F. Reiser + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + + John F. Reiser + + */ + + +#define STUB_AMD64_DARWIN_MACHO_FOLD_SIZE 1354 +#define STUB_AMD64_DARWIN_MACHO_FOLD_ADLER32 0x9f6f399d +#define STUB_AMD64_DARWIN_MACHO_FOLD_CRC32 0x7c7ef068 + +unsigned char stub_amd64_darwin_macho_fold[1354] = { +/* 0x0000 */ 232, 80, 0, 0, 0,131,249, 73,117, 74, 72,137,241, 72,137,254, +/* 0x0010 */ 235, 44,138, 7, 72,131,199, 1, 60,128,114, 10, 60,143,119, 6, +/* 0x0020 */ 128,127,254, 15,116, 6, 44,232, 60, 1,119, 35, 56, 23,117, 31, +/* 0x0030 */ 139, 7, 37, 0,255,255,255, 15,200, 41,248, 1,240,171, 72,131, +/* 0x0040 */ 233, 4,138, 7, 72,131,199, 1, 72,255,201,117,217,235, 5, 72, +/* 0x0050 */ 255,201,117,190,195, 65, 89, 72,137,223,139, 51, 72, 41,247,106, +/* 0x0060 */ 0,184, 0, 8, 0, 0,139, 79, 24, 57,193, 15, 66,200, 73,137, +/* 0x0070 */ 232, 73,137,228, 72, 41,204, 72,137,226, 65, 84,232, 97, 3, 0, +/* 0x0080 */ 0, 76,137,228,255,160,128, 0, 0, 0,139, 7, 15,200,137, 7, +/* 0x0090 */ 131,238, 4, 72,141,127, 4,119,241,195,176, 1,235, 2,176, 74, +/* 0x00a0 */ 235, 2,176, 73,235, 2,176,153,235, 2,176, 6,235, 2,176, 5, +/* 0x00b0 */ 235, 2,176,197,235, 2,176, 3, 15,182,192, 13, 0, 0, 0, 2, +/* 0x00c0 */ 73,137,202, 15, 5,115, 4, 72,131,200,255,195, 81, 72, 57, 23, +/* 0x00d0 */ 76,139, 71, 8, 72,141, 74,255,115, 10,191,127, 0, 0, 0,232, +/* 0x00e0 */ 182,255,255,255, 72,131,249,255,116, 17, 65, 15,182, 0, 72,255, +/* 0x00f0 */ 201, 73,255,192,136, 6, 72,255,198,235,233, 72, 1, 87, 8, 72, +/* 0x0100 */ 41, 23, 88,195, 65, 85, 73,137,213, 65, 84, 73,137,204, 85, 72, +/* 0x0110 */ 137,253, 83, 72,137,243, 72,131,236, 40, 72,131, 62, 0, 15,132, +/* 0x0120 */ 212, 0, 0, 0, 72,141,116, 36, 16,186, 12, 0, 0, 0, 72,137, +/* 0x0130 */ 239,232,150,255,255,255,139, 84, 36, 16,139,116, 36, 20,133,210, +/* 0x0140 */ 117, 21,129,254, 85, 80, 88, 33,117, 17, 72,131,125, 0, 0, 15, +/* 0x0150 */ 132,163, 0, 0, 0,235, 4,133,246,117, 10,191,127, 0, 0, 0, +/* 0x0160 */ 232, 53,255,255,255, 57,214,119,242,137,208, 72, 59, 3,119,235, +/* 0x0170 */ 57,214, 72,139, 67, 8,115, 90, 68, 15,182, 68, 36, 24,137, 84, +/* 0x0180 */ 36, 12, 72,141, 76, 36, 12, 72,139,125, 8, 72,137,194, 65,255, +/* 0x0190 */ 213,133,192,117,198,139,116, 36, 12, 59,116, 36, 16,117,188, 15, +/* 0x01a0 */ 182, 76, 36, 25,132,201, 15,149,194, 49,192, 77,133,228, 15,149, +/* 0x01b0 */ 192,133,194,116, 15, 15,182, 84, 36, 26, 15,182,201, 72,139,123, +/* 0x01c0 */ 8, 65,255,212,139, 68, 36, 20, 72, 1, 69, 8, 72, 41, 69, 0, +/* 0x01d0 */ 235, 13,137,242, 72,137,239, 72,137,198,232,237,254,255,255,139, +/* 0x01e0 */ 84, 36, 16, 72,139, 3, 72, 1, 83, 8, 72, 41,208, 72,133,192, +/* 0x01f0 */ 72,137, 3,233, 38,255,255,255, 72,131,196, 40, 91, 93, 65, 92, +/* 0x0200 */ 65, 93,195, 65, 87, 73,137,215, 65, 86, 65, 85, 65, 84, 73,137, +/* 0x0210 */ 252, 73,131,196, 32, 85, 83, 72,131,236, 88, 72,139,132, 36,144, +/* 0x0220 */ 0, 0, 0, 72,137,124, 36, 56,137,116, 36, 52,137, 76, 36, 48, +/* 0x0230 */ 76,137, 68, 36, 40, 76,137, 76, 36, 32, 72,137, 68, 36, 24, 49, +/* 0x0240 */ 192, 59, 71, 16, 72,199, 68, 36, 16, 0, 0, 0, 0,199, 68, 36, +/* 0x0250 */ 12, 0, 0, 0, 0, 15,131,115, 1, 0, 0, 65,139, 4, 36,131, +/* 0x0260 */ 248, 25, 15,133, 34, 1, 0, 0, 73,139, 68, 36, 24, 73,139, 84, +/* 0x0270 */ 36, 48, 72,137,195, 72,137,197, 73,137,213,129,227,255, 15, 0, +/* 0x0280 */ 0, 73,137,198, 77, 3,116, 36, 32, 72, 41,221, 73, 1,221, 72, +/* 0x0290 */ 137, 84, 36, 64, 72,137, 68, 36, 72,116, 65,131,200,255, 68,139, +/* 0x02a0 */ 76, 36, 52, 69, 3, 76, 36, 40, 72,133,210, 15, 69, 68, 36, 48, +/* 0x02b0 */ 77,133,255,117, 10, 72,133,210,185, 18, 0, 0, 0,117, 5,185, +/* 0x02c0 */ 18, 16, 0, 0, 65,137,192,186, 3, 0, 0, 0, 76,137,238, 72, +/* 0x02d0 */ 137,239,232,219,253,255,255, 72, 57,197,117,113, 77,133,255,116, +/* 0x02e0 */ 47, 73,131,124, 36, 48, 0,116, 39, 73,131,124, 36, 40, 0,117, +/* 0x02f0 */ 8, 72,139, 84, 36, 40, 72,137, 42, 72,139, 76, 36, 24, 72,139, +/* 0x0300 */ 84, 36, 32, 72,141,116, 36, 64, 76,137,255,232,244,253,255,255, +/* 0x0310 */ 76,137,235, 74,141, 84, 45, 0, 72,247,219,129,227,255, 15, 0, +/* 0x0320 */ 0, 72,137,216, 72,133,219,116, 11,198, 2, 0, 72,255,194, 72, +/* 0x0330 */ 255,200,235,243, 77,133,237,116, 30, 65,139, 84, 36, 60, 76,137, +/* 0x0340 */ 238, 72,137,239,232, 85,253,255,255,133,192,116, 10,191,127, 0, +/* 0x0350 */ 0, 0,232, 67,253,255,255, 73,141, 68, 29, 0, 72, 1,197, 76, +/* 0x0360 */ 57,245,115, 77, 65,139, 84, 36, 60, 73, 41,238, 69, 49,201, 65, +/* 0x0370 */ 131,200,255,185, 18, 16, 0, 0, 76,137,246, 72,137,239,232, 47, +/* 0x0380 */ 253,255,255, 72, 57,197,116, 41,235,195,131,232, 4,131,248, 1, +/* 0x0390 */ 119, 31, 72,184, 4, 0, 0, 0, 42, 0, 0, 0, 73, 57, 68, 36, +/* 0x03a0 */ 8, 73,141, 84, 36, 16, 72, 15, 69, 84, 36, 16, 72,137, 84, 36, +/* 0x03b0 */ 16, 65,139, 68, 36, 4,255, 68, 36, 12,139, 84, 36, 12, 73, 1, +/* 0x03c0 */ 196, 72,139, 68, 36, 56, 59, 80, 16,233,135,254,255,255, 72,139, +/* 0x03d0 */ 68, 36, 16, 72,131,196, 88, 91, 93, 65, 92, 65, 93, 65, 94, 65, +/* 0x03e0 */ 95,195, 65, 86, 73,137,206, 49,201, 65, 85, 69, 49,237, 65, 84, +/* 0x03f0 */ 77,137,204, 85, 72,137,213, 72,141, 87, 24, 83, 76,137,195, 72, +/* 0x0400 */ 131,236, 64,139,127, 24, 72,137,116, 36, 56, 72,139, 68, 36, 56, +/* 0x0410 */ 72,141,116, 36, 16, 72,137, 84, 36, 40, 72,137, 84, 36, 8, 76, +/* 0x0420 */ 137,194, 72,137,108, 36, 24, 72,137,124, 36, 16, 72,141,124, 36, +/* 0x0430 */ 32, 72,131,232, 24, 72,137, 68, 36, 32, 72,137, 4, 36,232,193, +/* 0x0440 */ 252,255,255, 65, 83, 73,137,217,131,201,255, 49,246, 72,137,239, +/* 0x0450 */ 72,141, 84, 36, 8, 65, 84, 76,139,132, 36,128, 0, 0, 0,232, +/* 0x0460 */ 159,253,255,255, 65, 89, 65, 90,139,117, 16, 72,141, 85, 32, 72, +/* 0x0470 */ 137,195, 49,201, 57,241, 15,131,190, 0, 0, 0,131, 58, 14, 15, +/* 0x0480 */ 133,168, 0, 0, 0,139,122, 8, 49,246, 72,141, 60, 58, 49,210, +/* 0x0490 */ 232, 25,252,255,255,133,192, 65,137,196,120, 22, 68,137,233, 76, +/* 0x04a0 */ 137,242, 72,137,238, 68,137,231,232,249,251,255,255, 73, 57,198, +/* 0x04b0 */ 116, 16,191,127, 0, 0, 0,232,222,251,255,255, 68,139,107, 8, +/* 0x04c0 */ 235,218,139, 69, 0, 61,202,254,186,190,116, 7, 61,190,186,254, +/* 0x04d0 */ 202,117, 49, 72, 15,182,117, 7, 72,137,239, 72,141, 93, 8, 72, +/* 0x04e0 */ 107,246, 20,131,198, 8,232,159,251,255,255,139, 69, 4, 49,201, +/* 0x04f0 */ 57,193,115, 16,129, 59, 7, 0, 0, 1,116,192,255,193, 72,131, +/* 0x0500 */ 195, 20,235,236, 65, 80, 68,137,238, 69, 49,201, 69, 49,192, 68, +/* 0x0510 */ 137,225,106, 0, 49,210, 72,137,239,232,229,252,255,255, 68,137, +/* 0x0520 */ 231, 72,137,195,232,129,251,255,255, 94, 95,235, 13,139, 66, 4, +/* 0x0530 */ 255,193, 72, 1,194,233, 58,255,255,255, 72,131,196, 64, 72,137, +/* 0x0540 */ 216, 91, 93, 65, 92, 65, 93, 65, 94,195 +}; diff --git a/src/stub/src/amd64-darwin.macho-entry.S b/src/stub/src/amd64-darwin.macho-entry.S new file mode 100644 index 00000000..3278a0de --- /dev/null +++ b/src/stub/src/amd64-darwin.macho-entry.S @@ -0,0 +1,207 @@ +/* +; amd64-darwin.macho-entry.S -- program entry point & decompressor (amd64 Mach-o) +; +; This file is part of the UPX executable compressor. +; +; Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer +; Copyright (C) 1996-2009 Laszlo Molnar +; Copyright (C) 2000-2009 John F. Reiser +; All Rights Reserved. +; +; UPX and the UCL library are free software; you can redistribute them +; and/or modify them under the terms of the GNU General Public License as +; published by the Free Software Foundation; either version 2 of +; the License, or (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; see the file COPYING. +; If not, write to the Free Software Foundation, Inc., +; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; +; Markus F.X.J. Oberhumer Laszlo Molnar +; +; +; John F. Reiser +; +; +*/ + +#include "arch/amd64/macros.S" +#include "arch/amd64/regs.h" + + +/************************************************************************* +// program entry point +// see glibc/sysdeps/amd64/elf/start.S +**************************************************************************/ + +section MACHMAINX +_start: .globl _start +// int3 + call main // push &decompress +ret_main: + +/* Returns 0 on success; non-zero on failure. */ +decompress: // (uchar const *src, size_t lsrc, uchar *dst, u32 &ldst, uint method) + +/* Arguments according to calling convention */ +#define src %arg1 +#define lsrc %arg2 +#define dst %arg3 +#define ldst %arg4 /* Out: actually a reference: &len_dst */ +#define meth %arg5l +#define methb %arg5b + + push %rbp; push %rbx // C callable + push ldst + push dst + addq src,lsrc; push lsrc // &input_eof + +M_NRV2B_LE32=2 // ../conf.h +M_NRV2D_LE32=5 +M_NRV2E_LE32=8 + + section NRV_HEAD + +/* Working registers */ +#define off %eax /* XXX: 2GB */ +#define len %ecx /* XXX: 2GB */ +#define lenq %rcx +#define bits %ebx +#define disp %rbp + + movq src,%rsi // hardware src for movsb, lodsb + movq dst,%rdi // hardware dst for movsb + xor bits,bits // empty; force refill + xor len,len // create loop invariant + orq $(~0),disp // -1: initial displacement + call setup // push &getbit [TUNED] +ra_setup: + +/* AMD64 branch prediction is much worse if there are more than 3 branches + per 16-byte block. The jnextb would suffer unless inlined. getnextb is OK + using closed subroutine to save space, and should be OK on cycles because + CALL+RET should be predicted. getnextb could partially expand, using closed + subroutine only for refill. +*/ +/* jump on next bit {0,1} with prediction {y==>likely, n==>unlikely} */ +/* Prediction omitted for now. */ +/* On refill: prefetch next byte, for latency reduction on literals and offsets. */ +#define jnextb0np jnextb0yp +#define jnextb0yp GETBITp; jnc +#define jnextb1np jnextb1yp +#define jnextb1yp GETBITp; jc +#define GETBITp \ + addl bits,bits; jnz 0f; \ + movl (%rsi),bits; subq $-4,%rsi; \ + adcl bits,bits; movb (%rsi),%dl; \ +0: +/* Same, but without prefetch (not useful for length of match.) */ +#define jnextb0n jnextb0y +#define jnextb0y GETBIT; jnc +#define jnextb1n jnextb1y +#define jnextb1y GETBIT; jc +#define GETBIT \ + addl bits,bits; jnz 0f; \ + movl (%rsi),bits; subq $-4,%rsi; \ + adcl bits,bits; \ +0: + +/* rotate next bit into bottom bit of reg */ +#define getnextbp(reg) call *%r11; adcl reg,reg +#define getnextb(reg) getnextbp(reg) + + +getbit: + addl bits,bits; jz refill // Carry= next bit + rep; ret +refill: + movl (%rsi),bits; subq $-4,%rsi // next 32 bits; set Carry + adcl bits,bits // LSB= 1 (CarryIn); CarryOut= next bit + movb (%rsi),%dl // speculate: literal, or bottom 8 bits of offset + rep; ret + +copy: // In: len, %rdi, disp; Out: 0==len, %rdi, disp; trashes %rax, %rdx + leaq (%rdi,disp),%rax; cmpl $5,len // <=3 is forced + movb (%rax),%dl; jbe copy1 // <=5 for better branch predict + cmpq $-4,disp; ja copy1 // 4-byte chunks would overlap + subl $4,len // adjust for termination cases +copy4: + movl (%rax),%edx; addq $4, %rax; subl $4,len + movl %edx,(%rdi); leaq 4(%rdi),%rdi; jnc copy4 + addl $4,len; movb (%rax),%dl; jz copy0 +copy1: + incq %rax; movb %dl,(%rdi); subl $1,len + movb (%rax),%dl + leaq 1(%rdi),%rdi; jnz copy1 +copy0: + rep; ret + +setup: + cld + pop %r11 // addq $ getbit - ra_setup,%r11 # &getbit + + section NRV2E +#include "arch/amd64/nrv2e_d.S" + + section NRV2D +#include "arch/amd64/nrv2d_d.S" + + section NRV2B +#include "arch/amd64/nrv2b_d.S" + +/* lzma has its own 'section's */ +#include "arch/amd64/lzma_d.S" + + section NRV_TAIL +/* NRV_TAIL is empty */ + + section MACHMAINY +eof: + pop %rcx // &input_eof + movq %rsi,%rax; subq %rcx,%rax // src -= eof; // return 0: good; else: bad + pop %rdx; subq %rdx,%rdi // dst -= original dst + pop %rcx; movl %edi,(%rcx) // actual length used at dst XXX: 4GB + pop %rbx; pop %rbp + ret + +end_decompress: .globl end_decompress + + /* IDENTSTR goes here */ + + section MACHMAINZ +#define PAGE_SIZE ( 1<<12) + +sz_b_info= 12 + sz_unc= 0 + sz_cpr= 4 + b_method= 8 + +// Decompress the rest of this loader, and jump to it. +unfold: + pop %rsi // &{ b_info:{sz_unc, sz_cpr, 4{byte}}, compressed_data...} + mov sz_cpr(%rsi),%eax + lea sz_b_info(%rsi,%rax),%rax + push %rax // &destination + movq %rax,%arg3 // %arg3= dst for unfolding + cld + lodsl; push %rax // allocate slot on stack + movq %rsp,%arg4 // &len_dst ==> used by lzma for EOF + lodsl; xchgl %eax,%arg1l // sz_cpr XXX: 4GB + lodsl; movzbl %al,%arg5l // b_method + xchg %arg1,%arg2 // XXX: 4GB + call *%rbp // decompress(&src, srclen, &dst, &dstlen, b_info.misc) + pop %rcx // discard len_dst + ret +main: + pop %rbp // &decompress + lea -4+ _start - ret_main(%rbp),%rbx // &total_length for fold: + call unfold + // compressed fold_elf86 follows + +// vi:ts=8:et:nowrap diff --git a/src/stub/src/amd64-darwin.macho-fold.S b/src/stub/src/amd64-darwin.macho-fold.S new file mode 100644 index 00000000..c4206fe3 --- /dev/null +++ b/src/stub/src/amd64-darwin.macho-fold.S @@ -0,0 +1,117 @@ +/* i386-darwin.macho-fold.S -- linkage to C code to process Mach-o binary +* +* This file is part of the UPX executable compressor. +* +* Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer +* Copyright (C) 1996-2009 Laszlo Molnar +* Copyright (C) 2000-2009 John F. Reiser +* All Rights Reserved. +* +* UPX and the UCL library are free software; you can redistribute them +* and/or modify them under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; see the file COPYING. +* If not, write to the Free Software Foundation, Inc., +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* Markus F.X.J. Oberhumer Laszlo Molnar +* +* +* John F. Reiser +* +*/ + +#include "arch/amd64/macros.S" + +sz_b_info= 12 + sz_unc= 0 + sz_cpr= 4 + +sz_l_info= 12 +sz_p_info= 12 + +_start: .globl _start # ignored, but silence "cannot find entry symbol _start" from ld + + +fold_begin: // In: %rbx= &total_length; %rbp= &decompress +// int3 + call L90 # push &L90 +#include "arch/amd64/bxx.S" +L90: + pop %arg6 # L90; &amdbxx: f_unfilter + movq %rbx,%arg1 + movl (%rbx),%arg2l // total length; offset to {l_info; p_info; b_info} + subq %arg2,%arg1 // &{l_info; p_ifo, b_info} + push $0 # default value for mhdrp + movl $2048,%eax + movl sz_unc+sz_p_info+sz_l_info(%arg1),%arg4l // sz_mhdr + cmpl %eax,%arg4l; cmovb %eax,%arg4l // at least 2KiB for /usr/lib/dyld + movq %rbp,%arg5 // f_decompress + movq %rsp,%r12 // remember for un-alloca + subq %arg4,%rsp // alloca + movq %rsp,%arg3 // temp char mhdr[sz_mhdr] + push %r12 // (arg7) mhdrpp= &mhdrp + call upx_main # Out: rax= &Mach_AMD64_thread_state of dyld + movq %r12,%rsp // unalloca +AMD64_ts_rip= 16*8 + jmp *AMD64_ts_rip(%rax) # %rsp: mhdrp, argc, argv... + +bswap: .globl bswap +0: + mov (%arg1),%eax + .byte 0x0f,0xc8 // bswap eax + mov %eax,(%arg1) + sub $4,%arg2l + lea 4(%arg1),%arg1 + ja 0b + ret + +SYS_exit =1 +SYS_read =3 +SYS_write =4 +SYS_open =5 +SYS_close =6 + +SYS_pread =0x99 +SYS_mmap =0xc5 +SYS_munmap =0x49 +SYS_mprotect =0x4a + +// lazy jmps enable compression of this code +exit: .globl exit + mov $SYS_exit,%al; jmp 2+ 0f; 0: +mprotect: .globl mprotect + mov $SYS_mprotect,%al; jmp 2+ 0f; 0: +munmap: .globl munmap + mov $SYS_munmap,%al; jmp 2+ 0f; 0: +pread: .globl pread + mov $SYS_pread,%al; jmp 2+ 0f; 0: +close: .globl close + mov $SYS_close,%al; jmp 2+ 0f; 0: +open: .globl open + mov $SYS_open,%al; jmp 2+ 0f; 0: +mmap: .globl mmap + mov $SYS_mmap,%al; jmp 2+ 0f; 0: +read: .globl read + mov $SYS_read,%al + + movzbl %al,%eax; or $0x02000000,%eax + mov %rcx,%r10 + syscall // .byte 0x0f,0x05 + jnc 0f + or $~0,%rax //mov errno,eax +0: + ret + +/* +vi:ts=8:et:nowrap +*/ + diff --git a/src/stub/src/amd64-darwin.macho-main.c b/src/stub/src/amd64-darwin.macho-main.c new file mode 100644 index 00000000..4d4215b1 --- /dev/null +++ b/src/stub/src/amd64-darwin.macho-main.c @@ -0,0 +1,464 @@ +/* amd64-darwin.macho-main.c -- loader stub for Mach-o AMD64 + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2009 Laszlo Molnar + Copyright (C) 2000-2009 John F. Reiser + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + + John F. Reiser + + */ + + +#include "include/darwin.h" + + +/************************************************************************* +// configuration section +**************************************************************************/ + +// In order to make it much easier to move this code at runtime and execute +// it at an address different from it load address: there must be no +// static data, and no string constants. + + +/************************************************************************* +// "file" util +**************************************************************************/ + +typedef struct { + size_t size; // must be first to match size[0] uncompressed size + void *buf; +} Extent; + + +static void +xread(Extent *x, void *buf, size_t count) +{ + unsigned char *p=x->buf, *q=buf; + size_t j; + if (x->size < count) { + exit(127); + } + for (j = count; 0!=j--; ++p, ++q) { + *q = *p; + } + x->buf += count; + x->size -= count; +} + + +/************************************************************************* +// util +**************************************************************************/ + +#if 1 //{ save space +#define ERR_LAB error: exit(127); +#define err_exit(a) goto error +#else //}{ save debugging time +#define ERR_LAB +static void +err_exit(int a) +{ + (void)a; // debugging convenience + exit(127); +} +#endif //} + + +/************************************************************************* +// UPX & NRV stuff +**************************************************************************/ + +struct l_info { // 12-byte trailer for loader (after macho headers) + unsigned l_checksum; + unsigned l_magic; // UPX_MAGIC_LE32 + unsigned short l_lsize; + unsigned char l_version; + unsigned char l_format; +}; +struct p_info { // 12-byte packed program header + unsigned p_progid; + unsigned p_filesize; + unsigned p_blocksize; +}; + +struct b_info { // 12-byte header before each compressed block + unsigned sz_unc; // uncompressed_size + unsigned sz_cpr; // compressed_size + unsigned char b_method; // compression algorithm + unsigned char b_ftid; // filter id + unsigned char b_cto8; // filter parameter + unsigned char b_unused; +}; + +typedef void f_unfilter( + nrv_byte *, // also addvalue + nrv_uint, + unsigned cto8, // junk in high 24 bits + unsigned ftid +); +typedef int f_expand( + const nrv_byte *, nrv_uint, + nrv_byte *, nrv_uint *, unsigned ); + +static void +unpackExtent( + Extent *const xi, // input + Extent *const xo, // output + f_expand *const f_decompress, + f_unfilter *f_unf +) +{ + while (xo->size) { + struct b_info h; + // Note: if h.sz_unc == h.sz_cpr then the block was not + // compressible and is stored in its uncompressed form. + + // Read and check block sizes. + xread(xi, (unsigned char *)&h, sizeof(h)); + if (h.sz_unc == 0) { // uncompressed size 0 -> EOF + if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic + err_exit(2); + if (xi->size != 0) // all bytes must be written + err_exit(3); + break; + } + if (h.sz_cpr <= 0) { + err_exit(4); +ERR_LAB + } + if (h.sz_cpr > h.sz_unc + || h.sz_unc > xo->size ) { + err_exit(5); + } + // Now we have: + // assert(h.sz_cpr <= h.sz_unc); + // assert(h.sz_unc > 0 && h.sz_unc <= blocksize); + // assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize); + + if (h.sz_cpr < h.sz_unc) { // Decompress block + nrv_uint out_len = h.sz_unc; // EOF for lzma + int const j = (*f_decompress)(xi->buf, h.sz_cpr, + xo->buf, &out_len, h.b_method); + if (j != 0 || out_len != (nrv_uint)h.sz_unc) + err_exit(7); + if (h.b_ftid!=0 && f_unf) { // have filter + (*f_unf)(xo->buf, out_len, h.b_cto8, h.b_ftid); + } + xi->buf += h.sz_cpr; + xi->size -= h.sz_cpr; + } + else { // copy literal block + xread(xi, xo->buf, h.sz_cpr); + } + xo->buf += h.sz_unc; + xo->size -= h.sz_unc; + } +} + +static void +upx_bzero(unsigned char *p, size_t len) +{ + if (len) do { + *p++= 0; + } while (--len); +} +#define bzero upx_bzero + + +// The PF_* and PROT_* bits are {1,2,4}; the conversion table fits in 32 bits. +#define REP8(x) \ + ((x)|((x)<<4)|((x)<<8)|((x)<<12)|((x)<<16)|((x)<<20)|((x)<<24)|((x)<<28)) +#define EXP8(y) \ + ((1&(y)) ? 0xf0f0f0f0 : (2&(y)) ? 0xff00ff00 : (4&(y)) ? 0xffff0000 : 0) +#define PF_TO_PROT(pf) \ + ((PROT_READ|PROT_WRITE|PROT_EXEC) & ( \ + ( (REP8(PROT_EXEC ) & EXP8(PF_X)) \ + |(REP8(PROT_READ ) & EXP8(PF_R)) \ + |(REP8(PROT_WRITE) & EXP8(PF_W)) \ + ) >> ((pf & (PF_R|PF_W|PF_X))<<2) )) + +typedef struct { + unsigned magic; + unsigned nfat_arch; +} Fat_header; +typedef struct { + unsigned cputype; + unsigned cpusubtype; + unsigned offset; + unsigned size; + unsigned align; /* shift count (log base 2) */ +} Fat_arch; + enum e8 { + FAT_MAGIC = 0xcafebabe, + FAT_CIGAM = 0xbebafeca + }; + enum e9 { + CPU_TYPE_I386 = 7, + CPU_TYPE_AMD64 = 0x01000007, + CPU_TYPE_ARM = 12, + CPU_TYPE_POWERPC = 0x00000012, + CPU_TYPE_POWERPC64 = 0x01000012 + }; + +typedef struct { + unsigned magic; + unsigned cputype; + unsigned cpysubtype; + unsigned filetype; + unsigned ncmds; + unsigned sizeofcmds; + unsigned flags; + unsigned reserved; +} Mach_header64; + enum e0 { + MH_MAGIC64 = 1+0xfeedface + }; + enum e2 { + MH_EXECUTE = 2 + }; + enum e3 { + MH_NOUNDEFS = 1 + }; + +typedef struct { + unsigned cmd; + unsigned cmdsize; +} Mach_load_command; + enum e4 { + LC_SEGMENT = 0x1, + LC_SEGMENT_64 = 0x19, + LC_THREAD = 0x4, + LC_UNIXTHREAD = 0x5, + LC_LOAD_DYLINKER = 0xe + }; + +typedef struct { + unsigned cmd; + unsigned cmdsize; + char segname[16]; + uint64_t vmaddr; + uint64_t vmsize; + uint64_t fileoff; + uint64_t filesize; + unsigned maxprot; + unsigned initprot; + unsigned nsects; + unsigned flags; +} Mach_segment_command; + enum e5 { + VM_PROT_READ = 1, + VM_PROT_WRITE = 2, + VM_PROT_EXECUTE = 4 + }; + +typedef struct { + uint64_t rax, rbx, rcx, rdx; + uint64_t rdi, rsi, rbp, rsp; + uint64_t r8, r9, r10, r11; + uint64_t r12, r13, r14, r15; + uint64_t rip, rflags; + uint64_t cs, fs, gs; +} Mach_AMD64_thread_state; + +typedef struct { + unsigned cmd; /* LC_THREAD or LC_UNIXTHREAD */ + unsigned cmdsize; /* total size of this command */ + unsigned flavor; + unsigned count; /* sizeof(following_thread_state)/4 */ + Mach_AMD64_thread_state state; +} Mach_thread_command; + enum e6 { + AMD64_THREAD_STATE = 4 // x86_THREAD_STATE64 + }; + enum e7 { + AMD64_THREAD_STATE_COUNT = sizeof(Mach_AMD64_thread_state)/4 + }; + +typedef union { + unsigned offset; /* from start of load command to string */ +} Mach_lc_str; + +#define MAP_FIXED 0x10 +#define MAP_PRIVATE 0x02 +#define MAP_ANON 0x1000 +//#define MAP_ANON 0x20 // x86 DEBUG ONLY +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_ANON_FD -1 + +extern void *mmap(void *, size_t, unsigned, unsigned, int, off_t); +ssize_t pread(int, void *, size_t, off_t); +extern void bswap(void *, unsigned); + +static Mach_AMD64_thread_state const * +do_xmap( + Mach_header64 const *const mhdr, + off_t const fat_offset, + Extent *const xi, + int const fdi, + Mach_header64 **mhdrpp, + f_expand *const f_decompress, + f_unfilter *const f_unf +) +{ + Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr); + Mach_AMD64_thread_state const *entry = 0; + unsigned j; + + for ( j=0; j < mhdr->ncmds; ++j, + (sc = (Mach_segment_command const *)(sc->cmdsize + (void const *)sc)) + ) if (LC_SEGMENT_64==sc->cmd) { + Extent xo; + size_t mlen = xo.size = sc->filesize; + unsigned char *addr = xo.buf = (unsigned char *)sc->vmaddr; + unsigned char *haddr = sc->vmsize + addr; + size_t frag = (int)(uint64_t)addr &~ PAGE_MASK; + addr -= frag; + mlen += frag; + + if (0!=mlen && addr != mmap(addr, mlen, VM_PROT_READ | VM_PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | + ((xi || 0==sc->filesize) ? MAP_ANON : 0), + ((0==sc->filesize) ? MAP_ANON_FD : fdi), sc->fileoff + fat_offset) ) { + err_exit(8); + } + if (xi && 0!=sc->filesize) { + if (0==sc->fileoff /*&& 0!=mhdrpp*/) { + *mhdrpp = (Mach_header64 *)(void *)addr; + } + unpackExtent(xi, &xo, f_decompress, f_unf); + } + /*bzero(addr, frag);*/ // fragment at lo end + frag = (-mlen) &~ PAGE_MASK; // distance to next page boundary + bzero(mlen+addr, frag); // fragment at hi end + if (0!=mlen && 0!=mprotect(addr, mlen, sc->initprot)) { + err_exit(10); +ERR_LAB + } + addr += mlen + frag; /* page boundary on hi end */ + if ( +#if defined(SIMULATE_ON_DEBIAN_EABI4) /*{*/ + 0!=addr && +#endif /*}*/ + addr < haddr) { // need pages for .bss + if (addr != mmap(addr, haddr - addr, sc->initprot, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, MAP_ANON_FD, 0 ) ) { + err_exit(9); + } + } + } + else if (LC_UNIXTHREAD==sc->cmd || LC_THREAD==sc->cmd) { + Mach_thread_command const *const thrc = (Mach_thread_command const *)sc; + if (AMD64_THREAD_STATE ==thrc->flavor + && AMD64_THREAD_STATE_COUNT==thrc->count ) { + entry = &thrc->state; + } + } + return entry; +} + + +extern void spin(void *, ...); + +/************************************************************************* +// upx_main - called by our entry code +// +**************************************************************************/ + +Mach_AMD64_thread_state const * +upx_main( + struct l_info const *const li, + size_t volatile sz_compressed, // total length + Mach_header64 *const mhdr, // temp char[sz_mhdr] for decompressing + size_t const sz_mhdr, + f_expand *const f_decompress, + f_unfilter *const f_unf, + Mach_header64 **const mhdrpp // Out: *mhdrpp= &real Mach_header64 +) +{ + Mach_AMD64_thread_state const *entry; + off_t fat_offset = 0; + Extent xi, xo, xi0; + xi.buf = CONST_CAST(unsigned char *, 1+ (struct p_info const *)(1+ li)); // &b_info + xi.size = sz_compressed - (sizeof(struct l_info) + sizeof(struct p_info)); + xo.buf = (unsigned char *)mhdr; + xo.size = ((struct b_info const *)(void const *)xi.buf)->sz_unc; + xi0 = xi; + + // Uncompress Macho headers + unpackExtent(&xi, &xo, f_decompress, 0); // never filtered? + + entry = do_xmap(mhdr, fat_offset, &xi0, MAP_ANON_FD, mhdrpp, f_decompress, f_unf); + + { // Map dyld dynamic loader + Mach_load_command const *lc = (Mach_load_command const *)(1+ mhdr); + unsigned j; + + for (j=0; j < mhdr->ncmds; ++j, + (lc = (Mach_load_command const *)(lc->cmdsize + (void const *)lc)) + ) if (LC_LOAD_DYLINKER==lc->cmd) { + char const *const dyld_name = ((Mach_lc_str const *)(1+ lc))->offset + + (char const *)lc; + int const fdi = open(dyld_name, O_RDONLY, 0); + if (0 > fdi) { + err_exit(18); + } +fat: + if ((ssize_t)sz_mhdr!=pread(fdi, (void *)mhdr, sz_mhdr, fat_offset)) { +ERR_LAB + err_exit(19); + } + switch (mhdr->magic) { + case MH_MAGIC64: break; + case FAT_CIGAM: + case FAT_MAGIC: { + // stupid Apple: waste code and a page fault on EVERY execve + Fat_header *const fh = (Fat_header *)mhdr; + Fat_arch *fa = (Fat_arch *)(1+ fh); + bswap(fh, sizeof(*fh) + (fh->nfat_arch>>24)*sizeof(*fa)); + for (j= 0; j < fh->nfat_arch; ++j, ++fa) { + if (CPU_TYPE_AMD64==fa->cputype) { + fat_offset= fa->offset; + goto fat; + } + } + } break; + } // switch + entry = do_xmap(mhdr, fat_offset, 0, fdi, 0, 0, 0); + close(fdi); + break; + } + } + + return entry; +} + + +/* +vi:ts=4:et:nowrap +*/ + diff --git a/src/stub/tmp/amd64-darwin.macho-entry.bin.dump b/src/stub/tmp/amd64-darwin.macho-entry.bin.dump new file mode 100644 index 00000000..6709e64a --- /dev/null +++ b/src/stub/tmp/amd64-darwin.macho-entry.bin.dump @@ -0,0 +1,54 @@ +file format elf64-x86-64 + +Sections: +Idx Name Size VMA LMA File off Algn Flags + 0 MACHMAINX 0000000d 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY + 1 NRV_HEAD 00000066 0000000000000000 0000000000000000 0000004d 2**0 CONTENTS, READONLY + 2 NRV2E 000000b7 0000000000000000 0000000000000000 000000b3 2**0 CONTENTS, RELOC, READONLY + 3 NRV2D 0000009e 0000000000000000 0000000000000000 0000016a 2**0 CONTENTS, RELOC, READONLY + 4 NRV2B 00000090 0000000000000000 0000000000000000 00000208 2**0 CONTENTS, RELOC, READONLY + 5 LZMA_ELF00 00000064 0000000000000000 0000000000000000 00000298 2**0 CONTENTS, RELOC, READONLY + 6 LZMA_DEC10 000009f7 0000000000000000 0000000000000000 000002fc 2**0 CONTENTS, READONLY + 7 LZMA_DEC20 000009f7 0000000000000000 0000000000000000 00000cf3 2**0 CONTENTS, READONLY + 8 LZMA_DEC30 00000014 0000000000000000 0000000000000000 000016ea 2**0 CONTENTS, READONLY + 9 NRV_TAIL 00000000 0000000000000000 0000000000000000 000016fe 2**0 CONTENTS, READONLY + 10 MACHMAINY 00000011 0000000000000000 0000000000000000 000016fe 2**0 CONTENTS, READONLY + 11 MACHMAINZ 0000002b 0000000000000000 0000000000000000 0000170f 2**0 CONTENTS, READONLY +SYMBOL TABLE: +0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD +0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30 +0000000000000000 l d MACHMAINY 0000000000000000 MACHMAINY +0000000000000000 l d MACHMAINZ 0000000000000000 MACHMAINZ +0000000000000000 l d MACHMAINX 0000000000000000 MACHMAINX +0000000000000000 l d NRV2E 0000000000000000 NRV2E +0000000000000000 l d NRV2D 0000000000000000 NRV2D +0000000000000000 l d NRV2B 0000000000000000 NRV2B +0000000000000000 l d LZMA_ELF00 0000000000000000 LZMA_ELF00 +0000000000000000 l d LZMA_DEC10 0000000000000000 LZMA_DEC10 +0000000000000000 l d LZMA_DEC20 0000000000000000 LZMA_DEC20 +0000000000000000 l d NRV_TAIL 0000000000000000 NRV_TAIL +0000000000000000 g MACHMAINX 0000000000000000 _start +0000000000000011 g MACHMAINY 0000000000000000 end_decompress + +RELOCATION RECORDS FOR [MACHMAINX]: +OFFSET TYPE VALUE +0000000000000001 R_X86_64_PC32 MACHMAINZ+0x000000000000001d + +RELOCATION RECORDS FOR [NRV2E]: +OFFSET TYPE VALUE +00000000000000ae R_X86_64_PC32 NRV_HEAD+0x0000000000000021 +000000000000005b R_X86_64_PC32 MACHMAINY+0xfffffffffffffffc + +RELOCATION RECORDS FOR [NRV2D]: +OFFSET TYPE VALUE +0000000000000095 R_X86_64_PC32 NRV_HEAD+0x0000000000000021 +000000000000005b R_X86_64_PC32 MACHMAINY+0xfffffffffffffffc + +RELOCATION RECORDS FOR [NRV2B]: +OFFSET TYPE VALUE +000000000000008a R_X86_64_PC32 NRV_HEAD+0x0000000000000021 +0000000000000052 R_X86_64_PC32 MACHMAINY+0xfffffffffffffffc + +RELOCATION RECORDS FOR [LZMA_ELF00]: +OFFSET TYPE VALUE +0000000000000006 R_X86_64_PC32 LZMA_DEC30+0x0000000000000010