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

Some ELF related cleanups.

committer: mfx <mfx> 977488389 +0000
This commit is contained in:
Markus F.X.J. Oberhumer 2000-12-22 12:33:09 +00:00
parent dbbc47a334
commit d168d85650
5 changed files with 70 additions and 66 deletions

View File

@ -65,19 +65,20 @@ struct Elf_LE32_Phdr
LE32 p_memsz; /* Segment size in memory */ LE32 p_memsz; /* Segment size in memory */
LE32 p_flags; /* Segment flags */ LE32 p_flags; /* Segment flags */
LE32 p_align; /* Segment alignment */ LE32 p_align; /* Segment alignment */
// Values for p_type
enum { PT_LOAD = 1 }; /* Loadable program segment */
// Values for p_flags
enum { PF_X = (1 << 0) }; /* Segment is executable */
enum { PF_W = (1 << 1) }; /* Segment is writable */
enum { PF_R = (1 << 2) }; /* Segment is readable */
}; };
// Values for p_type
#define PT_LOAD 1 /* Loadable program segment */
// Values for p_flags
#define PF_X (1 << 0) /* Segment is executable */
#define PF_W (1 << 1) /* Segment is writable */
#define PF_R (1 << 2) /* Segment is readable */
#endif /* already included */ #endif /* already included */
/* /*
vi:ts=4:et vi:ts=4:et
*/ */

View File

