mirror of
https://github.com/upx/upx
synced 2025-10-05 19:20:23 +08:00
work in progress: de-compression of --android-shlib
OK except for asl_delta not removed from DT_INIT, DT_INIT_ARRAY, DT_FINI_ARRAY, DT_PREINIT_ARRAY modified: ../p_lx_elf.cpp
This commit is contained in:
parent
7d2913709c
commit
9fdddfc332
|
@ -2873,8 +2873,9 @@ void PackLinuxElf64::pack1(OutputFile *fo, Filter & /*ft*/)
|
||||||
page_mask = ~0ull<<lg2_page;
|
page_mask = ~0ull<<lg2_page;
|
||||||
|
|
||||||
progid = 0; // getRandomId(); not useful, so do not clutter
|
progid = 0; // getRandomId(); not useful, so do not clutter
|
||||||
|
sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
|
||||||
if (0!=xct_off) { // shared library
|
if (0!=xct_off) { // shared library
|
||||||
sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
|
sz_elf_hdrs = xct_off;
|
||||||
lowmem.alloc(xct_off + (!opt->o_unix.android_shlib
|
lowmem.alloc(xct_off + (!opt->o_unix.android_shlib
|
||||||
? 0
|
? 0
|
||||||
: e_shnum * sizeof(Elf64_Shdr)));
|
: e_shnum * sizeof(Elf64_Shdr)));
|
||||||
|
@ -3295,25 +3296,24 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
|
||||||
uip->ui_total_passes -= !!is_shlib; // not .data of shlib
|
uip->ui_total_passes -= !!is_shlib; // not .data of shlib
|
||||||
|
|
||||||
// compress extents
|
// compress extents
|
||||||
unsigned hdr_u_len = sizeof(Elf64_Ehdr) + sz_phdrs;
|
unsigned hdr_u_len = xct_off;
|
||||||
|
|
||||||
unsigned total_in = xct_off - (is_shlib ? hdr_u_len : 0);
|
unsigned total_in = 0;
|
||||||
unsigned total_out = xct_off;
|
unsigned total_out = sz_elf_hdrs;
|
||||||
|
|
||||||
uip->ui_pass = 0;
|
uip->ui_pass = 0;
|
||||||
ft.addvalue = 0;
|
ft.addvalue = 0;
|
||||||
|
|
||||||
int nx = 0;
|
int nx = 0;
|
||||||
for (k = 0; k < e_phnum; ++k) if (PT_LOAD64==get_te32(&phdri[k].p_type)) {
|
for (k = 0; k < e_phnum; ++k)
|
||||||
|
if (PT_LOAD64==get_te32(&phdri[k].p_type)) {
|
||||||
if (ft.id < 0x40) {
|
if (ft.id < 0x40) {
|
||||||
// FIXME: ?? ft.addvalue = phdri[k].p_vaddr;
|
// FIXME: ?? ft.addvalue = phdri[k].p_vaddr;
|
||||||
}
|
}
|
||||||
x.offset = get_te64(&phdri[k].p_offset);
|
x.offset = get_te64(&phdri[k].p_offset);
|
||||||
x.size = get_te64(&phdri[k].p_filesz);
|
x.size = get_te64(&phdri[k].p_filesz);
|
||||||
if (0 == nx) { // 1st PT_LOAD64 must cover Ehdr at 0==p_offset
|
if (0 == nx) { // 1st PT_LOAD64 must cover Ehdr at 0==p_offset
|
||||||
unsigned const delta = !is_shlib
|
unsigned const delta = xct_off;
|
||||||
? (sizeof(Elf64_Ehdr) + sz_phdrs) // main executable
|
|
||||||
: xct_off; // shared library
|
|
||||||
if (ft.id < 0x40) {
|
if (ft.id < 0x40) {
|
||||||
// FIXME: ?? ft.addvalue += asl_delta;
|
// FIXME: ?? ft.addvalue += asl_delta;
|
||||||
}
|
}
|
||||||
|
@ -3600,26 +3600,23 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
||||||
|| !mem_size_valid(1, blocksize, OVERHEAD))
|
|| !mem_size_valid(1, blocksize, OVERHEAD))
|
||||||
throwCantUnpack("p_info corrupted");
|
throwCantUnpack("p_info corrupted");
|
||||||
|
|
||||||
#define MAX_ELF_HDR 1024
|
|
||||||
union {
|
|
||||||
unsigned char buf[MAX_ELF_HDR];
|
|
||||||
//struct { Elf64_Ehdr ehdr; Elf64_Phdr phdr; } e;
|
|
||||||
} u;
|
|
||||||
Elf64_Ehdr *const ehdr = (Elf64_Ehdr *) u.buf;
|
|
||||||
Elf64_Phdr const *phdr = 0;
|
|
||||||
|
|
||||||
ibuf.alloc(blocksize + OVERHEAD);
|
ibuf.alloc(blocksize + OVERHEAD);
|
||||||
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||||
fi->readx(&bhdr, szb_info);
|
fi->readx(&bhdr, szb_info);
|
||||||
ph.u_len = get_te32(&bhdr.sz_unc);
|
ph.u_len = get_te32(&bhdr.sz_unc);
|
||||||
ph.c_len = get_te32(&bhdr.sz_cpr);
|
ph.c_len = get_te32(&bhdr.sz_cpr);
|
||||||
if (ph.c_len > (unsigned)file_size || ph.c_len == 0 || ph.u_len == 0
|
if (ph.c_len > (unsigned)file_size || ph.c_len == 0 || ph.u_len == 0
|
||||||
|| ph.u_len > sizeof(u))
|
|| ph.u_len > orig_file_size)
|
||||||
throwCantUnpack("b_info corrupted");
|
throwCantUnpack("b_info corrupted");
|
||||||
ph.filter_cto = bhdr.b_cto8;
|
ph.filter_cto = bhdr.b_cto8;
|
||||||
|
|
||||||
|
#define MAX_ELF_HDR 1024
|
||||||
|
MemBuffer u(ph.u_len);
|
||||||
|
Elf64_Ehdr *const ehdr = (Elf64_Ehdr *)&u[0];
|
||||||
|
Elf64_Phdr const *phdr = 0;
|
||||||
|
|
||||||
// Uncompress Ehdr and Phdrs.
|
// Uncompress Ehdr and Phdrs.
|
||||||
if (ibuf.getSize() < ph.c_len || sizeof(u) < ph.u_len)
|
if (ibuf.getSize() < ph.c_len)
|
||||||
throwCompressedDataViolation();
|
throwCompressedDataViolation();
|
||||||
fi->readx(ibuf, ph.c_len);
|
fi->readx(ibuf, ph.c_len);
|
||||||
decompress(ibuf, (upx_byte *)ehdr, false);
|
decompress(ibuf, (upx_byte *)ehdr, false);
|
||||||
|
@ -3740,7 +3737,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.buf + sizeof(*ehdr));
|
phdr = (Elf64_Phdr *)&u[sizeof(*ehdr)];
|
||||||
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
|
||||||
|
@ -3777,7 +3774,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
||||||
if (is_shlib) { // the non-first PT_LOAD
|
if (is_shlib) { // the non-first PT_LOAD
|
||||||
int n_ptload = 0;
|
int n_ptload = 0;
|
||||||
unsigned load_off = 0;
|
unsigned load_off = 0;
|
||||||
phdr = (Elf64_Phdr *) (u.buf + sizeof(*ehdr));
|
phdr = (Elf64_Phdr *)&u[sizeof(*ehdr)];
|
||||||
for (unsigned j= 0; j < u_phnum; ++j, ++phdr) {
|
for (unsigned j= 0; j < u_phnum; ++j, ++phdr) {
|
||||||
if (PT_LOAD64==get_te32(&phdr->p_type) && 0!=n_ptload++) {
|
if (PT_LOAD64==get_te32(&phdr->p_type) && 0!=n_ptload++) {
|
||||||
load_off = get_te64(&phdr->p_offset);
|
load_off = get_te64(&phdr->p_offset);
|
||||||
|
@ -3792,7 +3789,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Restore DT_INIT.d_val
|
// Restore DT_INIT.d_val
|
||||||
phdr = (Elf64_Phdr *) (u.buf + sizeof(*ehdr));
|
phdr = (Elf64_Phdr *)&u[sizeof(*ehdr)];
|
||||||
for (unsigned j= 0; j < u_phnum; ++j, ++phdr) {
|
for (unsigned j= 0; j < u_phnum; ++j, ++phdr) {
|
||||||
if (phdr->PT_DYNAMIC==get_te32(&phdr->p_type)) {
|
if (phdr->PT_DYNAMIC==get_te32(&phdr->p_type)) {
|
||||||
unsigned const dyn_off = get_te64(&phdr->p_offset);
|
unsigned const dyn_off = get_te64(&phdr->p_offset);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user