unpackExtent() segregates rewrite() from write()
Fix the reported output file size when un-compressing. Part of https://github.com/upx/upx/issues/60 modified: p_lx_elf.cpp modified: p_unix.cpp modified: p_unix.h
This commit is contained in:
+16
-2
@@ -3388,6 +3388,12 @@ 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.buf + sizeof(*ehdr));
|
phdr = (Elf64_Phdr *) (u.buf + sizeof(*ehdr));
|
||||||
|
upx_uint64_t hi_offset(0);
|
||||||
|
for (unsigned j = 0; j < u_phnum; ++j) {
|
||||||
|
if (PT_LOAD64==phdr[j].p_type
|
||||||
|
&& hi_offset < phdr[j].p_offset)
|
||||||
|
hi_offset = phdr[j].p_offset;
|
||||||
|
}
|
||||||
for (unsigned j = 0; j < u_phnum; ++j) {
|
for (unsigned j = 0; j < u_phnum; ++j) {
|
||||||
unsigned const size = find_LOAD_gap(phdr, j, u_phnum);
|
unsigned const size = find_LOAD_gap(phdr, j, u_phnum);
|
||||||
if (size) {
|
if (size) {
|
||||||
@@ -3396,7 +3402,8 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
if (fo)
|
if (fo)
|
||||||
fo->seek(where, SEEK_SET);
|
fo->seek(where, SEEK_SET);
|
||||||
unpackExtent(size, fo, total_in, total_out,
|
unpackExtent(size, fo, total_in, total_out,
|
||||||
c_adler, u_adler, false, szb_info);
|
c_adler, u_adler, false, szb_info,
|
||||||
|
(phdr[j].p_offset != hi_offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3959,6 +3966,12 @@ void PackLinuxElf32::unpack(OutputFile *fo)
|
|||||||
|
|
||||||
// The gaps between PT_LOAD and after last PT_LOAD
|
// The gaps between PT_LOAD and after last PT_LOAD
|
||||||
phdr = (Elf32_Phdr *) (u.buf + sizeof(*ehdr));
|
phdr = (Elf32_Phdr *) (u.buf + sizeof(*ehdr));
|
||||||
|
unsigned hi_offset(0);
|
||||||
|
for (unsigned j = 0; j < u_phnum; ++j) {
|
||||||
|
if (PT_LOAD32==phdr[j].p_type
|
||||||
|
&& hi_offset < phdr[j].p_offset)
|
||||||
|
hi_offset = phdr[j].p_offset;
|
||||||
|
}
|
||||||
for (unsigned j = 0; j < u_phnum; ++j) {
|
for (unsigned j = 0; j < u_phnum; ++j) {
|
||||||
unsigned const size = find_LOAD_gap(phdr, j, u_phnum);
|
unsigned const size = find_LOAD_gap(phdr, j, u_phnum);
|
||||||
if (size) {
|
if (size) {
|
||||||
@@ -3967,7 +3980,8 @@ void PackLinuxElf32::unpack(OutputFile *fo)
|
|||||||
if (fo)
|
if (fo)
|
||||||
fo->seek(where, SEEK_SET);
|
fo->seek(where, SEEK_SET);
|
||||||
unpackExtent(size, fo, total_in, total_out,
|
unpackExtent(size, fo, total_in, total_out,
|
||||||
c_adler, u_adler, false, szb_info);
|
c_adler, u_adler, false, szb_info,
|
||||||
|
(phdr[j].p_offset != hi_offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -448,7 +448,7 @@ void PackUnix::packExtent(
|
|||||||
void PackUnix::unpackExtent(unsigned wanted, OutputFile *fo,
|
void PackUnix::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, unsigned szb_info
|
bool first_PF_X, unsigned szb_info, bool is_rewrite
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
b_info hdr; memset(&hdr, 0, sizeof(hdr));
|
b_info hdr; memset(&hdr, 0, sizeof(hdr));
|
||||||
@@ -501,8 +501,14 @@ void PackUnix::unpackExtent(unsigned wanted, OutputFile *fo,
|
|||||||
total_in += sz_cpr;
|
total_in += sz_cpr;
|
||||||
total_out += sz_unc;
|
total_out += sz_unc;
|
||||||
// write block
|
// write block
|
||||||
if (fo)
|
if (fo) {
|
||||||
fo->write(ibuf + j, sz_unc);
|
if (is_rewrite) {
|
||||||
|
fo->rewrite(ibuf + j, sz_unc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fo->write(ibuf + j, sz_unc);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (wanted < (unsigned)sz_unc)
|
if (wanted < (unsigned)sz_unc)
|
||||||
throwCantUnpack("corrupt b_info");
|
throwCantUnpack("corrupt b_info");
|
||||||
wanted -= sz_unc;
|
wanted -= sz_unc;
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ protected:
|
|||||||
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,
|
unsigned &c_adler, unsigned &u_adler,
|
||||||
bool first_PF_X, unsigned szb_info );
|
bool first_PF_X, unsigned szb_info, bool is_rewrite = false);
|
||||||
|
|
||||||
int exetype;
|
int exetype;
|
||||||
unsigned blocksize;
|
unsigned blocksize;
|
||||||
|
|||||||
Reference in New Issue
Block a user