@ -39,23 +39,29 @@
#include "p_lx_exc.h" #include "p_lx_exc.h"
#include "p_lx_elf.h" #include "p_lx_elf.h"
#define PT_LOAD Elf_LE32_Phdr::PT_LOAD
/*************************************************************************
//
**************************************************************************/
static const static const
#include "stub/l_le_n2b.h" #include "stub/l_le_n2b.h"
static const static const
#include "stub/l_le_n2d.h" #include "stub/l_le_n2d.h"
PackLinuxI386elf::PackLinuxI386elf(InputFile *f) :
super(f), phdri(NULL)
{
}
PackLinuxI386elf::~PackLinuxI386elf() PackLinuxI386elf::~PackLinuxI386elf()
{ {
delete[] phdri; delete[] phdri;
} }
PackLinuxI386elf::PackLinuxI386elf(InputFile *f)
:super(f)
,phdri(NULL)
{
}
const upx_byte *PackLinuxI386elf::getLoader() const const upx_byte *PackLinuxI386elf::getLoader() const
{ {
if (M_IS_NRV2B(opt->method)) if (M_IS_NRV2B(opt->method))
@ -78,26 +84,6 @@ int PackLinuxI386elf::getLoaderSize() const
} }
static inline off_t min_off_t(off_t a, off_t b)
{
return a < b ? a : b;
}
static inline off_t max_off_t(off_t a, off_t b)
{
return a > b ? a : b;
}
static off_t getbrk(Elf_LE32_Phdr const *phdr, int e_phnum)
{
off_t brka = 0;
for (int j = 0; j < e_phnum; ++phdr, ++j) if (PT_LOAD==phdr->p_type) {
brka = max_off_t(brka, phdr->p_vaddr + phdr->p_memsz);
}
return brka;
}
void PackLinuxI386elf::updateLoader(OutputFile *fo) void PackLinuxI386elf::updateLoader(OutputFile *fo)
{ {
#define PAGE_MASK (~0<<12) #define PAGE_MASK (~0<<12)
@ -165,7 +151,9 @@ void PackLinuxI386elf::patchLoader()
bool PackLinuxI386elf::canPack() bool PackLinuxI386elf::canPack()
{ {
unsigned char buf[sizeof(Elf_LE32_Ehdr) + 16*sizeof(Elf_LE32_Phdr)]; unsigned char buf[sizeof(Elf_LE32_Ehdr) + 14*sizeof(Elf_LE32_Phdr)];
assert(sizeof(buf) <= 512);
exetype = 0; exetype = 0;
// FIXME: add special checks for uncompresed "vmlinux" kernel // FIXME: add special checks for uncompresed "vmlinux" kernel
@ -181,20 +169,20 @@ bool PackLinuxI386elf::canPack()
// additional requirements for linux/elf386 // additional requirements for linux/elf386
if (ehdr->e_ehsize != sizeof(*ehdr)) { if (ehdr->e_ehsize != sizeof(*ehdr)) {
throwCantPack("invalid Ehdr e_ehsize"); throwCantPack("invalid Ehdr e_ehsize; try `--force-execve'");
return false; return false;
} }
if (ehdr->e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr if (ehdr->e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
throwCantPack("non-contiguous Ehdr/Phdr"); throwCantPack("non-contiguous Ehdr/Phdr; try `--force-execve'");
return false; return false;
} }
// The first PT_LOAD must cover the beginning of the file (0==p_offset). // The first PT_LOAD must cover the beginning of the file (0==p_offset).
Elf_LE32_Phdr const *phdr = (Elf_LE32_Phdr const *)(buf + ehdr->e_phoff); Elf_LE32_Phdr const *phdr = (Elf_LE32_Phdr const *)(buf + ehdr->e_phoff);
for (unsigned j=0; j < ehdr->e_phnum; ++phdr, ++j) { for (unsigned j=0; j < ehdr->e_phnum; ++phdr, ++j) {
if (j >= 16) if (j >= 14)
return false; return false;
if (PT_LOAD==phdr->p_type) { if (phdr->PT_LOAD == phdr->p_type) {
if (phdr->p_offset!=0) if (phdr->p_offset!=0)
return false; return false;
exetype = 1; exetype = 1;
@ -216,7 +204,7 @@ void PackLinuxI386elf::packExtent(
fi->seek(x.offset, SEEK_SET); fi->seek(x.offset, SEEK_SET);
for (off_t rest = x.size; 0 != rest; ) for (off_t rest = x.size; 0 != rest; )
{ {
int l = fi->readx(ibuf, min_off_t(rest, opt->unix.blocksize)); int l = fi->readx(ibuf, UPX_MIN(rest, (off_t)blocksize));
if (l == 0) if (l == 0)
break; break;
rest -= l; rest -= l;

View File

@ -34,6 +34,8 @@
#include "p_unix.h" #include "p_unix.h"
#include "p_lx_exc.h" #include "p_lx_exc.h"
#define PT_LOAD Elf_LE32_Phdr::PT_LOAD
/************************************************************************* /*************************************************************************
// linux/386 (generic "execve" format) // linux/386 (generic "execve" format)
@ -85,7 +87,7 @@ int PackLinuxI386::getLoaderPrefixSize() const
/************************************************************************* /*************************************************************************
// // some ELF utitlity functions
**************************************************************************/ **************************************************************************/
// basic check of an Linux ELF Ehdr // basic check of an Linux ELF Ehdr
@ -113,6 +115,24 @@ int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
} }
off_t PackLinuxI386::getbrk(const Elf_LE32_Phdr *phdr, int e_phnum) const
{
off_t brka = 0;
for (int j = 0; j < e_phnum; ++phdr, ++j) {
if (phdr->PT_LOAD == phdr->p_type) {
off_t b = phdr->p_vaddr + phdr->p_memsz;
if (b > brka)
brka = b;
}
}
return brka;
}
/*************************************************************************
//
**************************************************************************/
bool PackLinuxI386::canPack() bool PackLinuxI386::canPack()
{ {
if (exetype != 0) if (exetype != 0)
@ -225,7 +245,7 @@ void PackLinuxI386::patchLoaderChecksum()
void PackLinuxI386::updateLoader(OutputFile *fo) void PackLinuxI386::updateLoader(OutputFile *fo)
{ {
#define PAGE_MASK (~0<<12) #define PAGE_MASK (~0<<12)
Elf_LE32_Ehdr *ehdr = (Elf_LE32_Ehdr *)(unsigned char *)loader; Elf_LE32_Ehdr *const ehdr = (Elf_LE32_Ehdr *)(unsigned char *)loader;
ehdr->e_phnum = 2; ehdr->e_phnum = 2;
// The first Phdr maps the stub (instructions, data, bss) rwx. // The first Phdr maps the stub (instructions, data, bss) rwx.
@ -237,7 +257,7 @@ void PackLinuxI386::updateLoader(OutputFile *fo)
phdro->p_offset = lsize; phdro->p_offset = lsize;
phdro->p_paddr = phdro->p_vaddr = 0x00400000 + (lsize &~ PAGE_MASK); phdro->p_paddr = phdro->p_vaddr = 0x00400000 + (lsize &~ PAGE_MASK);
phdro->p_memsz = phdro->p_filesz = fo->getBytesWritten() - lsize; phdro->p_memsz = phdro->p_filesz = fo->getBytesWritten() - lsize;
phdro->p_flags = PF_R; phdro->p_flags = phdro->PF_R;
phdro->p_align = -PAGE_MASK; phdro->p_align = -PAGE_MASK;
patchLoaderChecksum(); patchLoaderChecksum();

View File

@ -46,16 +46,20 @@ public:
virtual bool canPack(); virtual bool canPack();
protected: protected:
// loader util
virtual const upx_byte *getLoader() const; virtual const upx_byte *getLoader() const;
virtual int getLoaderSize() const; virtual int getLoaderSize() const;
virtual int getLoaderPrefixSize() const; virtual int getLoaderPrefixSize() const;
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const; // patch util
virtual void patchLoader(); virtual void patchLoader();
virtual void patchLoaderChecksum(); virtual void patchLoaderChecksum();
virtual void updateLoader(OutputFile *); virtual void updateLoader(OutputFile *);
// ELF util
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const;
virtual off_t getbrk(const Elf_LE32_Phdr *phdr, int e_phnum) const;
enum { enum {
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX" UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
}; };

View File

@ -39,19 +39,25 @@
#include "p_lx_exc.h" #include "p_lx_exc.h"
#include "p_lx_sh.h" #include "p_lx_sh.h"
#define PT_LOAD Elf_LE32_Phdr::PT_LOAD
/*************************************************************************
//
**************************************************************************/
static const static const
#include "stub/l_sh_n2b.h" #include "stub/l_sh_n2b.h"
static const static const
#include "stub/l_sh_n2d.h" #include "stub/l_sh_n2d.h"
PackLinuxI386sh::~PackLinuxI386sh()
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
super(f), o_shname(0), l_shname(0)
{ {
} }
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) PackLinuxI386sh::~PackLinuxI386sh()
:super(f)
,o_shname(0)
,l_shname(0)
{ {
} }
@ -77,21 +83,6 @@ int PackLinuxI386sh::getLoaderSize() const
} }
static inline off_t max_off_t(off_t a, off_t b)
{
return a > b ? a : b;
}
static off_t getbrk(Elf_LE32_Phdr const *phdr, int e_phnum)
{
off_t brka = 0;
for (int j = 0; j < e_phnum; ++phdr, ++j) if (PT_LOAD==phdr->p_type) {
brka = max_off_t(brka, phdr->p_vaddr + phdr->p_memsz);
}
return brka;
}
void PackLinuxI386sh::patchLoader() void PackLinuxI386sh::patchLoader()
{ {
lsize = getLoaderSize(); lsize = getLoaderSize();