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

get rid of PT_DYNAMIC: not worth the space; instead, use "upx -d" then ldd

p_lx_exc.h p_lx_elf.cpp p_lx_exc.cpp p_lx_sh.cpp
	stub/l_lx_elf.c stub/l_lx_elf86.lds stub/fold_elf86.asm

committer: jreiser <jreiser> 981747384 +0000
This commit is contained in:
John Reiser 2001-02-09 19:36:24 +00:00
parent e866b2231f
commit 2ff824e631
7 changed files with 31 additions and 167 deletions

View File

@ -229,8 +229,7 @@ void PackLinuxI386elf::pack1(OutputFile *fo, Filter &)
fi->seek(ehdri.e_phoff, SEEK_SET); fi->seek(ehdri.e_phoff, SEEK_SET);
fi->readx(phdri, sz_phdrs); fi->readx(phdri, sz_phdrs);
generateElfHdr(fo, linux_i386elf_fold, phdri, ehdri.e_phnum, generateElfHdr(fo, linux_i386elf_fold, getbrk(phdri, ehdri.e_phnum) );
getbrk(phdri, ehdri.e_phnum) );
} }
void PackLinuxI386elf::pack2(OutputFile *fo, Filter &ft) void PackLinuxI386elf::pack2(OutputFile *fo, Filter &ft)

View File

