diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 7efedebc..eb0b4b3f 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -402,14 +402,14 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft) set_te32(&elfout.phdr[C_TEXT].p_filesz, v_hole); set_te32(&elfout.phdr[C_TEXT].p_memsz, v_hole); // Then compressed gaps (including debuginfo.) - unsigned total_in = 0, total_out = 0; + total_in = 0; total_out = 0; for (unsigned k = 0; k < e_phnum; ++k) { Extent x; x.size = find_LOAD_gap(phdri, k, e_phnum); if (x.size) { x.offset = get_te32(&phdri[k].p_offset) + get_te32(&phdri[k].p_filesz); - packExtent(x, total_in, total_out, nullptr, fo); + packExtent(x, nullptr, fo); } } // write block end marker (uncompressed size 0) @@ -526,14 +526,14 @@ off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft) set_te64(&elfout.phdr[C_TEXT].p_filesz, v_hole); set_te64(&elfout.phdr[C_TEXT].p_memsz, v_hole); // Then compressed gaps (including debuginfo.) - unsigned total_in = 0, total_out = 0; + total_in = 0; total_out = 0; for (unsigned k = 0; k < e_phnum; ++k) { Extent x; x.size = find_LOAD_gap(phdri, k, e_phnum); if (x.size) { x.offset = get_te64(&phdri[k].p_offset) + get_te64(&phdri[k].p_filesz); - packExtent(x, total_in, total_out, nullptr, fo); + packExtent(x, nullptr, fo); } } // write block end marker (uncompressed size 0) @@ -4045,8 +4045,8 @@ int PackLinuxElf32::pack2(OutputFile *fo, Filter &ft) // compress extents unsigned hdr_u_len = (is_shlib ? xct_off : (sizeof(Elf32_Ehdr) + sz_phdrs)); - unsigned total_in = (is_shlib ? 0 : xct_off); - unsigned total_out = (is_shlib ? sz_elf_hdrs : xct_off); + total_in = (is_shlib ? 0 : xct_off); + total_out = (is_shlib ? sz_elf_hdrs : xct_off); uip->ui_pass = 0; ft.addvalue = 0; @@ -4089,7 +4089,7 @@ int PackLinuxElf32::pack2(OutputFile *fo, Filter &ft) // throw NotCompressible for small .data Extents, which PowerPC // sometimes marks as PF_X anyway. So filter only first segment. if (k == nk_f || !is_shlib) { - packExtent(x, total_in, total_out, + packExtent(x, (k==nk_f ? &ft : nullptr ), fo, hdr_u_len); } else { @@ -4176,8 +4176,8 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft) // compress extents unsigned hdr_u_len = (is_shlib ? xct_off : (sizeof(Elf64_Ehdr) + sz_phdrs)); - unsigned total_in = (is_shlib ? 0 : xct_off); - unsigned total_out = (is_shlib ? sz_elf_hdrs : xct_off); + total_in = (is_shlib ? 0 : xct_off); + total_out = (is_shlib ? sz_elf_hdrs : xct_off); uip->ui_pass = 0; ft.addvalue = 0; @@ -4220,7 +4220,7 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft) // throw NotCompressible for small .data Extents, which PowerPC // sometimes marks as PF_X anyway. So filter only first segment. if (k == nk_f || !is_shlib) { - packExtent(x, total_in, total_out, + packExtent(x, (k==nk_f ? &ft : nullptr ), fo, hdr_u_len); } else { @@ -4573,8 +4573,8 @@ void PackLinuxElf64::unpack(OutputFile *fo) throwCantUnpack("bad e_phoff"); } unsigned const c_phnum = get_te16(&ehdri.e_phnum); - upx_uint64_t old_data_off = 0; - upx_uint64_t old_data_len = 0; + old_data_off = 0; + old_data_len = 0; upx_uint64_t old_dtinit = 0; unsigned is_asl = 0; // is Android Shared Library @@ -4633,8 +4633,8 @@ void PackLinuxElf64::unpack(OutputFile *fo) fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR); unsigned const u_phnum = get_te16(&ehdr->e_phnum); - unsigned total_in = 0; - unsigned total_out = 0; + total_in = 0; + total_out = 0; unsigned c_adler = upx_adler32(nullptr, 0); unsigned u_adler = upx_adler32(nullptr, 0); #define MAX_ELF_HDR 1024 @@ -4650,7 +4650,7 @@ void PackLinuxElf64::unpack(OutputFile *fo) if (is_shlib) { // Unpack and output the Ehdr and Phdrs for real. // This depends on position within input file fi. - unpackExtent(ph.u_len, fo, total_in, total_out, + unpackExtent(ph.u_len, fo, c_adler, u_adler, false, szb_info); // The first PT_LOAD. Part is not compressed (for benefit of rtld.) @@ -4730,7 +4730,7 @@ void PackLinuxElf64::unpack(OutputFile *fo) break; } } - unpackExtent(ph.u_len, fo, total_in, total_out, + unpackExtent(ph.u_len, fo, c_adler, u_adler, false, szb_info); } else { // main executable @@ -4744,12 +4744,12 @@ void PackLinuxElf64::unpack(OutputFile *fo) if (fo) fo->seek(offset, SEEK_SET); if (Elf64_Phdr::PF_X & get_te32(&phdr->p_flags)) { - unpackExtent(filesz, fo, total_in, total_out, + unpackExtent(filesz, fo, c_adler, u_adler, first_PF_X, szb_info); first_PF_X = false; } else { - unpackExtent(filesz, fo, total_in, total_out, + unpackExtent(filesz, fo, c_adler, u_adler, false, szb_info); } } @@ -4798,7 +4798,7 @@ void PackLinuxElf64::unpack(OutputFile *fo) get_te64(&phdr[j].p_filesz); if (fo) fo->seek(where, SEEK_SET); - unpackExtent(size, fo, total_in, total_out, + unpackExtent(size, fo, c_adler, u_adler, false, szb_info, (phdr[j].p_offset != hi_offset)); } @@ -5666,8 +5666,8 @@ void PackLinuxElf32::unpack(OutputFile *fo) throwCantUnpack("bad e_phoff"); } unsigned const c_phnum = get_te16(&ehdri.e_phnum); - unsigned old_data_off = 0; - unsigned old_data_len = 0; + old_data_off = 0; + old_data_len = 0; unsigned old_dtinit = 0; unsigned is_asl = 0; // is Android Shared Library @@ -5727,8 +5727,8 @@ void PackLinuxElf32::unpack(OutputFile *fo) fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR); unsigned const u_phnum = get_te16(&ehdr->e_phnum); - unsigned total_in = 0; - unsigned total_out = 0; + total_in = 0; + total_out = 0; unsigned c_adler = upx_adler32(nullptr, 0); unsigned u_adler = upx_adler32(nullptr, 0); #define MAX_ELF_HDR 512 @@ -5744,7 +5744,7 @@ void PackLinuxElf32::unpack(OutputFile *fo) if (is_shlib) { // Unpack and output the Ehdr and Phdrs for real. // This depends on position within input file fi. - unpackExtent(ph.u_len, fo, total_in, total_out, + unpackExtent(ph.u_len, fo, c_adler, u_adler, false, szb_info); // The first PT_LOAD. Part is not compressed (for benefit of rtld.) @@ -5824,7 +5824,7 @@ void PackLinuxElf32::unpack(OutputFile *fo) break; } } - unpackExtent(ph.u_len, fo, total_in, total_out, + unpackExtent(ph.u_len, fo, c_adler, u_adler, false, szb_info); } else { // main executable @@ -5838,12 +5838,12 @@ void PackLinuxElf32::unpack(OutputFile *fo) if (fo) fo->seek(offset, SEEK_SET); if (Elf32_Phdr::PF_X & get_te32(&phdr->p_flags)) { - unpackExtent(filesz, fo, total_in, total_out, + unpackExtent(filesz, fo, c_adler, u_adler, first_PF_X, szb_info); first_PF_X = false; } else { - unpackExtent(filesz, fo, total_in, total_out, + unpackExtent(filesz, fo, c_adler, u_adler, false, szb_info); } } @@ -5892,7 +5892,7 @@ void PackLinuxElf32::unpack(OutputFile *fo) get_te32(&phdr[j].p_filesz); if (fo) fo->seek(where, SEEK_SET); - unpackExtent(size, fo, total_in, total_out, + unpackExtent(size, fo, c_adler, u_adler, false, szb_info, (phdr[j].p_offset != hi_offset)); } diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index e6a328ed..bcae8226 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -62,6 +62,7 @@ protected: virtual void defineSymbols(Filter const *); virtual void addStubEntrySections(Filter const *); virtual void unpack(OutputFile *fo); + unsigned old_data_off, old_data_len; // un_shlib virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const = 0; static unsigned elf_hash(char const *) /*const*/; @@ -268,6 +269,22 @@ protected: virtual off_t pack3(OutputFile *, Filter &); // append loader virtual void pack4(OutputFile *, Filter &); // append pack header virtual void unpack(OutputFile *fo); + virtual void un_shlib_1( + OutputFile *const fo, + unsigned &c_adler, + unsigned &u_adler, + Elf64_Ehdr const *ehdr, + Elf64_Phdr const *const dynhdr, + unsigned const orig_file_size, + unsigned const szb_info + ); + virtual void un_DT_INIT( + Elf64_Phdr const *phdr, + unsigned u_phnum, + unsigned old_dtinit, + OutputFile *fo, + unsigned is_asl + ); virtual void unRela64(upx_uint64_t dt_rela, Elf64_Rela *rela0, unsigned relasz, MemBuffer &membuf, upx_uint64_t const load_off, upx_uint64_t const old_dtinit, OutputFile *fo); diff --git a/src/p_lx_interp.cpp b/src/p_lx_interp.cpp index c8cad2fe..2cb7a02f 100644 --- a/src/p_lx_interp.cpp +++ b/src/p_lx_interp.cpp @@ -234,8 +234,8 @@ void PackLinuxElf32x86interp::unpack(OutputFile *fo) fi->readx(ibuf, ph.c_len); decompress(ibuf, (upx_byte *)ehdr, false); - unsigned total_in = 0; - unsigned total_out = 0; + total_in = 0; + total_out = 0; unsigned c_adler = upx_adler32(nullptr, 0); unsigned u_adler = upx_adler32(nullptr, 0); off_t ptload0hi=0, ptload1lo=0, ptload1sz=0; @@ -255,12 +255,12 @@ void PackLinuxElf32x86interp::unpack(OutputFile *fo) if (fo) fo->seek(phdr->p_offset, SEEK_SET); if (Elf32_Phdr::PF_X & phdr->p_flags) { - unpackExtent(phdr->p_filesz, fo, total_in, total_out, + unpackExtent(phdr->p_filesz, fo, c_adler, u_adler, first_PF_X, szb_info); first_PF_X = false; } else { - unpackExtent(phdr->p_filesz, fo, total_in, total_out, + unpackExtent(phdr->p_filesz, fo, c_adler, u_adler, false, szb_info); } } @@ -269,13 +269,13 @@ void PackLinuxElf32x86interp::unpack(OutputFile *fo) if (0!=ptload1sz && ptload0hi < ptload1lo) { // alignment hole? if (fo) fo->seek(ptload0hi, SEEK_SET); - unpackExtent(ptload1lo - ptload0hi, fo, total_in, total_out, + unpackExtent(ptload1lo - ptload0hi, fo, 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, + unpackExtent(orig_file_size - total_out, fo, c_adler, u_adler, false, szb_info); } diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 36024fea..d37c81d9 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -1055,8 +1055,8 @@ int PackMachBase::pack2(OutputFile *fo, Filter &ft) // append compressed bo } // compress extents - unsigned total_in = 0; - unsigned total_out = 0; + total_in = 0; + total_out = 0; unsigned hdr_u_len = mhdri.sizeofcmds + sizeof(mhdri); @@ -1098,7 +1098,7 @@ int PackMachBase::pack2(OutputFile *fo, Filter &ft) // append compressed bo } ptr = (Mach_segment_command const *)(ptr->cmdsize + (char const *)ptr); } - packExtent(x, total_in, total_out, + packExtent(x, (do_filter ? &ft : nullptr), fo, hdr_u_len, b_extra ); if (do_filter) { exe_filesize_max = 0; @@ -1114,7 +1114,7 @@ int PackMachBase::pack2(OutputFile *fo, Filter &ft) // append compressed bo x.size = find_SEGMENT_gap(k, fi->st_size()); if (x.size) { x.offset = msegcmd[k].fileoff +msegcmd[k].filesize; - packExtent(x, total_in, total_out, nullptr, fo); + packExtent(x, nullptr, fo); } } @@ -1454,8 +1454,8 @@ void PackMachBase::unpack(OutputFile *fo) n_segment += (lc_seg==msegcmd[j].cmd); } - unsigned total_in = 0; - unsigned total_out = 0; + total_in = 0; + total_out = 0; unsigned c_adler = upx_adler32(nullptr, 0); unsigned u_adler = upx_adler32(nullptr, 0); @@ -1467,7 +1467,7 @@ void PackMachBase::unpack(OutputFile *fo) } if (fo) fo->seek(msegcmd[k].fileoff, SEEK_SET); - unpackExtent(msegcmd[k].filesize, fo, total_in, total_out, + unpackExtent(msegcmd[k].filesize, fo, c_adler, u_adler, false, sizeof(bhdr)); if (my_filetype==Mach_header::MH_DYLIB) { break; // only the first lc_seg when MH_DYLIB @@ -1515,7 +1515,7 @@ void PackMachBase::unpack(OutputFile *fo) unsigned const where = msegcmd[j].fileoff +msegcmd[j].filesize; if (fo) fo->seek(where, SEEK_SET); - unpackExtent(size, fo, total_in, total_out, + unpackExtent(size, fo, c_adler, u_adler, false, sizeof(bhdr)); } } diff --git a/src/p_unix.cpp b/src/p_unix.cpp index 9a5b8a6d..79a5e0be 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -137,8 +137,8 @@ int PackUnix::getStrategy(Filter &/*ft*/) int PackUnix::pack2(OutputFile *fo, Filter &ft) { // compress blocks - unsigned total_in = 0; - unsigned total_out = 0; + total_in = 0; + total_out = 0; // FIXME: ui_total_passes is not correct with multiple blocks... // ui_total_passes = (file_size + blocksize - 1) / blocksize; @@ -318,8 +318,6 @@ void PackUnix::pack(OutputFile *fo) void PackUnix::packExtent( const Extent &x, - unsigned &total_in, - unsigned &total_out, Filter *ft, OutputFile *fo, unsigned hdr_u_len, @@ -450,7 +448,6 @@ void PackUnix::packExtent( } void PackUnix::unpackExtent(unsigned wanted, OutputFile *fo, - unsigned &total_in, unsigned &total_out, unsigned &c_adler, unsigned &u_adler, bool first_PF_X, unsigned szb_info, bool is_rewrite ) @@ -602,8 +599,8 @@ void PackUnix::unpack(OutputFile *fo) ibuf.alloc(blocksize + OVERHEAD); // decompress blocks - unsigned total_in = 0; - unsigned total_out = 0; + total_in = 0; + total_out = 0; memset(&bhdr, 0, sizeof(bhdr)); for (;;) { diff --git a/src/p_unix.h b/src/p_unix.h index 5c6329e3..7e0acd74 100644 --- a/src/p_unix.h +++ b/src/p_unix.h @@ -73,12 +73,12 @@ protected: off_t size; }; virtual void packExtent(const Extent &x, - unsigned &total_in, unsigned &total_out, Filter *, OutputFile *, + Filter *, OutputFile *, unsigned hdr_len = 0, unsigned b_extra = 0); virtual void unpackExtent(unsigned wanted, OutputFile *fo, - unsigned &total_in, unsigned &total_out, unsigned &c_adler, unsigned &u_adler, bool first_PF_X, unsigned szb_info, bool is_rewrite = false); + unsigned total_in, total_out; // unpack int exetype; unsigned blocksize;