From 9945c30517a8a1b6673198a9da144fc62f249647 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Fri, 18 Apr 2025 08:09:30 -0700 Subject: [PATCH] MacOS: add decompressor sections into generated stub Compressed output is now generated, but runtime code needs fixing. modified: p_mach.cpp modified: stub/Makefile --- src/p_mach.cpp | 94 +++++++++++++++++------- src/stub/Makefile | 5 +- src/stub/tmp/amd64-darwin.macho-fold.map | 66 +++++++++++++++++ 3 files changed, 136 insertions(+), 29 deletions(-) diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 1ebbb592..533986ec 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -487,39 +487,77 @@ PackMachBase::buildMachLoader( Filter const *ft ) { - initLoader(proto, szproto); + MemBuffer mb_cprLoader; + unsigned sz_cpr = 0; + unsigned sz_unc = 0; + unsigned method = 0; + upx_byte const *uncLoader = nullptr; + + if (0 < szfold) { + if (1) { // main program with ELF2 de-compressor (folded portion) + initLoader(fold, szfold); + char sec[200]; memset(sec, 0, sizeof(sec)); // debug convenience + int len = 0; + unsigned m_decompr = methods_used | (1u << (0xFF & ph_forced_method(ph.method))); + len += snprintf(sec, sizeof(sec), "%s", ".text,EXP_HEAD"); + if (((1u<small ? "LZMA_DEC10" : "LZMA_DEC20")); + } + len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "EXP_TAIL"); + if (hasLoaderSection("SYSCALLS")) { + len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "SYSCALLS"); + } + if (hasLoaderSection("STRCON")) { + len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "STRCON"); + } + (void)len; + NO_printf("\n%s\n", sec); + addLoader(sec, nullptr); + relocateLoader(); + { + int sz_unc_int; + uncLoader = linker->getLoader(&sz_unc_int); + sz_unc = sz_unc_int; + } + method = M_NRV2B_LE32; // requires unaligned fetch + } struct b_info h; memset(&h, 0, sizeof(h)); - unsigned fold_hdrlen = 0; - if (0 < szfold) { - h.sz_unc = (szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen); - h.b_method = (unsigned char) ph.method; - h.b_ftid = (unsigned char) ph.filter; - h.b_cto8 = (unsigned char) ph.filter_cto; - } - unsigned char const *const uncLoader = fold_hdrlen + fold; + h.b_method = method; + // _Ehdr and _Phdr are NOT filtered, so Leave h.b_ftid and h.b_cto8 as zero. - MemBuffer cprLoader_buf(sizeof(h) + h.sz_unc); - unsigned char *const cprLoader = (unsigned char *)cprLoader_buf.getVoidPtr(); - if (0 < szfold) { - unsigned sz_cpr = 0; - int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &sz_cpr, - nullptr, ph.method, 10, nullptr, nullptr ); - h.sz_cpr = sz_cpr; - if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc) - throwInternalError("loader compression failed"); - } - memcpy(cprLoader, &h, sizeof(h)); + mb_cprLoader.allocForCompression(sizeof(h) + sz_unc); + unsigned char *const cprLoader = (unsigned char *)mb_cprLoader; // less typing - // This adds the definition to the "library", to be used later. - linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr, 0); - - int const GAP = 128; // must match stub/l_mac_ppc.S - int const NO_LAP = 64; // must match stub/src/*darwin*.S - segTEXT.vmsize = h.sz_unc - h.sz_cpr + GAP + NO_LAP; - - addStubEntrySections(ft); + h.sz_unc = sz_unc; + h.sz_cpr = mb_cprLoader.getSize(); // max that upx_compress may use + { + int r = upx_compress(uncLoader, sz_unc, sizeof(h) + cprLoader, &sz_cpr, + nullptr, ph_forced_method(method), 10, nullptr, nullptr ); + h.sz_cpr = sz_cpr; // actual length used + if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc) + throwInternalError("loader compression failed"); + } + set_te32(&h.sz_cpr, h.sz_cpr); + set_te32(&h.sz_unc, h.sz_unc); + memcpy(cprLoader, &h, sizeof(h)); // cprLoader will become FOLDEXEC + } // end (0 < szfold) + initLoader(proto, szproto, -1, sz_cpr); + NO_printf("FOLDEXEC unc=%#x cpr=%#x\n", sz_unc, sz_cpr); + linker->addSection("FOLDEXEC", mb_cprLoader, sizeof(b_info) + sz_cpr, 0); + addLoader("MACHMAINX,MACHMAINZ,FOLDEXEC,IDENTSTR"); defineSymbols(ft); relocateLoader(); } diff --git a/src/stub/Makefile b/src/stub/Makefile index 2cde482d..14a428f7 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -395,7 +395,10 @@ amd64-darwin.macho-entry.h : $(srcdir)/src/$$T.S # -Map tmp/amd64-darwin.macho-fold.map \ # tmp/amd64-darwin.macho-fold.o tmp/amd64-darwin.macho-main.o \ # -o tmp/amd64-darwin.macho-fold.bin -amd64-darwin.macho-fold.h : tmp/$$T.o tmp/amd64-darwin.macho-main.o +amd64-darwin.macho-fold.h : \ + tmp/$$T.o \ + tmp/amd64-expand.o \ + tmp/amd64-darwin.macho-main.o $(call tc,ld) --no-warn-mismatch --strip-all --oformat binary -Map tmp/$T.map $(filter %.o,$^) -o tmp/$T.bin chmod a-x tmp/$T.bin $(call tc,bin2h) tmp/$T.bin $@ diff --git a/src/stub/tmp/amd64-darwin.macho-fold.map b/src/stub/tmp/amd64-darwin.macho-fold.map index 06e294ed..58f36ebd 100644 --- a/src/stub/tmp/amd64-darwin.macho-fold.map +++ b/src/stub/tmp/amd64-darwin.macho-fold.map @@ -8,6 +8,7 @@ Linker script and memory map TARGET(elf64-x86-64) LOAD tmp/amd64-darwin.macho-fold.o +LOAD tmp/amd64-expand.o LOAD tmp/amd64-darwin.macho-main.o 0x0000000008048000 PROVIDE (__executable_start, 0x8048000) 0x0000000008048000 . = (0x8048000 + SIZEOF_HEADERS) @@ -86,6 +87,7 @@ LOAD tmp/amd64-darwin.macho-main.o 0x00000000080480c4 open 0x00000000080480b4 mprotect 0x00000000080480c0 close + .text 0x00000000080481d0 0x0 tmp/amd64-expand.o .text 0x00000000080481d0 0x7cc tmp/amd64-darwin.macho-main.o 0x00000000080483cd do_xmap 0x000000000804836e my_bkpt @@ -178,6 +180,7 @@ LOAD tmp/amd64-darwin.macho-main.o .data 0x000000000804999c 0x0 *(.data .data.* .gnu.linkonce.d.*) .data 0x000000000804999c 0x0 tmp/amd64-darwin.macho-fold.o + .data 0x000000000804999c 0x0 tmp/amd64-expand.o .data 0x000000000804999c 0x0 tmp/amd64-darwin.macho-main.o *(.gnu.linkonce.d.*personality*) @@ -191,6 +194,7 @@ LOAD tmp/amd64-darwin.macho-main.o *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) .bss 0x000000000804999c 0x0 tmp/amd64-darwin.macho-fold.o + .bss 0x000000000804999c 0x0 tmp/amd64-expand.o .bss 0x000000000804999c 0x0 tmp/amd64-darwin.macho-main.o *(COMMON) 0x000000000804999c . = ALIGN ((. != 0x0)?0x4:0x1) @@ -275,3 +279,65 @@ LOAD tmp/amd64-darwin.macho-main.o /DISCARD/ *(.note.GNU-stack) OUTPUT(tmp/amd64-darwin.macho-fold.bin binary) + 0x000000000804999c . = ALIGN (0x1) + 0x000000000804999c __start_EXP_HEAD = . + +EXP_HEAD 0x0000000000000000 0xfe + EXP_HEAD 0x0000000000000000 0xfe tmp/amd64-expand.o + 0x0000000000000000 f_expand + 0x00000000000000fe __stop_EXP_HEAD = . + 0x00000000000000fe . = ALIGN (0x1) + 0x00000000000000fe __start_NRV2E = . + +NRV2E 0x0000000000000000 0xe8 + NRV2E 0x0000000000000000 0xe8 tmp/amd64-expand.o + 0x00000000000000e8 __stop_NRV2E = . + 0x00000000000000e8 . = ALIGN (0x1) + 0x00000000000000e8 __start_NRV2D = . + +NRV2D 0x0000000000000000 0xdb + NRV2D 0x0000000000000000 0xdb tmp/amd64-expand.o + 0x00000000000000db __stop_NRV2D = . + 0x00000000000000db . = ALIGN (0x1) + 0x00000000000000db __start_NRV2B = . + +NRV2B 0x0000000000000000 0xc4 + NRV2B 0x0000000000000000 0xc4 tmp/amd64-expand.o + 0x00000000000000c4 __stop_NRV2B = . + 0x00000000000000c4 . = ALIGN (0x1) + 0x00000000000000c4 __start_LZMA_DAISY = . + +LZMA_DAISY 0x0000000000000000 0xa + LZMA_DAISY 0x0000000000000000 0xa tmp/amd64-expand.o + 0x000000000000000a __stop_LZMA_DAISY = . + 0x000000000000000a . = ALIGN (0x1) + 0x000000000000000a __start_LZMA_ELF00 = . + +LZMA_ELF00 0x0000000000000000 0x5b + LZMA_ELF00 0x0000000000000000 0x5b tmp/amd64-expand.o + 0x000000000000005b __stop_LZMA_ELF00 = . + 0x000000000000005b . = ALIGN (0x1) + 0x000000000000005b __start_LZMA_DEC10 = . + +LZMA_DEC10 0x0000000000000000 0x463 + LZMA_DEC10 0x0000000000000000 0x463 tmp/amd64-expand.o + 0x0000000000000463 __stop_LZMA_DEC10 = . + 0x0000000000000463 . = ALIGN (0x1) + 0x0000000000000463 __start_LZMA_DEC20 = . + +LZMA_DEC20 0x0000000000000000 0x9f7 + LZMA_DEC20 0x0000000000000000 0x9f7 tmp/amd64-expand.o + 0x00000000000009f7 __stop_LZMA_DEC20 = . + 0x00000000000009f7 . = ALIGN (0x1) + 0x00000000000009f7 __start_LZMA_DEC30 = . + +LZMA_DEC30 0x0000000000000000 0x19 + LZMA_DEC30 0x0000000000000000 0x19 tmp/amd64-expand.o + 0x0000000000000019 __stop_LZMA_DEC30 = . + 0x000000000000001c . = ALIGN (0x4) + 0x000000000000001c __start_EXP_TAIL = . + +EXP_TAIL 0x0000000000000000 0x14 + EXP_TAIL 0x0000000000000000 0x14 tmp/amd64-expand.o + 0x0000000000000014 upx_mmap_and_fd + 0x0000000000000014 __stop_EXP_TAIL = .