mirror of
https://github.com/upx/upx.git
synced 2024-12-04 02:42:20 +00:00
WIP: PackLinuxElf64::unpack working for shared libraries (non-Android)
modified: p_lx_elf.cpp modified: p_lx_elf.h modified: p_unix.cpp
This commit is contained in:
parent
c9cb42df40
commit
35555bfb8a
224
src/p_lx_elf.cpp
224
src/p_lx_elf.cpp
@ -4568,6 +4568,7 @@ PackLinuxElf64::unRela64(
|
|||||||
|
|
||||||
void PackLinuxElf64::un_shlib_1(
|
void PackLinuxElf64::un_shlib_1(
|
||||||
OutputFile *const fo,
|
OutputFile *const fo,
|
||||||
|
Elf64_Phdr *const phdro,
|
||||||
unsigned &c_adler,
|
unsigned &c_adler,
|
||||||
unsigned &u_adler,
|
unsigned &u_adler,
|
||||||
Elf64_Phdr const *const dynhdr,
|
Elf64_Phdr const *const dynhdr,
|
||||||
@ -4637,15 +4638,16 @@ void PackLinuxElf64::un_shlib_1(
|
|||||||
c_adler, u_adler, false, szb_info);
|
c_adler, u_adler, false, szb_info);
|
||||||
|
|
||||||
// Copy (slide) the remaining PT_LOAD; they are not compressed
|
// Copy (slide) the remaining PT_LOAD; they are not compressed
|
||||||
Elf64_Phdr *phdr = phdri;
|
Elf64_Phdr *phdr = phdro;
|
||||||
unsigned slide = 0;
|
unsigned slide = 0;
|
||||||
int first = 0;
|
int first = 0;
|
||||||
for (unsigned k = 0; k < e_phnum; ++k, ++phdr) {
|
for (unsigned k = 0; k < e_phnum; ++k, ++phdr) {
|
||||||
if (PT_LOAD64==get_te32(&phdr->p_type)) {
|
unsigned type = get_te32(&phdr->p_type);
|
||||||
unsigned vaddr = get_te64(&phdr->p_vaddr);
|
unsigned vaddr = get_te64(&phdr->p_vaddr);
|
||||||
if (xct_off <= vaddr) {
|
unsigned offset = get_te64(&phdr->p_offset);
|
||||||
unsigned offset = get_te64(&phdr->p_offset);
|
unsigned filesz = get_te64(&phdr->p_filesz);
|
||||||
unsigned filesz = get_te64(&phdr->p_filesz);
|
if (xct_off <= vaddr) {
|
||||||
|
if (PT_LOAD64==type) {
|
||||||
if (0==first++) { // the partially-compressed PT_LOAD
|
if (0==first++) { // the partially-compressed PT_LOAD
|
||||||
set_te64(&phdr->p_filesz, ph.u_len + xct_off - vaddr);
|
set_te64(&phdr->p_filesz, ph.u_len + xct_off - vaddr);
|
||||||
set_te64(&phdr->p_memsz, ph.u_len + xct_off - vaddr);
|
set_te64(&phdr->p_memsz, ph.u_len + xct_off - vaddr);
|
||||||
@ -4653,134 +4655,111 @@ void PackLinuxElf64::un_shlib_1(
|
|||||||
else { // subsequent PT_LOAD
|
else { // subsequent PT_LOAD
|
||||||
fi->seek(offset, SEEK_SET);
|
fi->seek(offset, SEEK_SET);
|
||||||
fi->readx(ibuf, filesz);
|
fi->readx(ibuf, filesz);
|
||||||
|
total_in += filesz;
|
||||||
|
|
||||||
if (0==slide) {
|
if (0==slide) {
|
||||||
slide = vaddr - offset;
|
slide = vaddr - offset;
|
||||||
}
|
}
|
||||||
set_te64(&phdr->p_offset, slide + offset);
|
if (fo) {
|
||||||
fo->seek(slide + offset, SEEK_SET);
|
fo->seek(slide + offset, SEEK_SET);
|
||||||
fo->write(ibuf, filesz);
|
fo->write(ibuf, filesz);
|
||||||
|
total_out = filesz + slide + offset; // high-water mark
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set_te64(&phdr->p_offset, slide + offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fi->seek(xct_off + sizeof(linfo) + sizeof(p_info) + sizeof(b_info) + up4(ph.c_len), SEEK_SET); // loader offset
|
if (fo) { // Rewrite Phdrs after sliding
|
||||||
|
fo->seek(sizeof(Elf64_Ehdr), SEEK_SET);
|
||||||
|
fo->rewrite(phdro, e_phnum * sizeof(Elf64_Phdr));
|
||||||
|
}
|
||||||
|
// loader offset
|
||||||
|
fi->seek(xct_off + sizeof(linfo) + sizeof(p_info) + sizeof(b_info) + up4(ph.c_len), SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxElf64::un_DT_INIT(
|
void PackLinuxElf64::un_DT_INIT(
|
||||||
Elf64_Phdr const *phdr0,
|
|
||||||
unsigned u_phnum,
|
|
||||||
unsigned old_dtinit,
|
unsigned old_dtinit,
|
||||||
|
Elf64_Phdr const *const phdro,
|
||||||
|
Elf64_Phdr const *const dynhdr, // in phdri
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
unsigned is_asl
|
unsigned is_asl
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// DT_INIT must be restored.
|
// DT_INIT must be restored.
|
||||||
// Search the Phdrs of compressed
|
|
||||||
int n_ptload = 0;
|
|
||||||
old_data_off = 0;
|
|
||||||
old_data_len = 0;
|
|
||||||
Elf64_Phdr const *phdr = phdr0;
|
|
||||||
for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
|
|
||||||
if (PT_LOAD64==get_te32(&phdr->p_type) && 0!=n_ptload++) {
|
|
||||||
old_data_off = get_te64(&phdr->p_offset);
|
|
||||||
old_data_len = get_te64(&phdr->p_filesz);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If android_shlib, then the asl_delta relocations must be un-done.
|
// If android_shlib, then the asl_delta relocations must be un-done.
|
||||||
upx_uint64_t load_off = 0;
|
upx_uint64_t dt_pltrelsz(0), dt_jmprel(0);
|
||||||
phdr = phdr0;
|
upx_uint64_t dt_relasz(0), dt_rela(0);
|
||||||
n_ptload = 0;
|
upx_uint64_t const dyn_len = get_te64(&dynhdr->p_filesz);
|
||||||
for (unsigned j= 0; j < u_phnum; ++j, ++phdr) {
|
upx_uint64_t const dyn_off = get_te64(&dynhdr->p_offset);
|
||||||
if (PT_LOAD64==get_te32(&phdr->p_type) && 0!=n_ptload++) {
|
if ((unsigned long)file_size < (dyn_len + dyn_off)) {
|
||||||
load_off = get_te64(&phdr->p_offset);
|
char msg[50]; snprintf(msg, sizeof(msg),
|
||||||
load_va = get_te64(&phdr->p_vaddr);
|
"bad PT_DYNAMIC .p_filesz %#lx", (long unsigned)dyn_len);
|
||||||
fi->seek(old_data_off, SEEK_SET);
|
throwCantUnpack(msg);
|
||||||
fi->readx(ibuf, old_data_len);
|
}
|
||||||
total_in += old_data_len;
|
fi->seek(dyn_off, SEEK_SET);
|
||||||
total_out += old_data_len;
|
fi->readx(ibuf, dyn_len);
|
||||||
|
Elf64_Dyn *dyn = (Elf64_Dyn *)(void *)ibuf;
|
||||||
|
dynseg = dyn; invert_pt_dynamic(dynseg, get_te64(&dynhdr->p_filesz));
|
||||||
|
for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
|
||||||
|
upx_uint64_t const tag = get_te64(&dyn->d_tag);
|
||||||
|
upx_uint64_t val = get_te64(&dyn->d_val);
|
||||||
|
if (is_asl) switch (tag) {
|
||||||
|
case Elf64_Dyn::DT_RELASZ: { dt_relasz = val; } break;
|
||||||
|
case Elf64_Dyn::DT_RELA: { dt_rela = val; } break;
|
||||||
|
case Elf64_Dyn::DT_PLTRELSZ: { dt_pltrelsz = val; } break;
|
||||||
|
case Elf64_Dyn::DT_JMPREL: { dt_jmprel = val; } break;
|
||||||
|
|
||||||
Elf64_Phdr const *udynhdr = phdr0;
|
case Elf64_Dyn::DT_PLTGOT:
|
||||||
for (unsigned j3= 0; j3 < u_phnum; ++j3, ++udynhdr)
|
case Elf64_Dyn::DT_PREINIT_ARRAY:
|
||||||
if (Elf64_Phdr::PT_DYNAMIC==get_te32(&udynhdr->p_type)) {
|
case Elf64_Dyn::DT_INIT_ARRAY:
|
||||||
upx_uint64_t dt_pltrelsz(0), dt_jmprel(0);
|
case Elf64_Dyn::DT_FINI_ARRAY:
|
||||||
upx_uint64_t dt_relasz(0), dt_rela(0);
|
case Elf64_Dyn::DT_FINI: {
|
||||||
upx_uint64_t const dyn_len = get_te64(&udynhdr->p_filesz);
|
set_te64(&dyn->d_val, val - asl_delta);
|
||||||
upx_uint64_t const dyn_off = get_te64(&udynhdr->p_offset);
|
}; break;
|
||||||
if ((unsigned long)file_size < (dyn_len + dyn_off)) {
|
} // end switch() on tag when is_asl
|
||||||
char msg[50]; snprintf(msg, sizeof(msg),
|
if (upx_dt_init == tag) {
|
||||||
"bad PT_DYNAMIC .p_filesz %#lx", (long unsigned)dyn_len);
|
if (Elf64_Dyn::DT_INIT == tag) {
|
||||||
throwCantUnpack(msg);
|
set_te64(&dyn->d_val, old_dtinit);
|
||||||
}
|
if (!old_dtinit) { // compressor took the slot
|
||||||
if (dyn_off < load_off) {
|
dyn->d_tag = Elf64_Dyn::DT_NULL;
|
||||||
continue; // Oops. Not really is_shlib ? [built by 'rust' ?]
|
dyn->d_val = 0;
|
||||||
}
|
}
|
||||||
Elf64_Dyn *dyn = (Elf64_Dyn *)((unsigned char *)ibuf +
|
}
|
||||||
(dyn_off - load_off));
|
else if (Elf64_Dyn::DT_INIT_ARRAY == tag
|
||||||
dynseg = dyn; invert_pt_dynamic(dynseg, get_te64(&udynhdr->p_filesz));
|
|| Elf64_Dyn::DT_PREINIT_ARRAY == tag) {
|
||||||
for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
|
if (val < load_va || (long unsigned)file_size < (long unsigned)val) {
|
||||||
upx_uint64_t const tag = get_te64(&dyn->d_tag);
|
char msg[50]; snprintf(msg, sizeof(msg),
|
||||||
upx_uint64_t val = get_te64(&dyn->d_val);
|
"Bad Dynamic tag %#lx %#lx",
|
||||||
if (is_asl) switch (tag) {
|
(long unsigned)tag, (long unsigned)val);
|
||||||
case Elf64_Dyn::DT_RELASZ: { dt_relasz = val; } break;
|
throwCantUnpack(msg);
|
||||||
case Elf64_Dyn::DT_RELA: { dt_rela = val; } break;
|
}
|
||||||
case Elf64_Dyn::DT_PLTRELSZ: { dt_pltrelsz = val; } break;
|
set_te64(&ibuf[val - load_va], old_dtinit
|
||||||
case Elf64_Dyn::DT_JMPREL: { dt_jmprel = val; } break;
|
+ (is_asl ? asl_delta : 0)); // counter-act unRel64
|
||||||
|
}
|
||||||
case Elf64_Dyn::DT_PLTGOT:
|
}
|
||||||
case Elf64_Dyn::DT_PREINIT_ARRAY:
|
}
|
||||||
case Elf64_Dyn::DT_INIT_ARRAY:
|
if (fo) { // Write updated dt_*.val
|
||||||
case Elf64_Dyn::DT_FINI_ARRAY:
|
upx_uint64_t dyn_offo = get_te64(&phdro[dynhdr - phdri].p_offset);
|
||||||
case Elf64_Dyn::DT_FINI: {
|
fo->seek(dyn_offo, SEEK_SET);
|
||||||
set_te64(&dyn->d_val, val - asl_delta);
|
fo->rewrite(ibuf, dyn_len);
|
||||||
}; break;
|
}
|
||||||
} // end switch()
|
if (is_asl) {
|
||||||
if (upx_dt_init == tag) {
|
lowmem.alloc(xct_off);
|
||||||
if (Elf64_Dyn::DT_INIT == tag) {
|
fi->seek(0, SEEK_SET);
|
||||||
set_te64(&dyn->d_val, old_dtinit);
|
fi->read(lowmem, xct_off); // contains relocation tables
|
||||||
if (!old_dtinit) { // compressor took the slot
|
if (dt_relasz && dt_rela) {
|
||||||
dyn->d_tag = Elf64_Dyn::DT_NULL;
|
Elf64_Rela *const rela0 = (Elf64_Rela *)lowmem.subref(
|
||||||
dyn->d_val = 0;
|
"bad Rela offset", dt_rela, dt_relasz);
|
||||||
}
|
unRela64(dt_rela, rela0, dt_relasz, ibuf, load_va, old_dtinit, fo);
|
||||||
}
|
}
|
||||||
else if (Elf64_Dyn::DT_INIT_ARRAY == tag
|
if (dt_pltrelsz && dt_jmprel) { // FIXME: overlap w/ DT_REL ?
|
||||||
|| Elf64_Dyn::DT_PREINIT_ARRAY == tag) {
|
Elf64_Rela *const jmp0 = (Elf64_Rela *)lowmem.subref(
|
||||||
if (val < load_va || (long unsigned)file_size < (long unsigned)val) {
|
"bad Jmprel offset", dt_jmprel, dt_pltrelsz);
|
||||||
char msg[50]; snprintf(msg, sizeof(msg),
|
unRela64(dt_jmprel, jmp0, dt_pltrelsz, ibuf, load_va, old_dtinit, fo);
|
||||||
"Bad Dynamic tag %#lx %#lx",
|
}
|
||||||
(long unsigned)tag, (long unsigned)val);
|
// Modified relocation tables are re-written by unRela64
|
||||||
throwCantUnpack(msg);
|
}
|
||||||
}
|
|
||||||
set_te64(&ibuf[val - load_va], old_dtinit
|
|
||||||
+ (is_asl ? asl_delta : 0)); // counter-act unRel64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Modified DT_*.d_val are re-written later from ibuf[]
|
|
||||||
}
|
|
||||||
if (is_asl) {
|
|
||||||
lowmem.alloc(xct_off);
|
|
||||||
fi->seek(0, SEEK_SET);
|
|
||||||
fi->read(lowmem, xct_off); // contains relocation tables
|
|
||||||
if (dt_relasz && dt_rela) {
|
|
||||||
Elf64_Rela *const rela0 = (Elf64_Rela *)lowmem.subref(
|
|
||||||
"bad Rela offset", dt_rela, dt_relasz);
|
|
||||||
unRela64(dt_rela, rela0, dt_relasz, ibuf, load_va, old_dtinit, fo);
|
|
||||||
}
|
|
||||||
if (dt_pltrelsz && dt_jmprel) { // FIXME: overlap w/ DT_REL ?
|
|
||||||
Elf64_Rela *const jmp0 = (Elf64_Rela *)lowmem.subref(
|
|
||||||
"bad Jmprel offset", dt_jmprel, dt_pltrelsz);
|
|
||||||
unRela64(dt_jmprel, jmp0, dt_pltrelsz, ibuf, load_va, old_dtinit, fo);
|
|
||||||
}
|
|
||||||
// Modified relocation tables are re-written by unRela64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fo) {
|
|
||||||
fo->seek(get_te64(&phdr->p_offset), SEEK_SET);
|
|
||||||
fo->rewrite(ibuf, old_data_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxElf64::unpack(OutputFile *fo)
|
void PackLinuxElf64::unpack(OutputFile *fo)
|
||||||
@ -4834,6 +4813,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
unsigned u_adler = upx_adler32(nullptr, 0);
|
unsigned u_adler = upx_adler32(nullptr, 0);
|
||||||
|
|
||||||
unsigned is_shlib = 0;
|
unsigned is_shlib = 0;
|
||||||
|
MemBuffer phdro;
|
||||||
Elf64_Phdr const *const dynhdr = elf_find_ptype(Elf64_Phdr::PT_DYNAMIC, phdri, c_phnum);
|
Elf64_Phdr const *const dynhdr = elf_find_ptype(Elf64_Phdr::PT_DYNAMIC, phdri, c_phnum);
|
||||||
if (dynhdr) {
|
if (dynhdr) {
|
||||||
upx_uint64_t dyn_offset = get_te64(&dynhdr->p_offset);
|
upx_uint64_t dyn_offset = get_te64(&dynhdr->p_offset);
|
||||||
@ -4843,9 +4823,10 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
if (!(Elf64_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf64_Dyn::DT_FLAGS_1))) {
|
if (!(Elf64_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf64_Dyn::DT_FLAGS_1))) {
|
||||||
is_shlib = 1;
|
is_shlib = 1;
|
||||||
u_phnum = get_te16(&ehdri.e_phnum);
|
u_phnum = get_te16(&ehdri.e_phnum);
|
||||||
un_shlib_1(fo, c_adler, u_adler, dynhdr, orig_file_size, szb_info);
|
phdro.alloc(u_phnum * sizeof(Elf64_Phdr));
|
||||||
|
memcpy(phdro, phdri, u_phnum * sizeof(*phdri));
|
||||||
|
un_shlib_1(fo, (Elf64_Phdr *)(void *)phdro, c_adler, u_adler, dynhdr, orig_file_size, szb_info);
|
||||||
*ehdr = ehdri;
|
*ehdr = ehdri;
|
||||||
memcpy(1+ehdr, phdri, u_phnum * sizeof(*phdri));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // main executable
|
else { // main executable
|
||||||
@ -4873,6 +4854,8 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
if ((umin64(MAX_ELF_HDR, ph.u_len) - sizeof(Elf64_Ehdr))/sizeof(Elf64_Phdr) < u_phnum) {
|
if ((umin64(MAX_ELF_HDR, ph.u_len) - sizeof(Elf64_Ehdr))/sizeof(Elf64_Phdr) < u_phnum) {
|
||||||
throwCantUnpack("bad compressed e_phnum");
|
throwCantUnpack("bad compressed e_phnum");
|
||||||
}
|
}
|
||||||
|
phdro.alloc(u_phnum * sizeof(Elf64_Phdr));
|
||||||
|
memcpy(phdro, 1+ ehdr, u_phnum * sizeof(Elf64_Phdr));
|
||||||
#undef MAX_ELF_HDR
|
#undef MAX_ELF_HDR
|
||||||
|
|
||||||
// Decompress each PT_LOAD.
|
// Decompress each PT_LOAD.
|
||||||
@ -4926,7 +4909,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The gaps between PT_LOAD and after last PT_LOAD
|
// The gaps between PT_LOAD and after last PT_LOAD
|
||||||
phdr = (Elf64_Phdr *)&u[sizeof(*ehdr)];
|
phdr = (Elf64_Phdr *)(void *)phdro;
|
||||||
upx_uint64_t hi_offset(0);
|
upx_uint64_t hi_offset(0);
|
||||||
for (unsigned j = 0; j < u_phnum; ++j) {
|
for (unsigned j = 0; j < u_phnum; ++j) {
|
||||||
if (PT_LOAD64==phdr[j].p_type
|
if (PT_LOAD64==phdr[j].p_type
|
||||||
@ -4942,7 +4925,8 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
fo->seek(where, SEEK_SET);
|
fo->seek(where, SEEK_SET);
|
||||||
unpackExtent(size, fo,
|
unpackExtent(size, fo,
|
||||||
c_adler, u_adler, false, szb_info,
|
c_adler, u_adler, false, szb_info,
|
||||||
(phdr[j].p_offset != hi_offset));
|
is_shlib && ((phdr[j].p_offset != hi_offset)));
|
||||||
|
// FIXME: should not depend on is_shlib ?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4961,7 +4945,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_shlib) {
|
if (is_shlib) {
|
||||||
un_DT_INIT(phdr, u_phnum, old_dtinit, fo, is_asl);
|
un_DT_INIT(old_dtinit, (Elf64_Phdr *)(void *)phdro, dynhdr, fo, is_asl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update header with totals
|
// update header with totals
|
||||||
|
@ -271,6 +271,7 @@ protected:
|
|||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
virtual void un_shlib_1(
|
virtual void un_shlib_1(
|
||||||
OutputFile *const fo,
|
OutputFile *const fo,
|
||||||
|
Elf64_Phdr *const phdro,
|
||||||
unsigned &c_adler,
|
unsigned &c_adler,
|
||||||
unsigned &u_adler,
|
unsigned &u_adler,
|
||||||
Elf64_Phdr const *const dynhdr,
|
Elf64_Phdr const *const dynhdr,
|
||||||
@ -278,9 +279,9 @@ protected:
|
|||||||
unsigned const szb_info
|
unsigned const szb_info
|
||||||
);
|
);
|
||||||
virtual void un_DT_INIT(
|
virtual void un_DT_INIT(
|
||||||
Elf64_Phdr const *phdr,
|
|
||||||
unsigned u_phnum,
|
|
||||||
unsigned old_dtinit,
|
unsigned old_dtinit,
|
||||||
|
Elf64_Phdr const *phdro,
|
||||||
|
Elf64_Phdr const *dynhdr, // in phdri
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
unsigned is_asl
|
unsigned is_asl
|
||||||
);
|
);
|
||||||
|
@ -470,6 +470,7 @@ void PackUnix::unpackExtent(unsigned wanted, OutputFile *fo,
|
|||||||
|
|
||||||
int j = blocksize + OVERHEAD - sz_cpr;
|
int j = blocksize + OVERHEAD - sz_cpr;
|
||||||
fi->readx(ibuf+j, sz_cpr);
|
fi->readx(ibuf+j, sz_cpr);
|
||||||
|
total_in += sz_cpr;
|
||||||
// update checksum of compressed data
|
// update checksum of compressed data
|
||||||
c_adler = upx_adler32(ibuf + j, sz_cpr, c_adler);
|
c_adler = upx_adler32(ibuf + j, sz_cpr, c_adler);
|
||||||
// decompress
|
// decompress
|
||||||
@ -499,8 +500,6 @@ void PackUnix::unpackExtent(unsigned wanted, OutputFile *fo,
|
|||||||
}
|
}
|
||||||
// update checksum of uncompressed data
|
// update checksum of uncompressed data
|
||||||
u_adler = upx_adler32(ibuf + j, sz_unc, u_adler);
|
u_adler = upx_adler32(ibuf + j, sz_unc, u_adler);
|
||||||
total_in += sz_cpr;
|
|
||||||
total_out += sz_unc;
|
|
||||||
// write block
|
// write block
|
||||||
if (fo) {
|
if (fo) {
|
||||||
if (is_rewrite) {
|
if (is_rewrite) {
|
||||||
@ -508,6 +507,7 @@ void PackUnix::unpackExtent(unsigned wanted, OutputFile *fo,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fo->write(ibuf + j, sz_unc);
|
fo->write(ibuf + j, sz_unc);
|
||||||
|
total_out += sz_unc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wanted < (unsigned)sz_unc)
|
if (wanted < (unsigned)sz_unc)
|
||||||
|
Loading…
Reference in New Issue
Block a user