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

debug PackLinuxElf32armBe. Also unify subroutines.

This commit is contained in:
John Reiser 2006-06-13 15:51:29 -07:00
parent bd8acbde97
commit dcc704a357
3 changed files with 50 additions and 51 deletions

View File

@ -337,11 +337,11 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
typedef TT_Elf ::Ehdr<BE32,BE32,BE32,LE16> Elf_BE32_Ehdr; typedef TT_Elf ::Ehdr<BE32,BE32,BE32,BE16> Elf_BE32_Ehdr;
typedef TT_Elf32::Phdr<BE32,BE32,BE32> Elf_BE32_Phdr; typedef TT_Elf32::Phdr<BE32,BE32,BE32> Elf_BE32_Phdr;
typedef TT_Elf32::Shdr<BE32,BE32,BE32> Elf_BE32_Shdr; typedef TT_Elf32::Shdr<BE32,BE32,BE32> Elf_BE32_Shdr;
typedef TT_Elf ::Dyn <BE32,BE32> Elf_BE32_Dyn; typedef TT_Elf ::Dyn <BE32,BE32> Elf_BE32_Dyn;
typedef TT_Elf32::Sym <LE16,BE32,void> Elf_BE32_Sym; typedef TT_Elf32::Sym <BE16,BE32,void> Elf_BE32_Sym;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32)

View File

