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:
parent
2ff824e631
commit
a63b02ab69
|
@ -315,12 +315,12 @@ void PackLinuxI386elf::pack2(OutputFile *fo, Filter &ft)
|
||||||
void PackLinuxI386elf::unpackExtent(unsigned wanted, OutputFile *fo,
|
void PackLinuxI386elf::unpackExtent(unsigned wanted, OutputFile *fo,
|
||||||
unsigned &total_in, unsigned &total_out,
|
unsigned &total_in, unsigned &total_out,
|
||||||
unsigned &c_adler, unsigned &u_adler,
|
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) {
|
while (wanted) {
|
||||||
b_info hdr;
|
fi->readx(&hdr, szb_info);
|
||||||
fi->readx(&hdr, sizeof(hdr));
|
|
||||||
int const sz_unc = ph.u_len = get_native32(&hdr.sz_unc);
|
int const sz_unc = ph.u_len = get_native32(&hdr.sz_unc);
|
||||||
int const sz_cpr = ph.c_len = get_native32(&hdr.sz_cpr);
|
int const sz_cpr = ph.c_len = get_native32(&hdr.sz_cpr);
|
||||||
ph.filter_cto = hdr.b_cto8;
|
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_Ehdr *const ehdr = (Elf_LE32_Ehdr *)bufehdr;
|
||||||
Elf_LE32_Phdr const *phdr = (Elf_LE32_Phdr *)(1+ehdr);
|
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);
|
fi->seek(overlay_offset, SEEK_SET);
|
||||||
p_info hbuf;
|
p_info hbuf;
|
||||||
fi->readx(&hbuf, sizeof(hbuf));
|
fi->readx(&hbuf, sizeof(hbuf));
|
||||||
|
@ -381,8 +391,8 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
|
||||||
throwCantUnpack("file header corrupted");
|
throwCantUnpack("file header corrupted");
|
||||||
|
|
||||||
ibuf.alloc(blocksize + OVERHEAD);
|
ibuf.alloc(blocksize + OVERHEAD);
|
||||||
b_info bhdr;
|
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||||
fi->readx(&bhdr, sizeof(bhdr));
|
fi->readx(&bhdr, szb_info);
|
||||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
ph.u_len = get_native32(&bhdr.sz_unc);
|
||||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
ph.c_len = get_native32(&bhdr.sz_cpr);
|
||||||
ph.filter_cto = bhdr.b_cto8;
|
ph.filter_cto = bhdr.b_cto8;
|
||||||
|
@ -399,7 +409,7 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
|
||||||
|
|
||||||
// decompress PT_LOAD
|
// decompress PT_LOAD
|
||||||
bool first_PF_X = true;
|
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) {
|
for (unsigned j=0; j < ehdr->e_phnum; ++phdr, ++j) {
|
||||||
if (PT_LOAD==phdr->p_type) {
|
if (PT_LOAD==phdr->p_type) {
|
||||||
if (0==ptload0hi) {
|
if (0==ptload0hi) {
|
||||||
|
@ -412,12 +422,12 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
|
||||||
fo->seek(phdr->p_offset, SEEK_SET);
|
fo->seek(phdr->p_offset, SEEK_SET);
|
||||||
if (Elf_LE32_Phdr::PF_X & phdr->p_flags) {
|
if (Elf_LE32_Phdr::PF_X & phdr->p_flags) {
|
||||||
unpackExtent(phdr->p_filesz, fo, total_in, total_out,
|
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;
|
first_PF_X = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unpackExtent(phdr->p_filesz, fo, total_in, total_out,
|
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)
|
if (fo)
|
||||||
fo->seek(ptload0hi, SEEK_SET);
|
fo->seek(ptload0hi, SEEK_SET);
|
||||||
unpackExtent(ptload1lo - ptload0hi, fo, total_in, total_out,
|
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 (total_out != orig_file_size) { // non-PT_LOAD stuff
|
||||||
if (fo)
|
if (fo)
|
||||||
fo->seek(0, SEEK_END);
|
fo->seek(0, SEEK_END);
|
||||||
unpackExtent(orig_file_size - total_out, fo, total_in, total_out,
|
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
|
// 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);
|
unsigned const sz_unc = ph.u_len = get_native32(&bhdr.sz_unc);
|
||||||
|
|
||||||
if (sz_unc == 0) { // uncompressed size 0 -> EOF
|
if (sz_unc == 0) { // uncompressed size 0 -> EOF
|
||||||
|
|
|
@ -62,7 +62,8 @@ protected:
|
||||||
unsigned &total_in, unsigned &total_out, Filter *, OutputFile *);
|
unsigned &total_in, unsigned &total_out, Filter *, OutputFile *);
|
||||||
virtual void unpackExtent(unsigned wanted, OutputFile *fo,
|
virtual void unpackExtent(unsigned wanted, OutputFile *fo,
|
||||||
unsigned &total_in, unsigned &total_out,
|
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:
|
protected:
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
|
|
@ -303,6 +303,17 @@ int PackUnix::canUnpack()
|
||||||
|
|
||||||
void PackUnix::unpack(OutputFile *fo)
|
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 c_adler = upx_adler32(0, NULL, 0);
|
||||||
unsigned u_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
|
// decompress blocks
|
||||||
unsigned total_in = 0;
|
unsigned total_in = 0;
|
||||||
unsigned total_out = 0;
|
unsigned total_out = 0;
|
||||||
|
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
#define buf ibuf
|
#define buf ibuf
|
||||||
int i;
|
int i;
|
||||||
b_info bhdr;
|
|
||||||
unsigned sz_unc, sz_cpr;
|
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.u_len = sz_unc = get_native32(&bhdr.sz_unc);
|
||||||
ph.c_len = sz_cpr = get_native32(&bhdr.sz_cpr);
|
ph.c_len = sz_cpr = get_native32(&bhdr.sz_cpr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user