1
0
mirror of https://github.com/upx/upx.git synced 2025-08-11 22:52:30 +08:00

MacOS: add decompressor sections into generated stub

Compressed output is now generated, but runtime code needs fixing.
	modified:   p_mach.cpp
	modified:   stub/Makefile
This commit is contained in:
John Reiser
2025-04-18 08:09:30 -07:00
parent 5247c8320d
commit 9945c30517
3 changed files with 136 additions and 29 deletions

View File

@ -487,39 +487,77 @@ PackMachBase<T>::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<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) {
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B");
}
if (((1u<<M_NRV2D_LE32)|(1u<<M_NRV2D_8)|(1u<<M_NRV2D_LE16)) & m_decompr) {
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2D");
}
if (((1u<<M_NRV2E_LE32)|(1u<<M_NRV2E_8)|(1u<<M_NRV2E_LE16)) & m_decompr) {
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2E");
}
if (((1u<<M_LZMA)) & m_decompr) {
len += snprintf(&sec[len], sizeof(sec) - len,
",LZMA_DAISY,LZMA_ELF00,%s,LZMA_DEC30",
(opt->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();
}

View File

@ -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 $@

View File

@ -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 = .