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_flags; /* Segment flags */
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 */
/*
vi:ts=4:et
*/

View File

@ -39,23 +39,29 @@
#include "p_lx_exc.h"
#include "p_lx_elf.h"
#define PT_LOAD Elf_LE32_Phdr::PT_LOAD
/*************************************************************************
//
**************************************************************************/
static const
#include "stub/l_le_n2b.h"
static const
#include "stub/l_le_n2d.h"
PackLinuxI386elf::PackLinuxI386elf(InputFile *f) :
super(f), phdri(NULL)
{
}
PackLinuxI386elf::~PackLinuxI386elf()
{
delete[] phdri;
}
PackLinuxI386elf::PackLinuxI386elf(InputFile *f)
:super(f)
,phdri(NULL)
{
}
const upx_byte *PackLinuxI386elf::getLoader() const
{
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)
{
#define PAGE_MASK (~0<<12)
@ -165,7 +151,9 @@ void PackLinuxI386elf::patchLoader()
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;
// FIXME: add special checks for uncompresed "vmlinux" kernel
@ -181,20 +169,20 @@ bool PackLinuxI386elf::canPack()
// additional requirements for linux/elf386
if (ehdr->e_ehsize != sizeof(*ehdr)) {
throwCantPack("invalid Ehdr e_ehsize");
throwCantPack("invalid Ehdr e_ehsize; try `--force-execve'");
return false;
}
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;
}
// 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);
for (unsigned j=0; j < ehdr->e_phnum; ++phdr, ++j) {
if (j >= 16)
if (j >= 14)
return false;
if (PT_LOAD==phdr->p_type) {
if (phdr->PT_LOAD == phdr->p_type) {
if (phdr->p_offset!=0)
return false;
exetype = 1;
@ -214,9 +202,9 @@ void PackLinuxI386elf::packExtent(
)
{
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)
break;
rest -= l;

View File

@ -34,6 +34,8 @@
#include "p_unix.h"
#include "p_lx_exc.h"
#define PT_LOAD Elf_LE32_Phdr::PT_LOAD
/*************************************************************************
// linux/386 (generic "execve" format)
@ -85,7 +87,7 @@ int PackLinuxI386::getLoaderPrefixSize() const
/*************************************************************************
//
// some ELF utitlity functions
**************************************************************************/
// 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()
{
if (exetype != 0)
@ -225,7 +245,7 @@ void PackLinuxI386::patchLoaderChecksum()
void PackLinuxI386::updateLoader(OutputFile *fo)
{
#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;
// 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_paddr = phdro->p_vaddr = 0x00400000 + (lsize &~ PAGE_MASK);
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;
patchLoaderChecksum();

View File

@ -46,16 +46,20 @@ public:
virtual bool canPack();
protected:
// loader util
virtual const upx_byte *getLoader() const;
virtual int getLoaderSize() const;
virtual int getLoaderPrefixSize() const;
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const;
// patch util
virtual void patchLoader();
virtual void patchLoaderChecksum();
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 {
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
};

View File

@ -39,19 +39,25 @@
#include "p_lx_exc.h"
#include "p_lx_sh.h"
#define PT_LOAD Elf_LE32_Phdr::PT_LOAD
/*************************************************************************
//
**************************************************************************/
static const
#include "stub/l_sh_n2b.h"
static const
#include "stub/l_sh_n2d.h"
PackLinuxI386sh::~PackLinuxI386sh()
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
super(f), o_shname(0), l_shname(0)
{
}
PackLinuxI386sh::PackLinuxI386sh(InputFile *f)
:super(f)
,o_shname(0)
,l_shname(0)
PackLinuxI386sh::~PackLinuxI386sh()
{
}
@ -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()
{
lsize = getLoaderSize();