diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 748a136b..8500a0a6 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -54,6 +54,11 @@ static const static const #include "stub/arm-darwin.macho-fold.h" +static const +#include "stub/arm64-darwin.macho-entry.h" +static const +#include "stub/arm64-darwin.macho-fold.h" + // Packing a Darwin (Mach-o) Mac OS X dylib (dynamic shared library) // is restricted. UPX gets control as the -init function, at the very // end of processing by dyld. Relocation, loading of dependent libraries, @@ -131,6 +136,11 @@ const int *PackMachARMEL::getCompressionMethods(int method, int level) const return Packer::getDefaultCompressionMethods_8(method, level); } +const int *PackMachARM64EL::getCompressionMethods(int method, int level) const +{ + return Packer::getDefaultCompressionMethods_8(method, level); +} + PackMachPPC32::PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC, Mach_header::MH_EXECUTE, Mach_thread_command::PPC_THREAD_STATE, @@ -170,12 +180,23 @@ PackMachARMEL::PackMachARMEL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM, sizeof(Mach_ARM_thread_state)>>2, sizeof(threado)) { } +PackMachARM64EL::PackMachARM64EL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM, + Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::ARM_THREAD_STATE, + sizeof(Mach_ARM64_thread_state)>>2, sizeof(threado)) +{ } + int const *PackMachARMEL::getFilters() const { static const int filters[] = { 0x50, FT_END }; return filters; } +int const *PackMachARM64EL::getFilters() const +{ + static const int filters[] = { 0x51, FT_END }; + return filters; +} + Linker *PackMachPPC32::newLinker() const { return new ElfLinkerPpc32; @@ -196,6 +217,11 @@ Linker *PackMachARMEL::newLinker() const return new ElfLinkerArmLE; } +Linker *PackMachARM64EL::newLinker() const +{ + return new ElfLinkerArm64LE; +} + template void PackMachBase::addStubEntrySections(Filter const *) @@ -305,6 +331,21 @@ void PackMachARMEL::addStubEntrySections(Filter const * /*ft*/) addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL); } +void PackMachARM64EL::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); +} + template void PackMachBase::defineSymbols(Filter const *) { @@ -391,6 +432,14 @@ PackMachARMEL::buildLoader(const Filter *ft) stub_arm_darwin_macho_fold, sizeof(stub_arm_darwin_macho_fold), ft ); } +void +PackMachARM64EL::buildLoader(const Filter *ft) +{ + buildMachLoader( + stub_arm64_darwin_macho_entry, sizeof(stub_arm64_darwin_macho_entry), + stub_arm64_darwin_macho_fold, sizeof(stub_arm64_darwin_macho_fold), ft ); +} + void PackDylibI386::buildLoader(const Filter *ft) { @@ -652,6 +701,50 @@ void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader fo->rewrite(&linfo, sizeof(linfo)); } +void PackMachARM64EL::pack4(OutputFile *fo, Filter &ft) // append PackHeader +{ + // offset of p_info in compressed file + overlay_offset = sizeof(mhdro) + sizeof(segZERO) + + sizeof(segXHDR) + sizeof(secXHDR) + + sizeof(segTEXT) + sizeof(secTEXT) + + sizeof(segLINK) + sizeof(threado) + sizeof(linfo); + if (my_filetype==Mach_header::MH_EXECUTE) { + overlay_offset += sizeof(uuid_cmd) + sizeof(linkitem); + } + + super::pack4(fo, ft); + unsigned const t = fo->getBytesWritten(); + segTEXT.filesize = t; + segTEXT.vmsize += t; // utilize GAP + NO_LAP + sz_unc - sz_cpr + secTEXT.offset = overlay_offset - sizeof(linfo); + secTEXT.addr = segTEXT.vmaddr + secTEXT.offset; + secTEXT.size = segTEXT.filesize - secTEXT.offset; + secXHDR.offset = overlay_offset - sizeof(linfo); + if (my_filetype==Mach_header::MH_EXECUTE) { + secXHDR.offset -= sizeof(uuid_cmd) + sizeof(linkitem); + } + secXHDR.addr += secXHDR.offset; + unsigned foff1 = (PAGE_MASK & (~PAGE_MASK + segTEXT.filesize)); + if (foff1 < segTEXT.vmsize) + foff1 += PAGE_SIZE; // codesign disallows overhang + segLINK.fileoff = foff1; + segLINK.vmaddr = segTEXT.vmaddr + foff1; + fo->seek(foff1 - 1, SEEK_SET); fo->write("", 1); + fo->seek(sizeof(mhdro), SEEK_SET); + fo->rewrite(&segZERO, sizeof(segZERO)); + fo->rewrite(&segXHDR, sizeof(segXHDR)); + fo->rewrite(&secXHDR, sizeof(secXHDR)); + fo->rewrite(&segTEXT, sizeof(segTEXT)); + fo->rewrite(&secTEXT, sizeof(secTEXT)); + fo->rewrite(&segLINK, sizeof(segLINK)); + fo->rewrite(&threado, sizeof(threado)); + if (my_filetype==Mach_header::MH_EXECUTE) { + fo->rewrite(&uuid_cmd, sizeof(uuid_cmd)); + fo->rewrite(&linkitem, sizeof(linkitem)); + } + fo->rewrite(&linfo, sizeof(linfo)); +} + template void PackMachBase::pack4dylib( // append PackHeader OutputFile *const fo, @@ -906,6 +999,20 @@ void PackMachARMEL::pack3(OutputFile *fo, Filter &ft) // append loader super::pack3(fo, ft); } +void PackMachARM64EL::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.pc = len + sizeof(disp) + segTEXT.vmaddr; /* entry address */ + super::pack3(fo, ft); +} + void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader { TE32 disp; @@ -1156,6 +1263,16 @@ void PackMachARMEL::pack1_setup_threado(OutputFile *const fo) fo->write(&threado, sizeof(threado)); } +void PackMachARM64EL::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)); +} + template void PackMachBase::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header { diff --git a/src/p_mach.h b/src/p_mach.h index fa522383..4d1256a4 100644 --- a/src/p_mach.h +++ b/src/p_mach.h @@ -320,28 +320,9 @@ __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; +} // namespace N_Mach - 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; - - Word gs, fs, es, ds; - Word edi, esi, ebp, esp; - Word ebx, edx, ecx, eax; - Word eip, cs, efl; - Word uesp, ss; -__packed_struct_end() +namespace N_Mach32 { template __packed_struct(Mach_ARM_thread_state) @@ -354,14 +335,22 @@ __packed_struct(Mach_ARM_thread_state) Word cpsr; __packed_struct_end() -} // namespace N_Mach - -namespace N_Mach32 { - } // namespace N_Mach32 namespace N_Mach64 { +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_ppc_thread_state64) typedef typename TMachITypes::Word Word; @@ -382,6 +371,22 @@ __packed_struct(Mach_ppc_thread_state64) Word vrsave; /* Vector Save Register */ __packed_struct_end() +template __packed_struct(Mach_ARM64_thread_state) + typedef typename TMachITypes::Xword Xword; + typedef typename TMachITypes::Word Word; + + Xword x0, x1, x2, x3; + Xword x4, x5, x6, x7; + Xword x8, x9, x10, x11; + Xword x12, x13, x14, x15; + Xword x16, x17, x18, x19; + Xword x20, x21, x22, x23; + Xword x24, x25, x26, x27; + Xword x28, fp, lr, sp; + Xword pc; + Word cpsr; +__packed_struct_end() + } // namespace N_Mach64 namespace N_Mach { @@ -413,10 +418,10 @@ struct MachClass_32 typedef N_Mach::Mach_twolevel_hints_command Mach_twolevel_hints_command; typedef N_Mach::Mach_linkedit_data_command Mach_linkedit_data_command; typedef N_Mach::Mach_uuid_command Mach_uuid_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; + typedef N_Mach32::Mach_ARM_thread_state Mach_ARM_thread_state; static void compileTimeAssertions() { BeLePolicy::compileTimeAssertions(); @@ -452,6 +457,9 @@ struct MachClass_64 typedef N_Mach::Mach_linkedit_data_command Mach_linkedit_data_command; typedef N_Mach::Mach_uuid_command Mach_uuid_command; + typedef N_Mach64::Mach_AMD64_thread_state Mach_AMD64_thread_state; + typedef N_Mach64::Mach_ARM64_thread_state Mach_ARM64_thread_state; + static void compileTimeAssertions() { BeLePolicy::compileTimeAssertions(); COMPILE_TIME_ASSERT(sizeof(Addr) == 8) @@ -530,7 +538,8 @@ typedef MachClass_LE64::Mach_uuid_command MachLE64_uuid_command; 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_LE64::Mach_AMD64_thread_state Mach_AMD64_thread_state; +typedef MachClass_LE64::Mach_ARM64_thread_state Mach_ARM64_thread_state; typedef MachClass_LE32::Mach_ARM_thread_state Mach_ARM_thread_state; #include "p_unix.h" @@ -839,6 +848,40 @@ protected: Mach_thread_command threado; }; +class PackMachARM64EL : public PackMachBase +{ + typedef PackMachBase super; + +public: + PackMachARM64EL(InputFile *f); + + virtual int getFormat() const { return UPX_F_MACH_ARM64EL; } + virtual const char *getName() const { return "Mach/ARM64EL"; } + virtual const char *getFullName(const options_t *) const { return "ARM64EL-darwin.macho"; } +protected: + virtual const int *getCompressionMethods(int method, int level) const; + 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_ARM64_thread_state state; + #define WANT_MACH_THREAD_ENUM 1 + #include "p_mach_enum.h" + __packed_struct_end() + + Mach_thread_command threado; +}; + class PackMachFat : public Packer { typedef Packer super; diff --git a/src/stub/Makefile b/src/stub/Makefile index 5eb601e2..4792817b 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -59,6 +59,8 @@ STUBS += amd64-linux.shlib-init.h STUBS += amd64-win64.pep.h STUBS += arm-darwin.macho-entry.h STUBS += arm-darwin.macho-fold.h +STUBS += arm64-darwin.macho-entry.h +STUBS += arm64-darwin.macho-fold.h STUBS += arm-linux.elf-entry.h STUBS += arm-linux.elf-fold.h STUBS += arm-linux.kernel.vmlinux-head.h @@ -421,6 +423,47 @@ tmp/arm-darwin.macho-main.o : $(srcdir)/src/$$T.c $(call tc,f-objstrip,$@) +# /*********************************************************************** +# // arm64-darwin.macho +# ************************************************************************/ + +# info: we use the tc settings from arm64-linux.elf, but override v4 with v5 +arm64-darwin.macho%.h : tc_list = arm64-linux.elf default +arm64-darwin.macho%.h : tc_bfdname = elf64-littleaarch64 +tc.arm64-darwin.macho-entry.gcc = /usr/bin/aarch64-linux-gnu-gcc -nostdinc -MMD -MT $@ +tc.arm64-darwin.macho-fold.gcc = /usr/bin/aarch64-linux-gnu-gcc -nostdinc -MMD -MT $@ +tc.arm64-darwin.macho-main.gcc = /usr/bin/aarch64-linux-gnu-gcc -nostdinc -MMD -MT $@ + +tc.arm64-darwin.macho-fold.ld = /usr/bin/aarch64-linux-gnu-ld + +tc.arm64-darwin.macho-entry.objcopy = /usr/bin/aarch64-linux-gnu-objcopy -F elf64-littleaarch64 +tc.arm64-darwin.macho-fold.objcopy = /usr/bin/aarch64-linux-gnu-objcopy -F elf64-littleaarch64 +tc.arm64-darwin.macho-main.objcopy = /usr/bin/aarch64-linux-gnu-objcopy -F elf64-littleaarch64 + +tc.arm64-darwin.macho-entry.objdump = /usr/bin/aarch64-linux-gnu-objdump +tc.arm64-darwin.macho-fold.objdump = /usr/bin/aarch64-linux-gnu-objdump +tc.arm64-darwin.macho-main.objdump = /usr/bin/aarch64-linux-gnu-objdump + +arm64-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 $@ + +arm64-darwin.macho-fold.h : tmp/$$T.o tmp/arm64-darwin.macho-main.o + $(call tc,ld) --no-warn-mismatch --strip-all -Map tmp/$T.map $(filter %.o,$^) -o tmp/$T.tmp + $(call tc,objcopy) -O binary tmp/$T.tmp tmp/$T.bin + chmod a-x tmp/$T.bin + $(call tc,bin2h) tmp/$T.bin $@ + +tmp/arm64-darwin.macho-fold.o : $(srcdir)/src/$$T.S + $(call tc,gcc) -c $< -o $@ + $(call tc,f-objstrip,$@) + +tmp/arm64-darwin.macho-main.o : $(srcdir)/src/$$T.c + $(call tc,gcc) -c -Os $< -o $@ + $(call tc,f-objstrip,$@) + + # /*********************************************************************** # // arm-linux.elf # ************************************************************************/ diff --git a/src/stub/arm64-darwin.macho-entry.h b/src/stub/arm64-darwin.macho-entry.h new file mode 100644 index 00000000..0b60d64c --- /dev/null +++ b/src/stub/arm64-darwin.macho-entry.h @@ -0,0 +1,331 @@ +/* arm64-darwin.macho-entry.h + created from arm64-darwin.macho-entry.bin, 4659 (0x1233) bytes + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2015 Laszlo Molnar + Copyright (C) 2000-2015 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_ARM64_DARWIN_MACHO_ENTRY_SIZE 4659 +#define STUB_ARM64_DARWIN_MACHO_ENTRY_ADLER32 0x850945bc +#define STUB_ARM64_DARWIN_MACHO_ENTRY_CRC32 0x8a39bd1d + +unsigned char stub_arm64_darwin_macho_entry[4659] = { +/* 0x0000 */ 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x0010 */ 1, 0,183, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x0020 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, +/* 0x0030 */ 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 64, 0, 13, 0, 10, 0, +/* 0x0040 */ 255, 19, 0,209,224, 7,177,169,226, 15, 1,169,228, 23, 2,169, +/* 0x0050 */ 230, 31, 3,169,232, 39, 4,169,234, 47, 5,169,236, 55, 6,169, +/* 0x0060 */ 238, 63, 7,169,240, 71, 8,169,242, 79, 9,169,244, 87, 10,169, +/* 0x0070 */ 246, 95, 11,169,248,103, 12,169,250,111, 13,169,252,119, 14,169, +/* 0x0080 */ 0, 0, 0,148,226,143,190,169,254, 11, 0,249, 7, 64, 33,139, +/* 0x0090 */ 5, 0,128, 18, 4, 0,176, 82, 29, 0, 0, 20,227, 19,193,168, +/* 0x00a0 */ 0, 0, 7,203, 66, 0, 3,203,130, 0, 0,185,228, 3, 0,170, +/* 0x00b0 */ 224, 3, 3,170,225, 3, 2,170,224, 7,191,169, 35, 0,128, 82, +/* 0x00c0 */ 8, 0,176, 82, 0, 16, 32,212,224, 7,193,168, 3, 0,128, 82, +/* 0x00d0 */ 8, 0,176, 82, 0, 16, 32,212,224, 3, 4,170,254,135, 64,248, +/* 0x00e0 */ 192, 3, 31,214,132, 0, 4, 43, 68, 0, 0, 52,192, 3, 31,214, +/* 0x00f0 */ 4, 20, 64, 56,132, 0, 4, 58,132, 32, 9, 83,132, 0, 4, 43, +/* 0x0100 */ 192, 3, 31,214, 3, 20, 64, 56, 67, 20, 0, 56,246,255,255,151, +/* 0x0110 */ 162,255,255, 84, 33, 0,128, 82, 4, 0, 0, 20, 33, 4, 0, 81, +/* 0x0120 */ 241,255,255,151, 33, 0, 1, 26,239,255,255,151, 33, 0, 1, 26, +/* 0x0130 */ 237,255,255,151, 67,255,255, 84, 35, 12, 0,113, 1, 0,128, 82, +/* 0x0140 */ 35, 1, 0, 84, 5, 20, 64, 56,165, 32, 3, 42,229, 3, 37, 42, +/* 0x0150 */ 101,250,255, 52,191, 0, 0,114,165,124, 1, 19,161, 1, 0, 84, +/* 0x0160 */ 3, 0, 0, 20,224,255,255,151, 66, 1, 0, 84, 33, 0,128, 82, +/* 0x0170 */ 221,255,255,151,226, 0, 0, 84,219,255,255,151, 33, 0, 1, 26, +/* 0x0180 */ 217,255,255,151,163,255,255, 84, 33, 16, 0, 17, 4, 0, 0, 20, +/* 0x0190 */ 213,255,255,151, 33, 0, 1, 26, 33, 8, 0, 17,191, 0, 20, 49, +/* 0x01a0 */ 33, 52,129, 26, 67,192, 33,139, 99,240, 95, 56, 67,200,101, 56, +/* 0x01b0 */ 67, 20, 0, 56, 33, 4, 0,113,161,255,255, 84,212,255,255, 23, +/* 0x01c0 */ 226,143,190,169,254, 11, 0,249, 7, 64, 33,139, 5, 0,128, 18, +/* 0x01d0 */ 4, 0,176, 82, 29, 0, 0, 20,227, 19,193,168, 0, 0, 7,203, +/* 0x01e0 */ 66, 0, 3,203,130, 0, 0,185,228, 3, 0,170,224, 3, 3,170, +/* 0x01f0 */ 225, 3, 2,170,224, 7,191,169, 35, 0,128, 82, 8, 0,176, 82, +/* 0x0200 */ 0, 16, 32,212,224, 7,193,168, 3, 0,128, 82, 8, 0,176, 82, +/* 0x0210 */ 0, 16, 32,212,224, 3, 4,170,254,135, 64,248,192, 3, 31,214, +/* 0x0220 */ 132, 0, 4, 43, 68, 0, 0, 52,192, 3, 31,214, 4, 20, 64, 56, +/* 0x0230 */ 132, 0, 4, 58,132, 32, 9, 83,132, 0, 4, 43,192, 3, 31,214, +/* 0x0240 */ 3, 20, 64, 56, 67, 20, 0, 56,246,255,255,151,162,255,255, 84, +/* 0x0250 */ 33, 0,128, 82, 4, 0, 0, 20, 33, 4, 0, 81,241,255,255,151, +/* 0x0260 */ 33, 0, 1, 58,239,255,255,151, 33, 0, 1, 58,237,255,255,151, +/* 0x0270 */ 67,255,255, 84, 35, 12, 0,113, 1, 0,128, 82, 35, 1, 0, 84, +/* 0x0280 */ 5, 20, 64, 56,165, 32, 3, 42,229, 3, 37, 42,101,250,255, 52, +/* 0x0290 */ 163, 0, 1, 83,165,124, 1, 83, 99, 0, 3, 43, 2, 0, 0, 20, +/* 0x02a0 */ 224,255,255,151, 33, 0, 1, 58,222,255,255,151, 33, 0, 1, 58, +/* 0x02b0 */ 225, 0, 0, 84, 33, 0,128, 82,218,255,255,151, 33, 0, 1, 58, +/* 0x02c0 */ 216,255,255,151,163,255,255, 84, 33, 8, 0, 17, 33, 4, 0, 17, +/* 0x02d0 */ 191, 0, 20, 49, 33, 52,129, 26, 67, 0, 64, 57, 67,200,101, 56, +/* 0x02e0 */ 67, 20, 0, 56, 33, 4, 0,113,161,255,255, 84,215,255,255, 23, +/* 0x02f0 */ 1, 64, 33,139,225, 11,190,169,227,123, 1,169, 5, 0,128, 18, +/* 0x0300 */ 4, 0,176, 82, 37, 0, 0, 20,228, 11, 64,249,225,143,193,168, +/* 0x0310 */ 0, 0, 1,203, 66, 0, 3,203,130, 0, 0,185,228, 3, 0,170, +/* 0x0320 */ 224, 3, 3,170,225, 3, 2,170,224, 7,191,169, 35, 0,128, 82, +/* 0x0330 */ 8, 0,176, 82, 0, 16, 32,212,224, 7,193,168, 3, 0,128, 82, +/* 0x0340 */ 8, 0,176, 82, 0, 16, 32,212,224, 3, 4,170,254,135, 64,248, +/* 0x0350 */ 192, 3, 31,214,132, 0, 4, 43, 68, 0, 0, 52,192, 3, 31,214, +/* 0x0360 */ 4, 20, 64, 56,132, 0, 4, 26,132, 32, 9, 83,132, 0, 4, 43, +/* 0x0370 */ 192, 3, 31,214, 33, 0,128, 82,240, 3, 30,170,246,255,255,151, +/* 0x0380 */ 33, 0, 1, 58,244,255,255,151,163,255,255, 84, 0, 2, 31,214, +/* 0x0390 */ 3, 20, 64, 56, 67, 20, 0, 56,239,255,255,151,162,255,255, 84, +/* 0x03a0 */ 245,255,255,151, 35, 12, 0,113, 1, 0,128, 82,163, 0, 0, 84, +/* 0x03b0 */ 5, 20, 64, 56,165, 32, 3, 42,229, 3, 37, 42,101,250,255, 52, +/* 0x03c0 */ 229,255,255,151, 33, 0, 1, 58,227,255,255,151, 33, 0, 1, 58, +/* 0x03d0 */ 97, 0, 0, 84,232,255,255,151, 33, 8, 0, 17,191, 0, 52, 49, +/* 0x03e0 */ 33, 36,129, 26, 67,200,101, 56, 33, 4, 0,113, 67, 20, 0, 56, +/* 0x03f0 */ 162,255,255, 84,233,255,255, 23, 3,224,191, 18,159, 3, 3,107, +/* 0x0400 */ 40, 1, 0, 84, 68, 14, 64,169,127, 0, 4,235, 32, 3, 0, 84, +/* 0x0410 */ 100, 4, 0,145, 68, 6, 0,249,156, 95, 24, 83, 98, 0, 64, 57, +/* 0x0420 */ 91, 32, 27, 42, 35, 0, 64,121,130,127, 11, 83, 66,124, 3, 27, +/* 0x0430 */ 95, 0, 27,107, 8, 1, 0, 84, 0,120, 31, 83, 99, 20, 67, 75, +/* 0x0440 */ 123, 3, 2, 75,156, 3, 2, 75, 35, 0, 0,121, 0, 4, 0, 17, +/* 0x0450 */ 192, 3, 31,214, 4, 0,129, 82,252, 3, 2, 42,130, 0, 3, 75, +/* 0x0460 */ 0,120, 31, 83, 99, 20,130, 11, 35, 0, 0,121,192, 3, 31,214, +/* 0x0470 */ 32, 0,128, 82,192, 3, 31,214, 95, 16, 0,113,205, 3, 0, 84, +/* 0x0480 */ 33, 0, 64, 57, 34, 0,128, 82, 63,128, 3,113, 8, 3, 0, 84, +/* 0x0490 */ 63,176, 0,113, 31, 8, 0,185, 9, 1, 0, 84, 2, 0,128, 82, +/* 0x04a0 */ 33,180, 0, 81, 66, 4, 0, 17, 33, 28, 0, 83, 63,176, 0,113, +/* 0x04b0 */ 136,255,255, 84, 2, 8, 0,185, 63, 32, 0,113, 31, 4, 0,185, +/* 0x04c0 */ 41, 1, 0, 84, 34, 0,128, 82, 33, 36, 0, 81,227, 3, 2, 42, +/* 0x04d0 */ 66, 4, 0, 17, 33, 28, 0, 83, 63, 32, 0,113,104,255,255, 84, +/* 0x04e0 */ 3, 4, 0,185, 2, 0,128, 82, 1, 0, 0,185,224, 3, 2, 42, +/* 0x04f0 */ 192, 3, 31,214, 34, 0,128, 82,224, 3, 2, 42,192, 3, 31,214, +/* 0x0500 */ 253,123,185,169, 8,128,128, 82,253, 3, 0,145,243, 83, 1,169, +/* 0x0510 */ 245, 91, 2,169,247, 99, 3,169,249,107, 4,169, 19, 60, 64, 41, +/* 0x0520 */ 14, 8, 64,185, 11, 8, 64,249,127, 0, 0,185,223, 0, 0,185, +/* 0x0530 */ 7, 4, 64,185, 0, 96,128, 82,103, 2, 7, 11, 7, 32,199, 26, +/* 0x0540 */ 32, 0,128, 82,231,216, 28, 49, 14, 32,206, 26, 0, 32,207, 26, +/* 0x0550 */ 206, 5, 0, 81, 15, 4, 0, 81, 0, 0,128,210,160, 0, 0, 84, +/* 0x0560 */ 104,121, 32,120, 0, 4, 0,145,255, 0, 0,107,168,255,255, 84, +/* 0x0570 */ 34, 64, 34,139, 27, 0,128, 82,162, 51, 0,249, 28, 0,128, 18, +/* 0x0580 */ 32, 4, 0,145, 42, 24, 0,145, 66, 4, 0,145, 31, 0, 2,235, +/* 0x0590 */ 232, 3, 0,170, 32, 32, 0, 84,160, 55, 0,249, 0, 4, 0,145, +/* 0x05a0 */ 31, 0, 10,235, 7,224, 95, 56,251, 32, 27, 42, 1,255,255, 84, +/* 0x05b0 */ 161, 27, 5,169,233, 3, 4,170,249, 3, 3,170,165, 37, 0, 52, +/* 0x05c0 */ 55, 0,128, 82, 26, 1,128, 82,246, 3, 23, 42,245, 3, 23, 42, +/* 0x05d0 */ 231, 3, 23, 42, 10, 0,128, 82, 13, 0,128, 82, 6, 0,128, 82, +/* 0x05e0 */ 84, 3, 19, 75,204, 1, 6, 10, 72,109, 28, 83,178,131, 1,145, +/* 0x05f0 */ 0, 0,128, 82,129,125, 64,147, 40,192, 40,139, 8,249,127,211, +/* 0x0600 */ 97, 1, 8,139,125,255,255,151, 0, 10, 0, 53,224, 1, 6, 10, +/* 0x0610 */ 168, 41,212, 26, 0, 32,211, 26, 95, 25, 0,113, 8, 0, 8, 11, +/* 0x0620 */ 0,117, 30, 83, 8, 0, 8, 75, 8, 93,120,211, 8,217, 28,145, +/* 0x0630 */ 104, 5, 8,139,141, 7, 0, 84,192, 0, 7, 75, 34, 0,128, 82, +/* 0x0640 */ 44,105, 96, 56, 4, 0, 0, 20,237, 1, 0, 53, 95,252, 3,113, +/* 0x0650 */ 236, 6, 0, 84,140,121, 31, 83,224, 3, 2, 42,141, 1, 24, 18, +/* 0x0660 */ 178,131, 1,145,161,125, 64,147, 33, 0, 4,145, 33,192, 34,139, +/* 0x0670 */ 1, 5, 1,139, 97,255,255,151,226, 3, 0, 42, 98,254, 7, 54, +/* 0x0680 */ 109,254,255, 53, 95,252, 3,113, 44, 5, 0, 84, 1,197, 34,139, +/* 0x0690 */ 224, 3, 2, 42,178,131, 1,145, 88,255,255,151, 31,252, 3,113, +/* 0x06a0 */ 226, 3, 0, 42, 77,255,255, 84, 13, 28, 0, 83, 95, 13, 0,113, +/* 0x06b0 */ 45, 73, 38, 56,198, 4, 0, 17, 12, 4, 0, 84, 10, 0,128, 82, +/* 0x06c0 */ 191, 0, 6,107, 8,249,255, 84, 1,224,191, 18,159, 3, 1,107, +/* 0x06d0 */ 200, 28, 0, 84,162, 7, 70,169, 63, 0, 2,235,224, 21, 0, 84, +/* 0x06e0 */ 40, 4, 0,145,168, 55, 0,249,156, 95, 24, 83, 32, 0, 64, 57, +/* 0x06f0 */ 27, 32, 27, 42,160, 43, 64,249,243, 83, 65,169, 8, 1, 0,203, +/* 0x0700 */ 160, 47, 64,249, 40, 3, 0,185,245, 91, 66,169, 6, 0, 0,185, +/* 0x0710 */ 0, 0,128, 82,247, 99, 67,169,249,107, 68,169,253,123,199,168, +/* 0x0720 */ 192, 3, 31,214, 34, 0,128, 82,217,255,255, 23, 77, 28, 0, 83, +/* 0x0730 */ 45, 73, 38, 56,198, 4, 0, 17, 95, 37, 0,113, 76, 12, 0, 84, +/* 0x0740 */ 74, 13, 0, 81,223,255,255, 23, 77,125, 64,147,178,131, 1,145, +/* 0x0750 */ 173, 1, 3,145, 0, 0,128, 82,173,249,127,211, 97, 1, 13,139, +/* 0x0760 */ 38,255,255,151, 64, 11, 0, 53, 96, 0,128, 82, 95, 25, 0,113, +/* 0x0770 */ 247, 3, 22, 42, 10,192,159, 26,246, 3, 21, 42,120,145, 25,145, +/* 0x0780 */ 245, 3, 7, 42,178,131, 1,145,225, 3, 24,170, 0, 0,128, 82, +/* 0x0790 */ 26,255,255,151, 96, 12, 0, 53,140,113, 29, 83,232, 0,128, 18, +/* 0x07a0 */ 109, 0,128, 82,140,125, 64,147,140, 9, 0,145, 12, 7, 12,139, +/* 0x07b0 */ 32, 0,128, 82,178,131, 1,145,129, 69, 32,139, 15,255,255,151, +/* 0x07c0 */ 173, 5, 0,113,129,255,255, 84, 95, 13, 0,113, 8, 0, 8, 11, +/* 0x07d0 */ 236, 5, 0, 84,103, 0,128, 82,204, 0,128, 82, 31, 1, 7,107, +/* 0x07e0 */ 32, 0,128, 82, 7,209,135, 26,231,100, 26, 83,231,124, 64,147, +/* 0x07f0 */ 231,192, 6,145,231,248,127,211,225, 68, 32,139,178,131, 1,145, +/* 0x0800 */ 97, 1, 1,139,253,254,255,151,140, 5, 0,113, 97,255,255, 84, +/* 0x0810 */ 7, 0, 1, 81, 74, 29, 0, 17,255, 12, 0,113,236, 3, 7, 42, +/* 0x0820 */ 45, 3, 0, 84,255, 52, 0,113,224, 0, 0, 18,225,124, 1, 19, +/* 0x0830 */ 7, 0, 31, 50, 12, 12, 0, 84, 45, 4, 0, 81, 0, 86,128,210, +/* 0x0840 */ 231, 32,205, 26, 12,192, 44,203,140, 65, 39,139,108, 5, 12,139, +/* 0x0850 */ 140, 9, 0,209, 32, 0,128, 82,248, 3, 0, 42,129,197, 32,139, +/* 0x0860 */ 178,131, 1,145,229,254,255,151, 3, 0, 0, 18,225, 0, 24, 42, +/* 0x0870 */ 127, 0, 31,107, 39, 16,135, 26,173, 5, 0,113, 24,123, 31, 83, +/* 0x0880 */ 225,254,255, 84,231, 4, 0, 49, 0,242,255, 84,255, 0, 6,107, +/* 0x0890 */ 0, 9, 0, 17, 40, 8, 0, 84,225, 3, 6, 42,194, 0, 7, 75, +/* 0x08a0 */ 0, 4, 0, 81,198, 4, 0, 17, 31, 0, 31,107,160, 16, 70,122, +/* 0x08b0 */ 45,105, 98, 56, 45, 73, 33, 56,225, 3, 6, 42, 8,255,255, 84, +/* 0x08c0 */ 128,255,255, 23, 74, 25, 0, 81,126,255,255, 23,161, 97, 0,145, +/* 0x08d0 */ 178,131, 1,145, 97, 1, 1,139, 0, 0,128, 82,199,254,255,151, +/* 0x08e0 */ 128, 3, 0, 53, 1,129, 7,145,178,131, 1,145, 97, 1, 1,139, +/* 0x08f0 */ 194,254,255,151, 64, 9, 0, 53, 6, 5, 0, 52,192, 0, 7, 75, +/* 0x0900 */ 95, 25, 0,113,106, 1,128, 82, 45,105, 96, 56, 32, 1,128, 82, +/* 0x0910 */ 45, 73, 38, 56, 74,193,128, 26,198, 4, 0, 17,105,255,255, 23, +/* 0x0920 */ 178,131, 1,145, 1, 11, 0,145, 0, 0,128, 82,179,254,255,151, +/* 0x0930 */ 232, 3, 0, 42,160, 2, 0, 53,128,113, 29, 83,109, 0,128, 82, +/* 0x0940 */ 0,124, 64,147, 0, 8, 2,145, 12, 7, 0,139,153,255,255, 23, +/* 0x0950 */ 161,193, 0,145,178,131, 1,145, 97, 1, 1,139, 0, 0,128, 82, +/* 0x0960 */ 166,254,255,151, 64, 6, 0, 53, 95, 25, 0,113,224, 3, 7, 42, +/* 0x0970 */ 106, 1,128, 82,231, 3, 21, 42, 74,193,154, 26,245, 3, 0, 42, +/* 0x0980 */ 120,161, 41,145,128,255,255, 23, 12, 19, 8,145,232, 29,128, 18, +/* 0x0990 */ 13, 1,128, 82,135,255,255, 23,243, 83, 65,169,245, 91, 66,169, +/* 0x09a0 */ 247, 99, 67,169,249,107, 68,169, 32, 0,128, 82,253,123,199,168, +/* 0x09b0 */ 192, 3, 31,214,172, 51, 64,249, 33, 20, 0, 81, 3,224,191, 18, +/* 0x09c0 */ 159, 3, 3,107,231,120, 31, 83, 40, 1, 0, 84,162, 55, 64,249, +/* 0x09d0 */ 95, 0, 12,235, 68, 4, 0,145, 0,254,255, 84,164, 55, 0,249, +/* 0x09e0 */ 156, 95, 24, 83, 64, 0, 64, 57, 27, 32, 27, 42,128,127, 1, 83, +/* 0x09f0 */ 31, 0, 27,107,252, 3, 0, 42,104, 0, 0, 84,123, 3, 0, 75, +/* 0x0a00 */ 231, 0, 0, 50, 33, 4, 0,113,193,253,255, 84,231,108, 28, 83, +/* 0x0a10 */ 108, 17, 25,145,141, 0,128, 82,143,255,255, 23,224, 3, 21, 42, +/* 0x0a20 */ 245, 3, 7, 42,231, 3, 0, 42,208,255,255, 23,161, 33, 1,145, +/* 0x0a30 */ 178,131, 1,145, 97, 1, 1,139, 0, 0,128, 82,111,254,255,151, +/* 0x0a40 */ 160, 0, 0, 53,224, 3, 21, 42,245, 3, 22, 42,246, 3, 0, 42, +/* 0x0a50 */ 198,255,255, 23,224, 3, 21, 42,245, 3, 23, 42,247, 3, 22, 42, +/* 0x0a60 */ 246, 3, 0, 42,193,255,255, 23,168, 55, 64,249, 34,255,255, 23, +/* 0x0a70 */ 6, 0,128, 82, 32,255,255, 23,195, 3, 64,185,193, 7, 64,185, +/* 0x0a80 */ 194, 67, 33,139, 66, 48, 0,145,192, 67, 35,139, 0, 0, 3,145, +/* 0x0a90 */ 228, 3, 1, 42, 73,204, 95,184,132, 16, 0, 81, 9,204, 31,184, +/* 0x0aa0 */ 164,255,255, 53,196, 11, 64,185,222, 3, 2,145,227,143, 31,184, +/* 0x0ab0 */ 227, 3, 0,145,226, 3, 30,170,171, 32, 1,209,234, 3, 30,170, +/* 0x0ac0 */ 160, 0, 63,214, 64, 1, 31,214,229, 3, 30,170,235,255,255,151, +/* 0x0ad0 */ 102,105,108,101, 32,102,111,114,109, 97,116, 32,101,108,102, 54, +/* 0x0ae0 */ 52, 45,108,105,116,116,108,101, 97, 97,114, 99,104, 54, 52, 10, +/* 0x0af0 */ 10, 83,101, 99,116,105,111,110,115, 58, 10, 73,100,120, 32, 78, +/* 0x0b00 */ 97,109,101, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 83,105,122, +/* 0x0b10 */ 101, 32, 32, 32, 32, 32, 32, 86, 77, 65, 32, 32, 32, 32, 32, 32, +/* 0x0b20 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 76, 77, 65, 32, 32, 32, 32, +/* 0x0b30 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 70,105,108,101, 32, +/* 0x0b40 */ 111,102,102, 32, 32, 65,108,103,110, 32, 32, 70,108, 97,103,115, +/* 0x0b50 */ 10, 32, 32, 48, 32, 77, 65, 67, 72, 77, 65, 73, 78, 88, 32, 32, +/* 0x0b60 */ 32, 32, 32, 48, 48, 48, 48, 48, 48, 52, 52, 32, 32, 48, 48, 48, +/* 0x0b70 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x0b80 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, +/* 0x0b90 */ 32, 48, 48, 48, 48, 48, 48, 52, 48, 32, 32, 50, 42, 42, 50, 32, +/* 0x0ba0 */ 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 76, 79, 67, +/* 0x0bb0 */ 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 49, 32, 78, +/* 0x0bc0 */ 82, 86, 95, 72, 69, 65, 68, 32, 32, 32, 32, 32, 32, 48, 48, 48, +/* 0x0bd0 */ 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0be0 */ 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, +/* 0x0bf0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, +/* 0x0c00 */ 48, 56, 52, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, +/* 0x0c10 */ 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, +/* 0x0c20 */ 50, 32, 78, 82, 86, 50, 69, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x0c30 */ 48, 48, 48, 48, 48, 49, 51, 99, 32, 32, 48, 48, 48, 48, 48, 48, +/* 0x0c40 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, +/* 0x0c50 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, +/* 0x0c60 */ 48, 48, 48, 48, 56, 52, 32, 32, 50, 42, 42, 50, 32, 32, 67, 79, +/* 0x0c70 */ 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, +/* 0x0c80 */ 10, 32, 32, 51, 32, 78, 82, 86, 50, 68, 32, 32, 32, 32, 32, 32, +/* 0x0c90 */ 32, 32, 32, 48, 48, 48, 48, 48, 49, 51, 48, 32, 32, 48, 48, 48, +/* 0x0ca0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x0cb0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, +/* 0x0cc0 */ 32, 48, 48, 48, 48, 48, 49, 99, 48, 32, 32, 50, 42, 42, 50, 32, +/* 0x0cd0 */ 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, +/* 0x0ce0 */ 78, 76, 89, 10, 32, 32, 52, 32, 78, 82, 86, 50, 66, 32, 32, 32, +/* 0x0cf0 */ 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 49, 48, 56, 32, 32, +/* 0x0d00 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0d10 */ 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0d20 */ 48, 48, 32, 32, 48, 48, 48, 48, 48, 50,102, 48, 32, 32, 50, 42, +/* 0x0d30 */ 42, 50, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, +/* 0x0d40 */ 65, 68, 79, 78, 76, 89, 10, 32, 32, 53, 32, 78, 82, 86, 95, 84, +/* 0x0d50 */ 65, 73, 76, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 54, 56, +/* 0x0d60 */ 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0d70 */ 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0d80 */ 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 51,102, 56, 32, +/* 0x0d90 */ 32, 50, 42, 42, 50, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, +/* 0x0da0 */ 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 54, 32, 77, 65, +/* 0x0db0 */ 67, 72, 77, 65, 73, 78, 89, 32, 32, 32, 32, 32, 48, 48, 48, 48, +/* 0x0dc0 */ 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0dd0 */ 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0de0 */ 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 97, +/* 0x0df0 */ 55, 56, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, +/* 0x0e00 */ 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 55, +/* 0x0e10 */ 32, 77, 65, 67, 72, 77, 65, 73, 78, 90, 32, 32, 32, 32, 32, 48, +/* 0x0e20 */ 48, 48, 48, 48, 48, 53, 56, 32, 32, 48, 48, 48, 48, 48, 48, 48, +/* 0x0e30 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, +/* 0x0e40 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, +/* 0x0e50 */ 48, 48, 97, 55, 56, 32, 32, 50, 42, 42, 50, 32, 32, 67, 79, 78, +/* 0x0e60 */ 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, +/* 0x0e70 */ 83, 89, 77, 66, 79, 76, 32, 84, 65, 66, 76, 69, 58, 10, 48, 48, +/* 0x0e80 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, +/* 0x0e90 */ 32, 32, 32, 32,100, 32, 32, 77, 65, 67, 72, 77, 65, 73, 78, 90, +/* 0x0ea0 */ 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0eb0 */ 48, 32, 77, 65, 67, 72, 77, 65, 73, 78, 90, 10, 48, 48, 48, 48, +/* 0x0ec0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, +/* 0x0ed0 */ 32, 32,100, 32, 32, 77, 65, 67, 72, 77, 65, 73, 78, 88, 9, 48, +/* 0x0ee0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, +/* 0x0ef0 */ 77, 65, 67, 72, 77, 65, 73, 78, 88, 10, 48, 48, 48, 48, 48, 48, +/* 0x0f00 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32, +/* 0x0f10 */ 100, 32, 32, 78, 82, 86, 95, 72, 69, 65, 68, 9, 48, 48, 48, 48, +/* 0x0f20 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 78, 82, 86, +/* 0x0f30 */ 95, 72, 69, 65, 68, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0f40 */ 48, 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 78, +/* 0x0f50 */ 82, 86, 50, 69, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0f60 */ 48, 48, 48, 48, 48, 32, 78, 82, 86, 50, 69, 10, 48, 48, 48, 48, +/* 0x0f70 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, +/* 0x0f80 */ 32, 32,100, 32, 32, 78, 82, 86, 50, 68, 9, 48, 48, 48, 48, 48, +/* 0x0f90 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 78, 82, 86, 50, +/* 0x0fa0 */ 68, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0fb0 */ 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 78, 82, 86, 50, 66, +/* 0x0fc0 */ 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0fd0 */ 48, 32, 78, 82, 86, 50, 66, 10, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x0fe0 */ 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, +/* 0x0ff0 */ 32, 78, 82, 86, 95, 84, 65, 73, 76, 9, 48, 48, 48, 48, 48, 48, +/* 0x1000 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 78, 82, 86, 95, 84, +/* 0x1010 */ 65, 73, 76, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1020 */ 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 77, 65, 67, +/* 0x1030 */ 72, 77, 65, 73, 78, 89, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1040 */ 48, 48, 48, 48, 48, 48, 48, 32, 77, 65, 67, 72, 77, 65, 73, 78, +/* 0x1050 */ 89, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1060 */ 48, 48, 32,103, 32, 32, 32, 32, 32, 32, 32, 77, 65, 67, 72, 77, +/* 0x1070 */ 65, 73, 78, 88, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1080 */ 48, 48, 48, 48, 48, 32, 95,115,116, 97,114,116, 10, 48, 48, 48, +/* 0x1090 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,103, 32, +/* 0x10a0 */ 32, 32, 32, 32, 70, 32, 78, 82, 86, 50, 69, 9, 48, 48, 48, 48, +/* 0x10b0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 99, 32,117, 99,108, +/* 0x10c0 */ 95,110,114,118, 50,101, 95,100,101, 99,111,109,112,114,101,115, +/* 0x10d0 */ 115, 95, 56, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x10e0 */ 48, 48, 48, 48, 32,103, 32, 32, 32, 32, 32, 70, 32, 78, 82, 86, +/* 0x10f0 */ 50, 68, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1100 */ 49, 51, 48, 32,117, 99,108, 95,110,114,118, 50,100, 95,100,101, +/* 0x1110 */ 99,111,109,112,114,101,115,115, 95, 56, 10, 48, 48, 48, 48, 48, +/* 0x1120 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,103, 32, 32, 32, +/* 0x1130 */ 32, 32, 70, 32, 78, 82, 86, 50, 66, 9, 48, 48, 48, 48, 48, 48, +/* 0x1140 */ 48, 48, 48, 48, 48, 48, 48, 49, 48, 56, 32,117, 99,108, 95,110, +/* 0x1150 */ 114,118, 50, 98, 95,100,101, 99,111,109,112,114,101,115,115, 95, +/* 0x1160 */ 56, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1170 */ 48, 48, 32,103, 32, 32, 32, 32, 32, 32, 32, 77, 65, 67, 72, 77, +/* 0x1180 */ 65, 73, 78, 89, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1190 */ 48, 48, 48, 48, 48, 32,101,110,100, 95,100,101, 99,111,109,112, +/* 0x11a0 */ 114,101,115,115, 10, 10, 82, 69, 76, 79, 67, 65, 84, 73, 79, 78, +/* 0x11b0 */ 32, 82, 69, 67, 79, 82, 68, 83, 32, 70, 79, 82, 32, 91, 77, 65, +/* 0x11c0 */ 67, 72, 77, 65, 73, 78, 88, 93, 58, 10, 79, 70, 70, 83, 69, 84, +/* 0x11d0 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 84, 89, 80, 69, 32, +/* 0x11e0 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, +/* 0x11f0 */ 85, 69, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1200 */ 48, 52, 48, 32, 82, 95, 65, 65, 82, 67, 72, 54, 52, 95, 67, 65, +/* 0x1210 */ 76, 76, 50, 54, 32, 32, 77, 65, 67, 72, 77, 65, 73, 78, 90, 43, +/* 0x1220 */ 48,120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1230 */ 53, 48, 10 +}; diff --git a/src/stub/arm64-darwin.macho-fold.h b/src/stub/arm64-darwin.macho-fold.h new file mode 100644 index 00000000..776fe7e2 --- /dev/null +++ b/src/stub/arm64-darwin.macho-fold.h @@ -0,0 +1,158 @@ +/* arm64-darwin.macho-fold.h + created from arm64-darwin.macho-fold.bin, 1904 (0x770) bytes + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2015 Laszlo Molnar + Copyright (C) 2000-2015 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_ARM64_DARWIN_MACHO_FOLD_SIZE 1904 +#define STUB_ARM64_DARWIN_MACHO_FOLD_ADLER32 0xb0ecb637 +#define STUB_ARM64_DARWIN_MACHO_FOLD_CRC32 0x2d74a7c6 + +unsigned char stub_arm64_darwin_macho_fold[1904] = { +/* 0x0000 */ 97, 1, 64,249,231, 3, 4,145, 96, 65, 33,203, 3, 24, 64,185, +/* 0x0010 */ 9, 0,132, 82,127, 0, 9,107, 99,128,137, 26,255, 67, 35,203, +/* 0x0020 */ 226, 3, 0,145,101, 2, 0, 16, 40, 1, 0,148, 30,120, 64,249, +/* 0x0030 */ 252,119, 78,169,250,111, 77,169,248,103, 76,169,246, 95, 75,169, +/* 0x0040 */ 244, 87, 74,169,242, 79, 73,169,240, 71, 72,169,238, 63, 71,169, +/* 0x0050 */ 236, 55, 70,169,234, 47, 69,169,232, 39, 68,169,230, 31, 67,169, +/* 0x0060 */ 228, 23, 66,169,226, 15, 65,169,224, 7,207,168,192, 3, 31,214, +/* 0x0070 */ 99, 28, 0, 18,127, 64, 1,113, 1, 2, 0, 84, 33,124, 2, 83, +/* 0x0080 */ 192, 1, 0,180,161, 1, 0, 52, 33, 4, 0, 81, 2, 88, 97,184, +/* 0x0090 */ 67,124, 26, 83,127,148, 0,113,193, 0, 0, 84, 67, 20, 6, 18, +/* 0x00a0 */ 66, 0, 1, 75, 66,100, 0, 18, 66, 0, 3, 42, 2, 88, 33,184, +/* 0x00b0 */ 63, 0, 0,113,161,254,255, 84,192, 3, 31,214,192, 3, 31,214, +/* 0x00c0 */ 40, 0,128, 82, 0, 16, 32,212,192, 3, 31,214,104, 0,128, 82, +/* 0x00d0 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214,136, 0,128, 82, +/* 0x00e0 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214,168, 0,128, 82, +/* 0x00f0 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214,200, 0,128, 82, +/* 0x0100 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214,168, 5,128, 82, +/* 0x0110 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214, 40, 9,128, 82, +/* 0x0120 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214, 72, 9,128, 82, +/* 0x0130 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214,168, 24,128, 82, +/* 0x0140 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214, 40, 19,128, 82, +/* 0x0150 */ 0, 16, 32,212,192, 3, 31,214,192, 3, 31,214,233, 31,128, 82, +/* 0x0160 */ 41, 29, 16, 50, 6, 0, 0, 20, 2, 0, 64,185, 35, 1, 2, 10, +/* 0x0170 */ 34, 97,194, 10, 66, 32,195, 42, 2, 68, 0,184, 33, 16, 0,113, +/* 0x0180 */ 74,255,255, 84,192, 3, 31,214, 3, 16, 64,169,127, 0, 2,235, +/* 0x0190 */ 99, 0, 0, 84, 3, 0,128,210, 5, 0, 0, 20,253,123,191,169, +/* 0x01a0 */ 224, 15,128, 82,253, 3, 0,145,198,255,255,151, 95, 0, 3,235, +/* 0x01b0 */ 160, 0, 0, 84,133,104, 99, 56, 37,104, 35, 56, 99, 4, 0,145, +/* 0x01c0 */ 251,255,255, 23, 1, 4, 64,249, 33, 0, 2,139, 1, 4, 0,249, +/* 0x01d0 */ 1, 0, 64,249, 34, 0, 2,203, 2, 0, 0,249,192, 3, 95,214, +/* 0x01e0 */ 253,123,187,169,253, 3, 0,145,243, 83, 1,169,245, 91, 2,169, +/* 0x01f0 */ 244, 3, 0,170,243, 3, 1,170,246, 3, 2,170,245, 3, 3,170, +/* 0x0200 */ 96, 2, 64,249, 32, 7, 0,180,161, 3, 1,145,224, 3, 20,170, +/* 0x0210 */ 130, 1,128,210,221,255,255,151,160, 7, 72, 41, 0, 1, 0, 53, +/* 0x0220 */ 160, 10,138, 82, 0, 43,164,114, 63, 0, 0,107,225, 0, 0, 84, +/* 0x0230 */ 128, 2, 64,249,160, 5, 0,180, 4, 0, 0, 20, 31, 0, 1,107, +/* 0x0240 */ 36, 32, 95,122, 97, 0, 0, 84,224, 15,128, 82,157,255,255,151, +/* 0x0250 */ 98, 2, 64,249, 95, 64, 32,235,131,255,255, 84, 31, 0, 1,107, +/* 0x0260 */ 9, 3, 0, 84,160, 63, 0,185,163,243, 0,145,164, 35, 65, 57, +/* 0x0270 */ 98, 6, 64,249,128, 6, 64,249,192, 2, 63,214, 96,254,255, 53, +/* 0x0280 */ 160,135, 71, 41, 63, 0, 0,107, 1,254,255, 84,163, 39, 65, 57, +/* 0x0290 */ 127, 0, 31,107,164, 18, 95,250,128, 0, 0, 84,162, 43, 65, 57, +/* 0x02a0 */ 96, 6, 64,249,160, 2, 63,214,128, 6, 64,169,162, 71, 64,185, +/* 0x02b0 */ 33, 0, 2,139, 0, 0, 2,203,128, 6, 0,169, 5, 0, 0, 20, +/* 0x02c0 */ 226, 3, 1, 42, 97, 6, 64,249,224, 3, 20,170,175,255,255,151, +/* 0x02d0 */ 96, 6, 64,169,162, 67, 64,185, 33, 0, 2,139, 0, 0, 2,203, +/* 0x02e0 */ 96, 6, 0,169,199,255,255, 23,243, 83, 65,169,245, 91, 66,169, +/* 0x02f0 */ 253,123,197,168,192, 3, 95,214,253,123,182,169,253, 3, 0,145, +/* 0x0300 */ 245, 91, 2,169,247, 99, 3,169,243, 83, 1,169,249,107, 4,169, +/* 0x0310 */ 251,115, 5,169,247, 3, 0,170,244, 3, 2,170,248, 3, 3, 42, +/* 0x0320 */ 25,112, 0,145, 22, 0,128, 82, 21, 0,128,210, 92, 2,130, 82, +/* 0x0330 */ 164, 67, 0,249,166, 23, 7,169,161,143, 0,185,224, 18, 64,185, +/* 0x0340 */ 223, 2, 0,107, 34, 11, 0, 84, 32, 3, 64,185, 31,100, 0,113, +/* 0x0350 */ 193, 8, 0, 84, 51, 19, 64,249,147, 8, 0,180, 32, 15, 64,249, +/* 0x0360 */ 33, 27, 64,249, 19, 0, 19,139, 26,204,116,146,161, 3, 9,169, +/* 0x0370 */ 0, 44, 64,146, 27, 0, 1,171, 32, 9, 0, 84, 63, 0, 31,235, +/* 0x0380 */ 67, 2,130, 82, 4, 19,159, 90,116, 0, 0,181, 67, 2,128, 82, +/* 0x0390 */ 131, 3,131, 26,160,143, 64,185, 98, 0,128, 82, 37, 23, 64,249, +/* 0x03a0 */ 225, 3, 27,170, 5, 0, 5, 11,224, 3, 26,170,100,255,255,151, +/* 0x03b0 */ 95, 3, 0,235, 96, 0, 0, 84,224, 15,128, 82, 65,255,255,151, +/* 0x03c0 */ 116, 1, 0,180, 32, 27, 64,249, 32, 1, 0,180, 32, 23, 64,249, +/* 0x03d0 */ 96, 0, 0,181,160, 67, 64,249, 26, 0, 0,249,163, 11, 71,169, +/* 0x03e0 */ 161, 67, 2,145,224, 3, 20,170,126,255,255,151,227, 3, 27,203, +/* 0x03f0 */ 99, 44, 64,242,224, 0, 0, 84, 65, 3, 27,139, 0, 0,128,210, +/* 0x0400 */ 63,104, 32, 56, 0, 4, 0,145, 31, 0, 3,235,161,255,255, 84, +/* 0x0410 */ 27, 1, 0,180, 34, 63, 64,185,225, 3, 27,170,224, 3, 26,170, +/* 0x0420 */ 163, 55, 0,249, 66,255,255,151,163, 55, 64,249, 96,252,255, 53, +/* 0x0430 */ 103, 3, 3,139, 90, 3, 7,139,127, 2, 26,235,137, 2, 0, 84, +/* 0x0440 */ 34, 63, 64,185, 5, 0,128, 82, 4, 0,128, 18, 67, 2,130, 82, +/* 0x0450 */ 97, 2, 26,203,224, 3, 26,170, 57,255,255,151, 95, 3, 0,235, +/* 0x0460 */ 96, 1, 0, 84,213,255,255, 23, 0, 16, 0, 81, 31, 4, 0,113, +/* 0x0470 */ 232, 0, 0, 84, 34, 0,128,210, 33, 7, 64,249,130, 8,192,242, +/* 0x0480 */ 32, 67, 0,145, 63, 0, 2,235,181, 18,128,154, 32, 7, 64,185, +/* 0x0490 */ 214, 6, 0, 17, 57, 3, 0,139,169,255,255, 23, 3, 0,128,210, +/* 0x04a0 */ 52,249,255,181,227,255,255, 23,224, 3, 21,170,243, 83, 65,169, +/* 0x04b0 */ 245, 91, 66,169,247, 99, 67,169,249,107, 68,169,251,115, 69,169, +/* 0x04c0 */ 253,123,202,168,192, 3, 95,214,253,123,183,169,253, 3, 0,145, +/* 0x04d0 */ 243, 83, 1,169,245, 91, 2,169,161, 47, 0,249, 1, 96, 0,145, +/* 0x04e0 */ 0, 24, 64,185,243, 3, 2,170,161,131, 6,169,161, 47, 64,249, +/* 0x04f0 */ 246, 3, 3,170,162, 63, 0,249, 3, 0,128,210, 33, 96, 0,209, +/* 0x0500 */ 161, 51, 0,249,226, 3, 4,170,244, 3, 4,170,160, 7, 70,169, +/* 0x0510 */ 160, 7, 8,169,161,195, 1,145,160,131, 1,145,245, 3, 6,170, +/* 0x0520 */ 247, 99, 3,169,249,107, 4,169,247, 3, 5,170, 45,255,255,151, +/* 0x0530 */ 229, 3, 20,170,162, 3, 2,145, 1, 0,128, 82,230, 3, 23,170, +/* 0x0540 */ 228, 3, 21,170, 3, 0,128, 18,224, 3, 19,170,107,255,255,151, +/* 0x0550 */ 244, 3, 0,170, 98, 18, 64,185, 96,114, 0,145, 1, 0,128, 82, +/* 0x0560 */ 63, 0, 2,107,192, 7, 0, 84, 3, 0, 64,185,127, 56, 0,113, +/* 0x0570 */ 225, 6, 0, 84, 3, 4, 64,249, 2, 0,128, 82, 1, 0,128, 82, +/* 0x0580 */ 0, 0, 3,139,218,254,255,151,245, 3, 0, 42, 0, 4,248, 55, +/* 0x0590 */ 216, 87,151, 82, 26, 0,128, 82,216, 95,185,114,151, 2,128, 82, +/* 0x05a0 */ 25, 1,128,210, 19, 0, 0, 20, 96, 2, 64,185, 31, 0, 24,107, +/* 0x05b0 */ 97, 3, 0, 84, 97, 30, 64, 57,224, 3, 19,170,116, 34, 0,145, +/* 0x05c0 */ 33,124, 23, 27, 33, 32, 0, 17,229,254,255,151, 96, 6, 64,185, +/* 0x05d0 */ 0,100,183,155, 96, 2, 0,139,159, 2, 0,235, 0, 2, 0, 84, +/* 0x05e0 */ 129, 2, 64,185, 63, 48, 0,113, 97, 1, 0, 84,154, 10, 64,185, +/* 0x05f0 */ 227, 3, 26, 42,226, 3, 22,170,225, 3, 19,170,224, 3, 21, 42, +/* 0x0600 */ 211,254,255,151, 31, 0, 22,235, 0,253,255, 84,224, 15,128, 82, +/* 0x0610 */ 172,254,255,151,148, 82, 0,145,240,255,255, 23, 6, 0,128,210, +/* 0x0620 */ 5, 0,128,210, 4, 0,128,210,227, 3, 21, 42, 2, 0,128,210, +/* 0x0630 */ 225, 3, 26, 42,224, 3, 19,170, 48,255,255,151,244, 3, 0,170, +/* 0x0640 */ 224, 3, 21, 42,174,254,255,151, 5, 0, 0, 20, 3, 4, 64,185, +/* 0x0650 */ 33, 4, 0, 17, 0, 0, 3,139,194,255,255, 23,224, 3, 20,170, +/* 0x0660 */ 243, 83, 65,169,245, 91, 66,169,247, 99, 67,169,249,107, 68,169, +/* 0x0670 */ 253,123,201,168,192, 3, 95,214, 20, 0, 0, 0, 0, 0, 0, 0, +/* 0x0680 */ 1,122, 82, 0, 4,120, 30, 1, 27, 12, 31, 0, 0, 0, 0, 0, +/* 0x0690 */ 36, 0, 0, 0, 28, 0, 0, 0,240,250,255,255, 88, 0, 0, 0, +/* 0x06a0 */ 0, 70, 14, 16,157, 2,158, 1, 66, 13, 29, 65, 12, 31, 0,221, +/* 0x06b0 */ 222, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, +/* 0x06c0 */ 32,251,255,255, 24, 1, 0, 0, 0, 65, 14, 80,157, 10,158, 9, +/* 0x06d0 */ 65, 13, 29, 66,147, 8,148, 7,149, 6,150, 5, 2, 65,222,221, +/* 0x06e0 */ 213,214,211,212, 12, 31, 0, 0, 68, 0, 0, 0,116, 0, 0, 0, +/* 0x06f0 */ 8,252,255,255,208, 1, 0, 0, 0, 65, 14,160, 1,157, 20,158, +/* 0x0700 */ 19, 65, 13, 29, 69,149, 16,150, 15,151, 14,152, 13,147, 18,148, +/* 0x0710 */ 17,153, 12,154, 11,155, 10,156, 9, 2,108,222,221,219,220,217, +/* 0x0720 */ 218,215,216,213,214,211,212, 12, 31, 0, 0, 0, 0, 0, 0, 0, +/* 0x0730 */ 60, 0, 0, 0,188, 0, 0, 0,144,253,255,255,176, 1, 0, 0, +/* 0x0740 */ 0, 65, 14,144, 1,157, 18,158, 17, 65, 13, 29, 69,147, 16,148, +/* 0x0750 */ 15,149, 14,150, 13, 81,151, 12,152, 11,153, 10,154, 9, 2, 83, +/* 0x0760 */ 222,221,217,218,215,216,213,214,211,212, 12, 31, 0, 0, 0, 0 +}; diff --git a/src/stub/src/arch/arm/v8a/lzma_d.S b/src/stub/src/arch/arm/v8a/lzma_d.S new file mode 100644 index 00000000..f27e04f2 --- /dev/null +++ b/src/stub/src/arch/arm/v8a/lzma_d.S @@ -0,0 +1,471 @@ +rcGetBit.2736: + mov w3, 16777215 + cmp w28, w3 + bhi .L2 + ldp x4, x3, [x18] + cmp x3, x4 + beq .L5 + add x4, x3, 1 + str x4, [x18, 8] + lsl w28, w28, 8 + ldrb w2, [x3] + orr w27, w2, w27, lsl 8 +.L2: + ldrh w3, [x1] + lsr w2, w28, 11 + mul w2, w2, w3 + cmp w2, w27 + bhi .L7 + lsl w0, w0, 1 + sub w3, w3, w3, lsr 5 + sub w27, w27, w2 + sub w28, w28, w2 + strh w3, [x1] + add w0, w0, 1 + ret +.L7: + mov w4, 2048 + mov w28, w2 + sub w2, w4, w3 + lsl w0, w0, 1 + add w3, w3, w2, asr 5 + strh w3, [x1] + ret +.L5: + mov w0, 1 + ret + +LzmaDecodeProperties: + cmp w2, 4 + ble .L14 + ldrb w1, [x1] + mov w2, 1 + cmp w1, 224 + bhi .L9 + cmp w1, 44 + str wzr, [x0, 8] + bls .L10 + mov w2, 0 +.L11: + sub w1, w1, #45 + add w2, w2, 1 + uxtb w1, w1 + cmp w1, 44 + bhi .L11 + str w2, [x0, 8] +.L10: + cmp w1, 8 + str wzr, [x0, 4] + bls .L12 + mov w2, 1 +.L13: + sub w1, w1, #9 + mov w3, w2 + add w2, w2, 1 + uxtb w1, w1 + cmp w1, 8 + bhi .L13 + str w3, [x0, 4] +.L12: + mov w2, 0 + str w1, [x0] +.L9: + mov w0, w2 + ret +.L14: + mov w2, 1 + mov w0, w2 + ret + +LzmaDecode: + stp x29, x30, [sp, -112]! + mov w8, 1024 + add x29, sp, 0 + stp x19, x20, [sp, 16] + stp x21, x22, [sp, 32] + stp x23, x24, [sp, 48] + stp x25, x26, [sp, 64] + ldp w19, w15, [x0] + ldr w14, [x0, 8] + ldr x11, [x0, 16] + str wzr, [x3] + str wzr, [x6] + ldr w7, [x0, 4] + mov w0, 768 + add w7, w19, w7 + lsl w7, w0, w7 + mov w0, 1 + adds w7, w7, 1846 + lsl w14, w0, w14 + lsl w0, w0, w15 + sub w14, w14, #1 + sub w15, w0, #1 + mov x0, 0 + beq .L22 +.L79: + strh w8, [x11, x0, lsl 1] + add x0, x0, 1 + cmp w7, w0 + bhi .L79 +.L22: + add x2, x1, x2, uxtw + mov w27, 0 + str x2, [x29, 96] + mov w28, -1 + add x0, x1, 1 + add x10, x1, 6 + add x2, x2, 1 +.L20: + cmp x0, x2 + mov x8, x0 + beq .L41 + str x0, [x29, 104] + add x0, x0, 1 + cmp x0, x10 + ldrb w7, [x0, -2] + orr w27, w7, w27, lsl 8 + bne .L20 + stp x1, x6, [x29, 80] + mov x9, x4 + mov x25, x3 + cbz w5, .L63 + mov w23, 1 + mov w26, 8 + mov w22, w23 + mov w21, w23 + mov w7, w23 + mov w10, 0 + mov w13, 0 + mov w6, 0 + sub w20, w26, w19 +.L60: + and w12, w14, w6 + lsl w8, w10, 4 + add x18, x29, 96 + mov w0, 0 + sxtw x1, w12 + add x8, x1, x8, sxtw + lsl x8, x8, 1 + add x1, x11, x8 + bl rcGetBit.2736 + cbnz w0, .L26 + and w0, w15, w6 + asr w8, w13, w20 + lsl w0, w0, w19 + cmp w10, 6 + add w8, w0, w8 + lsl w0, w8, 2 + sub w8, w0, w8 + ubfiz x8, x8, 8, 24 + add x8, x8, 1846 + add x8, x11, x8, lsl 1 + ble .L64 + sub w0, w6, w7 + mov w2, 1 + ldrb w12, [x9, x0] + b .L32 +.L96: + cbnz w13, .L29 +.L30: + cmp w2, 255 + bgt .L31 +.L32: + lsl w12, w12, 1 + mov w0, w2 + and w13, w12, 256 + add x18, x29, 96 + sxtw x1, w13 + add x1, x1, 256 + add x1, x1, x2, sxtw + add x1, x8, x1, lsl 1 + bl rcGetBit.2736 + mov w2, w0 + tbz x2, 0, .L96 + cbnz w13, .L30 +.L29: + cmp w2, 255 + bgt .L31 +.L33: + add x1, x8, x2, sxtw 1 + mov w0, w2 + add x18, x29, 96 + bl rcGetBit.2736 + cmp w0, 255 + mov w2, w0 + ble .L33 + uxtb w13, w0 + cmp w10, 3 + strb w13, [x9, w6, uxtw] + add w6, w6, 1 + bgt .L62 + mov w10, 0 +.L34: + cmp w5, w6 + bhi .L60 +.L58: + mov w1, 16777215 + cmp w28, w1 + bhi .L97 + ldp x2, x1, [x29, 96] + cmp x1, x2 + beq .L41 + add x8, x1, 1 + str x8, [x29, 104] + lsl w28, w28, 8 + ldrb w0, [x1] + orr w27, w0, w27, lsl 8 +.L25: + ldr x0, [x29, 80] + ldp x19, x20, [sp, 16] + sub x8, x8, x0 + ldr x0, [x29, 88] + str w8, [x25] + ldp x21, x22, [sp, 32] + str w6, [x0] + mov w0, 0 + ldp x23, x24, [sp, 48] + ldp x25, x26, [sp, 64] + ldp x29, x30, [sp], 112 + ret +.L64: + mov w2, 1 + b .L33 +.L31: + uxtb w13, w2 + strb w13, [x9, w6, uxtw] + add w6, w6, 1 +.L62: + cmp w10, 9 + bgt .L35 + sub w10, w10, #3 + b .L34 +.L26: + sxtw x13, w10 + add x18, x29, 96 + add x13, x13, 192 + mov w0, 0 + lsl x13, x13, 1 + add x1, x11, x13 + bl rcGetBit.2736 + cbnz w0, .L36 + mov w0, 3 + cmp w10, 6 + mov w23, w22 + csel w10, w0, wzr, gt + mov w22, w21 + add x24, x11, 1636 + mov w21, w7 +.L38: + add x18, x29, 96 + mov x1, x24 + mov w0, 0 + bl rcGetBit.2736 + cbnz w0, .L44 + lsl w12, w12, 3 + mov w8, -8 + mov w13, 3 + sxtw x12, w12 + add x12, x12, 2 + add x12, x24, x12, lsl 1 +.L45: + mov w0, 1 +.L47: + add x18, x29, 96 + add x1, x12, x0, uxtw 1 + bl rcGetBit.2736 + subs w13, w13, #1 + bne .L47 + cmp w10, 3 + add w8, w0, w8 + bgt .L48 + mov w7, 3 + mov w12, 6 + cmp w8, w7 + mov w0, 1 + csel w7, w8, w7, le + lsl w7, w7, 6 + sxtw x7, w7 + add x7, x7, 432 + lsl x7, x7, 1 +.L49: + add x1, x7, x0, uxtw 1 + add x18, x29, 96 + add x1, x11, x1 + bl rcGetBit.2736 + subs w12, w12, #1 + bne .L49 + sub w7, w0, #64 + add w10, w10, 7 + cmp w7, 3 + mov w12, w7 + ble .L50 + cmp w7, 13 + and w0, w7, 1 + asr w1, w7, 1 + orr w7, w0, 2 + bgt .L51 + sub w13, w1, #1 + mov x0, 688 + lsl w7, w7, w13 + sub x12, x0, x12, sxtw + add x12, x12, x7, uxtw + add x12, x11, x12, lsl 1 + sub x12, x12, #2 +.L52: + mov w0, 1 + mov w24, w0 +.L57: + add x1, x12, x0, sxtw 1 + add x18, x29, 96 + bl rcGetBit.2736 + and w3, w0, 1 + orr w1, w7, w24 + cmp w3, wzr + csel w7, w1, w7, ne + subs w13, w13, #1 + lsl w24, w24, 1 + bne .L57 +.L50: + adds w7, w7, 1 + beq .L58 +.L48: + cmp w7, w6 + add w0, w8, 2 + bhi .L41 + mov w1, w6 +.L59: + sub w2, w6, w7 + sub w0, w0, #1 + add w6, w6, 1 + cmp w0, wzr + ccmp w5, w6, 0, ne + ldrb w13, [x9, x2] + strb w13, [x9, w1, uxtw] + mov w1, w6 + bhi .L59 + b .L34 +.L35: + sub w10, w10, #6 + b .L34 +.L36: + add x1, x13, 24 + add x18, x29, 96 + add x1, x11, x1 + mov w0, 0 + bl rcGetBit.2736 + cbnz w0, .L39 + add x1, x8, 480 + add x18, x29, 96 + add x1, x11, x1 + bl rcGetBit.2736 + cbnz w0, .L67 + cbz w6, .L41 + sub w0, w6, w7 + cmp w10, 6 + mov w10, 11 + ldrb w13, [x9, x0] + mov w0, 9 + strb w13, [x9, w6, uxtw] + csel w10, w10, w0, gt + add w6, w6, 1 + b .L34 +.L44: + add x18, x29, 96 + add x1, x24, 2 + mov w0, 0 + bl rcGetBit.2736 + mov w8, w0 + cbnz w0, .L46 + lsl w0, w12, 3 + mov w13, 3 + sxtw x0, w0 + add x0, x0, 130 + add x12, x24, x0, lsl 1 + b .L45 +.L39: + add x1, x13, 48 + add x18, x29, 96 + add x1, x11, x1 + mov w0, 0 + bl rcGetBit.2736 + cbnz w0, .L98 +.L40: + cmp w10, 6 + mov w0, w7 + mov w10, 11 + mov w7, w21 + csel w10, w10, w26, gt + mov w21, w0 + add x24, x11, 2664 + b .L38 +.L46: + add x12, x24, 516 + mov w8, -240 + mov w13, 8 + b .L45 +.L41: + ldp x19, x20, [sp, 16] + ldp x21, x22, [sp, 32] + ldp x23, x24, [sp, 48] + ldp x25, x26, [sp, 64] + mov w0, 1 + ldp x29, x30, [sp], 112 + ret +.L51: + ldr x12, [x29, 96] + sub w1, w1, #5 + mov w3, 16777215 +.L55: + cmp w28, w3 + lsl w7, w7, 1 + bhi .L53 + ldr x2, [x29, 104] + cmp x2, x12 + add x4, x2, 1 + beq .L41 + str x4, [x29, 104] + lsl w28, w28, 8 + ldrb w0, [x2] + orr w27, w0, w27, lsl 8 +.L53: + lsr w0, w28, 1 + cmp w0, w27 + mov w28, w0 + bhi .L54 + sub w27, w27, w0 + orr w7, w7, 1 +.L54: + subs w1, w1, #1 + bne .L55 + lsl w7, w7, 4 + add x12, x11, 1604 + mov w13, 4 + b .L52 +.L67: + mov w0, w21 + mov w21, w7 + mov w7, w0 + b .L40 +.L98: + add x1, x13, 72 + add x18, x29, 96 + add x1, x11, x1 + mov w0, 0 + bl rcGetBit.2736 + cbnz w0, .L69 + mov w0, w21 + mov w21, w22 + mov w22, w0 + b .L40 +.L69: + mov w0, w21 + mov w21, w23 + mov w23, w22 + mov w22, w0 + b .L40 +.L97: + ldr x8, [x29, 104] + b .L25 +.L63: + mov w6, 0 + b .L25 diff --git a/src/stub/src/arch/arm/v8a/macros.S b/src/stub/src/arch/arm/v8a/macros.S new file mode 100644 index 00000000..af8f2919 --- /dev/null +++ b/src/stub/src/arch/arm/v8a/macros.S @@ -0,0 +1,116 @@ +/* +; macros.S -- +; +; This file is part of the UPX executable compressor. +; +; Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer +; Copyright (C) 1996-2015 Laszlo Molnar +; 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 +; +; +*/ + + .altmacro + +.macro section name + .section \name +.endm + +/* The order of #if-#elif matters: ARMEL_EABI4 takes precedence over ARM_OLDABI */ +#if defined(ARMEL_DARWIN) /*{*/ +__NR_SYSCALL_BASE = 0 +.macro do_sys N + mov w8,#\N + brk #0x80 // sets Carry iff error + // orrcs r0,r0,#(1<<31) // force negative on error; FIXME: needed? + ret +.endm +.macro do_sys7t N + do_sys \N +.endm + +.macro do_dcache_flush // In: r0=addr; r1=len + mov w3,#1 // _sys_dcache_flush + mov w8,#(1<<31) // syscall number? + brk #0x80 +.endm + +.macro do_icache_invalidate // In: r0=addr; r1=len + mov w3,#0 // _sys_icache_invalidate + mov w8,#(1<<31) // syscall number? + brk #0x80 +.endm +#elif defined(ARMEL_EABI4) /*}{*/ + +__NR_SYSCALL_BASE = 0 +.macro do_sys7t N + mov r7,#\N // syscall number + brk #0 +.endm +.macro do_sys N + mov r12,r7 // save r7 in ip + do_sys7t \N + mov r7,r12 // restore r7 from ip +.endm +.macro do_sys7t2 N + mov r7, #(\N) & 0xff // syscall number + orr r7,r7,#(\N) &~0xff // high bits + brk #0 +.endm +.macro do_sys2 N + mov r12,r7 // save r7 in ip + do_sys7t2 \N + mov r7,r12 // restore r7 from ip +.endm + +#elif defined(ARM_OLDABI) /*}{*/ + +__NR_SYSCALL_BASE = 0x900000 +.macro do_sys N + brk #\N +.endm +.macro do_sys7t N + do_sys \N +.endm +.macro do_sys2 N + brk #\N +.endm +.macro do_sys7t2 N + do_sys2 \N +.endm + +#else /*}{*/ +.macro do_sys N + error \N // ARM_OLDABI, ARMEL_EABI4, ARMEL_DARWIN ? +.endm +.macro do_sys2 N + error \N // ARM_OLDABI, ARMEL_EABI4, ARMEL_DARWIN ? +.endm +#endif /*}*/ + +.macro ret + br lr /* armv5 for thumb interworking */ +.endm + +.macro loadcon8 reg,val8 + .long (0xe3<<24)|(0xa0<<16)|((\reg<<4)<<8)+(\val8) /* mov \reg,#\val8 */ +.endm + +// vi:ts=8:et:nowrap diff --git a/src/stub/src/arch/arm/v8a/nrv2b_d8.S b/src/stub/src/arch/arm/v8a/nrv2b_d8.S new file mode 100644 index 00000000..091a0c7f --- /dev/null +++ b/src/stub/src/arch/arm/v8a/nrv2b_d8.S @@ -0,0 +1,147 @@ +/* nrv2b_d8.S -- ARM decompressor for NRV2B + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2015 Laszlo Molnar + Copyright (C) 2000-2015 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 lr x30 +#define ip0 x16 + +#define src x0 +#define len w1 +#define dst x2 +#define dstw w2 +#define tmp w3 +#define bits w4 +#define off w5 + +/* macros reduce "noise" when comparing this ARM code to corresponding THUMB code */ +#define PUSH1(r1) str r1, [sp,#-1*8]! +#define PUSH2(r1,r2) stp r1,r2,[sp,#-2*8]! +#define PUSH4(r1,r2,r3,r4) stp r1,r2,[sp,#-4*8]!; stp r3,r4,[sp,#2*8] +#define POP2(r1,r2) ldp r1,r2,[sp],#2*8 +#define POP3(r1,r2,r3) ldr r3,[sp,#2*8]; ldp r1,r2,[sp],#3*8 +#define ADD2( dst,src) add dst,dst,src +#define ADD2S(dst,src) adds dst,dst,src +#define ADC2( dst,src) adc dst,dst,src +#define ADC2S(dst,src) adcs dst,dst,src +#define SUB2( dst,src) sub dst,dst,src +#define SUB2S(dst,src) subs dst,dst,src +#define LDRB3(reg,psrc,incr) ldrb reg,psrc,incr +#define STRB3(reg,pdst,incr) strb reg,pdst,incr + +#undef GETBIT +#define GETBIT bl get1_n2b + +#define getnextb(reg) GETBIT; ADC2S(reg,reg) /* Set Condition Codes on result */ +#define jnextb0 GETBIT; bcc +#define jnextb1 GETBIT; bcs + +ucl_nrv2b_decompress_8: .globl ucl_nrv2b_decompress_8 // ARM mode + .type ucl_nrv2b_decompress_8, %function +/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst) */ + add x1,src,len,uxtw // x1= eof_src; + PUSH4(x1,x2,x3, lr) + mov off,#-1 // off= -1 initial condition + mov bits,#1<<31 // refill next time + b top_n2b + +eof_n2b: + POP3(x1,x3,x4) // x1= eof_src; r3= orig_dst; r4= plen_dst + SUB2(src,x1) // 0 if actual src length equals expected length + SUB2(dst,x3) // actual dst length + str dstw,[x4] + +#if defined(LINUX_ARM_CACHEFLUSH) /*{*/ + mov x4,x0 // save result value + mov x0,x3 // orig_dst + add x1,x3,dst // orig_dst + dst_len + mov w2,#0 + do_sys2 __ARM_NR_cacheflush // decompressed region + mov x0,x4 // result value +#endif /*}*/ +#if defined(DARWIN_ARM_CACHEFLUSH) /*{*/ + mov x4,x0 // save result value + mov x0,x3 // orig_dst + mov x1,dst // dst_len + PUSH2(x0,x1); do_dcache_flush + POP2 (x0,x1); do_icache_invalidate + mov x0,x4 // result value +#endif /*}*/ + + ldr lr,[sp],#8 + ret + +get1_n2b: + ADD2S(bits,bits); cbz bits,get8_n2b; ret +get8_n2b: // In: Carry set [from adding 0x80000000 (1<<31) to itself] + LDRB3(bits,[src],#1) // zero-extend next byte + ADC2(bits,bits) // double and insert CarryIn as low bit + lsl bits,bits,#23 // top 9 bits + ADD2S(bits,bits) // top 8 bits; CarryOut from doubling + ret + +ss11_n2b: // return len= [2..) + mov len,#1 // the msb + mov ip0,lr // outer ret.addr +1: + getnextb(len) + jnextb0 1b + br ip0 // outer ret + +lit_n2b: + LDRB3(tmp,[src],#1) + STRB3(tmp,[dst],#1) +top_n2b: + jnextb1 lit_n2b + + bl ss11_n2b // len= [2..) + subs tmp,len,#3 // set Carry + mov len,#0 // Carry unaffected + blo offprev_n2b // ss11 returned 2 + LDRB3(off,[src],#1) // low 8 bits + orr off,off,tmp,lsl #8 + mvn off,off; cbz off,eof_n2b // off= ~off +offprev_n2b: // In: 0==len + getnextb(len); getnextb(len); bne 1f // two bits; 1,2,3 ==> 2,3,4 + bl ss11_n2b // len= [2..) + ADD2(len,#2) // [2..) ==> [4..); +1: +/* 'cmn': add the inputs, set condition codes, discard the sum */ + cmn off,#0xd<<8 // within M2_MAX_OFFSET + cinc len,len,cc // too far away, so minimum match length is 3 +copy_n2b: // copy 1+len bytes + ldrb tmp,[dst,off,sxtw]; SUB2S(len,#1) + STRB3(tmp,[dst],#1); bhs copy_n2b + b top_n2b // exit with -1==len + + .size ucl_nrv2b_decompress_8, .-ucl_nrv2b_decompress_8 +/* +vi:ts=8:et:nowrap + */ + diff --git a/src/stub/src/arch/arm/v8a/nrv2d_d8.S b/src/stub/src/arch/arm/v8a/nrv2d_d8.S new file mode 100644 index 00000000..13fa0de6 --- /dev/null +++ b/src/stub/src/arch/arm/v8a/nrv2d_d8.S @@ -0,0 +1,206 @@ +/* nrv2d_d8.S -- ARM decompressor for NRV2D + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2015 Laszlo Molnar + Copyright (C) 2000-2015 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 SAFE 0 /* 1 for src+dst bounds checking: cost 76 bytes */ + +#define lr x30 + +#define src x0 +#define len w1 /* overlaps 'cnt' */ +#define dst x2 +#define dstw w2 +#define tmp w3 +#define tmpx x3 +#define bits w4 +#define off w5 +/* r6 UNUSED in ARM code unless DEBUG mode */ +#define srclim x7 +#if 1==SAFE /*{*/ +#define dstlim x12 /* FIXME */ +#endif /*}*/ + +#define cnt w1 /* overlaps 'len' while reading an offset */ + +/* macros reduce "noise" when comparing this ARM code to corresponding THUMB code */ +#define PUSH2(r1,r2) stp r1,r2,[sp,#-2*8]! +#define POP2(r1,r2) ldp r1,r2,[sp],#2*8 +#define PUSH3(r1,r2,r3) stp r1,r2,[sp,#-3*8]!; str r3,[sp,#2*8] + +#define ADD2( dst,src) add dst,dst,src +#define ADD2S(dst,src) adds dst,dst,src +#define ADC2( dst,src) adc dst,dst,src +#define ADC2S(dst,src) adcs dst,dst,src +#define SUB2( dst,src) sub dst,dst,src +#define SUB2S(dst,src) subs dst,dst,src +#define LDRB3(reg,psrc,incr) ldrb reg,psrc,incr +#define STRB3(reg,pdst,incr) strb reg,pdst,incr + +#if 1==SAFE /*{*/ +#define CHECK_SRC cmp srclim,src; bls bad_src_n2d /* Out: 1==Carry for get8_n2d */ +#define CHECK_DST cmp dst,dstlim; bhs bad_dst_n2d +#else /*}{*/ +#define CHECK_SRC /*empty*/ +#define CHECK_DST /*empty*/ +#endif /*}*/ + +#if 0 /*{ DEBUG only: check newly-decompressed against original dst */ +#define CHECK_BYTE \ + ldrb w6,[dst]; \ + cmp w6,tmp; beq 0f; bkpt; 0: +#else /*}{*/ +#define CHECK_BYTE /*empty*/ +#endif /*}*/ + +#undef GETBIT +#define GETBIT bl get1_n2d + +#undef getnextb +#define getnextb(reg) GETBIT; ADC2S(reg,reg) /* Out: condition code changed */ +#define jnextb0 GETBIT; bcc +#define jnextb1 GETBIT; bcs + +ucl_nrv2d_decompress_8: .globl ucl_nrv2d_decompress_8 // ARM mode + .type ucl_nrv2d_decompress_8, %function +/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst) + Actual decompressed length is stored through plen_dst. + For SAFE mode: at call, *plen_dst must be allowed length of output buffer. +*/ + PUSH3(x2,x3, lr) +#define sp_DST0 0 /* stack offset of original dst */ + add srclim,src,len,uxtw // srclim= eof_src; +#if 1==SAFE /*{*/ + ldr tmp,[x3] // len_dst + add dstlim,dst,tmp,uxtw +#endif /*}*/ + mov off,#-1 // off= -1 initial condition + mov bits,#1<<31 // refill next time + b top_n2d + +#if 1==SAFE /*{*/ +bad_dst_n2d: # return value will be 2 +bkpt + add src,srclim,#1 +bad_src_n2d: # return value will be 1 + ADD2(src,#1) +#endif /*}*/ +eof_n2d: + POP2(x3,x4) // r3= orig_dst; r4= plen_dst + SUB2(src,srclim) // 0 if actual src length equals expected length + SUB2(dst,x3) // actual dst length + str dstw,[x4] + +#if defined(LINUX_ARM_CACHEFLUSH) /*{*/ + mov x4,x0 // save result value + mov x0,x3 // orig_dst + add x1,x3,dst // orig_dst + dst_len + mov w2,#0 + do_sys2 __ARM_NR_cacheflush // decompressed region + mov x0,x4 // result value +#endif /*}*/ +#if defined(DARWIN_ARM_CACHEFLUSH) /*{*/ + mov x4,x0 // save result value + mov x0,x3 // orig_dst + mov x1,dst // dst_len + PUSH2(x0,x1); do_dcache_flush + POP2 (x0,x1); do_icache_invalidate + mov x0,x4 // result value +#endif /*}*/ + + ldr lr,[sp],#8 + ret + +get1_n2d: + ADD2S(bits,bits); cbz bits,get8_n2d; ret +get8_n2d: // In: Carry set [from adding 0x80000000 (1<<31) to itself] + CHECK_SRC; LDRB3(bits,[src],#1) // zero-extend next byte + ADC2S(bits,bits) // double and insert CarryIn as low bit + lsl bits,bits,#23 // top 9 bits + ADD2S(bits,bits) // top 8 bits; CarryOut from doubling + ret + +lit_n2d: + CHECK_SRC; LDRB3(tmp,[src],#1) + CHECK_BYTE + CHECK_DST; STRB3(tmp,[dst],#1) +top_n2d: + jnextb1 lit_n2d + mov cnt,#1; b getoff_n2d + +off_n2d: + SUB2(cnt,#1) + getnextb(cnt) +getoff_n2d: + getnextb(cnt) + jnextb0 off_n2d + + subs tmp,cnt,#3 // set Carry + mov len,#0 // Carry unaffected + blo offprev_n2d // cnt was 2; tests Carry only + CHECK_SRC; LDRB3(off,[src],#1) // low 7+1 bits + orr off,off,tmp,lsl #8 + mvn off,off; cbz off,eof_n2d // off= ~off + lsl tmp,off,#31; lsr off,off,#1; adds tmp,tmp,tmp + b len_n2d -4 // CHEAT [getnextb ends in ADC2(reg,reg)] + +offprev_n2d: + getnextb(len) +len_n2d: + getnextb(len); bne gotlen_n2d // 1..3 getnextb() must set Condition Code + mov len,#1 // begin ss11 +lenmore_n2d: + getnextb(len) + jnextb0 lenmore_n2d + ADD2(len,#2) // 2.. ==> 4.. +gotlen_n2d: // 'cmn': add the inputs, set condition codes, discard the sum + ADD2(len,#1) // 1..3 ==> 2..4; 4.. ==> 5.. + cmn off,#5<<8 // displ<=M2_MAX_OFFSET ==> no increment + csinc len,len,len,cc // too far away, so minimum match length is 3 +#if 1==SAFE /*{*/ + ldr tmp,[sp,#sp_DST0] + SUB2( tmp,dst) + SUB2S(tmp,off); bhi bad_dst_n2d // reaching back too far + + add tmp,dst,cnt + cmp tmp,dstlim; bhi bad_dst_n2d // too much output +#endif /*}*/ + ldrb tmp,[dst] // force cacheline allocate +copy_n2d: + ldrb tmp,[dst,off,sxtw] + CHECK_BYTE + STRB3(tmp,[dst],#1) + SUB2S(len,#1); bne copy_n2d + b top_n2d + + .size ucl_nrv2d_decompress_8, .-ucl_nrv2d_decompress_8 + +/* +vi:ts=8:et:nowrap + */ + diff --git a/src/stub/src/arch/arm/v8a/nrv2e_d32.S b/src/stub/src/arch/arm/v8a/nrv2e_d32.S new file mode 100644 index 00000000..14842ca5 --- /dev/null +++ b/src/stub/src/arch/arm/v8a/nrv2e_d32.S @@ -0,0 +1,208 @@ +/* nrv2e_d32.S -- ARM decompressor for NRV2E + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2008 Laszlo Molnar + Copyright (C) 2000-2008 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 SAFE 0 /* 1 for src+dst bounds checking: cost 76 bytes */ + +#define lr x30 + +#define src x0 +#define len w1 /* overlaps 'cnt' */ +#define dst x2 +#define dstw w2 +#define tmp w3 +#define tmpx x3 +#define bits w4 +#define off w5 +/* r6 UNUSED in ARM code unless DEBUG mode */ +#define srclim x7 +#if 1==SAFE /*{*/ +#define dstlim x12 +#endif /*}*/ + +#define cnt w1 /* overlaps 'len' while reading an offset */ + +/* macros reduce "noise" when comparing this ARM code to corresponding THUMB code */ +#define PUSH2(r1,r2) stp r1,r2,[sp,#-2*8]! +#define PUSH3(r1,r2,r3) stp r1,r2,[sp,#-3*8]!; str r3,[sp,#2*8] +#define POP2(r1,r2) ldp r1,r2,[sp],#2*8 +#define ADD2( dst,src) add dst,dst,src +#define ADD2S(dst,src) adds dst,dst,src +#define ADC2( dst,src) adc dst,dst,src +#define ADC2S(dst,src) adcs dst,dst,src +#define SUB2( dst,src) sub dst,dst,src +#define SUB2S(dst,src) subs dst,dst,src +#define LDRB3(reg,psrc,incr) ldrb reg,psrc,incr +#define STRB3(reg,pdst,incr) strb reg,pdst,incr + +#if 1==SAFE /*{*/ +#define CHECK_SRC cmp srclim,src; bls bad_src_n2e /* Out: 1==Carry for get32_n2e */ +#define CHECK_DST cmp dst,dstlim; bhs bad_dst_n2e +#else /*}{*/ +#define CHECK_SRC /*empty*/ +#define CHECK_DST /*empty*/ +#endif /*}*/ + +#if 0 /*{ DEBUG only: check newly-decompressed against original dst */ +#define CHECK_BYTE \ + ldrb w6,[dst]; \ + cmp w6,tmp; beq 0f; bkpt; 0: +#else /*}{*/ +#define CHECK_BYTE /*empty*/ +#endif /*}*/ + +#undef GETBIT +#define GETBIT bl get1_n2e + +#undef getnextb +#define getnextb(reg) GETBIT; ADC2(reg,reg) /* Out: condition code not changed */ +#define jnextb0 GETBIT; bcc +#define jnextb1 GETBIT; bcs + +ucl_nrv2e_decompress_32: .globl ucl_nrv2e_decompress_32 // ARM mode + .type ucl_nrv2e_decompress_32, %function +/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst) + Actual decompressed length is stored through plen_dst. + For SAFE mode: at call, *plen_dst must be allowed length of output buffer. +*/ + PUSH3(x2,x3, lr) +#define sp_DST0 0 /* stack offset of original dst */ + add srclim,src,len,uxtw // srclim= eof_src; +#if 1==SAFE /*{*/ + ldr tmp,[r3] // len_dst + add dstlim,tmp,dst +#endif /*}*/ + mov off,#-1 // off= -1 initial condition + mov bits,#1<<31 // refill next time + b top_n2e + +#if 1==SAFE /*{*/ +bad_dst_n2e: # return value will be 2 +bkpt + add src,srclim,#1 +bad_src_n2e: # return value will be 1 + ADD2(src,#1) +#endif /*}*/ +eof_n2e: + POP2(x3,x4) // r3= orig_dst; r4= plen_dst + SUB2(src,srclim) // 0 if actual src length equals expected length + SUB2(dst,x3) // actual dst length + str dstw,[x4] + +#if defined(LINUX_ARM_CACHEFLUSH) /*{*/ + mov x4,x0 // save result value + mov x0,x3 // orig_dst + add x1,x3,dst // orig_dst + dst_len + mov w2,#0 + do_sys2 __ARM_NR_cacheflush // decompressed region + mov x0,x4 // result value +#endif /*}*/ +#if defined(DARWIN_ARM_CACHEFLUSH) /*{*/ + mov x4,x0 // save result value + mov x0,x3 // orig_dst + mov x1,dst // dst_len + PUSH2(x0,x1); do_dcache_flush + POP {x0,x1}; do_icache_invalidate + mov x0,x4 // result value +#endif /*}*/ + + ldr lr,[sp],#8; br lr + +get1_n2e: + ADD2S(bits,bits); cbz bits,get32_n2e; ret +get32_n2e: // In: Carry set [from adding 0x80000000 (1<<31) to itself] + CHECK_SRC; ldr bits,[src],#4 + ADC2S(bits,bits) // double, insert CarryIn as low bit, record CarryOut + ret + +lit_n2e: + CHECK_SRC; LDRB3(tmp,[src],#1) + CHECK_BYTE + CHECK_DST; STRB3(tmp,[dst],#1) +top_n2e: + jnextb1 lit_n2e + mov cnt,#1; b getoff_n2e + +off_n2e: + SUB2(cnt,#1) + getnextb(cnt) +getoff_n2e: + getnextb(cnt) + jnextb0 off_n2e + + subs tmp,cnt,#3 // set Carry + mov len,#0 // Carry unaffected + blo offprev_n2e // cnt was 2; tests Carry only + CHECK_SRC; LDRB3(off,[src],#1) // low 7+1 bits + orr off,off,tmp,lsl #8 + mvn off,off; cbz off,eof_n2e // off= ~off + tst off,#1; asr off,off,#1; bne lenlast_n2e + b lenmore_n2e + +offprev_n2e: + jnextb1 lenlast_n2e +lenmore_n2e: + mov len,#1 + jnextb1 lenlast_n2e +len_n2e: + getnextb(len) + jnextb0 len_n2e + ADD2(len,#6-2) + b gotlen_n2e + +lenlast_n2e: + getnextb(len) // 0,1,2,3 + ADD2(len,#2) +gotlen_n2e: // 'cmn': add the inputs, set condition codes, discard the sum + cmn off,#5<<8 // within M2_MAX_OFFSET + cinc len,len,cc // too far away, so minimum match length is 3 +near_n2e: +#if 1==SAFE /*{*/ + ldr tmp,[sp,#sp_DST0] + SUB2( tmp,dst) + SUB2S(tmp,off); bhi bad_dst_n2e // reaching back too far + + add tmp,dst,cnt + cmp tmp,dstlim; bhi bad_dst_n2e // too much output +#endif /*}*/ + add tmpx,dst,len,uxtw + ldrb tmp,[tmpx,#-1] // force cacheline allocate +copy_n2e: + ldrb tmp,[dst,off,sxtw] + CHECK_BYTE + STRB3(tmp,[dst],#1) + SUB2S(len,#1); bne copy_n2e + b top_n2e + + .size ucl_nrv2e_decompress_32, .-ucl_nrv2e_decompress_32 + +/* +vi:ts=8:et:nowrap + */ + diff --git a/src/stub/src/arch/arm/v8a/nrv2e_d8.S b/src/stub/src/arch/arm/v8a/nrv2e_d8.S new file mode 100644 index 00000000..f4b24c37 --- /dev/null +++ b/src/stub/src/arch/arm/v8a/nrv2e_d8.S @@ -0,0 +1,213 @@ +/* armv4_n2e_d8.S -- ARM decompressor for NRV2E + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2015 Laszlo Molnar + Copyright (C) 2000-2015 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 SAFE 0 /* 1 for src+dst bounds checking: cost 76 bytes */ + +#define lr x30 + +#define src x0 +#define len w1 /* overlaps 'cnt' */ +#define dst x2 +#define dstw w2 +#define tmp w3 +#define tmpx x3 +#define bits w4 +#define off w5 +/* r6 UNUSED in ARM code unless DEBUG mode */ +#define srclim x7 +#if 1==SAFE /*{*/ +#define dstlim x12 /* FIXME */ +#endif /*}*/ + +#define cnt w1 /* overlaps 'len' while reading an offset */ + +/* macros reduce "noise" when comparing this ARM code to corresponding THUMB code */ +#define PUSH2(r1,r2) stp r1,r2,[sp,#-2*8]! +#define PUSH3(r1,r2,r3) stp r1,r2,[sp,#-3*8]!; str r3,[sp,#2*8] +#define POP2(r1,r2) ldp r1,r2,[sp],#2*8 +#define POP1(r1) ldr r1, [sp],# 8 +#define ADD2( dst,src) add dst,dst,src +#define ADD2S(dst,src) adds dst,dst,src +#define ADC2( dst,src) adc dst,dst,src +#define ADC2S(dst,src) adcs dst,dst,src +#define SUB2( dst,src) sub dst,dst,src +#define SUB2S(dst,src) subs dst,dst,src +#define LDRB3(reg,psrc,incr) ldrb reg,psrc,incr +#define STRB3(reg,pdst,incr) strb reg,pdst,incr + +#if 1==SAFE /*{*/ +#define CHECK_SRC cmp srclim,src; bls bad_src_n2e /* Out: 1==Carry for get8_n2e */ +#define CHECK_DST cmp dst,dstlim; bhs bad_dst_n2e +#else /*}{*/ +#define CHECK_SRC /*empty*/ +#define CHECK_DST /*empty*/ +#endif /*}*/ + +#if 0 /*{ DEBUG only: check newly-decompressed against original dst */ +#define CHECK_BYTE \ + ldrb w6,[dst]; \ + cmp w6,tmp; beq 0f; bkpt; 0: +#else /*}{*/ +#define CHECK_BYTE /*empty*/ +#endif /*}*/ + +#undef GETBIT +#define GETBIT bl get1_n2e + +#undef getnextb +#define getnextb(reg) GETBIT; ADC2(reg,reg) /* Out: condition code not changed */ +#define jnextb0 GETBIT; bcc +#define jnextb1 GETBIT; bcs + +ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8 // ARM mode + .type ucl_nrv2e_decompress_8, %function +/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst) + Actual decompressed length is stored through plen_dst. + For SAFE mode: at call, *plen_dst must be allowed length of output buffer. +*/ + PUSH3(x2,x3, lr) +#define sp_DST0 0 /* stack offset of original dst */ + add srclim,src,len,uxtw // srclim= eof_src; +#if 1==SAFE /*{*/ + ldr tmp,[r3] // len_dst + add dstlim,tmp,dst +#endif /*}*/ + mov off,#-1 // off= -1 initial condition + mov bits,#1<<31 // refill next time + b top_n2e + +#if 1==SAFE /*{*/ +bad_dst_n2e: # return value will be 2 +bkpt + add src,srclim,#1 +bad_src_n2e: # return value will be 1 + ADD2(src,#1) +#endif /*}*/ +eof_n2e: + POP2(x3,x4) // r3= orig_dst; r4= plen_dst + SUB2(src,srclim) // 0 if actual src length equals expected length + SUB2(dst,x3) // actual dst length + str dstw,[x4] + +#if defined(LINUX_ARM_CACHEFLUSH) /*{*/ + mov x4,x0 // save result value + mov x0,x3 // orig_dst + add x1,x3,dst // orig_dst + dst_len + mov x2,#0 + do_sys2 __ARM_NR_cacheflush // decompressed region + mov x0,x4 // result value +#endif /*}*/ +#if defined(DARWIN_ARM_CACHEFLUSH) /*{*/ + mov x4,x0 // save result value + mov x0,x3 // orig_dst + mov x1,dst // dst_len + PUSH2(x0,x1); do_dcache_flush + POP2 (x0,x1); do_icache_invalidate + mov x0,x4 // result value +#endif /*}*/ + + POP1(lr) + ret + +get1_n2e: + ADD2S(bits,bits); cbz bits,get8_n2e; ret +get8_n2e: + // In: Carry set [from adding 0x80000000 (1<<31) to itself] + CHECK_SRC; LDRB3(bits,[src],#1) // zero-extend next byte + ADC2S(bits,bits) // double and insert CarryIn as low bit + lsl bits,bits,#23 // top 9 bits + ADD2S(bits,bits) // top 8 bits; CarryOut from doubling + ret + +lit_n2e: + CHECK_SRC; LDRB3(tmp,[src],#1) + CHECK_BYTE + CHECK_DST; STRB3(tmp,[dst],#1) +top_n2e: + jnextb1 lit_n2e + mov cnt,#1; b getoff_n2e + +off_n2e: + SUB2(cnt,#1) + getnextb(cnt) +getoff_n2e: + getnextb(cnt) + jnextb0 off_n2e + + subs tmp,cnt,#3 // set Carry + mov len,#0 // Carry unaffected + blo offprev_n2e // cnt was 2; tests Carry only + CHECK_SRC; LDRB3(off,[src],#1) // low 7+1 bits + orr off,off,tmp,lsl #8 + mvn off,off; cbz off,eof_n2e // off= ~off + tst off,#1; asr off,off,#1; bne lenlast_n2e // branch on former bottom bit + b lenmore_n2e + +offprev_n2e: + jnextb1 lenlast_n2e +lenmore_n2e: + mov len,#1 + jnextb1 lenlast_n2e +len_n2e: + getnextb(len) + jnextb0 len_n2e + ADD2(len,#6-2) + b gotlen_n2e + +lenlast_n2e: + getnextb(len) // 0,1,2,3 + ADD2(len,#2) +gotlen_n2e: // 'cmn': add the inputs, set condition codes, discard the sum + cmn off,#5<<8 // within M2_MAX_OFFSET + csinc len,len,len,cc // too far away, so minimum match length is 3 +near_n2e: +#if 1==SAFE /*{*/ + ldr tmp,[sp,#sp_DST0] + SUB2( tmp,dst) + SUB2S(tmp,off); bhi bad_dst_n2e // reaching back too far + + add tmp,dst,cnt + cmp tmp,dstlim; bhi bad_dst_n2e // too much output +#endif /*}*/ + add tmpx,dst,len,sxtw + ldrb tmp,[tmpx,#-1] // force cacheline allocate +copy_n2e: + ldrb tmp,[dst,off,sxtw] + CHECK_BYTE + STRB3(tmp,[dst],#1) + SUB2S(len,#1); bne copy_n2e + b top_n2e + + .size ucl_nrv2e_decompress_8, .-ucl_nrv2e_decompress_8 + +/* +vi:ts=8:et:nowrap + */ + diff --git a/src/stub/src/arm64-darwin.macho-entry.S b/src/stub/src/arm64-darwin.macho-entry.S new file mode 100644 index 00000000..b96f73ff --- /dev/null +++ b/src/stub/src/arm64-darwin.macho-entry.S @@ -0,0 +1,156 @@ +/* arm-darwin.macho-entry.S -- iPhone program entry point & decompressor (Elf binary) +* +* This file is part of the UPX executable compressor. +* +* Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer +* Copyright (C) 1996-2015 Laszlo Molnar +* Copyright (C) 2000-2015 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 SIMULATE_ON_DEBIAN_EABI4 1 +#undef SIMULATE_ON_DEBIAN_EABI4 + +#ifdef SIMULATE_ON_DEBIAN_EABI4 /*{*/ + #define LINUX_ARM_CACHEFLUSH 1 /* SIMULATE_ON_DEBIAN_EABI4 */ + #define ARMEL_EABI4 1 /* SIMULATE_ON_DEBIAN_EABI4 */ +#else /*}{ usual case */ + #define DARWIN_ARM_CACHEFLUSH 1 + #define ARMEL_DARWIN 1 +#endif /*}*/ + +#define lr x30 + +#include "arch/arm/v8a/macros.S" + +sz_b_info= 12 + sz_unc= 0 + sz_cpr= 4 + b_method= 8 +sz_l_info= 12 +sz_p_info= 12 + +PROT_READ= 1 +PROT_WRITE= 2 +PROT_EXEC= 4 + +MAP_PRIVATE= 2 +MAP_FIXED= 0x10 +MAP_ANONYMOUS= 0x20 + +PAGE_SHIFT= 12 +PAGE_SIZE = -(~0< farthest prefetch; must match ../../p_mach.cpp +NO_LAP= 64 // avoid overlap for folded loader; must match ../../p_mach.cpp + +/* +vi:ts=8:et:nowrap +*/ + + diff --git a/src/stub/src/arm64-darwin.macho-fold.S b/src/stub/src/arm64-darwin.macho-fold.S new file mode 100644 index 00000000..402a3f12 --- /dev/null +++ b/src/stub/src/arm64-darwin.macho-fold.S @@ -0,0 +1,213 @@ +// arm-darwin.macho-fold.S -- linkage to C code to process Mach-O binary +// +// This file is part of the UPX executable compressor. +// +// Copyright (C) 2000-2015 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 SIMULATE_ON_DEBIAN_EABI4 1 +#undef SIMULATE_ON_DEBIAN_EABI4 + +#ifdef SIMULATE_ON_DEBIAN_EABI4 /*{*/ + #define LINUX_ARM_CACHEFLUSH 1 /* SIMULATE_ON_DEBIAN_EABI4 */ + #define ARMEL_EABI4 1 /* SIMULATE_ON_DEBIAN_EABI4 */ +#else /*}{ USUAL case */ + #define DARWIN_ARM_CACHEFLUSH 1 + #define ARMEL_DARWIN 1 +#endif /*}*/ + +#include "arch/arm/v8a/macros.S" + +sz_l_info = 12 +sz_p_info = 12 +sz_b_info = 12 + sz_unc= 0 + sz_cpr= 4 + b_method= 8 + +_start: .globl _start // ignored, but silence "cannot find entry symbol _start" from ld + +// control just falls through, after this part and compiled C code +// are uncompressed. + +fold_begin: +/* In: + x11= &sz_pack2; follows compressed program {l_info; p_info; b_info; data...} + x4= f_decompress + sp/ junk1,junk2,{30 original regs (omit sp,lr)},junk3,original_stack... +*/ +#define t0w w9 /* scratch value */ +lr .req x30 + ldr x1,[x11] // sz_pack2 + add x7,sp,#8*(2+(32-2)) // &junk3; will become &mhdrp + sub x0,x11,x1,uxtw // &{l_info; p_info; b_info} + ldr w3,[x0,#sz_unc + sz_l_info + sz_p_info] // sz_unc of Mach_header + mov t0w,#(1<<13) + cmp w3,t0w + csel w3,w3,t0w,hi // at least 8KiB + sub sp,sp,w3,uxtw // alloca + mov x2,sp // Mach_header *tmp + adr x5,f_unfilter + bl upx_main // (x0=l_info *, w1=sz_compressed, x2=Mach_header *tmp, + // w3=sz_mhdr, x4=f_decompress, x5=f_unfilter, x6= &Mach_header *) + ldr lr,[x0,#30*8] // entry: ((Mach_ARM_thread_state const *)dyld)->pc + ldp x28,x29,[sp,#8*28] + ldp x26,x27,[sp,#8*26] + ldp x24,x25,[sp,#8*24] + ldp x22,x23,[sp,#8*22] + ldp x20,x21,[sp,#8*20] + ldp x18,x19,[sp,#8*18] + ldp x16,x17,[sp,#8*16] + ldp x14,x15,[sp,#8*14] + ldp x12,x13,[sp,#8*12] + ldp x10,x11,[sp,#8*10] + ldp x8,x9,[sp,#8*8] + ldp x6,x7,[sp,#8*6] + ldp x4,x5,[sp,#8*4] + ldp x2,x3,[sp,#8*2] + ldp x0,x1,[sp],#8*30 + br lr + +f_unfilter: // (char *ptr, uint len, uint cto, uint fid) + ptr .req x0 + len .req w1 + cto .req w2 // unused + fid .req w3 + + t1 .req w2 + t2 .req w3 + +#ifndef FILTER_ID /*{*/ +#define FILTER_ID 0x50 /* little-endian */ +#endif /*}*/ + and fid,fid,#0xff + cmp fid,#FILTER_ID // last use of fid + bne unf_ret // no-op if not filter 0x50 + + lsr len,len,#2 // word count + cbz ptr,unf_ret // no-op if ptr is NULL + cbz len,unf_ret // no-op if len is 0 + +top_unf: + sub len,len,#1 + ldr t1,[ptr,len,uxtw #2] + lsr t2,t1,#26 + cmp t2, #045; bne tst_unf // not 'bl' subroutine call + and t2,t1,#077<<26 // all the non-displacement bits + sub t1,t1,len // convert to word-relative displacement + bic t1,t1,#077<<26 // restrict to displacement field + orr t1,t1,t2 // re-combine + str t1,[ptr,len,uxtw #2] +tst_unf: + cmp len,#0 + bne top_unf +unf_ret: + ret + + .unreq ptr + .unreq len + .unreq cto + .unreq fid + +spin: .globl spin + ret + +__NR_exit = 1 + __NR_SYSCALL_BASE +__NR_read = 3 + __NR_SYSCALL_BASE +__NR_write = 4 + __NR_SYSCALL_BASE +__NR_open = 5 + __NR_SYSCALL_BASE +__NR_close = 6 + __NR_SYSCALL_BASE +__NR_brk = 45 + __NR_SYSCALL_BASE + +__NR_mmap = 197 + __NR_SYSCALL_BASE +__NR_munmap = 73 + __NR_SYSCALL_BASE +__NR_mprotect = 74 + __NR_SYSCALL_BASE +__NR_pread = 153 + __NR_SYSCALL_BASE + +#ifdef SIMULATE_ON_DEBIAN_EABI4 /*{*/ +__NR_mmap = 192 + __NR_SYSCALL_BASE // mmap2 +__NR_munmap = 91 + __NR_SYSCALL_BASE +__NR_mprotect = 125 + __NR_SYSCALL_BASE +__NR_pread = 180 + __NR_SYSCALL_BASE +#endif /*}*/ + + .globl exit +exit: + do_sys __NR_exit + + .globl read +read: + do_sys __NR_read; ret + + .globl write +write: + do_sys __NR_write; ret + + .globl open +open: + do_sys __NR_open; ret + + .globl close +close: + do_sys __NR_close; ret + + .globl brk +brk: + do_sys __NR_brk; ret + + .globl munmap +munmap: + do_sys __NR_munmap; ret + + .globl mprotect +mprotect: + do_sys __NR_mprotect; ret + + .globl mmap +mmap: + do_sys __NR_mmap; ret + + .globl pread +pread: + do_sys __NR_pread; ret + + .globl bswap +bswap: + mov w9, #0xff + orr w9,w9,#0xff<<16 // w9= 0x00ff00ff + b bswap9 +bswap0: + ldr w2,[x0] // r2= A B C D + and w3,w9,w2 // r3= 0 B 0 D + and w2,w9,w2,ror #24 // r2= 0 C 0 A + orr w2,w2,w3,ror # 8 // r2= D C B A + str w2,[x0],#4 +bswap9: + subs w1,w1,#4 + bge bswap0 + ret + +// vi:ts=8:et:nowrap + diff --git a/src/stub/src/arm64-darwin.macho-main.c b/src/stub/src/arm64-darwin.macho-main.c new file mode 100644 index 00000000..34273973 --- /dev/null +++ b/src/stub/src/arm64-darwin.macho-main.c @@ -0,0 +1,468 @@ +/* arm-darwin.macho-main.c -- loader stub for Mach-o ARMEL + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2015 Laszlo Molnar + Copyright (C) 2000-2015 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 SIMULATE_ON_DEBIAN_EABI4 1 +#undef SIMULATE_ON_DEBIAN_EABI4 + +#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 /*empty*/ +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 + }; + enum e9 { + CPU_TYPE_I386 = 7, + 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; +} Mach_header; + enum e0 { + MH_MAGIC = 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]; + unsigned long vmaddr; + unsigned long vmsize; + unsigned long fileoff; + unsigned long 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 { + unsigned long x0, x1, x2, x3; + unsigned long x4, x5, x6, x7; + unsigned long x8, x9, x10, x11; + unsigned long x12, x13, x14, x15; + unsigned long x16, x17, x18, x19; + unsigned long x20, x21, x22, x23; + unsigned long x24, x25, x26, x27; + unsigned long x28, fp, lr, sp; + unsigned long pc; + unsigned int cpsr; +} Mach_ARM_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_ARM_thread_state state; +} Mach_thread_command; + enum e6 { + ARM_THREAD_STATE = 1 + }; + enum e7 { + ARM_THREAD_STATE_COUNT = sizeof(Mach_ARM_thread_state)/4 + }; + +typedef union { + unsigned long offset; /* from start of load command to string */ + char *ptr; +} 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_ARM_thread_state const * +do_xmap( + Mach_header const *const mhdr, + off_t const fat_offset, + Extent *const xi, + int const fdi, + Mach_header **mhdrpp, + f_expand *const f_decompress, + f_unfilter *const f_unf +) +{ + Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr); + Mach_ARM_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 && sc->vmsize!=0) { + 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 = (size_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_header *)(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 (ARM_THREAD_STATE ==thrc->flavor + && ARM_THREAD_STATE_COUNT==thrc->count ) { + entry = &thrc->state; + } + } + return entry; +} + + +extern void spin(void *, ...); + +/************************************************************************* +// upx_main - called by our entry code +// +**************************************************************************/ + +Mach_ARM_thread_state const * +upx_main( + struct l_info const *const li, + size_t volatile sz_compressed, // total length + Mach_header *const mhdr, // temp char[sz_mhdr] for decompressing + size_t const sz_mhdr, + f_expand *const f_decompress, + f_unfilter *const f_unf, + Mach_header **const mhdrpp // Out: *mhdrpp= &real Mach_header +) +{ + Mach_ARM_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_MAGIC: break; + 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_ARM==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/src/arm64-linux.elf-entry.S b/src/stub/src/arm64-linux.elf-entry.S new file mode 100644 index 00000000..6a4f8cdb --- /dev/null +++ b/src/stub/src/arm64-linux.elf-entry.S @@ -0,0 +1,271 @@ +/* aarch64-linux.elf-entry.S -- Linux program entry point & decompressor (Elf binary) +* +* This file is part of the UPX executable compressor. +* +* Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer +* Copyright (C) 1996-2015 Laszlo Molnar +* Copyright (C) 2000-2015 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 ARM_OLDABI 1 +#include "arch/arm/v4a/macros.S" + +#define bkpt .long 0xe7f001f0 /* reserved instr; Linux GNU eabi breakpoint */ +sz_Elf64_Ehdr= 64 +sz_Elf64_Phdr= 56 + +sz_b_info= 12 + sz_unc= 0 + sz_cpr= 4 + b_method= 8 +sz_l_info= 12 +sz_p_info= 12 + +PROT_READ= 1 +PROT_WRITE= 2 +PROT_EXEC= 4 + +MAP_FIXED= 0x10 + +PAGE_SHIFT= 12 +PAGE_SIZE = -(~0<'; strb r1,[r2],#1 + + mov r5,#3 @ rows to print +L600: @ each row + sub r0,r4,#TRACE_BUFLEN + sub r0,r0,sp + mov r0,r0,lsr #2; mov r1,#'\n'; bl trace_hex @ which block of 8 + + mov r6,#8 @ words per row +L610: @ each word + ldr r0,[r4],#4; mov r1,#' '; bl trace_hex @ next word + subs r6,r6,#1; bgt L610 + + subs r5,r5,#1; bgt L600 + + mov r0,#'\n'; strb r0,[r2],#1 + sub r2,r2,sp @ count + mov r1,sp @ buf + mov r0,#2 @ FD_STDERR +#if defined(ARMEL_EABI4) /*{*/ + mov r7,#__NR_write + swi 0 +#else /*}{*/ + swi __NR_write +#endif /*}*/ + add sp,sp,#TRACE_BUFLEN + ldmia sp!,{TRACE_REGS} + +trace_hex: // In: r0=val, r1=punctuation before, r2=ptr; Uses: r3, ip + strb r1,[r2],#1 @ punctuation + mov r3,#4*(8 -1) @ shift count + adr ip,hex +L620: + mov r1,r0,lsr r3 + and r1,r1,#0xf + ldrb r1,[ip, r1] + strb r1,[r2],#1 + subs r3,r3,#4; bge L620 + ret +hex: + .ascii "0123456789abcdef" +#endif /*}*/ + +f_decompress: +#define LINUX_ARM_CACHEFLUSH 1 + + section NRV_HEAD + // empty + section NRV_TAIL + // empty + + section NRV2E +#include "arch/arm/v4a/nrv2e_d8.S" + + section NRV2D +#include "arch/arm/v4a/nrv2d_d8.S" + + section NRV2B +#include "arch/arm/v4a/nrv2b_d8.S" + +#include "arch/arm/v4a/lzma_d.S" + + section ELFMAINY +end_decompress: .globl end_decompress + +msg_SELinux: + mov r2,#L71 - L70 // length + adr r1,L70 // message text + mov r0,#2 // fd stderr +#if defined(ARMEL_EABI4) /*{*/ + mov r7,#__NR_write + swi 0 +#else /*}{*/ + swi __NR_write +#endif /*}*/ +die: + mov r0,#127 +#if defined(ARMEL_EABI4) /*{*/ + mov r7,#__NR_exit + swi 0 +#else /*}{*/ + swi __NR_exit +#endif /*}*/ +L70: + .asciz "PROT_EXEC|PROT_WRITE failed.\n" +L71: + /* IDENTSTR goes here */ + + section ELFMAINZ +cpr0: .globl cpr0 + /* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */ + +/* +vi:ts=8:et:nowrap +*/ + diff --git a/src/stub/src/arm64-linux.elf-fold.S b/src/stub/src/arm64-linux.elf-fold.S new file mode 100644 index 00000000..06a6d7ec --- /dev/null +++ b/src/stub/src/arm64-linux.elf-fold.S @@ -0,0 +1,451 @@ +@ aarch64-linux.elf-fold.S -- linkage to C code to process Elf binary +@ +@ This file is part of the UPX executable compressor. +@ +@ Copyright (C) 2000-2015 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 ARM_OLDABI 1 +#include "arch/arm/v4a/macros.S" +#define bkpt .long 0xe7f001f0 /* reserved instr; Linux GNU eabi breakpoint */ + +sz_Elf64_Ehdr= 64 +sz_Elf64_Phdr= 56 +sz_l_info = 12 +sz_p_info = 12 +sz_b_info = 12 + sz_unc= 0 + sz_cpr= 4 + b_method= 8 + +MAP_PRIVATE= 0x02 +MAP_FIXED= 0x10 + +PROT_READ= 0x1 + +O_RDONLY= 0 + +PAGE_SHIFT= 12 +PAGE_SIZE = -(~0<'; strb r1,[r2],#1 + + mov r5,#3 @ rows to print +L600: @ each row + sub r0,r4,#TRACE_BUFLEN + sub r0,r0,sp + mov r0,r0,lsr #2; mov r1,#'\n'; bl trace_hex @ which block of 8 + + mov r6,#8 @ words per row +L610: @ each word + ldr r0,[r4],#4; mov r1,#' '; bl trace_hex @ next word + subs r6,r6,#1; bgt L610 + + subs r5,r5,#1; bgt L600 + + mov r0,#'\n'; strb r0,[r2],#1 + sub r2,r2,sp @ count + mov r1,sp @ buf + mov r0,#2 @ FD_STDERR +#if defined(ARMEL_EABI4) /*{*/ + mov r7,#__NR_write + swi 0 +#else /*}{*/ + swi __NR_write +#endif /*}*/ + add sp,sp,#TRACE_BUFLEN + ldmia sp!,{TRACE_REGS} + +trace_hex: // In: r0=val, r1=punctuation before, r2=ptr; Uses: r3, ip + strb r1,[r2],#1 @ punctuation + mov r3,#4*(8 -1) @ shift count + adr ip,hex +L620: + mov r1,r0,lsr r3 + and r1,r1,#0xf + ldrb r1,[ip, r1] + strb r1,[r2],#1 + subs r3,r3,#4; bge L620 + ret +hex: + .ascii "0123456789abcdef" +#endif /*}*/ + .unreq ptr + .unreq len + .unreq cto + .unreq fid + +__NR_exit = 1 + __NR_SYSCALL_BASE +__NR_read = 3 + __NR_SYSCALL_BASE +__NR_write = 4 + __NR_SYSCALL_BASE +__NR_open = 5 + __NR_SYSCALL_BASE +__NR_close = 6 + __NR_SYSCALL_BASE +__NR_unlink= 10 + __NR_SYSCALL_BASE +__NR_getpid= 20 + __NR_SYSCALL_BASE +__NR_brk = 45 + __NR_SYSCALL_BASE +__NR_readlink=85+ __NR_SYSCALL_BASE + + +__NR_mmap2 = 192 + __NR_SYSCALL_BASE +__NR_mprotect = 125 + __NR_SYSCALL_BASE +__NR_munmap = 91 + __NR_SYSCALL_BASE + +__ARM_NR_BASE = 0x0f0000 + __NR_SYSCALL_BASE +__ARM_NR_cacheflush = 2 + __ARM_NR_BASE + + .globl my_bkpt +my_bkpt: + bkpt + ret + + .globl exit +exit: + do_sys __NR_exit + + .globl read +read: + do_sys __NR_read; ret + + .globl write +write: + do_sys __NR_write; ret + + .globl open +open: + do_sys __NR_open; ret + + .globl close +close: + do_sys __NR_close; ret + + .globl unlink +unlink: + do_sys __NR_unlink; ret + + .globl getpid +getpid: + do_sys __NR_getpid; ret + + .globl brk +brk: + do_sys __NR_brk; ret + + .globl readlink +readlink: + do_sys __NR_readlink; ret + + .globl munmap +munmap: + do_sys __NR_munmap; ret + + .globl mprotect +mprotect: + do_sys __NR_mprotect; ret + + .globl __clear_cache +__clear_cache: + mov r2,#0 + do_sys2 __ARM_NR_cacheflush; ret + + .globl mmap +mmap: + str r5,[sp,#-4]!; ldr r5,[sp,#4+4] + str r4,[sp,#-4]!; ldr r4,[sp,#4+4] + mov r5,r5,lsr #12 @ convert to page number +mmap_do: + do_sys __NR_mmap2 + ldr r4,[sp],#4 + ldr r5,[sp],#4 + ret + +bits_privanon= -4+ fold_begin // entry stores: MAP_{PRIVATE|ANON} QNX vs linux + +mmap_privanon: .globl mmap_privanon + ldr r12,bits_privanon @ r12 === ip + str r5,[sp,#-4]!; mov r5,#0 @ offset= 0 + str r4,[sp,#-4]!; mvn r4,#0 @ fd= -1 + orr r3,r3,r12 @ flags |= MAP_{PRIVATE|ANON} [QNX vs Linux] + b mmap_do + + +#if DEBUG /*{*/ + +div10: .globl div10 + mov ip,r0 @ extra copy used at end + sub r1,r1,r1 @ hi + + mov r2,r0 @ copy lo + adds r0,r0,r0,lsl #3 @ 9*lo + adc r1,r1,r1,lsl #3 @ 9*hi + C + add r1,r1,r2,lsr #(32 - 3) @ bits shifted from lo to hi + + mov r2,r0 @ copy lo + adds r0,r0,r0,lsl #4 + adc r1,r1,r1,lsl #4 + add r1,r1,r2,lsr #(32 - 4) @ * 0x99 + + mov r2,r0 @ copy lo + adds r0,r0,r0,lsl #8 + adc r1,r1,r1,lsl #8 + add r1,r1,r2,lsr #(32 - 8) @ * 0x9999 + + mov r2,r0 @ copy lo + adds r0,r0,r0,lsl #16 + adc r1,r1,r1,lsl #16 + add r1,r1,r2,lsr #(32 - 16) @ * 0x99999999 + + subs r0,r0,ip,lsl #(32 - 1) @ - * 0x80000000 + sbc r1,r1,ip,lsr #1 @ * 0x19999999 + + adds r0,r0,ip + adc r0,r1,#0 @ * 0x0.1999999a + ret + +#endif /*}*/ + +@ vi:ts=8:et:nowrap + diff --git a/src/stub/tmp/arm64-darwin.macho-entry.bin.dump b/src/stub/tmp/arm64-darwin.macho-entry.bin.dump new file mode 100644 index 00000000..df4c9ed4 --- /dev/null +++ b/src/stub/tmp/arm64-darwin.macho-entry.bin.dump @@ -0,0 +1,30 @@ +file format elf64-littleaarch64 + +Sections: +Idx Name Size VMA LMA File off Algn Flags + 0 MACHMAINX 00000044 0000000000000000 0000000000000000 00000040 2**2 CONTENTS, RELOC, READONLY + 1 NRV_HEAD 00000000 0000000000000000 0000000000000000 00000084 2**0 CONTENTS, READONLY + 2 NRV2E 0000013c 0000000000000000 0000000000000000 00000084 2**2 CONTENTS, READONLY + 3 NRV2D 00000130 0000000000000000 0000000000000000 000001c0 2**2 CONTENTS, READONLY + 4 NRV2B 00000108 0000000000000000 0000000000000000 000002f0 2**2 CONTENTS, READONLY + 5 NRV_TAIL 00000680 0000000000000000 0000000000000000 000003f8 2**2 CONTENTS, READONLY + 6 MACHMAINY 00000000 0000000000000000 0000000000000000 00000a78 2**0 CONTENTS, READONLY + 7 MACHMAINZ 00000058 0000000000000000 0000000000000000 00000a78 2**2 CONTENTS, READONLY +SYMBOL TABLE: +0000000000000000 l d MACHMAINZ 0000000000000000 MACHMAINZ +0000000000000000 l d MACHMAINX 0000000000000000 MACHMAINX +0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD +0000000000000000 l d NRV2E 0000000000000000 NRV2E +0000000000000000 l d NRV2D 0000000000000000 NRV2D +0000000000000000 l d NRV2B 0000000000000000 NRV2B +0000000000000000 l d NRV_TAIL 0000000000000000 NRV_TAIL +0000000000000000 l d MACHMAINY 0000000000000000 MACHMAINY +0000000000000000 g MACHMAINX 0000000000000000 _start +0000000000000000 g F NRV2E 000000000000013c ucl_nrv2e_decompress_8 +0000000000000000 g F NRV2D 0000000000000130 ucl_nrv2d_decompress_8 +0000000000000000 g F NRV2B 0000000000000108 ucl_nrv2b_decompress_8 +0000000000000000 g MACHMAINY 0000000000000000 end_decompress + +RELOCATION RECORDS FOR [MACHMAINX]: +OFFSET TYPE VALUE +0000000000000040 R_AARCH64_CALL26 MACHMAINZ+0x0000000000000050