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:
parent
dbbc47a334
commit
d168d85650
17
src/p_elf.h
17
src/p_elf.h
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue
Block a user