mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
Moved the generic linux/386 format into the new p_lx_exc.{h,cpp} files.
committer: mfx <mfx> 977423460 +0000
This commit is contained in:
parent
5d74b7252d
commit
1d948c839d
17
src/Makefile
17
src/Makefile
|
@ -61,7 +61,8 @@ OBJECTS1 = \
|
|||
compress$o except$o file$o lefile$o \
|
||||
filter$o mem$o msg$o stdcxx$o work$o ui$o \
|
||||
packer$o packhead$o packmast$o \
|
||||
p_com$o p_djgpp2$o p_exe$o p_lx_elf$o p_lx_sep$o p_lx_sh$o \
|
||||
p_com$o p_djgpp2$o p_exe$o \
|
||||
p_lx_elf$o p_lx_exc$o p_lx_sep$o p_lx_sh$o \
|
||||
p_sys$o p_tmt$o p_tos$o \
|
||||
p_unix$o p_vmlinz$o p_w32pe$o p_wcle$o
|
||||
|
||||
|
@ -446,7 +447,8 @@ mygetopt$o: mygetopt.h
|
|||
packer$o: packer.h filter.h linker.h ui.h version.h
|
||||
packhead$o: packer.h
|
||||
packmast$o: packmast.h packer.h lefile.h \
|
||||
p_com.h p_djgpp2.h p_exe.h p_lx_elf.h p_lx_sep.h p_lx_sh.h \
|
||||
p_com.h p_djgpp2.h p_exe.h \
|
||||
p_lx_elf.h p_lx_exc.h p_lx_sep.h p_lx_sh.h \
|
||||
p_sys.h p_tmt.h p_tos.h \
|
||||
p_unix.h p_vmlinz.h p_vxd.h p_w32pe.h p_wcle.h
|
||||
ui$o: packer.h ui.h
|
||||
|
@ -458,10 +460,12 @@ p_djgpp2$o: packer.h p_djgpp2.h stub/stubify.h \
|
|||
stub/l_djgpp2.h
|
||||
p_exe$o: packer.h p_exe.h \
|
||||
stub/l_exe.h
|
||||
p_lx_elf$o: packer.h p_lx_elf.h p_unix.h p_elf.h \
|
||||
p_lx_elf$o: packer.h p_unix.h p_elf.h p_lx_exc.h p_lx_elf.h \
|
||||
stub/l_le_n2b.h stub/l_le_n2d.h
|
||||
p_lx_sep$o: packer.h p_lx_sep.h p_lx_elf.h p_unix.h p_elf.h
|
||||
p_lx_sh$o: packer.h p_lx_sh.h p_unix.h p_elf.h \
|
||||
p_lx_exc$o: packer.h p_unix.h p_elf.h p_lx_exc.h \
|
||||
stub/l_lx_n2b.h stub/l_lx_n2d.h
|
||||
p_lx_sep$o: packer.h p_unix.h p_elf.h p_lx_exc.h p_lx_elf.h p_lx_sep.h
|
||||
p_lx_sh$o: packer.h p_unix.h p_elf.h p_lx_exc.h p_lx_sh.h \
|
||||
stub/l_sh_n2b.h stub/l_sh_n2d.h
|
||||
p_sys$o: packer.h p_sys.h p_com.h \
|
||||
stub/l_sys.h
|
||||
|
@ -470,8 +474,7 @@ p_tmt$o: packer.h p_tmt.h \
|
|||
p_tos$o: packer.h p_tos.h \
|
||||
stub/l_t_n2b.h stub/l_t_n2bs.h \
|
||||
stub/l_t_n2d.h stub/l_t_n2ds.h
|
||||
p_unix$o: packer.h p_unix.h p_elf.h \
|
||||
stub/l_lx_n2b.h stub/l_lx_n2d.h
|
||||
p_unix$o: packer.h p_unix.h p_elf.h
|
||||
p_vmlinz$o: packer.h p_vmlinz.h \
|
||||
stub/l_vmlinz.h
|
||||
p_w32pe$o: packer.h p_w32pe.h \
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
#include "p_unix.h"
|
||||
#include "p_lx_exc.h"
|
||||
#include "p_lx_elf.h"
|
||||
|
||||
|
||||
|
|
237
src/p_lx_exc.cpp
Normal file
237
src/p_lx_exc.cpp
Normal file
|
@ -0,0 +1,237 @@
|
|||
/* p_lx_exc.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2000 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
#include "p_unix.h"
|
||||
#include "p_lx_exc.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/386 (generic "execve" format)
|
||||
**************************************************************************/
|
||||
|
||||
static const
|
||||
#include "stub/l_lx_n2b.h"
|
||||
static const
|
||||
#include "stub/l_lx_n2d.h"
|
||||
|
||||
|
||||
int PackLinuxI386::getCompressionMethod() const
|
||||
{
|
||||
if (M_IS_NRV2B(opt->method))
|
||||
return M_NRV2B_LE32;
|
||||
if (M_IS_NRV2D(opt->method))
|
||||
return M_NRV2D_LE32;
|
||||
return opt->level > 1 && file_size >= 512*1024 ? M_NRV2D_LE32 : M_NRV2B_LE32;
|
||||
}
|
||||
|
||||
|
||||
const upx_byte *PackLinuxI386::getLoader() const
|
||||
{
|
||||
if (M_IS_NRV2B(opt->method))
|
||||
return linux_i386exec_nrv2b_loader;
|
||||
if (M_IS_NRV2D(opt->method))
|
||||
return linux_i386exec_nrv2d_loader;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int PackLinuxI386::getLoaderSize() const
|
||||
{
|
||||
if (0!=lsize) {
|
||||
return lsize;
|
||||
}
|
||||
if (M_IS_NRV2B(opt->method))
|
||||
return sizeof(linux_i386exec_nrv2b_loader);
|
||||
if (M_IS_NRV2D(opt->method))
|
||||
return sizeof(linux_i386exec_nrv2d_loader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PackLinuxI386::getLoaderPrefixSize() const
|
||||
{
|
||||
return 116;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackLinuxI386::canPack()
|
||||
{
|
||||
if (exetype != 0)
|
||||
return super::canPack();
|
||||
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
unsigned char *buf = ehdr.e_ident;
|
||||
|
||||
fi->readx(&ehdr, sizeof(ehdr));
|
||||
fi->seek(0, SEEK_SET);
|
||||
|
||||
exetype = 0;
|
||||
const unsigned l = get_le32(buf);
|
||||
#if 0
|
||||
// NOTE: ELF executables are now handled by p_lx_elf.cpp.
|
||||
if (!memcmp(buf, "\x7f\x45\x4c\x46\x01\x01\x01", 7)) // ELF 32-bit LSB
|
||||
{
|
||||
// FIXME: add special checks for uncompresed "vmlinux" kernel
|
||||
exetype = 1;
|
||||
// now check the ELF header
|
||||
if (!memcmp(buf+8, "FreeBSD", 7)) // branded
|
||||
exetype = 0;
|
||||
if (ehdr.e_type != 2) // executable
|
||||
exetype = 0;
|
||||
if (ehdr.e_machine != 3 && ehdr.e_machine != 6) // Intel 80[34]86
|
||||
exetype = 0;
|
||||
if (ehdr.e_version != 1) // version
|
||||
exetype = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
||||
{
|
||||
// OMAGIC / NMAGIC / ZMAGIC / QMAGIC
|
||||
exetype = 2;
|
||||
// FIXME: N_TRSIZE, N_DRSIZE
|
||||
// FIXME: check for aout shared libraries
|
||||
}
|
||||
#if defined(__linux__)
|
||||
// only compress scripts when running under Linux
|
||||
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||
exetype = -2;
|
||||
#endif
|
||||
|
||||
return super::canPack();
|
||||
}
|
||||
|
||||
|
||||
void PackLinuxI386::patchLoader()
|
||||
{
|
||||
lsize = getLoaderSize();
|
||||
|
||||
// patch loader
|
||||
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||
// also, we sleep much longer when compressing a script.
|
||||
patch_le32(loader,lsize,"UPX4",exetype > 0 ? 3 : 15); // sleep time
|
||||
patch_le32(loader,lsize,"UPX3",exetype > 0 ? 0 : 0x7fffffff);
|
||||
patch_le32(loader,lsize,"UPX2",progid);
|
||||
patchVersion(loader,lsize);
|
||||
|
||||
Elf_LE32_Ehdr *const ehdr = (Elf_LE32_Ehdr *)(void *)loader;
|
||||
Elf_LE32_Phdr *const phdr = (Elf_LE32_Phdr *)(1+ehdr);
|
||||
|
||||
// stub/scripts/setfold.pl puts address of 'fold_begin' in phdr[1].p_offset
|
||||
off_t const fold_begin = phdr[1].p_offset;
|
||||
assert(fold_begin > 0);
|
||||
assert(fold_begin < (off_t)lsize);
|
||||
MemBuffer cprLoader(lsize);
|
||||
|
||||
// compress compiled C-code portion of loader
|
||||
upx_uint const uncLsize = lsize - fold_begin;
|
||||
upx_uint cprLsize;
|
||||
int r = upx_compress(loader + fold_begin, uncLsize, cprLoader, &cprLsize,
|
||||
NULL, opt->method, 10, NULL, NULL);
|
||||
if (r != UPX_E_OK || cprLsize >= uncLsize)
|
||||
throwInternalError("loaded compression failed");
|
||||
|
||||
memcpy(fold_begin+loader, cprLoader, cprLsize);
|
||||
lsize = fold_begin + cprLsize;
|
||||
phdr->p_filesz = lsize;
|
||||
// phdr->p_memsz is the decompressed size
|
||||
|
||||
// The beginning of our loader consists of a elf_hdr (52 bytes) and
|
||||
// one section elf_phdr (32 byte) now,
|
||||
// another section elf_phdr (32 byte) later, so we have 12 free bytes
|
||||
// from offset 116 to the program start at offset 128.
|
||||
// These 12 bytes are used for l_info by ::patchLoaderChecksum().
|
||||
assert(get_le32(loader + 28) == 52); // e_phoff
|
||||
assert(get_le32(loader + 32) == 0); // e_shoff
|
||||
assert(get_le16(loader + 40) == 52); // e_ehsize
|
||||
assert(get_le16(loader + 42) == 32); // e_phentsize
|
||||
assert(get_le16(loader + 44) == 1); // e_phnum
|
||||
assert(get_le16(loader + 48) == 0); // e_shnum
|
||||
assert(lsize > 128 && lsize < 4096);
|
||||
|
||||
patchLoaderChecksum();
|
||||
}
|
||||
|
||||
|
||||
void PackLinuxI386::patchLoaderChecksum()
|
||||
{
|
||||
l_info *const lp = (l_info *)(loader + getLoaderPrefixSize());
|
||||
// checksum for loader + p_info
|
||||
lp->l_checksum = 0; // (this checksum is currently unused)
|
||||
lp->l_magic = UPX_ELF_MAGIC;
|
||||
lp->l_lsize = (unsigned short) lsize;
|
||||
lp->l_version = (unsigned char) ph.version;
|
||||
lp->l_format = (unsigned char) ph.format;
|
||||
unsigned adler = upx_adler32(0,NULL,0);
|
||||
adler = upx_adler32(adler, loader, lsize + sizeof(p_info));
|
||||
lp->l_checksum = adler;
|
||||
}
|
||||
|
||||
|
||||
void PackLinuxI386::updateLoader(OutputFile *fo)
|
||||
{
|
||||
#define PAGE_MASK (~0<<12)
|
||||
Elf_LE32_Ehdr *ehdr = (Elf_LE32_Ehdr *)(unsigned char *)loader;
|
||||
ehdr->e_phnum = 2;
|
||||
|
||||
// The first Phdr maps the stub (instructions, data, bss) rwx.
|
||||
// The second Phdr maps the overlay r--,
|
||||
// to defend against /usr/bin/strip removing the overlay.
|
||||
Elf_LE32_Phdr *const phdro = 1+(Elf_LE32_Phdr *)(1+ehdr);
|
||||
|
||||
phdro->p_type = PT_LOAD;
|
||||
phdro->p_offset = lsize;
|
||||
phdro->p_paddr = phdro->p_vaddr = 0x00400000 + (lsize &~ PAGE_MASK);
|
||||
phdro->p_memsz = phdro->p_filesz = fo->getBytesWritten() - lsize;
|
||||
phdro->p_flags = PF_R;
|
||||
phdro->p_align = -PAGE_MASK;
|
||||
|
||||
patchLoaderChecksum();
|
||||
fo->seek(0, SEEK_SET);
|
||||
fo->rewrite(loader, 0x80);
|
||||
#undef PAGE_MASK
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
69
src/p_lx_exc.h
Normal file
69
src/p_lx_exc.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* p_lx_exc.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2000 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_LX_EXC_H
|
||||
#define __UPX_P_LX_EXC_H
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/386 (generic "execve" format)
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxI386 : public PackUnixLe32
|
||||
{
|
||||
typedef PackUnixLe32 super;
|
||||
public:
|
||||
PackLinuxI386(InputFile *f) : super(f) { }
|
||||
virtual int getFormat() const { return UPX_F_LINUX_i386; }
|
||||
virtual const char *getName() const { return "linux/386"; }
|
||||
virtual int getCompressionMethod() const;
|
||||
|
||||
virtual bool canPack();
|
||||
|
||||
protected:
|
||||
virtual const upx_byte *getLoader() const;
|
||||
virtual int getLoaderSize() const;
|
||||
virtual int getLoaderPrefixSize() const;
|
||||
|
||||
virtual void patchLoader();
|
||||
virtual void patchLoaderChecksum();
|
||||
virtual void updateLoader(OutputFile *);
|
||||
|
||||
enum {
|
||||
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
#include "p_unix.h"
|
||||
#include "p_lx_exc.h"
|
||||
#include "p_lx_elf.h"
|
||||
#include "p_lx_sep.h"
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
#include "p_unix.h"
|
||||
#include "p_lx_exc.h"
|
||||
#include "p_lx_sh.h"
|
||||
|
||||
static const
|
||||
|
|
192
src/p_unix.cpp
192
src/p_unix.cpp
|
@ -322,198 +322,6 @@ void PackUnix::unpack(OutputFile *fo)
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/i386 (generic "execve" format)
|
||||
**************************************************************************/
|
||||
|
||||
static const
|
||||
#include "stub/l_lx_n2b.h"
|
||||
static const
|
||||
#include "stub/l_lx_n2d.h"
|
||||
|
||||
|
||||
int PackLinuxI386::getCompressionMethod() const
|
||||
{
|
||||
if (M_IS_NRV2B(opt->method))
|
||||
return M_NRV2B_LE32;
|
||||
if (M_IS_NRV2D(opt->method))
|
||||
return M_NRV2D_LE32;
|
||||
return opt->level > 1 && file_size >= 512*1024 ? M_NRV2D_LE32 : M_NRV2B_LE32;
|
||||
}
|
||||
|
||||
|
||||
const upx_byte *PackLinuxI386::getLoader() const
|
||||
{
|
||||
if (M_IS_NRV2B(opt->method))
|
||||
return linux_i386exec_nrv2b_loader;
|
||||
if (M_IS_NRV2D(opt->method))
|
||||
return linux_i386exec_nrv2d_loader;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int PackLinuxI386::getLoaderSize() const
|
||||
{
|
||||
if (0!=lsize) {
|
||||
return lsize;
|
||||
}
|
||||
if (M_IS_NRV2B(opt->method))
|
||||
return sizeof(linux_i386exec_nrv2b_loader);
|
||||
if (M_IS_NRV2D(opt->method))
|
||||
return sizeof(linux_i386exec_nrv2d_loader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PackLinuxI386::getLoaderPrefixSize() const
|
||||
{
|
||||
return 116;
|
||||
}
|
||||
|
||||
|
||||
bool PackLinuxI386::canPack()
|
||||
{
|
||||
if (exetype != 0)
|
||||
return super::canPack();
|
||||
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
unsigned char *buf = ehdr.e_ident;
|
||||
|
||||
fi->readx(&ehdr, sizeof(ehdr));
|
||||
fi->seek(0, SEEK_SET);
|
||||
|
||||
exetype = 0;
|
||||
const unsigned l = get_le32(buf);
|
||||
#if 0
|
||||
// NOTE: ELF executables are now handled by p_lx_elf.cpp.
|
||||
if (!memcmp(buf, "\x7f\x45\x4c\x46\x01\x01\x01", 7)) // ELF 32-bit LSB
|
||||
{
|
||||
// FIXME: add special checks for uncompresed "vmlinux" kernel
|
||||
exetype = 1;
|
||||
// now check the ELF header
|
||||
if (!memcmp(buf+8, "FreeBSD", 7)) // branded
|
||||
exetype = 0;
|
||||
if (ehdr.e_type != 2) // executable
|
||||
exetype = 0;
|
||||
if (ehdr.e_machine != 3 && ehdr.e_machine != 6) // Intel 80[34]86
|
||||
exetype = 0;
|
||||
if (ehdr.e_version != 1) // version
|
||||
exetype = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
||||
{
|
||||
// OMAGIC / NMAGIC / ZMAGIC / QMAGIC
|
||||
exetype = 2;
|
||||
// FIXME: N_TRSIZE, N_DRSIZE
|
||||
// FIXME: check for aout shared libraries
|
||||
}
|
||||
#if defined(__linux__)
|
||||
// only compress scripts when running under Linux
|
||||
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||
exetype = -2;
|
||||
#endif
|
||||
|
||||
return super::canPack();
|
||||
}
|
||||
|
||||
|
||||
void PackLinuxI386::patchLoader()
|
||||
{
|
||||
lsize = getLoaderSize();
|
||||
|
||||
// patch loader
|
||||
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||
// also, we sleep much longer when compressing a script.
|
||||
patch_le32(loader,lsize,"UPX4",exetype > 0 ? 3 : 15); // sleep time
|
||||
patch_le32(loader,lsize,"UPX3",exetype > 0 ? 0 : 0x7fffffff);
|
||||
patch_le32(loader,lsize,"UPX2",progid);
|
||||
patchVersion(loader,lsize);
|
||||
|
||||
Elf_LE32_Ehdr *const ehdr = (Elf_LE32_Ehdr *)(void *)loader;
|
||||
Elf_LE32_Phdr *const phdr = (Elf_LE32_Phdr *)(1+ehdr);
|
||||
|
||||
// stub/scripts/setfold.pl puts address of 'fold_begin' in phdr[1].p_offset
|
||||
off_t const fold_begin = phdr[1].p_offset;
|
||||
assert(fold_begin > 0);
|
||||
assert(fold_begin < (off_t)lsize);
|
||||
MemBuffer cprLoader(lsize);
|
||||
|
||||
// compress compiled C-code portion of loader
|
||||
upx_uint const uncLsize = lsize - fold_begin;
|
||||
upx_uint cprLsize;
|
||||
int r = upx_compress(loader + fold_begin, uncLsize, cprLoader, &cprLsize,
|
||||
NULL, opt->method, 10, NULL, NULL);
|
||||
if (r != UPX_E_OK || cprLsize >= uncLsize)
|
||||
throwInternalError("loaded compression failed");
|
||||
|
||||
memcpy(fold_begin+loader, cprLoader, cprLsize);
|
||||
lsize = fold_begin + cprLsize;
|
||||
phdr->p_filesz = lsize;
|
||||
// phdr->p_memsz is the decompressed size
|
||||
|
||||
// The beginning of our loader consists of a elf_hdr (52 bytes) and
|
||||
// one section elf_phdr (32 byte) now,
|
||||
// another section elf_phdr (32 byte) later, so we have 12 free bytes
|
||||
// from offset 116 to the program start at offset 128.
|
||||
// These 12 bytes are used for l_info by ::patchLoaderChecksum().
|
||||
assert(get_le32(loader + 28) == 52); // e_phoff
|
||||
assert(get_le32(loader + 32) == 0); // e_shoff
|
||||
assert(get_le16(loader + 40) == 52); // e_ehsize
|
||||
assert(get_le16(loader + 42) == 32); // e_phentsize
|
||||
assert(get_le16(loader + 44) == 1); // e_phnum
|
||||
assert(get_le16(loader + 48) == 0); // e_shnum
|
||||
assert(lsize > 128 && lsize < 4096);
|
||||
|
||||
patchLoaderChecksum();
|
||||
}
|
||||
|
||||
|
||||
void PackLinuxI386::patchLoaderChecksum()
|
||||
{
|
||||
l_info *const lp = (l_info *)(loader + getLoaderPrefixSize());
|
||||
// checksum for loader + p_info
|
||||
lp->l_checksum = 0; // (this checksum is currently unused)
|
||||
lp->l_magic = UPX_ELF_MAGIC;
|
||||
lp->l_lsize = (unsigned short) lsize;
|
||||
lp->l_version = (unsigned char) ph.version;
|
||||
lp->l_format = (unsigned char) ph.format;
|
||||
unsigned adler = upx_adler32(0,NULL,0);
|
||||
adler = upx_adler32(adler, loader, lsize + sizeof(p_info));
|
||||
lp->l_checksum = adler;
|
||||
}
|
||||
|
||||
|
||||
void PackLinuxI386::updateLoader(OutputFile *fo)
|
||||
{
|
||||
#define PAGE_MASK (~0<<12)
|
||||
Elf_LE32_Ehdr *ehdr = (Elf_LE32_Ehdr *)(unsigned char *)loader;
|
||||
ehdr->e_phnum = 2;
|
||||
|
||||
// The first Phdr maps the stub (instructions, data, bss) rwx.
|
||||
// The second Phdr maps the overlay r--,
|
||||
// to defend against /usr/bin/strip removing the overlay.
|
||||
Elf_LE32_Phdr *const phdro = 1+(Elf_LE32_Phdr *)(1+ehdr);
|
||||
|
||||
phdro->p_type = PT_LOAD;
|
||||
phdro->p_offset = lsize;
|
||||
phdro->p_paddr = phdro->p_vaddr = 0x00400000 + (lsize &~ PAGE_MASK);
|
||||
phdro->p_memsz = phdro->p_filesz = fo->getBytesWritten() - lsize;
|
||||
phdro->p_flags = PF_R;
|
||||
phdro->p_align = -PAGE_MASK;
|
||||
|
||||
patchLoaderChecksum();
|
||||
fo->seek(0, SEEK_SET);
|
||||
fo->rewrite(loader, 0x80);
|
||||
#undef PAGE_MASK
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
|
30
src/p_unix.h
30
src/p_unix.h
|
@ -126,36 +126,6 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/i386 (generic "execve" format)
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxI386 : public PackUnixLe32
|
||||
{
|
||||
typedef PackUnixLe32 super;
|
||||
public:
|
||||
PackLinuxI386(InputFile *f) : super(f) { }
|
||||
virtual int getFormat() const { return UPX_F_LINUX_i386; }
|
||||
virtual const char *getName() const { return "linux/386"; }
|
||||
virtual int getCompressionMethod() const;
|
||||
|
||||
virtual bool canPack();
|
||||
|
||||
protected:
|
||||
virtual const upx_byte *getLoader() const;
|
||||
virtual int getLoaderSize() const;
|
||||
virtual int getLoaderPrefixSize() const;
|
||||
|
||||
virtual void patchLoader();
|
||||
virtual void patchLoaderChecksum();
|
||||
virtual void updateLoader(OutputFile *);
|
||||
|
||||
enum {
|
||||
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// solaris/sparc
|
||||
**************************************************************************/
|
||||
|
|
|
@ -34,8 +34,9 @@
|
|||
#include "p_com.h"
|
||||
#include "p_djgpp2.h"
|
||||
#include "p_exe.h"
|
||||
#include "p_elf.h"
|
||||
#include "p_unix.h"
|
||||
#include "p_elf.h"
|
||||
#include "p_lx_exc.h"
|
||||
#include "p_lx_elf.h"
|
||||
#include "p_lx_sep.h"
|
||||
#include "p_lx_sh.h"
|
||||
|
|
Loading…
Reference in New Issue
Block a user