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:
committed by
Markus F.X.J. Oberhumer
parent
85f0c5a445
commit
076aaf829a
+14
-4
@@ -4270,7 +4270,7 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!(Elf64_Phdr::PF_W & get_te64(&phdri[k].p_flags))) {
|
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,
|
// Also assume not the source for R_*_COPY relocation,
|
||||||
// therefore compress it.
|
// therefore compress it.
|
||||||
packExtent(x, &ft, fo, 0, 0, true);
|
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);
|
unsigned const limit_dynhdr = get_te64(&dynhdr->p_offset) + get_te64(&dynhdr->p_filesz);
|
||||||
fi->readx(ibuf, limit_dynhdr);
|
fi->readx(ibuf, limit_dynhdr);
|
||||||
overlay_offset -= sizeof(linfo);
|
overlay_offset -= sizeof(linfo);
|
||||||
|
loader_offset = 0;
|
||||||
xct_off = overlay_offset;
|
xct_off = overlay_offset;
|
||||||
e_shoff = get_te64(&ehdri.e_shoff);
|
e_shoff = get_te64(&ehdri.e_shoff);
|
||||||
if (e_shoff && e_shnum
|
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
|
if (!(Elf64_Phdr::PF_W & flags)) { // Read-only, so was compressed
|
||||||
fi->readx(&hdr.b, sizeof(hdr.b));
|
fi->readx(&hdr.b, sizeof(hdr.b));
|
||||||
fi->seek(-(off_t)sizeof(struct b_info), SEEK_CUR);
|
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.c_len = get_te32(&hdr.b.sz_cpr);
|
||||||
ph.u_len = get_te32(&hdr.b.sz_unc);
|
ph.u_len = get_te32(&hdr.b.sz_unc);
|
||||||
unpackExtent(ph.u_len, fo, c_adler, u_adler, false, szb_info);
|
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++) {
|
if (!once++) {
|
||||||
funpad4(fi);
|
funpad4(fi);
|
||||||
|
loader_offset = fi->tell();
|
||||||
}
|
}
|
||||||
fi->seek(i_offset, SEEK_SET);
|
fi->seek(i_offset, SEEK_SET);
|
||||||
fi->readx(ibuf, filesz);
|
fi->readx(ibuf, filesz);
|
||||||
@@ -4803,7 +4808,7 @@ void PackLinuxElf64::un_shlib_1(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// position fi at loader offset
|
// position fi at loader offset
|
||||||
fi->seek(overlay_offset, SEEK_SET); // FIXME?
|
fi->seek(loader_offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxElf64::un_DT_INIT(
|
void PackLinuxElf64::un_DT_INIT(
|
||||||
@@ -5027,7 +5032,12 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
ph.getPackHeaderSize() + sizeof(overlay_offset))
|
ph.getPackHeaderSize() + sizeof(overlay_offset))
|
||||||
< up4(file_size)) {
|
< up4(file_size)) {
|
||||||
// Loader is not at end; skip past it.
|
// 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));
|
unsigned d_info[6]; fi->readx(d_info, sizeof(d_info));
|
||||||
if (0==old_dtinit) {
|
if (0==old_dtinit) {
|
||||||
old_dtinit = get_te32(&d_info[2 + (0==d_info[0])]);
|
old_dtinit = get_te32(&d_info[2 + (0==d_info[0])]);
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ protected:
|
|||||||
upx_uint64_t user_init_va;
|
upx_uint64_t user_init_va;
|
||||||
unsigned user_init_off; // within file_image
|
unsigned user_init_off; // within file_image
|
||||||
unsigned linfo_off;
|
unsigned linfo_off;
|
||||||
|
unsigned loader_offset; // during de-compression
|
||||||
|
|
||||||
upx_uint16_t e_machine;
|
upx_uint16_t e_machine;
|
||||||
unsigned char ei_class;
|
unsigned char ei_class;
|
||||||
|
|||||||
+1
-1
@@ -384,7 +384,7 @@ void PackUnix::packExtent(
|
|||||||
ph.c_len = ph.u_len;
|
ph.c_len = ph.u_len;
|
||||||
memcpy(obuf, ibuf, ph.c_len);
|
memcpy(obuf, ibuf, ph.c_len);
|
||||||
// must update checksum of compressed data
|
// 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
|
// write block sizes
|
||||||
|
|||||||
Reference in New Issue
Block a user