@ -79,43 +79,15 @@ const int *PackLinuxI386::getFilters() const
return filters; return filters;
} }
Elf_LE32_Phdr const *
PackLinuxI386::find_DYNAMIC(Elf_LE32_Phdr const *phdr, unsigned n)
{
if (n) do if (PT_DYNAMIC==phdr->p_type) {
return phdr;
} while (++phdr, 0!=--n);
return 0;
}
unsigned
PackLinuxI386::find_file_offset(
unsigned const vaddr,
Elf_LE32_Phdr const *phdr,
unsigned e_phnum
)
{
if (e_phnum) do {
unsigned t = vaddr - phdr->p_vaddr;
if (t < phdr->p_memsz) {
return t + phdr->p_offset;
}
} while (++phdr, 0!=--e_phnum);
return ~0u;
}
void void
PackLinuxI386::generateElfHdr( PackLinuxI386::generateElfHdr(
OutputFile *const fo, OutputFile *const fo,
void const *const proto, void const *const proto,
Elf_LE32_Phdr const *const phdr0,
unsigned e_phnum,
unsigned const brka unsigned const brka
) )
{ {
cprElfHdr1 *const h1 = (cprElfHdr1 *)&elfout; cprElfHdr1 *const h1 = (cprElfHdr1 *)&elfout;
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout; cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
memcpy(h2, proto, sizeof(*h2)); memcpy(h2, proto, sizeof(*h2));
assert(h2->ehdr.e_phoff == sizeof(Elf_LE32_Ehdr)); assert(h2->ehdr.e_phoff == sizeof(Elf_LE32_Ehdr));
@ -147,12 +119,9 @@ PackLinuxI386::generateElfHdr(
fo->write(h1, sizeof(*h1)); fo->write(h1, sizeof(*h1));
} }
else if (ph.format==UPX_F_LINUX_ELF_i386) { else if (ph.format==UPX_F_LINUX_ELF_i386) {
int const j = ((char *)&h3->phdr[2]) - (char *)h3; assert(h2->ehdr.e_phnum==2);
memcpy(&h3->phdr[2], j + (char const *)proto, sizeof(h3->phdr[2])); memset(&h2->linfo, 0, sizeof(h2->linfo));
fo->write(h2, sizeof(*h2));
assert(h3->ehdr.e_phnum==3);
memset(&h3->linfo, 0, sizeof(h3->linfo));
fo->write(h3, sizeof(*h3));
} }
else if (ph.format==UPX_F_LINUX_SH_i386) { else if (ph.format==UPX_F_LINUX_SH_i386) {
assert(h2->ehdr.e_phnum==1); assert(h2->ehdr.e_phnum==1);
@ -163,99 +132,6 @@ PackLinuxI386::generateElfHdr(
else { else {
assert(false); // unknown ph.format, PackUnix::generateElfHdr assert(false); // unknown ph.format, PackUnix::generateElfHdr
} }
Elf_LE32_Phdr const *const phdrdyn = find_DYNAMIC(phdr0, e_phnum);
if (phdrdyn) { // propagate DT_NEEDED
MemBuffer dynhdr(phdrdyn->p_memsz);
fi->seek(phdrdyn->p_offset, SEEK_SET);
fi->read(dynhdr, phdrdyn->p_memsz);
unsigned strtabx = ~0u;
unsigned strsz = 0;
int j;
Elf_LE32_Dyn const *p = (Elf_LE32_Dyn const *)(unsigned char *)dynhdr;
int so_needed = 0;
for (j = phdrdyn->p_memsz / sizeof(*p); --j>=0; ++p) {
if (p->d_tag==DT_NEEDED) {
so_needed++;
}
if (p->d_tag==DT_STRTAB) {
strtabx = find_file_offset(p->d_val, phdr0, e_phnum);
}
if (p->d_tag==DT_STRSZ) {
strsz= p->d_val;
}
}
if (so_needed) {
assert(0!=strsz && ~0u!=strtabx);
MemBuffer strtab(strsz);
fi->seek(strtabx, SEEK_SET);
fi->read(strtab, strsz);
int c_needed = 1; // index 0 is reserved
p = (Elf_LE32_Dyn const *)(unsigned char *)dynhdr;
for (j = phdrdyn->p_memsz / sizeof(*p); --j>=0; ++p) {
if (p->d_tag==DT_NEEDED) {
c_needed += 1+ strlen(p->d_val + strtab);
}
}
MemBuffer newtab(c_needed);
unsigned char *cp = newtab;
*cp++ = 0;
p = (Elf_LE32_Dyn const *)(unsigned char *)dynhdr;
for (j = phdrdyn->p_memsz / sizeof(*p); --j>=0; ++p) {
if (p->d_tag==DT_NEEDED) {
unsigned char const *const str = p->d_val + strtab;
unsigned const len = 1+ strlen(str);
memcpy(cp, str, len);
cp += len;
}
}
Elf_LE32_Dyn outdyn[3 + so_needed], *q = &outdyn[0];
q->d_tag = DT_STRSZ;
q->d_val = c_needed; // + identsize;
++q;
q->d_tag = DT_STRTAB;
q->d_val = sizeof(*h3) + sizeof(outdyn) + h3->phdr[0].p_vaddr;
++q;
cp = 1+ newtab;
for (j= so_needed; --j>=0; ++q) {
q->d_tag = DT_NEEDED; q->d_val = cp - newtab;
cp += 1+ strlen(cp);
}
q->d_tag = DT_NULL; q->d_val = 0;
h3->phdr[2].p_type = PT_DYNAMIC;
h3->phdr[2].p_offset = sizeof(*h3);
h3->phdr[2].p_vaddr = sizeof(*h3) + h3->phdr[0].p_vaddr;
h3->phdr[2].p_paddr = h3->phdr[2].p_vaddr;
h3->phdr[2].p_filesz = sizeof(outdyn) + c_needed; // + identsize;
h3->phdr[2].p_memsz = h3->phdr[2].p_filesz;
h3->phdr[2].p_flags = Elf_LE32_Phdr::PF_R;
h3->phdr[2].p_align = 4;
pt_dynamic.alloc(h3->phdr[2].p_filesz);
j = 0;
memcpy(j + pt_dynamic, &outdyn[0], sizeof(outdyn));
j += sizeof(outdyn);
memcpy(j + pt_dynamic, newtab, c_needed);
j += c_needed;
#if 0 //{
memcpy(j + pt_dynamic, ident, identsize);
// FIXME ?? patchVersion(j + pt_dynamic, identsize);
j += identsize;
#endif //}
sz_dynamic = j;
#if 0 //{ debugging: see the results early
fo->seek(0, SEEK_SET);
fo->write(h3, sizeof(*h3));
#endif //}
fo->write(pt_dynamic, sz_dynamic);
}
}
} }
void void
@ -264,7 +140,7 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
// create a pseudo-unique program id for our paranoid stub // create a pseudo-unique program id for our paranoid stub
progid = getRandomId(); progid = getRandomId();
generateElfHdr(fo, linux_i386exec_fold, 0, 0, 0); generateElfHdr(fo, linux_i386exec_fold, 0);
} }
void void

