WIP: Elf64 shlib compress+decompress seems to work

modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
	modified:   p_unix.cpp
This commit is contained in:
John Reiser 2021-07-05 13:47:19 -07:00 committed by Markus F.X.J. Oberhumer
parent 85f0c5a445
commit 076aaf829a
3 changed files with 16 additions and 5 deletions

View File

@ -4270,7 +4270,7 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
}
else {
if (!(Elf64_Phdr::PF_W & get_te64(&phdri[k].p_flags))) {
// Read-only PT_LOAD, assume not written by relocationa.
// Read-only PT_LOAD, assume not written by relocations.
// Also assume not the source for R_*_COPY relocation,
// therefore compress it.
packExtent(x, &ft, fo, 0, 0, true);
@ -4694,6 +4694,7 @@ void PackLinuxElf64::un_shlib_1(
unsigned const limit_dynhdr = get_te64(&dynhdr->p_offset) + get_te64(&dynhdr->p_filesz);
fi->readx(ibuf, limit_dynhdr);
overlay_offset -= sizeof(linfo);
loader_offset = 0;
xct_off = overlay_offset;
e_shoff = get_te64(&ehdri.e_shoff);
if (e_shoff && e_shnum
@ -4784,13 +4785,17 @@ void PackLinuxElf64::un_shlib_1(
if (!(Elf64_Phdr::PF_W & flags)) { // Read-only, so was compressed
fi->readx(&hdr.b, sizeof(hdr.b));
fi->seek(-(off_t)sizeof(struct b_info), SEEK_CUR);
if (fo) {
fo->seek(o_offset, SEEK_SET);
}
ph.c_len = get_te32(&hdr.b.sz_cpr);
ph.u_len = get_te32(&hdr.b.sz_unc);
unpackExtent(ph.u_len, fo, c_adler, u_adler, false, szb_info);
}
else { // Writeable, so might be relocataed, so not compressed
else { // Writeable, so might written by rtld, so not compressed.
if (!once++) {
funpad4(fi);
loader_offset = fi->tell();
}
fi->seek(i_offset, SEEK_SET);
fi->readx(ibuf, filesz);
@ -4803,7 +4808,7 @@ void PackLinuxElf64::un_shlib_1(
}
}
// position fi at loader offset
fi->seek(overlay_offset, SEEK_SET); // FIXME?
fi->seek(loader_offset, SEEK_SET);
}
void PackLinuxElf64::un_DT_INIT(
@ -5027,7 +5032,12 @@ void PackLinuxElf64::unpack(OutputFile *fo)
ph.getPackHeaderSize() + sizeof(overlay_offset))
< up4(file_size)) {
// Loader is not at end; skip past it.
funpad4(fi); // MATCH01
if (loader_offset) {
fi->seek(loader_offset, SEEK_SET);
}
else {
funpad4(fi); // MATCH01
}
unsigned d_info[6]; fi->readx(d_info, sizeof(d_info));
if (0==old_dtinit) {
old_dtinit = get_te32(&d_info[2 + (0==d_info[0])]);

View File

@ -92,6 +92,7 @@ protected:
upx_uint64_t user_init_va;
unsigned user_init_off; // within file_image
unsigned linfo_off;
unsigned loader_offset; // during de-compression
upx_uint16_t e_machine;
unsigned char ei_class;

View File

@ -384,7 +384,7 @@ void PackUnix::packExtent(
ph.c_len = ph.u_len;
memcpy(obuf, ibuf, ph.c_len);
// must update checksum of compressed data
ph.c_adler = upx_adler32(ibuf, ph.u_len, ph.saved_c_adler);
ph.c_adler = upx_adler32(ibuf, ph.u_len, ph.c_adler);
}
// write block sizes