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:
+874
-873
File diff suppressed because it is too large
Load Diff
+1427
-1426
File diff suppressed because it is too large
Load Diff
+1435
-1434
File diff suppressed because it is too large
Load Diff
+848
-847
File diff suppressed because it is too large
Load Diff
+759
-758
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -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[]);
|
||||
|
||||
+19
-19
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user