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->readx(phdri, sz_phdrs);
generateElfHdr(fo, linux_i386elf_fold, phdri, ehdri.e_phnum,
getbrk(phdri, ehdri.e_phnum) );
generateElfHdr(fo, linux_i386elf_fold, getbrk(phdri, ehdri.e_phnum) );
}
void PackLinuxI386elf::pack2(OutputFile *fo, Filter &ft)

View File

@ -79,43 +79,15 @@ const int *PackLinuxI386::getFilters() const
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
PackLinuxI386::generateElfHdr(
OutputFile *const fo,
void const *const proto,
Elf_LE32_Phdr const *const phdr0,
unsigned e_phnum,
unsigned const brka
)
{
cprElfHdr1 *const h1 = (cprElfHdr1 *)&elfout;
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
memcpy(h2, proto, sizeof(*h2));
assert(h2->ehdr.e_phoff == sizeof(Elf_LE32_Ehdr));
@ -147,12 +119,9 @@ PackLinuxI386::generateElfHdr(
fo->write(h1, sizeof(*h1));
}
else if (ph.format==UPX_F_LINUX_ELF_i386) {
int const j = ((char *)&h3->phdr[2]) - (char *)h3;
memcpy(&h3->phdr[2], j + (char const *)proto, sizeof(h3->phdr[2]));
assert(h3->ehdr.e_phnum==3);
memset(&h3->linfo, 0, sizeof(h3->linfo));
fo->write(h3, sizeof(*h3));
assert(h2->ehdr.e_phnum==2);
memset(&h2->linfo, 0, sizeof(h2->linfo));
fo->write(h2, sizeof(*h2));
}
else if (ph.format==UPX_F_LINUX_SH_i386) {
assert(h2->ehdr.e_phnum==1);
@ -163,99 +132,6 @@ PackLinuxI386::generateElfHdr(
else {
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
@ -264,7 +140,7 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
// create a pseudo-unique program id for our paranoid stub
progid = getRandomId();
generateElfHdr(fo, linux_i386exec_fold, 0, 0, 0);
generateElfHdr(fo, linux_i386exec_fold, 0);
}
void

View File

@ -42,8 +42,6 @@ public:
virtual void generateElfHdr(
OutputFile *,
void const *proto,
Elf_LE32_Phdr const *const phdr0,
unsigned e_phnum,
unsigned brka
);
virtual int getFormat() const { return UPX_F_LINUX_i386; }
@ -60,13 +58,6 @@ protected:
// virtual void pack3(OutputFile *, Filter &); // append loader
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
virtual int getLoaderPrefixSize() const;
virtual int buildLinuxLoader(

View File

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

View File

@ -316,35 +316,30 @@ ERR_LAB
**************************************************************************/
void *upx_main(
char /*const*/ *const b1st_info,
Elf32_auxv_t *const av,
unsigned const sz_compressed,
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");
void *upx_main(
char /*const*/ *const b1st_info,
Elf32_auxv_t *const av,
unsigned const sz_compressed,
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;
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
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.
xo.size = sz_elfhdrs; xo.buf = (char *)ehdr;
xi.size = sz_pckhdrs;
unpackExtent(&xi, &xo, f_decompress, 0);
// Prepare to decompress the Elf headers again, into the first PT_LOAD.

View File

@ -32,7 +32,8 @@ PHDRS
{
text PT_LOAD FILEHDR PHDRS ;
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
{