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

make "upx -d" decompression backward compatible to 8-byte b_info

p_lx_elf.h p_lx_elf.cpp p_unix.cpp

committer: jreiser <jreiser> 981752402 +0000
This commit is contained in:
John Reiser 2001-02-09 21:00:02 +00:00
parent 2ff824e631
commit a63b02ab69
3 changed files with 36 additions and 14 deletions

View File

@ -315,12 +315,12 @@ void PackLinuxI386elf::pack2(OutputFile *fo, Filter &ft)
void PackLinuxI386elf::unpackExtent(unsigned wanted, OutputFile *fo,
unsigned &total_in, unsigned &total_out,
unsigned &c_adler, unsigned &u_adler,
bool first_PF_X
bool first_PF_X, unsigned szb_info
)
{
b_info hdr; memset(&hdr, 0, sizeof(hdr));
while (wanted) {
b_info hdr;
fi->readx(&hdr, sizeof(hdr));
fi->readx(&hdr, szb_info);
int const sz_unc = ph.u_len = get_native32(&hdr.sz_unc);
int const sz_cpr = ph.c_len = get_native32(&hdr.sz_cpr);
ph.filter_cto = hdr.b_cto8;
@ -372,6 +372,16 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
Elf_LE32_Ehdr *const ehdr = (Elf_LE32_Ehdr *)bufehdr;
Elf_LE32_Phdr const *phdr = (Elf_LE32_Phdr *)(1+ehdr);
unsigned szb_info = sizeof(b_info);
{
fi->seek(0, SEEK_SET);
fi->readx(bufehdr, MAX_ELF_HDR);
unsigned const e_entry = get_native32(&ehdr->e_entry);
if (e_entry < 0x401180) { /* old style, 8-byte b_info */
szb_info = 2*sizeof(unsigned);
}
}
fi->seek(overlay_offset, SEEK_SET);
p_info hbuf;
fi->readx(&hbuf, sizeof(hbuf));
@ -381,8 +391,8 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
throwCantUnpack("file header corrupted");
ibuf.alloc(blocksize + OVERHEAD);
b_info bhdr;
fi->readx(&bhdr, sizeof(bhdr));
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
fi->readx(&bhdr, szb_info);
ph.u_len = get_native32(&bhdr.sz_unc);
ph.c_len = get_native32(&bhdr.sz_cpr);
ph.filter_cto = bhdr.b_cto8;
@ -399,7 +409,7 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
// decompress PT_LOAD
bool first_PF_X = true;
fi->seek(- (off_t) (sizeof(bhdr) + ph.c_len), SEEK_CUR);
fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
for (unsigned j=0; j < ehdr->e_phnum; ++phdr, ++j) {
if (PT_LOAD==phdr->p_type) {
if (0==ptload0hi) {
@ -412,12 +422,12 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
fo->seek(phdr->p_offset, SEEK_SET);
if (Elf_LE32_Phdr::PF_X & phdr->p_flags) {
unpackExtent(phdr->p_filesz, fo, total_in, total_out,
c_adler, u_adler, first_PF_X);
c_adler, u_adler, first_PF_X, szb_info);
first_PF_X = false;
}
else {
unpackExtent(phdr->p_filesz, fo, total_in, total_out,
c_adler, u_adler, false);
c_adler, u_adler, false, szb_info);
}
}
}
@ -426,17 +436,17 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
if (fo)
fo->seek(ptload0hi, SEEK_SET);
unpackExtent(ptload1lo - ptload0hi, fo, total_in, total_out,
c_adler, u_adler, false);
c_adler, u_adler, false, szb_info);
}
if (total_out != orig_file_size) { // non-PT_LOAD stuff
if (fo)
fo->seek(0, SEEK_END);
unpackExtent(orig_file_size - total_out, fo, total_in, total_out,
c_adler, u_adler, false);
c_adler, u_adler, false, szb_info);
}
// check for end-of-file
fi->readx(&bhdr, sizeof(bhdr));
fi->readx(&bhdr, szb_info);
unsigned const sz_unc = ph.u_len = get_native32(&bhdr.sz_unc);
if (sz_unc == 0) { // uncompressed size 0 -> EOF

View File

@ -62,7 +62,8 @@ protected:
unsigned &total_in, unsigned &total_out, Filter *, OutputFile *);
virtual void unpackExtent(unsigned wanted, OutputFile *fo,
unsigned &total_in, unsigned &total_out,
unsigned &c_adler, unsigned &u_adler, bool first_PF_X);
unsigned &c_adler, unsigned &u_adler,
bool first_PF_X, unsigned szb_info );
protected:
virtual void pack1(OutputFile *, Filter &); // generate executable header

View File

@ -303,6 +303,17 @@ int PackUnix::canUnpack()
void PackUnix::unpack(OutputFile *fo)
{
unsigned szb_info = sizeof(b_info);
{
Elf_LE32_Ehdr ehdr;
fi->seek(0, SEEK_SET);
fi->readx(&ehdr, sizeof(ehdr));
unsigned const e_entry = get_native32(&ehdr.e_entry);
if (e_entry < 0x401180) { /* old style, 8-byte b_info */
szb_info = 2*sizeof(unsigned);
}
}
unsigned c_adler = upx_adler32(0, NULL, 0);
unsigned u_adler = upx_adler32(0, NULL, 0);
@ -332,14 +343,14 @@ void PackUnix::unpack(OutputFile *fo)
// decompress blocks
unsigned total_in = 0;
unsigned total_out = 0;
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
for (;;)
{
#define buf ibuf
int i;
b_info bhdr;
unsigned sz_unc, sz_cpr;
fi->readx(&bhdr, sizeof(bhdr));
fi->readx(&bhdr, szb_info);
ph.u_len = sz_unc = get_native32(&bhdr.sz_unc);
ph.c_len = sz_cpr = get_native32(&bhdr.sz_cpr);