1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

Allow pre-linking when compressing shared libraries

Such as Wine kernel32.dll etc.
https://github.com/upx/upx/issues/660
	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_fold.h
	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
This commit is contained in:
John Reiser 2023-04-03 13:18:21 -07:00
parent b9533f409c
commit 14521eb6dd
8 changed files with 5382 additions and 5375 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -442,6 +442,8 @@ upx_so_main( // returns &escape_hatch
{
unsigned long const PAGE_MASK = get_PAGE_MASK();
char *const va_load = (char *)&so_info->off_reloc - so_info->off_reloc;
Elf64_Phdr const *phdr = (Elf64_Phdr *)(1+ (Elf64_Ehdr *)(void *)va_load);
Elf64_Addr const base = (Elf64_Addr)va_load - phdr->p_vaddr;
So_info so_infc; // So_info Copy
memcpy(&so_infc, so_info, sizeof(so_infc)); // before de-compression overwrites
unsigned const xct_off = so_infc.off_xct_off;
@ -451,8 +453,8 @@ upx_so_main( // returns &escape_hatch
unsigned const cpr_len = (char *)so_info - cpr_ptr;
typedef void (*Dt_init)(int argc, char *argv[], char *envp[]);
Dt_init const dt_init = (Dt_init)(void *)(so_info->off_user_DT_INIT + va_load);
DPRINTF("upx_so_main va_load=%%p cpr_ptr=%%p cpr_len=%%x xct_off=%%x\\n",
va_load, cpr_ptr, cpr_len, xct_off);
DPRINTF("upx_so_main@%%p va_load=%%p base=%%p cpr_ptr=%%p cpr_len=%%x xct_off=%%x\\n",
upx_so_main, va_load, base, cpr_ptr, cpr_len, xct_off);
// DO NOT USE *so_info AFTER THIS!! It gets overwritten.
// Copy compressed data before de-compression overwrites it.
@ -493,7 +495,6 @@ upx_so_main( // returns &escape_hatch
struct b_info al_bi; // for aligned data from binfo
void *hatch = nullptr;
Elf64_Phdr const *phdr = (Elf64_Phdr *)(1+ (Elf64_Ehdr *)(void *)va_load);
unsigned n_phdr = ((Elf64_Ehdr *)(void *)va_load)->e_phnum;
for (; n_phdr > 0; --n_phdr, ++phdr)
if ( phdr->p_type == PT_LOAD && !(phdr->p_flags & PF_W)) {
@ -515,7 +516,7 @@ upx_so_main( // returns &escape_hatch
// Using .p_memsz implicitly handles .bss via MAP_ANONYMOUS.
// Omit any non-tcompressed prefix (below xct_off)
x1.buf = phdr->p_vaddr + pfx + va_load;
x1.buf = (char *)(phdr->p_vaddr + pfx + base);
x1.size = phdr->p_memsz - pfx;
pfx = (phdr->p_vaddr + pfx) & ~PAGE_MASK; // lo fragment on page
@ -532,11 +533,11 @@ upx_so_main( // returns &escape_hatch
if (!hatch && phdr->p_flags & PF_X) {
//#define PAGE_MASK ~0xFFFull
#if defined(__x86_64) //{
hatch = make_hatch_x86_64(phdr, (Elf64_Addr)va_load, ~PAGE_MASK);
hatch = make_hatch_x86_64(phdr, base, ~PAGE_MASK);
#elif defined(__powerpc64__) //}{
hatch = make_hatch_ppc64(phdr, (Elf64_Addr)va_load, ~PAGE_MASK);
hatch = make_hatch_ppc64(phdr, base, ~PAGE_MASK);
#elif defined(__aarch64__) //}{
hatch = make_hatch_arm64(phdr, (Elf64_Addr)va_load, ~PAGE_MASK);
hatch = make_hatch_arm64(phdr, base, ~PAGE_MASK);
#endif //}
}
// Exchange the bits with values 4 (PF_R, PROT_EXEC) and 1 (PF_X, PROT_READ)
@ -544,8 +545,8 @@ upx_so_main( // returns &escape_hatch
unsigned prot = 7& addr_string("@\x04\x02\x06\x01\x05\x03\x07")
[phdr->p_flags & (PF_R|PF_W|PF_X)];
DPRINTF("Pprotect %%p (%%p %%p %%x)\\n",
phdr, phdr->p_vaddr + va_load, phdr->p_memsz, prot);
Pprotect(phdr->p_vaddr + va_load, phdr->p_memsz, prot);
phdr, (char *)(phdr->p_vaddr + base), phdr->p_memsz, prot);
Pprotect( (char *)(phdr->p_vaddr + base), phdr->p_memsz, prot);
}
munmap(sideaddr, cpr_len);

View File

@ -485,6 +485,8 @@ upx_so_main( // returns &escape_hatch
)
{
char *const va_load = (char *)&so_info->off_reloc - so_info->off_reloc;
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ (Elf32_Ehdr *)(void *)va_load);
Elf32_Addr const base = (Elf32_Addr)va_load - phdr->p_vaddr;
So_info so_infc; // So_info Copy
memcpy(&so_infc, so_info, sizeof(so_infc)); // before de-compression overwrites
unsigned const xct_off = so_infc.off_xct_off;
@ -492,8 +494,8 @@ upx_so_main( // returns &escape_hatch
char *const cpr_ptr = so_infc.off_info + va_load;
unsigned const cpr_len = (char *)so_info - cpr_ptr;
DPRINTF("upx_so_main@%%p va_load=%%p cpr_ptr=%%p cpr_len=%%x xct_off=%%x\\n",
upx_so_main, va_load, cpr_ptr, cpr_len, xct_off);
DPRINTF("upx_so_main@%%p va_load=%%p base=%%p cpr_ptr=%%p cpr_len=%%x xct_off=%%x\\n",
upx_so_main, va_load, base, cpr_ptr, cpr_len, xct_off);
// Copy compressed data before de-compression overwrites it.
char *const sideaddr = mmap(nullptr, cpr_len, PROT_WRITE|PROT_READ,
@ -533,7 +535,6 @@ upx_so_main( // returns &escape_hatch
struct b_info al_bi; // for aligned data from binfo
void *hatch = nullptr;
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ (Elf32_Ehdr *)(void *)va_load);
unsigned n_phdr = ((Elf32_Ehdr *)(void *)va_load)->e_phnum;
for (; n_phdr > 0; --n_phdr, ++phdr)
if ( phdr->p_type == PT_LOAD && !(phdr->p_flags & PF_W)) {
@ -555,7 +556,7 @@ upx_so_main( // returns &escape_hatch
// Using .p_memsz implicitly handles .bss via MAP_ANONYMOUS.
// Omit any not-compressed prefix (below xct_off)
x1.buf = phdr->p_vaddr + pfx + va_load;
x1.buf = (char *)(phdr->p_vaddr + pfx + base);
x1.size = phdr->p_memsz - pfx;
pfx = (phdr->p_vaddr + pfx) & ~PAGE_MASK; // lo fragment on page
@ -572,16 +573,16 @@ upx_so_main( // returns &escape_hatch
if (!hatch && phdr->p_flags & PF_X) {
//#define PAGE_MASK ~0xFFFull
#if defined(__arm__) //{
hatch = make_hatch_arm(phdr, (Elf32_Addr)va_load);
hatch = make_hatch_arm(phdr, base);
#elif defined(__powerpc__) //}{
hatch = make_hatch_ppc(phdr, (Elf32_Addr)va_load, ~PAGE_MASK);
hatch = make_hatch_ppc(phdr, base, ~PAGE_MASK);
#elif defined(__i386__) //}{
hatch = make_hatch_i386(phdr, (Elf32_Addr)va_load);
hatch = make_hatch_i386(phdr, base);
#endif //}
}
DPRINTF("mprotect %%p (%%p %%p %%x)\\n",
phdr, phdr->p_vaddr + va_load, phdr->p_memsz, PF_TO_PROT(phdr->p_flags));
Pprotect( phdr->p_vaddr + va_load, phdr->p_memsz, PF_TO_PROT(phdr->p_flags));
phdr, (char *)(phdr->p_vaddr + base), phdr->p_memsz, PF_TO_PROT(phdr->p_flags));
Pprotect( (char *)(phdr->p_vaddr + base), phdr->p_memsz, PF_TO_PROT(phdr->p_flags));
}
typedef void (*Dt_init)(int argc, char *argv[], char *envp[]);

View File

@ -2,19 +2,19 @@ file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 SO_MAIN 05cc 0 0 040 2**4 CONTENTS
1 EXP_HEAD 0dc 0 0 060c 2**0 CONTENTS
2 NRV2E 0e5 0 0 06e8 2**0 CONTENTS
3 NRV2D 0d7 0 0 07cd 2**0 CONTENTS
4 NRV2B 0c1 0 0 08a4 2**0 CONTENTS
5 SO_HEAD 01b 0 0 0965 2**0 CONTENTS
6 ptr_NEXT 0 0 0 0980 2**0 CONTENTS
7 SO_TAIL 071 0 0 0980 2**0 CONTENTS
8 LZMA_ELF00 064 0 0 09f1 2**0 CONTENTS
9 LZMA_DEC10 09f7 0 0 0a55 2**0 CONTENTS
10 LZMA_DEC20 09f7 0 0 0144c 2**0 CONTENTS
11 LZMA_DEC30 018 0 0 01e43 2**0 CONTENTS
12 EXP_TAIL 0e 0 0 01e5b 2**0 CONTENTS
0 SO_MAIN 05d8 0 0 040 2**4 CONTENTS
1 EXP_HEAD 0dc 0 0 0618 2**0 CONTENTS
2 NRV2E 0e5 0 0 06f4 2**0 CONTENTS
3 NRV2D 0d7 0 0 07d9 2**0 CONTENTS
4 NRV2B 0c1 0 0 08b0 2**0 CONTENTS
5 SO_HEAD 01b 0 0 0971 2**0 CONTENTS
6 ptr_NEXT 0 0 0 098c 2**0 CONTENTS
7 SO_TAIL 071 0 0 098c 2**0 CONTENTS
8 LZMA_ELF00 064 0 0 09fd 2**0 CONTENTS
9 LZMA_DEC10 09f7 0 0 0a61 2**0 CONTENTS
10 LZMA_DEC20 09f7 0 0 01458 2**0 CONTENTS
11 LZMA_DEC30 018 0 0 01e4f 2**0 CONTENTS
12 EXP_TAIL 0e 0 0 01e67 2**0 CONTENTS
SYMBOL TABLE:
0000000000000000 l d EXP_HEAD 0 EXP_HEAD
0000000000000000 l d LZMA_DEC30 0 LZMA_DEC30
@ -44,7 +44,7 @@ SYMBOL TABLE:
000000000000004b g SO_TAIL 0 openat
000000000000005e g SO_TAIL 0 mprotect
0000000000000047 g SO_TAIL 0 close
0000000000000368 g F SO_MAIN 0264 upx_so_main
0000000000000368 g F SO_MAIN 0270 upx_so_main
RELOCATION RECORDS FOR [SO_MAIN]:
OFFSET TYPE VALUE
@ -60,11 +60,11 @@ OFFSET TYPE VALUE
000000000000030d R_X86_64_PLT32 memcpy+0xfffffffffffffffc
000000000000032e R_X86_64_PLT32 mmap+0xfffffffffffffffc
000000000000033c R_X86_64_PLT32 memcpy+0xfffffffffffffffc
00000000000003d9 R_X86_64_PLT32 mmap+0xfffffffffffffffc
00000000000003ea R_X86_64_PLT32 memcpy+0xfffffffffffffffc
0000000000000417 R_X86_64_PLT32 Pprotect+0xfffffffffffffffc
0000000000000588 R_X86_64_PLT32 Pprotect+0xfffffffffffffffc
00000000000005a1 R_X86_64_PLT32 munmap+0xfffffffffffffffc
00000000000003e9 R_X86_64_PLT32 mmap+0xfffffffffffffffc
00000000000003fa R_X86_64_PLT32 memcpy+0xfffffffffffffffc
0000000000000427 R_X86_64_PLT32 Pprotect+0xfffffffffffffffc
0000000000000595 R_X86_64_PLT32 Pprotect+0xfffffffffffffffc
00000000000005ad R_X86_64_PLT32 munmap+0xfffffffffffffffc
RELOCATION RECORDS FOR [NRV2E]:
OFFSET TYPE VALUE