View File

@ -42,8 +42,6 @@ public:
virtual void generateElfHdr( virtual void generateElfHdr(
OutputFile *, OutputFile *,
void const *proto, void const *proto,
Elf_LE32_Phdr const *const phdr0,
unsigned e_phnum,
unsigned brka unsigned brka
); );
virtual int getFormat() const { return UPX_F_LINUX_i386; } virtual int getFormat() const { return UPX_F_LINUX_i386; }
@ -60,13 +58,6 @@ protected:
// virtual void pack3(OutputFile *, Filter &); // append loader // virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader virtual void pack4(OutputFile *, Filter &); // append PackHeader
unsigned find_file_offset(
unsigned vaddr,
Elf_LE32_Phdr const *phdr,
unsigned e_phnum
);
Elf_LE32_Phdr const *find_DYNAMIC(Elf_LE32_Phdr const *phdr, unsigned n);
// loader util // loader util
virtual int getLoaderPrefixSize() const; virtual int getLoaderPrefixSize() const;
virtual int buildLinuxLoader( virtual int buildLinuxLoader(

View File

@ -134,7 +134,7 @@ bool PackLinuxI386sh::canPack()
void void
PackLinuxI386sh::pack1(OutputFile *fo, Filter &) PackLinuxI386sh::pack1(OutputFile *fo, Filter &)
{ {
generateElfHdr(fo, linux_i386sh_fold, 0, 0, 0x08048000); generateElfHdr(fo, linux_i386sh_fold, 0x08048000);
} }
/* /*

View File

@ -28,6 +28,7 @@
%define szElf32_Phdr 8*4 %define szElf32_Phdr 8*4
%define e_entry (16 + 2*2 + 4) %define e_entry (16 + 2*2 + 4)
%define p_memsz 5*4 %define p_memsz 5*4
%define szb_info 12
%define szl_info 12 %define szl_info 12
%define szp_info 12 %define szp_info 12
%define a_val 4 %define a_val 4
@ -57,19 +58,20 @@ fold_begin: ; enter: %ebx= &Elf32_Ehdr of this program
mov edi, esp mov edi, esp
call do_auxv call do_auxv
mov eax, [p_memsz + 2*szElf32_Phdr + szElf32_Ehdr + ebx] ; size of PT_DYNAMIC push ebx ; save &Elf32_Ehdr of this stub
sub esp, dword MAX_ELF_HDR + OVERHEAD sub esp, dword MAX_ELF_HDR + OVERHEAD
mov ecx, [e_entry + ebx] ; beyond compressed data lea eax, [szElf32_Ehdr + 2*szElf32_Phdr + szl_info + szp_info + ebx] ; 1st &b_info
push esp ; argument: temp space mov esi, [e_entry + ebx] ; beyond compressed data
lea eax, [szElf32_Ehdr + 3*szElf32_Phdr + szl_info + szp_info + ebx + eax] ; 1st &b_info sub esi, eax ; length of compressed data
push edi ; argument: AT_next mov ebx, [ eax] ; length of uncompressed ELF headers
sub ecx, eax ; length of compressed data mov edx, esp ;
push ebp ; argument: &decompress mov ecx, [4+ eax] ; length of compressed ELF headers
push ecx ; argument: sz_compressed add ecx, byte szb_info
push eax ; argument: 1st &b_info pusha ; (AT_next, sz_cpr, f_expand, &tmp_ehdr, {sz_unc, &tmp}, {sz_cpr, &b1st_info} )
EXTERN upx_main EXTERN upx_main
call upx_main ; entry = upx_main(b1st_info, sz_cpr, &decompress, AT_next, tmp_ehdr) call upx_main ; returns entry address
add esp, dword 5*4 + MAX_ELF_HDR + OVERHEAD ; remove 5 params, temp space add esp, dword 8*4 + MAX_ELF_HDR + OVERHEAD ; remove 8 params, temp space
pop ebx ; &Elf32_Ehdr of this stub
push eax ; save entry address push eax ; save entry address
mov edi, [a_val + edi] ; AT_PHDR mov edi, [a_val + edi] ; AT_PHDR

View File

@ -316,35 +316,30 @@ ERR_LAB
**************************************************************************/ **************************************************************************/
void *upx_main( void *upx_main(
char /*const*/ *const b1st_info, Elf32_auxv_t *const av,
unsigned const sz_compressed, unsigned const sz_compressed,
f_expand *const f_decompress, f_expand *const f_decompress,
Elf32_auxv_t *const av, Elf32_Ehdr *const ehdr,
Elf32_Ehdr *const ehdr struct Extent xo,
struct Extent xi
) __asm__("upx_main"); ) __asm__("upx_main");
void *upx_main( void *upx_main(
char /*const*/ *const b1st_info, Elf32_auxv_t *const av,
unsigned const sz_compressed, unsigned const sz_compressed,
f_expand *const f_decompress, f_expand *const f_decompress,
Elf32_auxv_t *const av, Elf32_Ehdr *const ehdr, // temp char[MAX_ELF_HDR+OVERHEAD]
Elf32_Ehdr *const ehdr // temp char[MAX_ELF_HDR+OVERHEAD] struct Extent xo, // {sz_unc, ehdr} for ELF headers
struct Extent xi // {sz_cpr, &b_info} for ELF headers
) )
{ {
Elf32_Phdr const *phdr = (Elf32_Phdr const *)(1+ehdr); Elf32_Phdr const *phdr = (Elf32_Phdr const *)(1+ ehdr);
Elf32_Addr entry; Elf32_Addr entry;
struct Extent xo;
struct Extent xi = { 0, b1st_info }; // location of 1st b_info
// sizeof(Ehdr+Phdrs), uncompressed
size_t const sz_elfhdrs = ((size_t *)xi.buf)[0];
// sizeof(Ehdr+Phdrs), compressed; including b_info header // sizeof(Ehdr+Phdrs), compressed; including b_info header
size_t const sz_pckhdrs = sizeof(struct b_info) + ((size_t *)xi.buf)[1]; size_t const sz_pckhdrs = xi.size;
// Uncompress Ehdr and Phdrs. // Uncompress Ehdr and Phdrs.
xo.size = sz_elfhdrs; xo.buf = (char *)ehdr;
xi.size = sz_pckhdrs;
unpackExtent(&xi, &xo, f_decompress, 0); unpackExtent(&xi, &xo, f_decompress, 0);
// Prepare to decompress the Elf headers again, into the first PT_LOAD. // Prepare to decompress the Elf headers again, into the first PT_LOAD.

View File

@ -32,7 +32,8 @@ PHDRS
{ {
text PT_LOAD FILEHDR PHDRS ; text PT_LOAD FILEHDR PHDRS ;
data PT_LOAD ; /* for setting brk(0) */ data PT_LOAD ; /* for setting brk(0) */
null PT_NULL; /* changed to PT_DYNAMIC for ldd */ /* 3rd Phdr was not worth it; use "upx -d" first, then apply ldd */
/*null PT_NULL;*/ /* changed to PT_DYNAMIC for ldd */
} }
SECTIONS SECTIONS
{ {