mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
more ELF shlib when no DT_INIT (especially Android): hook DT_INIT_ARRAY[0]
https://github.com/upx/upx/issues/191 [partial, not finished] modified: p_lx_elf.cpp modified: p_lx_elf.h modified: stub/src/arm.v4a-linux.shlib-init.S modified: stub/src/arm.v4t-linux.shlib-init.S
This commit is contained in:
parent
9b990c4eae
commit
5e9b6bd69d
|
@ -330,7 +330,7 @@ off_t PackLinuxElf::pack3(OutputFile *fo, Filter &ft) // return length of output
|
|||
if (xct_off) { // is_shlib
|
||||
upx_uint64_t const firstpc_va = (jni_onload_va
|
||||
? jni_onload_va
|
||||
: elf_unsigned_dynamic(upx_dt_init) );
|
||||
: user_init_va);
|
||||
set_te32(&disp, firstpc_va - load_va);
|
||||
fo->write(&disp, sizeof(disp)); // DT_INIT.d_val
|
||||
len += sizeof(disp);
|
||||
|
@ -401,11 +401,12 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||
set_te32(&elfout.phdr[1].p_flags, Elf32_Phdr::PF_W|Elf32_Phdr::PF_R);
|
||||
}
|
||||
if (0!=xct_off) { // shared library
|
||||
unsigned word = (Elf32_Ehdr::EM_ARM==e_machine) + load_va + sz_pack2; // Thumb mode
|
||||
set_te32(&file_image[user_init_off], word); // set the hook
|
||||
|
||||
unsigned off = fo->st_size();
|
||||
Elf32_Phdr *phdr = (Elf32_Phdr *)lowmem.subref(
|
||||
"bad e_phoff", e_phoff, e_phnum * sizeof(Elf32_Phdr));
|
||||
unsigned off = fo->st_size();
|
||||
unsigned off_init = 0; // where in file
|
||||
unsigned va_init = sz_pack2; // virtual address
|
||||
so_slide = 0;
|
||||
for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
|
||||
unsigned const len = get_te32(&phdr->p_filesz);
|
||||
|
@ -435,36 +436,15 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||
set_te32(&phdr->p_offset, so_slide + ioff);
|
||||
}
|
||||
else { // Change length of first PT_LOAD.
|
||||
va_init += get_te32(&phdr->p_vaddr);
|
||||
set_te32(&phdr->p_filesz, sz_pack2 + lsize);
|
||||
set_te32(&phdr->p_memsz, sz_pack2 + lsize);
|
||||
}
|
||||
continue; // all done with this PT_LOAD
|
||||
}
|
||||
// Compute new offset of &DT_INIT.d_val.
|
||||
if (Elf32_Phdr::PT_DYNAMIC==type) {
|
||||
off_init = ioff + ((xct_off < ioff) ? so_slide : 0);
|
||||
Elf32_Dyn *dyn = (Elf32_Dyn *)(void *)&file_image[ioff];
|
||||
for (int j2 = len; j2 > 0; ++dyn, j2 -= sizeof(*dyn)) {
|
||||
if (get_te32(&dyn->d_tag) == upx_dt_init) {
|
||||
off_init += (unsigned char *)&dyn->d_val
|
||||
- (unsigned char *)&file_image[ioff];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fall through to relocate .p_offset
|
||||
}
|
||||
if (xct_off < ioff)
|
||||
set_te32(&phdr->p_offset, so_slide + ioff);
|
||||
} // end each Phdr
|
||||
|
||||
if (off_init) { // change DT_INIT.d_val
|
||||
fo->seek(off_init, SEEK_SET);
|
||||
va_init |= (Elf32_Ehdr::EM_ARM==e_machine); // THUMB mode
|
||||
unsigned word; set_te32(&word, va_init);
|
||||
fo->rewrite(&word, sizeof(word));
|
||||
flen = fo->seek(0, SEEK_END);
|
||||
}
|
||||
if (opt->o_unix.android_shlib) {
|
||||
// Update {DYNAMIC}.sh_offset by so_slide.
|
||||
Elf32_Shdr *shdr = (Elf32_Shdr *)lowmem.subref(
|
||||
|
@ -1892,20 +1872,33 @@ bool PackLinuxElf32::canPack()
|
|||
xct_va = ~0u;
|
||||
if (e_shnum) {
|
||||
for (int j= e_shnum; --j>=0; ++shdr) {
|
||||
unsigned const sh_type = get_te32(&shdr->sh_type);
|
||||
if (Elf32_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
|
||||
xct_va = umin(xct_va, get_te32(&shdr->sh_addr));
|
||||
}
|
||||
// Hook the first slot of DT_PREINIT_ARRAY or DT_INIT_ARRAY.
|
||||
if (( Elf32_Dyn::DT_PREINIT_ARRAY==upx_dt_init
|
||||
&& Elf32_Shdr::SHT_PREINIT_ARRAY==sh_type)
|
||||
|| ( Elf32_Dyn::DT_INIT_ARRAY ==upx_dt_init
|
||||
&& Elf32_Shdr::SHT_INIT_ARRAY ==sh_type) ) {
|
||||
user_init_off = get_te32(&shdr->sh_offset);
|
||||
user_init_va = get_te32(&file_image[user_init_off]);
|
||||
}
|
||||
// By default /usr/bin/ld leaves 4 extra DT_NULL to support pre-linking.
|
||||
// Take one if DT_INIT is not present.
|
||||
if (Elf32_Shdr::SHT_DYNAMIC == get_te32(&shdr->sh_type)
|
||||
&& Elf32_Dyn::DT_INIT != upx_dt_init) {
|
||||
// Take one as a last resort.
|
||||
if ((Elf32_Dyn::DT_INIT==upx_dt_init || !upx_dt_init)
|
||||
&& Elf32_Shdr::SHT_DYNAMIC == sh_type) {
|
||||
unsigned const n = get_te32(&shdr->sh_size) / sizeof(Elf32_Dyn);
|
||||
Elf32_Dyn *dynp = const_cast<Elf32_Dyn *>(dynseg);
|
||||
for (; Elf32_Dyn::DT_NULL != dynp->d_tag; ++dynp) /* empty */ ;
|
||||
Elf32_Dyn *dynp = (Elf32_Dyn *)&file_image[shdr->sh_offset];
|
||||
for (; Elf32_Dyn::DT_NULL != dynp->d_tag; ++dynp) {
|
||||
if (upx_dt_init == get_te32(&dynp->d_tag)) {
|
||||
break; // re-found DT_INIT
|
||||
}
|
||||
}
|
||||
if ((1+ dynp) < (n+ dynseg)) { // not the terminator, so take it
|
||||
set_te32(&dynp->d_tag, Elf32_Dyn::DT_INIT);
|
||||
dynp->d_val = 0;
|
||||
upx_dt_init = Elf32_Dyn::DT_INIT;
|
||||
user_init_va = get_te32(&dynp->d_val); // 0 if (0==upx_dt_init)
|
||||
set_te32(&dynp->d_tag, upx_dt_init = Elf32_Dyn::DT_INIT);
|
||||
user_init_off = (char const *)&dynp->d_val - (char const *)&file_image[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,8 @@ protected:
|
|||
upx_uint64_t load_va; // PT_LOAD[0].p_vaddr
|
||||
upx_uint64_t xct_va; // minimum SHT_EXECINSTR virtual address
|
||||
upx_uint64_t jni_onload_va; // runtime &JNI_OnLoad
|
||||
upx_uint64_t user_init_va;
|
||||
unsigned user_init_off; // within file_image
|
||||
|
||||
upx_uint16_t e_machine;
|
||||
unsigned char ei_class;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -90,6 +90,7 @@ _start: .globl _start
|
|||
stmdb sp!,{arg1,arg2,arg3, eax,ecx,r6,r7, fp,lr,pc}
|
||||
mov fp,sp
|
||||
o_uinit= (3+4+2)*4 // pc
|
||||
str lr,[fp,#o_uinit] // default for empty user_init
|
||||
|
||||
bl main // push &f_decompress
|
||||
f_decompress:
|
||||
|
@ -185,7 +186,8 @@ main:
|
|||
sub tmp,esi,tmp // &b_info
|
||||
lodsl; cmp eax,#0; beq 0f
|
||||
add eax,ecx,eax // reloc DT_INIT for step 12
|
||||
0: str eax,[fp,#o_uinit]
|
||||
str eax,[fp,#o_uinit]
|
||||
0:
|
||||
lodsl; add eax,ecx,eax; push eax // reloc &hatch for step 10
|
||||
o_hatch= -1*4
|
||||
lodsl; add edi,ecx,eax // &l_info; also destination for decompress
|
||||
|
@ -310,18 +312,11 @@ supervise:
|
|||
error ARMEL_EABI4, ARM_OLDABI
|
||||
#endif //}
|
||||
ldmia sp!,{arg1,arg2,arg3, eax,ecx,r6,r7, fp,lr,pc}
|
||||
hatch_empty:
|
||||
ret
|
||||
|
||||
L620: // Implant escape hatch at end of .text
|
||||
ldr eax,[fp,#o_hatch]
|
||||
ldmia lr,{arg1,arg2,arg3}
|
||||
ldmia lr,{arg1,arg2}
|
||||
stmia eax,{arg1,arg2}
|
||||
ldr tmp,[fp,#o_uinit]
|
||||
cmp tmp,#0; bne 0f
|
||||
str arg3,[eax]
|
||||
str eax,[fp,#o_uinit]
|
||||
0:
|
||||
|
||||
//p_unflt
|
||||
ldmia sp!,{arg1,arg2,arg3,arg4, eax, r12} // r12= w_fragment [toss]
|
||||
|
|
|
@ -143,10 +143,11 @@ here:
|
|||
sub tmp,edi // offset(b_info)
|
||||
sub ecx,eax; //str ecx,[SP(o_reloc)]
|
||||
lsl edi,#12 // asl_delta
|
||||
ldr eax,[esi,#2*NBPW]; cmp eax,#0; beq 0f
|
||||
ldr eax,[esi,#2*NBPW]; cmp eax,#0; beq 0f // empty user_init
|
||||
add eax,ecx // reloc DT_INIT for step 12
|
||||
add eax,edi
|
||||
0: str eax,[SP(o_uinit)]
|
||||
str eax,[SP(o_uinit)]
|
||||
0:
|
||||
ldr edi,[esi,#4*NBPW]; add edi,ecx // dst for f_exp
|
||||
add esi,tmp,ecx // &b_info src for f_exp
|
||||
|
||||
|
@ -156,7 +157,7 @@ o_hatch=_ // 10
|
|||
_=2+_ // param space: munmap temp pages (step 9)
|
||||
p_unmap=_ // 12
|
||||
|
||||
push_ lr
|
||||
push_ lr // will be lr at entry to user_init
|
||||
o_lr=_ // 13
|
||||
ldr eax,[esi,#sz_cpr]; add esi,#sz_b_info
|
||||
add esi,eax // skip unpack helper block
|
||||
|
@ -348,13 +349,6 @@ _=-5+_ // 22
|
|||
bic edi,tmp // round_up(2, .p_memsz + .p_vaddr)
|
||||
ldr tmp,hatch // the 2 instructions
|
||||
str tmp,[edi]
|
||||
ldr tmp,[SP(o_uinit)]
|
||||
cmp tmp,#0; bne 0f
|
||||
ldrh tmp,hatch_empty
|
||||
strh tmp,[edi,#2*2]
|
||||
add tmp,edi,#2*2
|
||||
str tmp,[SP(o_uinit)]
|
||||
0:
|
||||
add edi,#1 // thumb mode
|
||||
str edi,[SP(o_hatch)]
|
||||
|
||||
|
@ -390,8 +384,6 @@ _=-3+_ // 9
|
|||
hatch:
|
||||
swi 0 // 0xdf00; munmap
|
||||
pop {r0,r1,r2,r3,r4,r5,r6,r7,pc} // 0xbdff; goto user DT_INIT
|
||||
hatch_empty:
|
||||
ret
|
||||
|
||||
.thumb_func
|
||||
movsl_subr:
|
||||
|
|
|
@ -2,18 +2,18 @@ file format elf32-littlearm
|
|||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn Flags
|
||||
0 ELFMAINX 00000010 00000000 00000000 00000034 2**0 CONTENTS, RELOC, READONLY
|
||||
1 NRV_HEAD 00000000 00000000 00000000 00000044 2**0 CONTENTS, READONLY
|
||||
2 NRV_TAIL 00000000 00000000 00000000 00000044 2**0 CONTENTS, READONLY
|
||||
3 NRV2E 0000013c 00000000 00000000 00000044 2**0 CONTENTS, RELOC, READONLY
|
||||
4 NRV2D 00000128 00000000 00000000 00000180 2**0 CONTENTS, RELOC, READONLY
|
||||
5 NRV2B 000000ec 00000000 00000000 000002a8 2**0 CONTENTS, RELOC, READONLY
|
||||
6 LZMA_ELF00 000000b8 00000000 00000000 00000394 2**0 CONTENTS, RELOC, READONLY
|
||||
7 LZMA_DEC20 00000938 00000000 00000000 0000044c 2**0 CONTENTS, RELOC, READONLY
|
||||
8 LZMA_DEC10 00000478 00000000 00000000 00000d84 2**0 CONTENTS, RELOC, READONLY
|
||||
9 LZMA_DEC30 00000000 00000000 00000000 000011fc 2**0 CONTENTS, READONLY
|
||||
10 ELFMAINY 0000003e 00000000 00000000 000011fc 2**0 CONTENTS, READONLY
|
||||
11 ELFMAINZ 00000328 00000000 00000000 0000123a 2**0 CONTENTS, RELOC, READONLY
|
||||
0 ELFMAINX 00000014 00000000 00000000 00000034 2**0 CONTENTS, RELOC, READONLY
|
||||
1 NRV_HEAD 00000000 00000000 00000000 00000048 2**0 CONTENTS, READONLY
|
||||
2 NRV_TAIL 00000000 00000000 00000000 00000048 2**0 CONTENTS, READONLY
|
||||
3 NRV2E 0000013c 00000000 00000000 00000048 2**0 CONTENTS, RELOC, READONLY
|
||||
4 NRV2D 00000128 00000000 00000000 00000184 2**0 CONTENTS, RELOC, READONLY
|
||||
5 NRV2B 000000ec 00000000 00000000 000002ac 2**0 CONTENTS, RELOC, READONLY
|
||||
6 LZMA_ELF00 000000b8 00000000 00000000 00000398 2**0 CONTENTS, RELOC, READONLY
|
||||
7 LZMA_DEC20 00000938 00000000 00000000 00000450 2**0 CONTENTS, RELOC, READONLY
|
||||
8 LZMA_DEC10 00000478 00000000 00000000 00000d88 2**0 CONTENTS, RELOC, READONLY
|
||||
9 LZMA_DEC30 00000000 00000000 00000000 00001200 2**0 CONTENTS, READONLY
|
||||
10 ELFMAINY 0000003e 00000000 00000000 00001200 2**0 CONTENTS, READONLY
|
||||
11 ELFMAINZ 00000310 00000000 00000000 0000123e 2**0 CONTENTS, RELOC, READONLY
|
||||
SYMBOL TABLE:
|
||||
00000000 l d NRV2E 00000000 NRV2E
|
||||
00000000 l d NRV2D 00000000 NRV2D
|
||||
|
@ -36,7 +36,7 @@ SYMBOL TABLE:
|
|||
|
||||
RELOCATION RECORDS FOR [ELFMAINX]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000c R_ARM_PC24 ELFMAINZ
|
||||
00000010 R_ARM_PC24 ELFMAINZ
|
||||
|
||||
RELOCATION RECORDS FOR [NRV2E]:
|
||||
OFFSET TYPE VALUE
|
||||
|
@ -258,15 +258,14 @@ OFFSET TYPE VALUE
|
|||
00000164 R_ARM_PC24 ELFMAINZ
|
||||
00000174 R_ARM_PC24 ELFMAINZ
|
||||
00000184 R_ARM_PC24 ELFMAINZ
|
||||
000001a8 R_ARM_PC24 ELFMAINZ
|
||||
000001bc R_ARM_PC24 ELFMAINZ
|
||||
00000218 R_ARM_PC24 ELFMAINZ
|
||||
00000220 R_ARM_PC24 ELFMAINZ
|
||||
00000234 R_ARM_PC24 ELFMAINZ
|
||||
00000248 R_ARM_PC24 ELFMAINZ
|
||||
00000270 R_ARM_PC24 ELFMAINZ
|
||||
00000284 R_ARM_PC24 ELFMAINZ
|
||||
000002ac R_ARM_PC24 ELFMAINZ
|
||||
000001a4 R_ARM_PC24 ELFMAINZ
|
||||
00000200 R_ARM_PC24 ELFMAINZ
|
||||
00000208 R_ARM_PC24 ELFMAINZ
|
||||
0000021c R_ARM_PC24 ELFMAINZ
|
||||
00000230 R_ARM_PC24 ELFMAINZ
|
||||
00000258 R_ARM_PC24 ELFMAINZ
|
||||
0000026c R_ARM_PC24 ELFMAINZ
|
||||
00000294 R_ARM_PC24 ELFMAINZ
|
||||
000002a4 R_ARM_PC24 ELFMAINZ
|
||||
000002b0 R_ARM_PC24 ELFMAINZ
|
||||
000002bc R_ARM_PC24 ELFMAINZ
|
||||
000002c8 R_ARM_PC24 ELFMAINZ
|
||||
000002d4 R_ARM_PC24 ELFMAINZ
|
||||
|
|
|
@ -13,7 +13,7 @@ Idx Name Size VMA LMA File off Algn Flags
|
|||
8 LZMA_DEC10 00000478 00000000 00000000 00000e14 2**0 CONTENTS, RELOC, READONLY
|
||||
9 LZMA_DEC30 00000000 00000000 00000000 0000128c 2**0 CONTENTS, READONLY
|
||||
10 ELFMAINY 0000003e 00000000 00000000 0000128c 2**0 CONTENTS, READONLY
|
||||
11 ELFMAINZ 00000194 00000000 00000000 000012cc 2**2 CONTENTS, RELOC, READONLY
|
||||
11 ELFMAINZ 00000184 00000000 00000000 000012cc 2**2 CONTENTS, RELOC, READONLY
|
||||
SYMBOL TABLE:
|
||||
00000000 l ELFMAINX 00000000 .real_start_ofELFMAINX
|
||||
00000000 l d NRV2E 00000000 NRV2E
|
||||
|
@ -255,12 +255,12 @@ OFFSET TYPE VALUE
|
|||
00000028 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000030 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000050 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
0000008a R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
000000aa R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
000000dc R_ARM_PC24 ELFMAINZ
|
||||
000000fa R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000120 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000138 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000142 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
0000014c R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000154 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
0000007c R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
0000009c R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
000000cc R_ARM_PC24 ELFMAINZ
|
||||
000000ea R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000110 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000128 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000132 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
0000013c R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
00000144 R_ARM_THM_CALL .real_start_ofELFMAINZ
|
||||
|
|
Loading…
Reference in New Issue
Block a user