@ -46,12 +46,7 @@
int int
PackLinuxElf32::checkEhdr( PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const
Elf32_Ehdr const *ehdr,
unsigned char e_machine,
unsigned char ei_class,
unsigned char ei_data
) const
{ {
const unsigned char * const buf = ehdr->e_ident; const unsigned char * const buf = ehdr->e_ident;
@ -94,12 +89,7 @@ PackLinuxElf32::checkEhdr(
} }
int int
PackLinuxElf64::checkEhdr( PackLinuxElf64::checkEhdr(Elf64_Ehdr const *ehdr) const
Elf64_Ehdr const *ehdr,
unsigned char e_machine,
unsigned char ei_class,
unsigned char ei_data
) const
{ {
const unsigned char * const buf = ehdr->e_ident; const unsigned char * const buf = ehdr->e_ident;
@ -141,7 +131,9 @@ PackLinuxElf64::checkEhdr(
} }
PackLinuxElf::PackLinuxElf(InputFile *f) PackLinuxElf::PackLinuxElf(InputFile *f)
: super(f) : super(f), file_image(NULL), dynstr(NULL),
sz_phdrs(0), sz_elf_hdrs(0),
e_machine(0), ei_class(0), ei_data(0)
{ {
} }
@ -151,7 +143,7 @@ PackLinuxElf::~PackLinuxElf()
PackLinuxElf32::PackLinuxElf32(InputFile *f) PackLinuxElf32::PackLinuxElf32(InputFile *f)
: super(f), phdri(NULL), : super(f), phdri(NULL),
file_image(NULL), dynseg(NULL), hashtab(NULL), dynstr(NULL), dynsym(NULL) dynseg(NULL), hashtab(NULL), dynsym(NULL)
{ {
} }
@ -264,6 +256,9 @@ void PackLinuxElf64::updateLoader(OutputFile *fo)
PackLinuxElf32ppc::PackLinuxElf32ppc(InputFile *f) PackLinuxElf32ppc::PackLinuxElf32ppc(InputFile *f)
: super(f) : super(f)
{ {
e_machine = Elf32_Ehdr::EM_PPC;
ei_class = Elf32_Ehdr::ELFCLASS32;
ei_data = Elf32_Ehdr::ELFDATA2MSB;
} }
PackLinuxElf32ppc::~PackLinuxElf32ppc() PackLinuxElf32ppc::~PackLinuxElf32ppc()
@ -273,6 +268,9 @@ PackLinuxElf32ppc::~PackLinuxElf32ppc()
PackLinuxElf64amd::PackLinuxElf64amd(InputFile *f) PackLinuxElf64amd::PackLinuxElf64amd(InputFile *f)
: super(f) : super(f)
{ {
e_machine = Elf64_Ehdr::EM_X86_64;
ei_class = Elf64_Ehdr::ELFCLASS64;
ei_data = Elf64_Ehdr::ELFDATA2LSB;
} }
PackLinuxElf64amd::~PackLinuxElf64amd() PackLinuxElf64amd::~PackLinuxElf64amd()
@ -590,6 +588,7 @@ static void
ehdr_bele(Elf_BE32_Ehdr *const ehdr_be, Elf_LE32_Ehdr const *const ehdr_le) ehdr_bele(Elf_BE32_Ehdr *const ehdr_be, Elf_LE32_Ehdr const *const ehdr_le)
{ {
memcpy(&ehdr_be->e_ident, &ehdr_le->e_ident, sizeof(ehdr_be->e_ident)); memcpy(&ehdr_be->e_ident, &ehdr_le->e_ident, sizeof(ehdr_be->e_ident));
ehdr_be->e_ident[Elf32_Ehdr::EI_DATA] = Elf32_Ehdr::ELFDATA2MSB;
ehdr_be->e_type = ehdr_le->e_type; ehdr_be->e_type = ehdr_le->e_type;
ehdr_be->e_machine = ehdr_le->e_machine; ehdr_be->e_machine = ehdr_le->e_machine;
ehdr_be->e_version = ehdr_le->e_version; ehdr_be->e_version = ehdr_le->e_version;
@ -614,7 +613,7 @@ PackLinuxElf32armBe::buildLoader(const Filter *ft) // FIXME
MemBuffer brev_fold (sz_fold); MemBuffer brev_fold (sz_fold);
brev(brev_loader, linux_elf32arm_loader, sz_loader); brev(brev_loader, linux_elf32arm_loader, sz_loader);
brev(brev_fold, linux_elf32arm_fold, sz_fold); brev(brev_fold, linux_elf32arm_fold, sz_fold);
ehdr_bele((Elf_BE32_Ehdr *)&brev_fold, (Elf_LE32_Ehdr const *)linux_elf32arm_fold); ehdr_bele((Elf_BE32_Ehdr *)brev_fold.getVoidPtr(), (Elf_LE32_Ehdr const *)linux_elf32arm_fold);
return buildLinuxLoader(brev_loader, sz_loader, brev_fold, sz_fold, ft); return buildLinuxLoader(brev_loader, sz_loader, brev_fold, sz_fold, ft);
} }
@ -657,8 +656,7 @@ PackLinuxElf32ppc::canPack()
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;
// now check the ELF header // now check the ELF header
if (checkEhdr(ehdr, Elf32_Ehdr::EM_PPC, if (checkEhdr(ehdr) != 0)
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2MSB) != 0)
return false; return false;
// additional requirements for linux/elf386 // additional requirements for linux/elf386
@ -719,8 +717,7 @@ PackLinuxElf64amd::canPack()
Elf64_Ehdr const *const ehdr = (Elf64_Ehdr const *)buf; Elf64_Ehdr const *const ehdr = (Elf64_Ehdr const *)buf;
// now check the ELF header // now check the ELF header
if (checkEhdr(ehdr, Elf64_Ehdr::EM_X86_64, if (checkEhdr(ehdr) != 0)
Elf64_Ehdr::ELFCLASS64, Elf64_Ehdr::ELFDATA2LSB) != 0)
return false; return false;
// additional requirements for linux/elf386 // additional requirements for linux/elf386
@ -943,7 +940,7 @@ void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft) // FIXME
cprElfHdr3 h3; cprElfHdr3 h3;
ehdr_bele((Elf_BE32_Ehdr *)&h3.ehdr, (Elf_LE32_Ehdr const *)linux_elf32arm_fold); ehdr_bele((Elf_BE32_Ehdr *)&h3.ehdr, (Elf_LE32_Ehdr const *)linux_elf32arm_fold);
brev((unsigned char *)&h3.phdr[0], brev((unsigned char *)&h3.phdr[0],
(unsigned char const *)(sizeof(Elf32_Ehdr) + &linux_elf32arm_fold), (unsigned char const *)(sizeof(Elf32_Ehdr) + (char const *)&linux_elf32arm_fold),
3*sizeof(Elf32_Phdr) ); 3*sizeof(Elf32_Phdr) );
generateElfHdr(fo, &h3, getbrk(phdri, ehdri.e_phnum) ); generateElfHdr(fo, &h3, getbrk(phdri, ehdri.e_phnum) );
@ -1369,14 +1366,14 @@ void PackLinuxElf32armBe::pack3(OutputFile *fo, Filter &ft)
adrc = PAGE_MASK & (~PAGE_MASK + adrc); // round up to page boundary adrc = PAGE_MASK & (~PAGE_MASK + adrc); // round up to page boundary
// patch in order of descending address // patch in order of descending address
patch_be32(p,lsize,"ADRX", adrx); // compressed input for eXpansion patch_be32(p,lsize,"XRDA", adrx); // compressed input for eXpansion
patch_be32(p,lsize,"LENX", len0 - hlen); patch_be32(p,lsize,"XNEL", len0 - hlen);
patch_be32(p,lsize,"CNTC", cntc); // count for copy patch_be32(p,lsize,"CTNC", cntc); // count for copy
patch_be32(p,lsize,"ADRC", adrc); // addr for copy patch_be32(p,lsize,"CRDA", adrc); // addr for copy
patch_be32(p,lsize,"LENM", lenm); // len for map patch_be32(p,lsize,"MNEL", lenm); // len for map
patch_be32(p,lsize,"ADRM", adrm); // addr for map patch_be32(p,lsize,"MRDA", adrm); // addr for map
#undef PAGE_SIZE #undef PAGE_SIZE
#undef PAGE_MASK #undef PAGE_MASK
@ -1671,6 +1668,9 @@ void PackLinuxElf64::unpack(OutputFile *fo)
PackLinuxElf32x86::PackLinuxElf32x86(InputFile *f) : super(f) PackLinuxElf32x86::PackLinuxElf32x86(InputFile *f) : super(f)
{ {
e_machine = Elf32_Ehdr::EM_386;
ei_class = Elf32_Ehdr::ELFCLASS32;
ei_data = Elf32_Ehdr::ELFDATA2LSB;
} }
PackLinuxElf32x86::~PackLinuxElf32x86() PackLinuxElf32x86::~PackLinuxElf32x86()
@ -1712,8 +1712,7 @@ bool PackLinuxElf32x86::canPack()
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;
// now check the ELF header // now check the ELF header
if (checkEhdr(ehdr, Elf32_Ehdr::EM_386, if (checkEhdr(ehdr) != 0)
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2LSB) != 0)
return false; return false;
// additional requirements for linux/elf386 // additional requirements for linux/elf386
@ -1810,6 +1809,9 @@ bool PackLinuxElf32x86::canPack()
PackLinuxElf32armLe::PackLinuxElf32armLe(InputFile *f) : super(f) PackLinuxElf32armLe::PackLinuxElf32armLe(InputFile *f) : super(f)
{ {
e_machine = Elf32_Ehdr::EM_ARM;
ei_class = Elf32_Ehdr::ELFCLASS32;
ei_data = Elf32_Ehdr::ELFDATA2LSB;
} }
PackLinuxElf32armLe::~PackLinuxElf32armLe() PackLinuxElf32armLe::~PackLinuxElf32armLe()
@ -1818,6 +1820,9 @@ PackLinuxElf32armLe::~PackLinuxElf32armLe()
PackLinuxElf32armBe::PackLinuxElf32armBe(InputFile *f) : super(f) PackLinuxElf32armBe::PackLinuxElf32armBe(InputFile *f) : super(f)
{ {
e_machine = Elf32_Ehdr::EM_ARM;
ei_class = Elf32_Ehdr::ELFCLASS32;
ei_data = Elf32_Ehdr::ELFDATA2MSB;
} }
PackLinuxElf32armBe::~PackLinuxElf32armBe() PackLinuxElf32armBe::~PackLinuxElf32armBe()
@ -1850,8 +1855,7 @@ bool PackLinuxElf32armLe::canPack()
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;
// now check the ELF header // now check the ELF header
if (checkEhdr(ehdr, Elf32_Ehdr::EM_ARM, if (checkEhdr(ehdr) != 0)
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2LSB) != 0)
return false; return false;
// additional requirements for linux/elfarm // additional requirements for linux/elfarm
@ -1959,8 +1963,7 @@ bool PackLinuxElf32armBe::canPack()
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;
// now check the ELF header // now check the ELF header
if (checkEhdr(ehdr, Elf32_Ehdr::EM_ARM, if (checkEhdr(ehdr) != 0)
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2MSB) != 0)
return false; return false;
// additional requirements for linux/elfarm // additional requirements for linux/elfarm
@ -2075,8 +2078,8 @@ PackLinuxElf32::elf_find_dynamic(unsigned int const key) const
{ {
Elf32_Dyn const *dynp= dynseg; Elf32_Dyn const *dynp= dynseg;
if (dynp) if (dynp)
for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (dynp->d_tag == key) { for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_native32(&dynp->d_tag)==key) {
unsigned const t= elf_get_offset_from_address(dynp->d_val); unsigned const t= elf_get_offset_from_address(get_native32(&dynp->d_val));
if (t) { if (t) {
return t + file_image; return t + file_image;
} }
@ -2102,12 +2105,12 @@ unsigned PackLinuxElf32::elf_hash(char const *p)
Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
{ {
if (hashtab && dynsym && dynstr) { if (hashtab && dynsym && dynstr) {
unsigned const nbucket = hashtab[0]; unsigned const nbucket = get_native32(&hashtab[0]);
unsigned const *const buckets = &hashtab[2]; unsigned const *const buckets = &hashtab[2];
unsigned const *const chains = &buckets[nbucket]; unsigned const *const chains = &buckets[nbucket];
unsigned const m = elf_hash(name) % nbucket; unsigned const m = elf_hash(name) % nbucket;
unsigned si; unsigned si;
for (si= buckets[m]; 0!=si; si= chains[si]) { for (si= get_native32(&buckets[m]); 0!=si; si= get_native32(&chains[si])) {
char const *const p= dynsym[si].st_name + dynstr; char const *const p= dynsym[si].st_name + dynstr;
if (0==strcmp(name, p)) { if (0==strcmp(name, p)) {
return &dynsym[si]; return &dynsym[si];

View File

@ -62,8 +62,15 @@ protected:
virtual void unpack(OutputFile *fo) = 0; virtual void unpack(OutputFile *fo) = 0;
protected: protected:
char *file_image; // if ET_DYN investigation
char const *dynstr; // from DT_STRTAB
unsigned sz_phdrs; // sizeof Phdr[] unsigned sz_phdrs; // sizeof Phdr[]
unsigned sz_elf_hdrs; // all Elf headers unsigned sz_elf_hdrs; // all Elf headers
unsigned short e_machine;
unsigned char ei_class;
unsigned char ei_data;
}; };
class PackLinuxElf32 : public PackLinuxElf class PackLinuxElf32 : public PackLinuxElf
@ -73,11 +80,7 @@ public:
PackLinuxElf32(InputFile *f); PackLinuxElf32(InputFile *f);
virtual ~PackLinuxElf32(); virtual ~PackLinuxElf32();
protected: protected:
virtual int checkEhdr( virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
Elf32_Ehdr const *ehdr,
unsigned char e_machine,
unsigned char ei_class,
unsigned char ei_data) const;
virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual void pack2(OutputFile *, Filter &); // append compressed data virtual void pack2(OutputFile *, Filter &); // append compressed data
@ -112,12 +115,9 @@ protected:
protected: protected:
Elf32_Ehdr ehdri; // from input file Elf32_Ehdr ehdri; // from input file
Elf32_Phdr *phdri; // for input file Elf32_Phdr *phdri; // for input file
unsigned sz_phdrs; // sizeof Phdr[]
char *file_image; // if ET_DYN investigation
Elf32_Dyn const *dynseg; // from PT_DYNAMIC Elf32_Dyn const *dynseg; // from PT_DYNAMIC
unsigned int const *hashtab; // from DT_HASH unsigned int const *hashtab; // from DT_HASH
char const *dynstr; // from DT_STRTAB
Elf32_Sym const *dynsym; // from DT_SYMTAB Elf32_Sym const *dynsym; // from DT_SYMTAB
struct cprElfHdr1 { struct cprElfHdr1 {
@ -154,11 +154,7 @@ public:
/*virtual int buildLoader(const Filter *);*/ /*virtual int buildLoader(const Filter *);*/
protected: protected:
virtual int checkEhdr( virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
Elf64_Ehdr const *ehdr,
unsigned char e_machine,
unsigned char ei_class,
unsigned char ei_data) const;
virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual void pack2(OutputFile *, Filter &); // append compressed data virtual void pack2(OutputFile *, Filter &); // append compressed data