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:
parent
e866b2231f
commit
2ff824e631
|
@ -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)
|
||||||
|
|
132
src/p_lx_exc.cpp
132
src/p_lx_exc.cpp
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user