1 /* p_lx_elf.cpp --
2 
3    This file is part of the UPX executable compressor.
4 
5    Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer
6    Copyright (C) 1996-2020 Laszlo Molnar
7    Copyright (C) 2000-2020 John F. Reiser
8    All Rights Reserved.
9 
10    UPX and the UCL library are free software; you can redistribute them
11    and/or modify them under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2 of
13    the License, or (at your option) any later version.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; see the file COPYING.
22    If not, write to the Free Software Foundation, Inc.,
23    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25    Markus F.X.J. Oberhumer              Laszlo Molnar
26    <markus@oberhumer.com>               <ezerotven+github@gmail.com>
27 
28    John F. Reiser
29    <jreiser@users.sourceforge.net>
30  */
31 
32 
33 #include "conf.h"
34 
35 #include "file.h"
36 #include "filter.h"
37 #include "linker.h"
38 #include "packer.h"
39 #include "p_elf.h"
40 #include "p_unix.h"
41 #include "p_lx_exc.h"
42 #include "p_lx_elf.h"
43 #include "ui.h"
44 
45 typedef upx_uint32_t u32_t;  // easier to type; more narrow
46 typedef upx_uint64_t u64_t;  // easier to type; more narrow
47 
48 #define PT_LOAD32   Elf32_Phdr::PT_LOAD
49 #define PT_LOAD64   Elf64_Phdr::PT_LOAD
50 #define PT_NOTE32   Elf32_Phdr::PT_NOTE
51 #define PT_NOTE64   Elf64_Phdr::PT_NOTE
52 #define PT_GNU_STACK32  Elf32_Phdr::PT_GNU_STACK
53 #define PT_GNU_STACK64  Elf64_Phdr::PT_GNU_STACK
54 
55 //static unsigned const EF_ARM_HASENTRY = 0x02;
56 static unsigned const EF_ARM_EABI_VER4 = 0x04000000;
57 static unsigned const EF_ARM_EABI_VER5 = 0x05000000;
58 
59 unsigned char PackLinuxElf::o_shstrtab[] = {  \
60 /*start*/       '\0',
61 /*offset  1*/   '.','n','o','t','e','.','g','n','u','.','b','u','i','l','d','-','i','d','\0',
62 /*offset 20*/   '.','s','h','s','t','r','t','a','b','\0'
63 };
64 
65 static unsigned
umin(unsigned a,unsigned b)66 umin(unsigned a, unsigned b)
67 {
68     return (a < b) ? a : b;
69 }
70 
71 static upx_uint64_t
umin64(upx_uint64_t a,upx_uint64_t b)72 umin64(upx_uint64_t a, upx_uint64_t b)
73 {
74     return (a < b) ? a : b;
75 }
76 
77 static unsigned
up4(unsigned x)78 up4(unsigned x)
79 {
80     return ~3u & (3+ x);
81 }
82 
83 #if 0  //{ unused
84 static unsigned
85 up8(unsigned x)
86 {
87     return ~7u & (7+ x);
88 }
89 #endif  //}
90 
91 static off_t
fpad4(OutputFile * fo)92 fpad4(OutputFile *fo)
93 {
94     off_t len = fo->st_size();
95     unsigned d = 3u & (0 - len);
96     unsigned zero = 0;
97     fo->write(&zero, d);
98     return d + len;
99 }
100 
101 static off_t
fpad8(OutputFile * fo)102 fpad8(OutputFile *fo)
103 {
104     off_t len = fo->st_size();
105     unsigned d = 7u & (0 - len);
106     upx_uint64_t zero = 0;
107     fo->write(&zero, d);
108     return d + len;
109 }
110 
111 static unsigned
funpad4(InputFile * fi)112 funpad4(InputFile *fi)
113 {
114     unsigned d = 3u & (0 - fi->tell());
115     if (d)
116         fi->seek(d, SEEK_CUR);
117     return d;
118 }
119 
alloc_file_image(MemBuffer & mb,off_t size)120 static void alloc_file_image(MemBuffer &mb, off_t size)
121 {
122     assert(mem_size_valid_bytes(size));
123     if (mb.getVoidPtr() == NULL) {
124         mb.alloc(size);
125     } else {
126         assert((u32_t)size <= mb.getSize());
127     }
128 }
129 
130 int
checkEhdr(Elf32_Ehdr const * ehdr) const131 PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const
132 {
133     const unsigned char * const buf = ehdr->e_ident;
134 
135     if (0!=memcmp(buf, "\x7f\x45\x4c\x46", 4)  // "\177ELF"
136     ||  buf[Elf32_Ehdr::EI_CLASS]!=ei_class
137     ||  buf[Elf32_Ehdr::EI_DATA] !=ei_data
138     ) {
139         return -1;
140     }
141     if (!memcmp(buf+8, "FreeBSD", 7))                   // branded
142         return 1;
143 
144     int const type = get_te16(&ehdr->e_type);
145     if (type != Elf32_Ehdr::ET_EXEC && type != Elf32_Ehdr::ET_DYN)
146         return 2;
147     if (get_te16(&ehdr->e_machine) != (unsigned) e_machine)
148         return 3;
149     if (get_te32(&ehdr->e_version) != Elf32_Ehdr::EV_CURRENT)
150         return 4;
151     if (e_phnum < 1)
152         return 5;
153     if (get_te16(&ehdr->e_phentsize) != sizeof(Elf32_Phdr))
154         return 6;
155 
156     if (type == Elf32_Ehdr::ET_EXEC) {
157         // check for Linux kernels
158         unsigned const entry = get_te32(&ehdr->e_entry);
159         if (entry == 0xC0100000)    // uncompressed vmlinux
160             return 1000;
161         if (entry == 0x00001000)    // compressed vmlinux
162             return 1001;
163         if (entry == 0x00100000)    // compressed bvmlinux
164             return 1002;
165     }
166 
167     // FIXME: add more checks for kernels
168 
169     // FIXME: add special checks for other ELF i386 formats, like
170     //        NetBSD, OpenBSD, Solaris, ....
171 
172     // success
173     return 0;
174 }
175 
176 int
checkEhdr(Elf64_Ehdr const * ehdr) const177 PackLinuxElf64::checkEhdr(Elf64_Ehdr const *ehdr) const
178 {
179     const unsigned char * const buf = ehdr->e_ident;
180     unsigned char osabi0 = buf[Elf32_Ehdr::EI_OSABI];
181     if (0==osabi0) {
182         osabi0 = opt->o_unix.osabi0;
183     }
184 
185     if (0!=memcmp(buf, "\x7f\x45\x4c\x46", 4)  // "\177ELF"
186     ||  buf[Elf64_Ehdr::EI_CLASS]!=ei_class
187     ||  buf[Elf64_Ehdr::EI_DATA] !=ei_data
188     ||                     osabi0!=ei_osabi
189     ) {
190         return -1;
191     }
192     if (!memcmp(buf+8, "FreeBSD", 7))                   // branded
193         return 1;
194 
195     int const type = get_te16(&ehdr->e_type);
196     if (type != Elf64_Ehdr::ET_EXEC && type != Elf64_Ehdr::ET_DYN)
197         return 2;
198     if (get_te16(&ehdr->e_machine) != (unsigned) e_machine)
199         return 3;
200     if (get_te32(&ehdr->e_version) != Elf64_Ehdr::EV_CURRENT)
201         return 4;
202     if (e_phnum < 1)
203         return 5;
204     if (get_te16(&ehdr->e_phentsize) != sizeof(Elf64_Phdr))
205         return 6;
206 
207     if (type == Elf64_Ehdr::ET_EXEC) {
208         // check for Linux kernels
209         upx_uint64_t const entry = get_te64(&ehdr->e_entry);
210         if (entry == 0xC0100000)    // uncompressed vmlinux
211             return 1000;
212         if (entry == 0x00001000)    // compressed vmlinux
213             return 1001;
214         if (entry == 0x00100000)    // compressed bvmlinux
215             return 1002;
216     }
217 
218     // FIXME: add more checks for kernels
219 
220     // FIXME: add special checks for other ELF i386 formats, like
221     //        NetBSD, OpenBSD, Solaris, ....
222 
223     // success
224     return 0;
225 }
226 
PackLinuxElf(InputFile * f)227 PackLinuxElf::PackLinuxElf(InputFile *f)
228     : super(f), e_phnum(0), dynstr(NULL),
229     sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), sz_pack2a(0),
230     lg2_page(12), page_size(1u<<lg2_page), is_pie(0),
231     xct_off(0), xct_va(0), jni_onload_va(0),
232     user_init_va(0), user_init_off(0),
233     e_machine(0), ei_class(0), ei_data(0), ei_osabi(0), osabi_note(NULL),
234     o_elf_shnum(0)
235 {
236     memset(dt_table, 0, sizeof(dt_table));
237 }
238 
~PackLinuxElf()239 PackLinuxElf::~PackLinuxElf()
240 {
241 }
242 
243 void
PackLinuxElf32help1(InputFile * f)244 PackLinuxElf32::PackLinuxElf32help1(InputFile *f)
245 {
246     e_type  = get_te16(&ehdri.e_type);
247     e_phnum = get_te16(&ehdri.e_phnum);
248     e_shnum = get_te16(&ehdri.e_shnum);
249     unsigned const e_phentsize = get_te16(&ehdri.e_phentsize);
250     if (ehdri.e_ident[Elf32_Ehdr::EI_CLASS]!=Elf32_Ehdr::ELFCLASS32
251     || sizeof(Elf32_Phdr) != e_phentsize
252     || (Elf32_Ehdr::ELFDATA2MSB == ehdri.e_ident[Elf32_Ehdr::EI_DATA]
253             && &N_BELE_RTP::be_policy != bele)
254     || (Elf32_Ehdr::ELFDATA2LSB == ehdri.e_ident[Elf32_Ehdr::EI_DATA]
255             && &N_BELE_RTP::le_policy != bele)) {
256         e_phoff = 0;
257         e_shoff = 0;
258         sz_phdrs = 0;
259         return;
260     }
261     if (0==e_phnum) throwCantUnpack("0==e_phnum");
262     e_phoff = get_te32(&ehdri.e_phoff);
263     unsigned const last_Phdr = e_phoff + e_phnum * sizeof(Elf32_Phdr);
264     if (last_Phdr < e_phoff || (unsigned long)file_size < last_Phdr) {
265         throwCantUnpack("bad e_phoff");
266     }
267     e_shoff = get_te32(&ehdri.e_shoff);
268     unsigned const last_Shdr = e_shoff + e_shnum * sizeof(Elf32_Shdr);
269     if (last_Shdr < e_shoff || (unsigned long)file_size < last_Shdr) {
270         if (opt->cmd == CMD_COMPRESS) {
271             throwCantUnpack("bad e_shoff");
272         }
273     }
274     sz_phdrs = e_phnum * e_phentsize;
275 
276     if (f && Elf32_Ehdr::ET_DYN!=e_type) {
277         unsigned const len = sz_phdrs + e_phoff;
278         alloc_file_image(file_image, len);
279         f->seek(0, SEEK_SET);
280         f->readx(file_image, len);
281         phdri= (Elf32_Phdr       *)(e_phoff + file_image);  // do not free() !!
282     }
283     if (f && Elf32_Ehdr::ET_DYN==e_type) {
284         // The DT_SYMTAB has no designated length.  Read the whole file.
285         alloc_file_image(file_image, file_size);
286         f->seek(0, SEEK_SET);
287         f->readx(file_image, file_size);
288         phdri= (Elf32_Phdr *)(e_phoff + file_image);  // do not free() !!
289         shdri= (Elf32_Shdr *)(e_shoff + file_image);  // do not free() !!
290         if (opt->cmd != CMD_COMPRESS) {
291             shdri = NULL;
292         }
293         sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);
294         if (sec_dynsym) {
295             unsigned t = get_te32(&sec_dynsym->sh_link);
296             if (e_shnum <= t)
297                 throwCantPack("bad dynsym->sh_link");
298             sec_dynstr = &shdri[t];
299         }
300 
301         Elf32_Phdr const *phdr= phdri;
302         for (int j = e_phnum; --j>=0; ++phdr)
303         if (Elf32_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
304             dynseg= (Elf32_Dyn const *)(check_pt_dynamic(phdr) + file_image);
305             invert_pt_dynamic(dynseg);
306         }
307         else if (PT_LOAD32==get_te32(&phdr->p_type)) {
308             check_pt_load(phdr);
309         }
310         // elf_find_dynamic() returns 0 if 0==dynseg.
311         dynstr =      (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);
312         dynsym = (Elf32_Sym const *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB);
313         gashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_GNU_HASH);
314         hashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_HASH);
315         jni_onload_sym = elf_lookup("JNI_OnLoad");
316         if (jni_onload_sym) {
317             jni_onload_va = get_te32(&jni_onload_sym->st_value);
318             jni_onload_va = 0;  // FIXME not understood; need example
319         }
320     }
321 }
322 
pack3(OutputFile * fo,Filter & ft)323 off_t PackLinuxElf::pack3(OutputFile *fo, Filter &ft) // return length of output
324 {
325     unsigned disp;
326     unsigned const zero = 0;
327     unsigned len = sz_pack2a;  // after headers and all PT_LOAD
328 
329     unsigned const t = (4 & len) ^ ((!!xct_off)<<2);  // 0 or 4
330     fo->write(&zero, t);
331     len += t;  // force sz_pack2 (0 mod 8)  [see below]
332 
333     set_te32(&disp, sz_elf_hdrs + sizeof(p_info) + sizeof(l_info) +
334         (!!xct_off & !!opt->o_unix.android_shlib));  // |1 iff android shlib
335     fo->write(&disp, sizeof(disp));  // offset(b_info)
336     len += sizeof(disp);
337     set_te32(&disp, len);  // distance back to beginning (detect dynamic reloc)
338     fo->write(&disp, sizeof(disp));
339     len += sizeof(disp);
340 
341     if (xct_off) {  // is_shlib
342         upx_uint64_t const firstpc_va = (jni_onload_va
343             ? jni_onload_va
344             : user_init_va);
345         set_te32(&disp, firstpc_va - load_va);
346         fo->write(&disp, sizeof(disp));  // DT_INIT.d_val
347         len += sizeof(disp);
348 
349         set_te32(&disp, hatch_off);
350         fo->write(&disp, sizeof(disp));  // offset(hatch)
351         len += sizeof(disp);
352 
353         if (opt->o_unix.android_shlib) {
354             xct_off += asl_delta;  // the extra page
355         }
356         set_te32(&disp, xct_off);
357         fo->write(&disp, sizeof(disp));  // offset(dst for f_exp)
358         len += sizeof(disp);
359     }
360     sz_pack2 = len;  // 0 mod 8  [see above]
361 
362     super::pack3(fo, ft);  // append the decompressor
363     set_te16(&linfo.l_lsize, up4(  // MATCH03: up4
364     get_te16(&linfo.l_lsize) + len - sz_pack2a));
365 
366     return fpad4(fo);  // MATCH03
367 }
368 
pack3(OutputFile * fo,Filter & ft)369 off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
370 {
371     off_t flen = super::pack3(fo, ft);  // loader follows compressed PT_LOADs
372     // NOTE: PackLinuxElf::pack3  adjusted xct_off for the extra page
373 
374     unsigned v_hole = sz_pack2 + lsize;
375     set_te32(&elfout.phdr[0].p_filesz, v_hole);
376     set_te32(&elfout.phdr[0].p_memsz,  v_hole);
377     // Then compressed gaps (including debuginfo.)
378     unsigned total_in = 0, total_out = 0;
379     for (unsigned k = 0; k < e_phnum; ++k) {
380         Extent x;
381         x.size = find_LOAD_gap(phdri, k, e_phnum);
382         if (x.size) {
383             x.offset = get_te32(&phdri[k].p_offset) +
384                        get_te32(&phdri[k].p_filesz);
385             packExtent(x, total_in, total_out, 0, fo);
386         }
387     }
388     // write block end marker (uncompressed size 0)
389     b_info hdr; memset(&hdr, 0, sizeof(hdr));
390     set_le32(&hdr.sz_cpr, UPX_MAGIC_LE32);
391     fo->write(&hdr, sizeof(hdr));
392     flen = fpad4(fo);
393 
394     set_te32(&elfout.phdr[0].p_filesz, sz_pack2 + lsize);
395     set_te32(&elfout.phdr[0].p_memsz,  sz_pack2 + lsize);
396     if (0==xct_off) { // not shared library; adjust PT_LOAD
397         // .p_align can be big for segments, but Linux uses 4KiB pages.
398         // This allows [vvar], [vdso], etc to sneak into the gap
399         // between end_text and data, which we wish to prevent
400         // because the expanded program will use that space.
401         // So: pretend 4KiB pages.
402         unsigned pm = (Elf64_Ehdr::EM_PPC64 == e_machine)
403             ? page_mask  // reducing to 4KiB DOES NOT WORK ??
404             : ((~(unsigned)0)<<12);
405         pm = page_mask;  // Revert until consequences can be analyzed
406         v_hole = pm & (~pm + v_hole + get_te32(&elfout.phdr[0].p_vaddr));
407         set_te32(&elfout.phdr[1].p_vaddr, v_hole);
408         set_te32(&elfout.phdr[1].p_align, ((unsigned)0) - pm);
409         elfout.phdr[1].p_paddr = elfout.phdr[1].p_vaddr;
410         elfout.phdr[1].p_offset = 0;
411         set_te32(&elfout.phdr[1].p_memsz, getbrk(phdri, e_phnum) - v_hole);
412         set_te32(&elfout.phdr[1].p_flags, Elf32_Phdr::PF_W|Elf32_Phdr::PF_R);
413     }
414     if (0!=xct_off) {  // shared library
415         unsigned word = (Elf32_Ehdr::EM_ARM==e_machine) + load_va + sz_pack2;  // Thumb mode
416         set_te32(&file_image[user_init_off], word);  // set the hook
417 
418         Elf32_Phdr *phdr = (Elf32_Phdr *)lowmem.subref(
419                 "bad e_phoff", e_phoff, e_phnum * sizeof(Elf32_Phdr));
420         unsigned off = fo->st_size();
421         so_slide = 0;
422         for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
423             unsigned const len  = get_te32(&phdr->p_filesz);
424             unsigned const ioff = get_te32(&phdr->p_offset);
425             unsigned       align= get_te32(&phdr->p_align);
426             unsigned const type = get_te32(&phdr->p_type);
427             if (Elf32_Phdr::PT_INTERP==type) {
428                 // Rotate to highest position, so it can be lopped
429                 // by decrementing e_phnum.
430                 memcpy((unsigned char *)ibuf, phdr, sizeof(*phdr));  // extract
431                 memmove(phdr, 1+phdr, (e_phnum - (1+ j))*sizeof(*phdr));  // overlapping
432                 memcpy(&phdr[e_phnum - (1+ j)], (unsigned char *)ibuf, sizeof(*phdr));  // to top
433                 --phdr; --e_phnum;
434                 set_te16(&ehdri.e_phnum, e_phnum);
435                 set_te16(&((Elf32_Ehdr *)(unsigned char *)lowmem)->e_phnum, e_phnum);
436                 continue;
437             }
438             if (PT_LOAD32 == type) {
439                 if ((xct_off - ioff) < len) { // Change length of compressed PT_LOAD.
440                     set_te32(&phdr->p_filesz, sz_pack2 + lsize - ioff);
441                     set_te32(&phdr->p_memsz,  sz_pack2 + lsize - ioff);
442                 }
443                 else if (xct_off < ioff) { // Slide subsequent PT_LOAD.
444                     if ((1u<<12) < align) {
445                         align = 1u<<12;
446                         set_te32(&phdr->p_align, align);
447                     }
448                     off += (align-1) & (ioff - off);
449                     fo->seek(  off, SEEK_SET);
450                     fo->write(&file_image[ioff], len);
451                     so_slide = off - ioff;
452                     set_te32(&phdr->p_offset, so_slide + ioff);
453                 }
454                 continue;  // all done with this PT_LOAD
455             }
456             if (xct_off < ioff)
457                 set_te32(&phdr->p_offset, so_slide + ioff);
458         }  // end each Phdr
459 
460         if (opt->o_unix.android_shlib) {
461             // Update {DYNAMIC}.sh_offset by so_slide.
462             Elf32_Shdr *shdr = (Elf32_Shdr *)lowmem.subref(
463                     "bad e_shoff", xct_off - asl_delta, e_shnum * sizeof(Elf32_Shdr));
464             for (unsigned j = 0; j < e_shnum; ++shdr, ++j) {
465                 unsigned sh_type = get_te32(&shdr->sh_type);
466                 if (Elf32_Shdr::SHT_DYNAMIC == get_te32(&shdr->sh_type)) {
467                     unsigned offset = get_te32(&shdr->sh_offset);
468                     set_te32(&shdr->sh_offset, so_slide + offset );
469                     fo->seek((j * sizeof(Elf32_Shdr)) + xct_off - asl_delta, SEEK_SET);
470                     fo->rewrite(shdr, sizeof(*shdr));
471                     fo->seek(0, SEEK_END);
472                 }
473                 if (Elf32_Shdr::SHT_REL == sh_type
474                 &&  n_jmp_slot
475                 &&  !strcmp(".rel.plt", get_te32(&shdr->sh_name) + shstrtab)) {
476                     unsigned f_off = elf_get_offset_from_address(plt_off);
477                     fo->seek(so_slide + f_off, SEEK_SET);  // FIXME: assumes PT_LOAD[1]
478                     fo->rewrite(&file_image[f_off], n_jmp_slot * 4);
479                  }
480             }
481         }
482         else { // !opt->o_unix.android_shlib)
483             ehdri.e_shnum = 0;
484             ehdri.e_shoff = 0;
485             ehdri.e_shstrndx = 0;
486         }
487     }
488     return flen;
489 }
490 
pack3(OutputFile * fo,Filter & ft)491 off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft)
492 {
493     off_t flen = super::pack3(fo, ft);  // loader follows compressed PT_LOADs
494     // NOTE: PackLinuxElf::pack3  adjusted xct_off for the extra page
495 
496     unsigned v_hole = sz_pack2 + lsize;
497     set_te64(&elfout.phdr[0].p_filesz, v_hole);
498     set_te64(&elfout.phdr[0].p_memsz,  v_hole);
499     // Then compressed gaps (including debuginfo.)
500     unsigned total_in = 0, total_out = 0;
501     for (unsigned k = 0; k < e_phnum; ++k) {
502         Extent x;
503         x.size = find_LOAD_gap(phdri, k, e_phnum);
504         if (x.size) {
505             x.offset = get_te64(&phdri[k].p_offset) +
506                        get_te64(&phdri[k].p_filesz);
507             packExtent(x, total_in, total_out, 0, fo);
508         }
509     }
510     // write block end marker (uncompressed size 0)
511     b_info hdr; memset(&hdr, 0, sizeof(hdr));
512     set_le32(&hdr.sz_cpr, UPX_MAGIC_LE32);
513     fo->write(&hdr, sizeof(hdr));
514     flen = fpad4(fo);
515 
516     set_te64(&elfout.phdr[0].p_filesz, sz_pack2 + lsize);
517     set_te64(&elfout.phdr[0].p_memsz,  sz_pack2 + lsize);
518     if (0==xct_off) { // not shared library; adjust PT_LOAD
519         // On amd64: (2<<20)==.p_align, but Linux uses 4KiB pages.
520         // This allows [vvar], [vdso], etc to sneak into the gap
521         // between end_text and data, which we wish to prevent
522         // because the expanded program will use that space.
523         // So: pretend 4KiB pages.
524         upx_uint64_t const pm = (
525                Elf64_Ehdr::EM_X86_64 ==e_machine
526             //|| Elf64_Ehdr::EM_AARCH64==e_machine
527             //|| Elf64_Ehdr::EM_PPC64  ==e_machine  /* DOES NOT WORK! */
528             )
529             ? ((~(upx_uint64_t)0)<<12)
530             : page_mask;
531         v_hole = pm & (~pm + v_hole + get_te64(&elfout.phdr[0].p_vaddr));
532         set_te64(&elfout.phdr[1].p_vaddr, v_hole);
533         set_te64(&elfout.phdr[1].p_align, ((upx_uint64_t)0) - pm);
534         elfout.phdr[1].p_paddr = elfout.phdr[1].p_vaddr;
535         elfout.phdr[1].p_offset = 0;
536         set_te64(&elfout.phdr[1].p_memsz, getbrk(phdri, e_phnum) - v_hole);
537         set_te32(&elfout.phdr[1].p_flags, Elf32_Phdr::PF_W|Elf32_Phdr::PF_R);
538     }
539     if (0!=xct_off) {  // shared library
540         upx_uint64_t word = load_va + sz_pack2;
541         set_te64(&file_image[user_init_off], word);  // set the hook
542 
543         Elf64_Phdr *phdr = (Elf64_Phdr *)lowmem.subref(
544                 "bad e_phoff", e_phoff, e_phnum * sizeof(Elf64_Phdr));
545         unsigned off = fo->st_size();
546         so_slide = 0;
547         for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
548             upx_uint64_t const len  = get_te64(&phdr->p_filesz);
549             upx_uint64_t const ioff = get_te64(&phdri[j].p_offset);
550             upx_uint64_t       align= get_te64(&phdr->p_align);
551             unsigned const type = get_te32(&phdr->p_type);
552             if (Elf64_Phdr::PT_INTERP==type) {
553                 // Rotate to highest position, so it can be lopped
554                 // by decrementing e_phnum.
555                 memcpy((unsigned char *)ibuf, phdr, sizeof(*phdr));  // extract
556                 memmove(phdr, 1+phdr, (e_phnum - (1+ j))*sizeof(*phdr));  // overlapping
557                 memcpy(&phdr[e_phnum - (1+ j)], (unsigned char *)ibuf, sizeof(*phdr));  // to top
558                 --phdr; --e_phnum;
559                 set_te16(&ehdri.e_phnum, e_phnum);
560                 set_te16(&((Elf64_Ehdr *)(unsigned char *)lowmem)->e_phnum, e_phnum);
561                 continue;
562             }
563             if (PT_LOAD64 == type) {
564                 if ((xct_off - ioff) < len) { // Change length of compressed PT_LOAD.
565                     set_te64(&phdr->p_filesz, sz_pack2 + lsize - ioff);
566                     set_te64(&phdr->p_memsz,  sz_pack2 + lsize - ioff);
567                 }
568                 else if (xct_off < ioff) {  // Slide subsequent PT_LOAD.
569                     // AMD64 chip supports page sizes of 4KiB, 2MiB, and 1GiB;
570                     // the operating system chooses one.  .p_align typically
571                     // is a forward-looking 2MiB.  In 2009 Linux chooses 4KiB.
572                     // We choose 4KiB to waste less space.  If Linux chooses
573                     // 2MiB later, then our output will not run.
574                     if ((1u<<12) < align
575                     &&  Elf64_Ehdr::EM_X86_64 ==e_machine
576                     ) {
577                         align = 1u<<12;
578                         set_te64(&phdr->p_align, align);
579                     }
580                     off += (align-1) & (ioff - off);
581                     fo->seek(  off, SEEK_SET);
582                     fo->write(&file_image[ioff], len);
583                     so_slide = off - ioff;
584                     set_te64(&phdr->p_offset, so_slide + ioff);
585                 }
586                 continue;  // all done with this PT_LOAD
587             }
588             if (xct_off < ioff)
589                 set_te64(&phdr->p_offset, so_slide + ioff);
590         }  // end each Phdr
591 
592         if (opt->o_unix.android_shlib) {
593             // Update {DYNAMIC}.sh_offset by so_slide.
594             Elf64_Shdr *shdr = (Elf64_Shdr *)lowmem.subref(
595                     "bad e_shoff", xct_off - asl_delta, e_shnum * sizeof(Elf64_Shdr));
596             for (unsigned j = 0; j < e_shnum; ++shdr, ++j) {
597                 unsigned sh_type = get_te32(&shdr->sh_type);
598                 if (Elf64_Shdr::SHT_DYNAMIC == sh_type) {
599                     upx_uint64_t offset = get_te64(&shdr->sh_offset);
600                     set_te64(&shdr->sh_offset, so_slide + offset);
601                     fo->seek((j * sizeof(Elf64_Shdr)) + xct_off - asl_delta, SEEK_SET);
602                     fo->rewrite(shdr, sizeof(*shdr));
603                     fo->seek(0, SEEK_END);
604                 }
605                 if (Elf64_Shdr::SHT_RELA == sh_type
606                 &&  n_jmp_slot
607                 &&  !strcmp(".rela.plt", get_te32(&shdr->sh_name) + shstrtab)) {
608                     upx_uint64_t f_off = elf_get_offset_from_address(plt_off);
609                     fo->seek(so_slide + f_off, SEEK_SET);  // FIXME: assumes PT_LOAD[1]
610                     fo->rewrite(&file_image[f_off], n_jmp_slot * 8);
611                 }
612             }
613         }
614         else { // !opt->o_unix.android_shlib)
615             ehdri.e_shnum = 0;
616             ehdri.e_shoff = 0;
617             ehdri.e_shstrndx = 0;
618         }
619     }
620     return flen;
621 }
622 
623 void
addStubEntrySections(Filter const *)624 PackLinuxElf::addStubEntrySections(Filter const *)
625 {
626     addLoader("ELFMAINX", NULL);
627     if (hasLoaderSection("ELFMAINXu")) {
628             // brk() trouble if static
629         addLoader("ELFMAINXu", NULL);
630     }
631    //addLoader(getDecompressorSections(), NULL);
632     addLoader(
633         ( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL"
634         : M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL"
635         : M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL"
636         : M_IS_LZMA(ph.method)  ? "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"
637         : NULL), NULL);
638     if (hasLoaderSection("CFLUSH"))
639         addLoader("CFLUSH");
640     addLoader("ELFMAINY,IDENTSTR", NULL);
641     if (hasLoaderSection("ELFMAINZe")) { // ppc64 big-endian only
642         addLoader("ELFMAINZe", NULL);
643     }
644     addLoader("+40,ELFMAINZ", NULL);
645     if (hasLoaderSection("ANDMAJNZ")) { // Android trouble with args to DT_INIT
646         if (opt->o_unix.android_shlib) {
647             addLoader("ANDMAJNZ", NULL);  // constant PAGE_SIZE
648         }
649         else {
650             addLoader("ELFMAJNZ", NULL);  // PAGE_SIZE from AT_PAGESZ
651         }
652         addLoader("ELFMAKNZ", NULL);
653     }
654     if (hasLoaderSection("ELFMAINZu")) {
655         addLoader("ELFMAINZu", NULL);
656     }
657     addLoader("FOLDEXEC", NULL);
658 }
659 
660 
defineSymbols(Filter const *)661 void PackLinuxElf::defineSymbols(Filter const *)
662 {
663     linker->defineSymbol("O_BINFO", (!!opt->o_unix.is_ptinterp) | o_binfo);
664 }
665 
defineSymbols(Filter const * ft)666 void PackLinuxElf32::defineSymbols(Filter const *ft)
667 {
668     PackLinuxElf::defineSymbols(ft);
669 }
670 
defineSymbols(Filter const * ft)671 void PackLinuxElf64::defineSymbols(Filter const *ft)
672 {
673     PackLinuxElf::defineSymbols(ft);
674 }
675 
PackLinuxElf32(InputFile * f)676 PackLinuxElf32::PackLinuxElf32(InputFile *f)
677     : super(f), phdri(NULL), shdri(NULL),
678     gnu_stack(NULL), note_body(NULL),
679     page_mask(~0u<<lg2_page),
680     dynseg(NULL), hashtab(NULL), gashtab(NULL), dynsym(NULL),
681     jni_onload_sym(NULL),
682     shstrtab(NULL),
683     sec_strndx(NULL), sec_dynsym(NULL), sec_dynstr(NULL)
684     , symnum_end(0)
685 {
686     memset(&ehdri, 0, sizeof(ehdri));
687     if (f) {
688         f->seek(0, SEEK_SET);
689         f->readx(&ehdri, sizeof(ehdri));
690     }
691 }
692 
~PackLinuxElf32()693 PackLinuxElf32::~PackLinuxElf32()
694 {
695     delete[] note_body;
696 }
697 
PackLinuxElf64(InputFile * f)698 PackLinuxElf64::PackLinuxElf64(InputFile *f)
699     : super(f), phdri(NULL), shdri(NULL),
700     gnu_stack(NULL), note_body(NULL),
701     page_mask(~0ull<<lg2_page),
702     dynseg(NULL), hashtab(NULL), gashtab(NULL), dynsym(NULL),
703     jni_onload_sym(NULL),
704     shstrtab(NULL),
705     sec_strndx(NULL), sec_dynsym(NULL), sec_dynstr(NULL)
706     , symnum_end(0)
707 {
708     memset(&ehdri, 0, sizeof(ehdri));
709     if (f) {
710         f->seek(0, SEEK_SET);
711         f->readx(&ehdri, sizeof(ehdri));
712     }
713 }
714 
~PackLinuxElf64()715 PackLinuxElf64::~PackLinuxElf64()
716 {
717     delete[] note_body;
718 }
719 
720 // FIXME: should be templated with PackLinuxElf32help1
721 void
PackLinuxElf64help1(InputFile * f)722 PackLinuxElf64::PackLinuxElf64help1(InputFile *f)
723 {
724     e_type  = get_te16(&ehdri.e_type);
725     e_phnum = get_te16(&ehdri.e_phnum);
726     e_shnum = get_te16(&ehdri.e_shnum);
727     unsigned const e_phentsize = get_te16(&ehdri.e_phentsize);
728     if (ehdri.e_ident[Elf64_Ehdr::EI_CLASS]!=Elf64_Ehdr::ELFCLASS64
729     || sizeof(Elf64_Phdr) != e_phentsize
730     || (Elf64_Ehdr::ELFDATA2MSB == ehdri.e_ident[Elf64_Ehdr::EI_DATA]
731             && &N_BELE_RTP::be_policy != bele)
732     || (Elf64_Ehdr::ELFDATA2LSB == ehdri.e_ident[Elf64_Ehdr::EI_DATA]
733             && &N_BELE_RTP::le_policy != bele)) {
734         e_phoff = 0;
735         e_shoff = 0;
736         sz_phdrs = 0;
737         return;
738     }
739     if (0==e_phnum) throwCantUnpack("0==e_phnum");
740     e_phoff = get_te64(&ehdri.e_phoff);
741     upx_uint64_t const last_Phdr = e_phoff + e_phnum * sizeof(Elf64_Phdr);
742     if (last_Phdr < e_phoff || (unsigned long)file_size < last_Phdr) {
743         throwCantUnpack("bad e_phoff");
744     }
745     e_shoff = get_te64(&ehdri.e_shoff);
746     upx_uint64_t const last_Shdr = e_shoff + e_shnum * sizeof(Elf64_Shdr);
747     if (last_Shdr < e_shoff || (unsigned long)file_size < last_Shdr) {
748         if (opt->cmd == CMD_COMPRESS) {
749             throwCantUnpack("bad e_shoff");
750         }
751     }
752     sz_phdrs = e_phnum * e_phentsize;
753 
754     if (f && Elf64_Ehdr::ET_DYN!=e_type) {
755         unsigned const len = sz_phdrs + e_phoff;
756         alloc_file_image(file_image, len);
757         f->seek(0, SEEK_SET);
758         f->readx(file_image, len);
759         phdri= (Elf64_Phdr       *)(e_phoff + file_image);  // do not free() !!
760     }
761     if (f && Elf64_Ehdr::ET_DYN==e_type) {
762         // The DT_SYMTAB has no designated length.  Read the whole file.
763         alloc_file_image(file_image, file_size);
764         f->seek(0, SEEK_SET);
765         f->readx(file_image, file_size);
766         phdri= (Elf64_Phdr *)(e_phoff + file_image);  // do not free() !!
767         shdri= (Elf64_Shdr *)(e_shoff + file_image);  // do not free() !!
768         if (opt->cmd != CMD_COMPRESS) {
769             shdri = NULL;
770         }
771         sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
772         if (sec_dynsym) {
773             unsigned t = get_te32(&sec_dynsym->sh_link);
774             if (e_shnum <= t)
775                 throwCantPack("bad dynsym->sh_link");
776             sec_dynstr = &shdri[t];
777         }
778 
779         Elf64_Phdr const *phdr= phdri;
780         for (int j = e_phnum; --j>=0; ++phdr)
781         if (Elf64_Phdr::PT_DYNAMIC==get_te64(&phdr->p_type)) {
782             dynseg= (Elf64_Dyn const *)(check_pt_dynamic(phdr) + file_image);
783             invert_pt_dynamic(dynseg);
784         }
785         else if (PT_LOAD64==get_te32(&phdr->p_type)) {
786             check_pt_load(phdr);
787         }
788         // elf_find_dynamic() returns 0 if 0==dynseg.
789         dynstr =      (char const *)elf_find_dynamic(Elf64_Dyn::DT_STRTAB);
790         dynsym = (Elf64_Sym const *)elf_find_dynamic(Elf64_Dyn::DT_SYMTAB);
791         gashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_GNU_HASH);
792         hashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_HASH);
793         jni_onload_sym = elf_lookup("JNI_OnLoad");
794         if (jni_onload_sym) {
795             jni_onload_va = get_te64(&jni_onload_sym->st_value);
796             jni_onload_va = 0;  // FIXME not understood; need example
797         }
798     }
799 }
800 
newLinker() const801 Linker* PackLinuxElf64amd::newLinker() const
802 {
803     return new ElfLinkerAMD64;
804 }
805 
newLinker() const806 Linker* PackLinuxElf64arm::newLinker() const
807 {
808     return new ElfLinkerArm64LE;
809 }
810 
811 int const *
getCompressionMethods(int method,int level) const812 PackLinuxElf::getCompressionMethods(int method, int level) const
813 {
814     // No real dependency on LE32.
815     return Packer::getDefaultCompressionMethods_le32(method, level);
816 }
817 
818 int const *
getCompressionMethods(int method,int level) const819 PackLinuxElf32armLe::getCompressionMethods(int method, int level) const
820 {
821     return Packer::getDefaultCompressionMethods_8(method, level);
822 }
823 
824 int const *
getCompressionMethods(int method,int level) const825 PackLinuxElf32armBe::getCompressionMethods(int method, int level) const
826 {
827     return Packer::getDefaultCompressionMethods_8(method, level);
828 }
829 
830 int const *
getFilters() const831 PackLinuxElf32ppc::getFilters() const
832 {
833     static const int filters[] = {
834         0xd0,
835     FT_END };
836     return filters;
837 }
838 
839 int const *
getFilters() const840 PackLinuxElf64ppcle::getFilters() const
841 {
842     static const int filters[] = {
843         0xd0,
844     FT_END };
845     return filters;
846 }
847 
848 int const *
getFilters() const849 PackLinuxElf64ppc::getFilters() const
850 {
851     static const int filters[] = {
852         0xd0,
853     FT_END };
854     return filters;
855 }
856 
857 int const *
getFilters() const858 PackLinuxElf64amd::getFilters() const
859 {
860     static const int filters[] = {
861         0x49,
862     FT_END };
863     return filters;
864 }
865 
866 int const *
getFilters() const867 PackLinuxElf64arm::getFilters() const
868 {
869     static const int filters[] = {
870         0x52,
871     FT_END };
872     return filters;
873 }
874 
patchLoader()875 void PackLinuxElf32::patchLoader()
876 {
877 }
878 
patchLoader()879 void PackLinuxElf64::patchLoader()
880 {
881 }
882 
ARM_updateLoader(OutputFile *)883 void PackLinuxElf32::ARM_updateLoader(OutputFile * /*fo*/)
884 {
885     set_te32(&elfout.ehdr.e_entry, sz_pack2 +
886         linker->getSymbolOffset("_start") +
887         get_te32(&elfout.phdr[0].p_vaddr));
888 }
889 
updateLoader(OutputFile * fo)890 void PackLinuxElf32armLe::updateLoader(OutputFile *fo)
891 {
892     ARM_updateLoader(fo);
893 }
894 
updateLoader(OutputFile * fo)895 void PackLinuxElf32armBe::updateLoader(OutputFile *fo)
896 {
897     ARM_updateLoader(fo);
898 }
899 
updateLoader(OutputFile * fo)900 void PackLinuxElf32mipsel::updateLoader(OutputFile *fo)
901 {
902     ARM_updateLoader(fo);  // not ARM specific; (no 32-bit immediates)
903 }
904 
updateLoader(OutputFile * fo)905 void PackLinuxElf32mipseb::updateLoader(OutputFile *fo)
906 {
907     ARM_updateLoader(fo);  // not ARM specific; (no 32-bit immediates)
908 }
909 
updateLoader(OutputFile *)910 void PackLinuxElf32::updateLoader(OutputFile * /*fo*/)
911 {
912     unsigned start = linker->getSymbolOffset("_start");
913     unsigned vbase = get_te32(&elfout.phdr[0].p_vaddr);
914     set_te32(&elfout.ehdr.e_entry, start + sz_pack2 + vbase);
915 }
916 
updateLoader(OutputFile *)917 void PackLinuxElf64::updateLoader(OutputFile * /*fo*/)
918 {
919     if (xct_off) {
920         return;  // FIXME elfout has no values at all
921     }
922     upx_uint64_t const vbase = get_te64(&elfout.phdr[0].p_vaddr);
923     unsigned start = linker->getSymbolOffset("_start");
924 
925     if (get_te16(&elfout.ehdr.e_machine)==Elf64_Ehdr::EM_PPC64
926     &&  elfout.ehdr.e_ident[Elf64_Ehdr::EI_DATA]==Elf64_Ehdr::ELFDATA2MSB) {
927         unsigned descr = linker->getSymbolOffset("entry_descr");
928 
929         // External relocation of PPC64 function descriptor.
930         upx_uint64_t dot_entry = start + sz_pack2 + vbase;
931         upx_byte *p = getLoader();
932 
933         set_te64(&p[descr], dot_entry);
934         set_te64(&elfout.ehdr.e_entry, descr + sz_pack2 + vbase);
935     }
936     else {
937         set_te64(&elfout.ehdr.e_entry, start + sz_pack2 + vbase);
938     }
939 }
940 
PackLinuxElf32ppc(InputFile * f)941 PackLinuxElf32ppc::PackLinuxElf32ppc(InputFile *f)
942     : super(f)
943 {
944     e_machine = Elf32_Ehdr::EM_PPC;
945     ei_class  = Elf32_Ehdr::ELFCLASS32;
946     ei_data   = Elf32_Ehdr::ELFDATA2MSB;
947     ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
948 }
949 
~PackLinuxElf32ppc()950 PackLinuxElf32ppc::~PackLinuxElf32ppc()
951 {
952 }
953 
newLinker() const954 Linker* PackLinuxElf32ppc::newLinker() const
955 {
956     return new ElfLinkerPpc32;
957 }
958 
PackLinuxElf64ppcle(InputFile * f)959 PackLinuxElf64ppcle::PackLinuxElf64ppcle(InputFile *f)
960     : super(f), lg2_page(16), page_size(1u<<lg2_page)
961 {
962     e_machine = Elf64_Ehdr::EM_PPC64;
963     ei_class  = Elf64_Ehdr::ELFCLASS64;
964     ei_data   = Elf64_Ehdr::ELFDATA2LSB;
965     ei_osabi  = Elf64_Ehdr::ELFOSABI_LINUX;
966 }
967 
PackLinuxElf64ppc(InputFile * f)968 PackLinuxElf64ppc::PackLinuxElf64ppc(InputFile *f)
969     : super(f), lg2_page(16), page_size(1u<<lg2_page)
970 {
971     e_machine = Elf64_Ehdr::EM_PPC64;
972     ei_class  = Elf64_Ehdr::ELFCLASS64;
973     ei_data   = Elf64_Ehdr::ELFDATA2MSB;
974     ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
975 }
976 
~PackLinuxElf64ppcle()977 PackLinuxElf64ppcle::~PackLinuxElf64ppcle()
978 {
979 }
980 
~PackLinuxElf64ppc()981 PackLinuxElf64ppc::~PackLinuxElf64ppc()
982 {
983 }
984 
newLinker() const985 Linker* PackLinuxElf64ppcle::newLinker() const
986 {
987     return new ElfLinkerPpc64le;
988 }
989 
newLinker() const990 Linker* PackLinuxElf64ppc::newLinker() const
991 {
992     return new ElfLinkerPpc64;
993 }
994 
PackLinuxElf64amd(InputFile * f)995 PackLinuxElf64amd::PackLinuxElf64amd(InputFile *f)
996     : super(f)
997 {
998     // Why did PackLinuxElf64Le set lg2_page = 16 ?
999     // It causes trouble for check_pt_dynamic() from canPack().
1000     lg2_page = 12;  page_size = 1u<<lg2_page;
1001     e_machine = Elf64_Ehdr::EM_X86_64;
1002     ei_class = Elf64_Ehdr::ELFCLASS64;
1003     ei_data = Elf64_Ehdr::ELFDATA2LSB;
1004     ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
1005 }
1006 
PackLinuxElf64arm(InputFile * f)1007 PackLinuxElf64arm::PackLinuxElf64arm(InputFile *f)
1008     : super(f)
1009 {
1010     e_machine = Elf64_Ehdr::EM_AARCH64;
1011     ei_class = Elf64_Ehdr::ELFCLASS64;
1012     ei_data = Elf64_Ehdr::ELFDATA2LSB;
1013     ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
1014 }
1015 
~PackLinuxElf64amd()1016 PackLinuxElf64amd::~PackLinuxElf64amd()
1017 {
1018 }
1019 
~PackLinuxElf64arm()1020 PackLinuxElf64arm::~PackLinuxElf64arm()
1021 {
1022 }
1023 
1024 static unsigned
umax(unsigned a,unsigned b)1025 umax(unsigned a, unsigned b)
1026 {
1027     if (a <= b) {
1028         return b;
1029     }
1030     return a;
1031 }
1032 
addStubEntrySections(Filter const * ft)1033 void PackLinuxElf32x86::addStubEntrySections(Filter const *ft)
1034 {
1035     int const n_mru = ft->n_mru;  // FIXME: belongs to filter? packerf?
1036 
1037 // Rely on "+80CXXXX" [etc] in getDecompressorSections() packer_c.cpp */
1038 //    // Here is a quick summary of the format of the output file:
1039 //    linker->setLoaderAlignOffset(
1040 //            // Elf32_Ehdr
1041 //        sizeof(elfout.ehdr) +
1042 //            // Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
1043 //        (get_te16(&elfout.ehdr.e_phentsize) * get_te16(&elfout.ehdr.e_phnum)) +
1044 //            // checksum UPX! lsize version format
1045 //        sizeof(l_info) +
1046 //            // PT_DYNAMIC with DT_NEEDED "forwarded" from original file
1047 //        ((get_te16(&elfout.ehdr.e_phnum)==3)
1048 //            ? (unsigned) get_te32(&elfout.phdr[2].p_memsz)
1049 //            : 0) +
1050 //            // p_progid, p_filesize, p_blocksize
1051 //        sizeof(p_info) +
1052 //            // compressed data
1053 //        b_len + ph.c_len );
1054 
1055             // entry to stub
1056     addLoader("LEXEC000", NULL);
1057 
1058     if (ft->id) {
1059         { // decompr, unfilter are separate
1060             addLoader("LXUNF000", NULL);
1061             addLoader("LXUNF002", NULL);
1062                 if (0x80==(ft->id & 0xF0)) {
1063                     if (256==n_mru) {
1064                         addLoader("MRUBYTE0", NULL);
1065                     }
1066                     else if (n_mru) {
1067                         addLoader("LXMRU005", NULL);
1068                     }
1069                     if (n_mru) {
1070                         addLoader("LXMRU006", NULL);
1071                     }
1072                     else {
1073                         addLoader("LXMRU007", NULL);
1074                     }
1075             }
1076             else if (0x40==(ft->id & 0xF0)) {
1077                 addLoader("LXUNF008", NULL);
1078             }
1079             addLoader("LXUNF010", NULL);
1080         }
1081         if (n_mru) {
1082             addLoader("LEXEC009", NULL);
1083         }
1084     }
1085     addLoader("LEXEC010", NULL);
1086     addLoader(getDecompressorSections(), NULL);
1087     addLoader("LEXEC015", NULL);
1088     if (ft->id) {
1089         {  // decompr, unfilter are separate
1090             if (0x80!=(ft->id & 0xF0)) {
1091                 addLoader("LXUNF042", NULL);
1092             }
1093         }
1094         addFilter32(ft->id);
1095         { // decompr, unfilter are separate
1096             if (0x80==(ft->id & 0xF0)) {
1097                 if (0==n_mru) {
1098                     addLoader("LXMRU058", NULL);
1099                 }
1100             }
1101             addLoader("LXUNF035", NULL);
1102         }
1103     }
1104     else {
1105         addLoader("LEXEC017", NULL);
1106     }
1107 
1108     addLoader("IDENTSTR", NULL);
1109     addLoader("LEXEC020", NULL);
1110     addLoader("FOLDEXEC", NULL);
1111 }
1112 
defineSymbols(Filter const * const ft)1113 void PackLinuxElf32x86::defineSymbols(Filter const *const ft)
1114 {
1115     PackLinuxElf32::defineSymbols(ft);
1116 
1117     if (0x80==(ft->id & 0xF0)) {
1118         int const mru = ft->n_mru ? 1+ ft->n_mru : 0;
1119         if (mru && mru!=256) {
1120             unsigned const is_pwr2 = (0==((mru -1) & mru));
1121             linker->defineSymbol("NMRU", mru - is_pwr2);
1122         }
1123     }
1124 }
1125 
1126 void
buildLinuxLoader(upx_byte const * const proto,unsigned const szproto,upx_byte const * const fold,unsigned const szfold,Filter const * ft)1127 PackLinuxElf32::buildLinuxLoader(
1128     upx_byte const *const proto,
1129     unsigned        const szproto,
1130     upx_byte const *const fold,
1131     unsigned        const szfold,
1132     Filter const *ft
1133 )
1134 {
1135     initLoader(proto, szproto);
1136 
1137   if (0 < szfold) {
1138     struct b_info h; memset(&h, 0, sizeof(h));
1139     unsigned fold_hdrlen = 0;
1140     cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
1141     fold_hdrlen = umax(0x80, sizeof(hf->ehdr) +
1142         get_te16(&hf->ehdr.e_phentsize) * get_te16(&hf->ehdr.e_phnum) +
1143             sizeof(l_info) );
1144     h.sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen));
1145     h.b_method = (unsigned char) ph.method;
1146     h.b_ftid = (unsigned char) ph.filter;
1147     h.b_cto8 = (unsigned char) ph.filter_cto;
1148     unsigned char const *const uncLoader = fold_hdrlen + fold;
1149 
1150     h.sz_cpr = MemBuffer::getSizeForCompression(h.sz_unc + (0==h.sz_unc));
1151     unsigned char *const cprLoader = New(unsigned char, sizeof(h) + h.sz_cpr);
1152     {
1153     unsigned h_sz_cpr = h.sz_cpr;
1154     int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &h_sz_cpr,
1155         NULL, ph.method, 10, NULL, NULL );
1156     h.sz_cpr = h_sz_cpr;
1157     if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
1158         throwInternalError("loader compression failed");
1159     }
1160 #if 0  //{  debugging only
1161     if (M_IS_LZMA(ph.method)) {
1162         ucl_uint tmp_len = h.sz_unc;  // LZMA uses this as EOF
1163         unsigned char *tmp = New(unsigned char, tmp_len);
1164         memset(tmp, 0, tmp_len);
1165         int r = upx_decompress(sizeof(h) + cprLoader, h.sz_cpr, tmp, &tmp_len, h.b_method, NULL);
1166         if (r == UPX_E_OUT_OF_MEMORY)
1167             throwOutOfMemoryException();
1168         printf("\n%d %d: %d %d %d\n", h.b_method, r, h.sz_cpr, h.sz_unc, tmp_len);
1169         for (unsigned j=0; j < h.sz_unc; ++j) if (tmp[j]!=uncLoader[j]) {
1170             printf("%d: %x %x\n", j, tmp[j], uncLoader[j]);
1171         }
1172         delete[] tmp;
1173     }
1174 #endif  //}
1175     unsigned const sz_cpr = h.sz_cpr;
1176     set_te32(&h.sz_cpr, h.sz_cpr);
1177     set_te32(&h.sz_unc, h.sz_unc);
1178     memcpy(cprLoader, &h, sizeof(h));
1179 
1180     // This adds the definition to the "library", to be used later.
1181     linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + sz_cpr, 0);
1182     delete [] cprLoader;
1183   }
1184   else {
1185     linker->addSection("FOLDEXEC", "", 0, 0);
1186   }
1187 
1188     addStubEntrySections(ft);
1189 
1190     if (0==xct_off)
1191         defineSymbols(ft);  // main program only, not for shared lib
1192     relocateLoader();
1193 }
1194 
1195 void
buildLinuxLoader(upx_byte const * const proto,unsigned const szproto,upx_byte const * const fold,unsigned const szfold,Filter const * ft)1196 PackLinuxElf64::buildLinuxLoader(
1197     upx_byte const *const proto,
1198     unsigned        const szproto,
1199     upx_byte const *const fold,
1200     unsigned        const szfold,
1201     Filter const *ft
1202 )
1203 {
1204     initLoader(proto, szproto);
1205 
1206   if (0 < szfold) {
1207     struct b_info h; memset(&h, 0, sizeof(h));
1208     unsigned fold_hdrlen = 0;
1209     cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
1210     fold_hdrlen = umax(0x80, sizeof(hf->ehdr) +
1211         get_te16(&hf->ehdr.e_phentsize) * get_te16(&hf->ehdr.e_phnum) +
1212             sizeof(l_info) );
1213     h.sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen));
1214     h.b_method = (unsigned char) ph.method;
1215     h.b_ftid = (unsigned char) ph.filter;
1216     h.b_cto8 = (unsigned char) ph.filter_cto;
1217     unsigned char const *const uncLoader = fold_hdrlen + fold;
1218 
1219     h.sz_cpr = MemBuffer::getSizeForCompression(h.sz_unc + (0==h.sz_unc));
1220     unsigned char *const cprLoader = New(unsigned char, sizeof(h) + h.sz_cpr);
1221     {
1222     unsigned h_sz_cpr = h.sz_cpr;
1223     int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &h_sz_cpr,
1224         NULL, ph.method, 10, NULL, NULL );
1225     h.sz_cpr = h_sz_cpr;
1226     if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
1227         throwInternalError("loader compression failed");
1228     }
1229 #if 0  //{  debugging only
1230     if (M_IS_LZMA(ph.method)) {
1231         ucl_uint tmp_len = h.sz_unc;  // LZMA uses this as EOF
1232         unsigned char *tmp = New(unsigned char, tmp_len);
1233         memset(tmp, 0, tmp_len);
1234         int r = upx_decompress(sizeof(h) + cprLoader, h.sz_cpr, tmp, &tmp_len, h.b_method, NULL);
1235         if (r == UPX_E_OUT_OF_MEMORY)
1236             throwOutOfMemoryException();
1237         printf("\n%d %d: %d %d %d\n", h.b_method, r, h.sz_cpr, h.sz_unc, tmp_len);
1238         for (unsigned j=0; j < h.sz_unc; ++j) if (tmp[j]!=uncLoader[j]) {
1239             printf("%d: %x %x\n", j, tmp[j], uncLoader[j]);
1240         }
1241         delete[] tmp;
1242     }
1243 #endif  //}
1244     unsigned const sz_cpr = h.sz_cpr;
1245     set_te32(&h.sz_cpr, h.sz_cpr);
1246     set_te32(&h.sz_unc, h.sz_unc);
1247     memcpy(cprLoader, &h, sizeof(h));
1248 
1249     // This adds the definition to the "library", to be used later.
1250     linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + sz_cpr, 0);
1251     delete [] cprLoader;
1252   }
1253   else {
1254     linker->addSection("FOLDEXEC", "", 0, 0);
1255   }
1256 
1257     addStubEntrySections(ft);
1258 
1259     if (0==xct_off)
1260         defineSymbols(ft);  // main program only, not for shared lib
1261     relocateLoader();
1262 }
1263 
1264 void
defineSymbols(Filter const * ft)1265 PackLinuxElf64amd::defineSymbols(Filter const *ft)
1266 {
1267     PackLinuxElf64::defineSymbols(ft);
1268 }
1269 
1270 static const
1271 #include "stub/i386-linux.elf-entry.h"
1272 static const
1273 #include "stub/i386-linux.elf-fold.h"
1274 static const
1275 #include "stub/i386-linux.shlib-init.h"
1276 
1277 void
buildLoader(const Filter * ft)1278 PackLinuxElf32x86::buildLoader(const Filter *ft)
1279 {
1280     if (0!=xct_off) {  // shared library
1281         buildLinuxLoader(
1282             stub_i386_linux_shlib_init, sizeof(stub_i386_linux_shlib_init),
1283             NULL,                       0,                                ft );
1284         return;
1285     }
1286     unsigned char tmp[sizeof(stub_i386_linux_elf_fold)];
1287     memcpy(tmp, stub_i386_linux_elf_fold, sizeof(stub_i386_linux_elf_fold));
1288     checkPatch(NULL, 0, 0, 0);  // reset
1289     if (opt->o_unix.is_ptinterp) {
1290         unsigned j;
1291         for (j = 0; j < sizeof(stub_i386_linux_elf_fold)-1; ++j) {
1292             if (0x60==tmp[  j]
1293             &&  0x47==tmp[1+j] ) {
1294                 /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
1295                 tmp[  j] = 0x47;
1296                 tmp[1+j] = 0x60;
1297                 break;
1298             }
1299         }
1300     }
1301     buildLinuxLoader(
1302         stub_i386_linux_elf_entry, sizeof(stub_i386_linux_elf_entry),
1303         tmp,                       sizeof(stub_i386_linux_elf_fold),  ft );
1304 }
1305 
1306 static const
1307 #include "stub/i386-bsd.elf-entry.h"
1308 static const
1309 #include "stub/i386-bsd.elf-fold.h"
1310 
1311 void
buildLoader(const Filter * ft)1312 PackBSDElf32x86::buildLoader(const Filter *ft)
1313 {
1314     unsigned char tmp[sizeof(stub_i386_bsd_elf_fold)];
1315     memcpy(tmp, stub_i386_bsd_elf_fold, sizeof(stub_i386_bsd_elf_fold));
1316     checkPatch(NULL, 0, 0, 0);  // reset
1317     if (opt->o_unix.is_ptinterp) {
1318         unsigned j;
1319         for (j = 0; j < sizeof(stub_i386_bsd_elf_fold)-1; ++j) {
1320             if (0x60==tmp[  j]
1321             &&  0x47==tmp[1+j] ) {
1322                 /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
1323                 tmp[  j] = 0x47;
1324                 tmp[1+j] = 0x60;
1325                 break;
1326             }
1327         }
1328     }
1329     buildLinuxLoader(
1330         stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
1331         tmp,                     sizeof(stub_i386_bsd_elf_fold), ft);
1332 }
1333 
1334 static const
1335 #include "stub/i386-netbsd.elf-entry.h"
1336 
1337 static const
1338 #include "stub/i386-netbsd.elf-fold.h"
1339 
1340 #define WANT_NHDR_ENUM
1341 #include "p_elf_enum.h"
1342 
1343 void
buildLoader(const Filter * ft)1344 PackNetBSDElf32x86::buildLoader(const Filter *ft)
1345 {
1346     unsigned char tmp[sizeof(stub_i386_netbsd_elf_fold)];
1347     memcpy(tmp, stub_i386_netbsd_elf_fold, sizeof(stub_i386_netbsd_elf_fold));
1348     checkPatch(NULL, 0, 0, 0);  // reset
1349     if (opt->o_unix.is_ptinterp) {
1350         unsigned j;
1351         for (j = 0; j < sizeof(stub_i386_netbsd_elf_fold)-1; ++j) {
1352             if (0x60==tmp[  j]
1353             &&  0x47==tmp[1+j] ) {
1354                 /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
1355                 tmp[  j] = 0x47;
1356                 tmp[1+j] = 0x60;
1357                 break;
1358             }
1359         }
1360     }
1361     buildLinuxLoader(
1362         stub_i386_netbsd_elf_entry, sizeof(stub_i386_netbsd_elf_entry),
1363         tmp,                        sizeof(stub_i386_netbsd_elf_fold), ft);
1364 }
1365 
1366 static const
1367 #include "stub/i386-openbsd.elf-fold.h"
1368 
1369 void
buildLoader(const Filter * ft)1370 PackOpenBSDElf32x86::buildLoader(const Filter *ft)
1371 {
1372     unsigned char tmp[sizeof(stub_i386_openbsd_elf_fold)];
1373     memcpy(tmp, stub_i386_openbsd_elf_fold, sizeof(stub_i386_openbsd_elf_fold));
1374     checkPatch(NULL, 0, 0, 0);  // reset
1375     if (opt->o_unix.is_ptinterp) {
1376         unsigned j;
1377         for (j = 0; j < sizeof(stub_i386_openbsd_elf_fold)-1; ++j) {
1378             if (0x60==tmp[  j]
1379             &&  0x47==tmp[1+j] ) {
1380                 /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
1381                 tmp[  j] = 0x47;
1382                 tmp[1+j] = 0x60;
1383                 break;
1384             }
1385         }
1386     }
1387     buildLinuxLoader(
1388         stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
1389         tmp,                     sizeof(stub_i386_openbsd_elf_fold), ft);
1390 }
1391 
1392 static const
1393 #include "stub/arm.v5a-linux.elf-entry.h"
1394 static const
1395 #include "stub/arm.v5a-linux.elf-fold.h"
1396 static const
1397 #include "stub/arm.v5t-linux.shlib-init.h"
1398 
1399 static const
1400 #include "stub/arm.v4a-linux.elf-entry.h"
1401 static const
1402 #include "stub/arm.v4a-linux.elf-fold.h"
1403 #if 0
1404 static const
1405 #include "stub/arm.v4a-linux.shlib-init.h"
1406 #endif
1407 
1408 static const
1409 #include "stub/armeb.v4a-linux.elf-entry.h"
1410 static const
1411 #include "stub/armeb.v4a-linux.elf-fold.h"
1412 
1413 #include "mem.h"
1414 
1415 void
buildLoader(Filter const * ft)1416 PackLinuxElf32armBe::buildLoader(Filter const *ft)
1417 {
1418     buildLinuxLoader(
1419         stub_armeb_v4a_linux_elf_entry, sizeof(stub_armeb_v4a_linux_elf_entry),
1420         stub_armeb_v4a_linux_elf_fold,  sizeof(stub_armeb_v4a_linux_elf_fold), ft);
1421 }
1422 
1423 void
buildLoader(Filter const * ft)1424 PackLinuxElf32armLe::buildLoader(Filter const *ft)
1425 {
1426     if (Elf32_Ehdr::ELFOSABI_LINUX==ei_osabi) {
1427 
1428         if (0!=xct_off) {  // shared library
1429             buildLinuxLoader(
1430                 stub_arm_v5t_linux_shlib_init, sizeof(stub_arm_v5t_linux_shlib_init),
1431                 NULL,                      0,                                ft );
1432             return;
1433         }
1434         buildLinuxLoader(
1435             stub_arm_v5a_linux_elf_entry, sizeof(stub_arm_v5a_linux_elf_entry),
1436             stub_arm_v5a_linux_elf_fold,  sizeof(stub_arm_v5a_linux_elf_fold), ft);
1437     }
1438     else {
1439         buildLinuxLoader(
1440             stub_arm_v4a_linux_elf_entry, sizeof(stub_arm_v4a_linux_elf_entry),
1441             stub_arm_v4a_linux_elf_fold,  sizeof(stub_arm_v4a_linux_elf_fold), ft);
1442     }
1443 }
1444 
1445 static const
1446 #include "stub/mipsel.r3000-linux.elf-entry.h"
1447 static const
1448 #include "stub/mipsel.r3000-linux.elf-fold.h"
1449 static const
1450 #include "stub/mipsel.r3000-linux.shlib-init.h"
1451 
1452 void
buildLoader(Filter const * ft)1453 PackLinuxElf32mipsel::buildLoader(Filter const *ft)
1454 {
1455     if (0!=xct_off) {  // shared library
1456         buildLinuxLoader(
1457             stub_mipsel_r3000_linux_shlib_init, sizeof(stub_mipsel_r3000_linux_shlib_init),
1458             NULL,                        0,                                 ft );
1459         return;
1460     }
1461     buildLinuxLoader(
1462         stub_mipsel_r3000_linux_elf_entry, sizeof(stub_mipsel_r3000_linux_elf_entry),
1463         stub_mipsel_r3000_linux_elf_fold,  sizeof(stub_mipsel_r3000_linux_elf_fold), ft);
1464 }
1465 
1466 static const
1467 #include "stub/mips.r3000-linux.elf-entry.h"
1468 static const
1469 #include "stub/mips.r3000-linux.elf-fold.h"
1470 static const
1471 #include "stub/mips.r3000-linux.shlib-init.h"
1472 
1473 void
buildLoader(Filter const * ft)1474 PackLinuxElf32mipseb::buildLoader(Filter const *ft)
1475 {
1476     if (0!=xct_off) {  // shared library
1477         buildLinuxLoader(
1478             stub_mips_r3000_linux_shlib_init, sizeof(stub_mips_r3000_linux_shlib_init),
1479             NULL,                        0,                                 ft );
1480         return;
1481     }
1482     buildLinuxLoader(
1483         stub_mips_r3000_linux_elf_entry, sizeof(stub_mips_r3000_linux_elf_entry),
1484         stub_mips_r3000_linux_elf_fold,  sizeof(stub_mips_r3000_linux_elf_fold), ft);
1485 }
1486 
1487 static const
1488 #include "stub/powerpc-linux.elf-entry.h"
1489 static const
1490 #include "stub/powerpc-linux.elf-fold.h"
1491 
1492 void
buildLoader(const Filter * ft)1493 PackLinuxElf32ppc::buildLoader(const Filter *ft)
1494 {
1495     buildLinuxLoader(
1496         stub_powerpc_linux_elf_entry, sizeof(stub_powerpc_linux_elf_entry),
1497         stub_powerpc_linux_elf_fold,  sizeof(stub_powerpc_linux_elf_fold), ft);
1498 }
1499 
1500 static const
1501 #include "stub/powerpc64le-linux.elf-entry.h"
1502 static const
1503 #include "stub/powerpc64le-linux.elf-fold.h"
1504 
1505 void
buildLoader(const Filter * ft)1506 PackLinuxElf64ppcle::buildLoader(const Filter *ft)
1507 {
1508     buildLinuxLoader(
1509         stub_powerpc64le_linux_elf_entry, sizeof(stub_powerpc64le_linux_elf_entry),
1510         stub_powerpc64le_linux_elf_fold,  sizeof(stub_powerpc64le_linux_elf_fold), ft);
1511 }
1512 
1513 static const
1514 #include "stub/powerpc64-linux.elf-entry.h"
1515 static const
1516 #include "stub/powerpc64-linux.elf-fold.h"
1517 
1518 void
buildLoader(const Filter * ft)1519 PackLinuxElf64ppc::buildLoader(const Filter *ft)
1520 {
1521     buildLinuxLoader(
1522         stub_powerpc64_linux_elf_entry, sizeof(stub_powerpc64_linux_elf_entry),
1523         stub_powerpc64_linux_elf_fold,  sizeof(stub_powerpc64_linux_elf_fold), ft);
1524 }
1525 
1526 static const
1527 #include "stub/amd64-linux.elf-entry.h"
1528 static const
1529 #include "stub/amd64-linux.elf-fold.h"
1530 static const
1531 #include "stub/amd64-linux.shlib-init.h"
1532 
1533 void
buildLoader(const Filter * ft)1534 PackLinuxElf64amd::buildLoader(const Filter *ft)
1535 {
1536     if (0!=xct_off) {  // shared library
1537         buildLinuxLoader(
1538             stub_amd64_linux_shlib_init, sizeof(stub_amd64_linux_shlib_init),
1539             NULL,                        0,                                 ft );
1540         return;
1541     }
1542     buildLinuxLoader(
1543         stub_amd64_linux_elf_entry, sizeof(stub_amd64_linux_elf_entry),
1544         stub_amd64_linux_elf_fold,  sizeof(stub_amd64_linux_elf_fold), ft);
1545 }
1546 
1547 static const
1548 #include "stub/arm64-linux.elf-entry.h"
1549 static const
1550 #include "stub/arm64-linux.elf-fold.h"
1551 static const
1552 #include "stub/arm64-linux.shlib-init.h"
1553 
1554 void
buildLoader(const Filter * ft)1555 PackLinuxElf64arm::buildLoader(const Filter *ft)
1556 {
1557     if (0!=xct_off) {  // shared library
1558         buildLinuxLoader(
1559             stub_arm64_linux_shlib_init, sizeof(stub_arm64_linux_shlib_init),
1560             NULL,                        0,                                 ft );
1561         return;
1562     }
1563     buildLinuxLoader(
1564         stub_arm64_linux_elf_entry, sizeof(stub_arm64_linux_elf_entry),
1565         stub_arm64_linux_elf_fold,  sizeof(stub_arm64_linux_elf_fold), ft);
1566 }
1567 
1568 void
invert_pt_dynamic(Elf32_Dyn const * dynp)1569 PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp)
1570 {
1571     if (dt_table[Elf32_Dyn::DT_NULL]) {
1572         return;  // not 1st time; do not change upx_dt_init
1573     }
1574     Elf32_Dyn const *const dynp0 = dynp;
1575     unsigned ndx = 1+ 0;
1576     if (dynp)
1577     for (; ; ++ndx, ++dynp) {
1578         unsigned const d_tag = get_te32(&dynp->d_tag);
1579         if (d_tag < DT_NUM) {
1580             if (Elf32_Dyn::DT_NEEDED != d_tag
1581             &&  dt_table[d_tag]
1582             &&    get_te32(&dynp->d_val)
1583                != get_te32(&dynp0[-1+ dt_table[d_tag]].d_val)) {
1584                 char msg[50]; snprintf(msg, sizeof(msg),
1585                     "duplicate DT_%#x: [%#x] [%#x]",
1586                     d_tag, -1+ dt_table[d_tag], -1+ ndx);
1587                 throwCantPack(msg);
1588             }
1589             dt_table[d_tag] = ndx;
1590         }
1591         if (Elf32_Dyn::DT_NULL == d_tag) {
1592             break;  // check here so that dt_table[DT_NULL] is set
1593         }
1594     }
1595     upx_dt_init = 0;
1596          if (dt_table[Elf32_Dyn::DT_INIT])          upx_dt_init = Elf32_Dyn::DT_INIT;
1597     else if (dt_table[Elf32_Dyn::DT_PREINIT_ARRAY]) upx_dt_init = Elf32_Dyn::DT_PREINIT_ARRAY;
1598     else if (dt_table[Elf32_Dyn::DT_INIT_ARRAY])    upx_dt_init = Elf32_Dyn::DT_INIT_ARRAY;
1599 
1600     unsigned const z_str = dt_table[Elf32_Dyn::DT_STRSZ];
1601     if (z_str) {
1602         strtab_end = get_te32(&dynp0[-1+ z_str].d_val);
1603         if ((u32_t)file_size <= strtab_end) { // FIXME: weak
1604             char msg[50]; snprintf(msg, sizeof(msg),
1605                 "bad DT_STRSZ %#x", strtab_end);
1606             throwCantPack(msg);
1607         }
1608     }
1609     unsigned const x_sym = dt_table[Elf32_Dyn::DT_SYMTAB];
1610     unsigned const x_str = dt_table[Elf32_Dyn::DT_STRTAB];
1611     if (x_sym && x_str) {
1612         upx_uint32_t const v_sym = get_te32(&dynp0[-1+ x_sym].d_val);
1613         upx_uint32_t const v_str = get_te32(&dynp0[-1+ x_str].d_val);
1614         unsigned const  z_sym = dt_table[Elf32_Dyn::DT_SYMENT];
1615         unsigned const sz_sym = !z_sym ? sizeof(Elf32_Sym)
1616             : get_te32(&dynp0[-1+ z_sym].d_val);
1617         if (sz_sym < sizeof(Elf32_Sym)) {
1618             char msg[50]; snprintf(msg, sizeof(msg),
1619                 "bad DT_SYMENT %x", sz_sym);
1620             throwCantPack(msg);
1621         }
1622         if (v_sym < v_str) {
1623             symnum_end = (v_str - v_sym) / sz_sym;
1624         }
1625         if (symnum_end < 1) {
1626             throwCantPack("bad DT_SYMTAB");
1627         }
1628     }
1629     // DT_HASH often ends at DT_SYMTAB
1630     unsigned const v_hsh = elf_unsigned_dynamic(Elf32_Dyn::DT_HASH);
1631     if (v_hsh && file_image) {
1632         hashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_HASH);
1633         if (!hashtab) {
1634             char msg[40]; snprintf(msg, sizeof(msg),
1635                "bad DT_HASH %#x", v_hsh);
1636             throwCantPack(msg);
1637         }
1638         unsigned const nbucket = get_te32(&hashtab[0]);
1639         unsigned const *const buckets = &hashtab[2];
1640         unsigned const *const chains = &buckets[nbucket]; (void)chains;
1641 
1642         unsigned const v_sym = !x_sym ? 0 : get_te32(&dynp0[-1+ x_sym].d_val);
1643         if (!nbucket || !v_sym
1644         || (nbucket>>31) || (file_size/sizeof(unsigned)) <= (2*nbucket)  // FIXME: weak
1645         || ((v_hsh < v_sym) && (v_sym - v_hsh) < (sizeof(unsigned)*2  // headers
1646                 + sizeof(*buckets)*nbucket  // buckets
1647                 + sizeof(*chains) *nbucket  // chains
1648            ))
1649         ) {
1650             char msg[90]; snprintf(msg, sizeof(msg),
1651                 "bad DT_HASH nbucket=%#x  len=%#x",
1652                 nbucket, (v_sym - v_hsh));
1653             throwCantPack(msg);
1654         }
1655     }
1656     // DT_GNU_HASH often ends at DT_SYMTAB;  FIXME: not for Android?
1657     unsigned const v_gsh = elf_unsigned_dynamic(Elf32_Dyn::DT_GNU_HASH);
1658     if (v_gsh && file_image) {
1659         gashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_GNU_HASH);
1660         if (!gashtab) {
1661             char msg[40]; snprintf(msg, sizeof(msg),
1662                "bad DT_GNU_HASH %#x", v_gsh);
1663             throwCantPack(msg);
1664         }
1665         unsigned const n_bucket = get_te32(&gashtab[0]);
1666         unsigned const n_bitmask = get_te32(&gashtab[2]);
1667         unsigned const gnu_shift = get_te32(&gashtab[3]);
1668         unsigned const *const bitmask = (unsigned const *)(void const *)&gashtab[4];
1669         unsigned     const *const buckets = (unsigned const *)&bitmask[n_bitmask];
1670         unsigned     const *const hasharr = &buckets[n_bucket]; (void)hasharr;
1671       //unsigned     const *const gashend = &hasharr[n_bucket];  // minimum
1672 
1673         unsigned const v_sym = !x_sym ? 0 : get_te32(&dynp0[-1+ x_sym].d_val);
1674         if (!n_bucket || !n_bitmask || !v_sym
1675         || (-1+ n_bitmask) & n_bitmask  // not a power of 2
1676         || 8*sizeof(unsigned) <= gnu_shift  // shifted result always == 0
1677         || (n_bucket>>30)  // fie on fuzzers
1678         || (n_bitmask>>30)
1679         || (file_size / sizeof(unsigned)) <= (n_bitmask + 2*n_bucket)  // FIXME: weak
1680         // FIXME: next test does work for Android?
1681         || ((v_gsh < v_sym) && (v_sym - v_gsh) < (sizeof(unsigned)*4  // headers
1682                 + sizeof(*bitmask)*n_bitmask  // bitmask
1683                 + sizeof(*buckets)*n_bucket  // buckets
1684                 + sizeof(*hasharr)*n_bucket  // hasharr
1685             ))
1686         ) {
1687             char msg[90]; snprintf(msg, sizeof(msg),
1688                 "bad DT_GNU_HASH n_bucket=%#x  n_bitmask=%#x  len=%#x",
1689                 n_bucket, n_bitmask, v_sym - v_gsh);
1690             throwCantPack(msg);
1691         }
1692     }
1693     unsigned const e_shstrndx = get_te16(&ehdri.e_shstrndx);
1694     if (e_shnum <= e_shstrndx
1695     &&  !(0==e_shnum && 0==e_shstrndx) ) {
1696         char msg[40]; snprintf(msg, sizeof(msg),
1697             "bad .e_shstrndx %d >= .e_shnum %d", e_shstrndx, e_shnum);
1698         throwCantPack(msg);
1699     }
1700 }
1701 
1702 Elf32_Phdr const *
elf_find_ptype(unsigned type,Elf32_Phdr const * phdr,unsigned phnum)1703 PackLinuxElf32::elf_find_ptype(unsigned type, Elf32_Phdr const *phdr, unsigned phnum)
1704 {
1705     for (unsigned j = 0; j < phnum; ++j, ++phdr) {
1706         if (type == get_te32(&phdr->p_type)) {
1707             return phdr;
1708         }
1709     }
1710     return 0;
1711 }
1712 
1713 Elf64_Phdr const *
elf_find_ptype(unsigned type,Elf64_Phdr const * phdr,unsigned phnum)1714 PackLinuxElf64::elf_find_ptype(unsigned type, Elf64_Phdr const *phdr, unsigned phnum)
1715 {
1716     for (unsigned j = 0; j < phnum; ++j, ++phdr) {
1717         if (type == get_te32(&phdr->p_type)) {
1718             return phdr;
1719         }
1720     }
1721     return 0;
1722 }
1723 
elf_find_section_name(char const * const name) const1724 Elf32_Shdr const *PackLinuxElf32::elf_find_section_name(
1725     char const *const name
1726 ) const
1727 {
1728     Elf32_Shdr const *shdr = shdri;
1729     if (!shdr) {
1730         return 0;
1731     }
1732     int j = e_shnum;
1733     for (; 0 <=--j; ++shdr) {
1734         unsigned const sh_name = get_te32(&shdr->sh_name);
1735         if ((u32_t)file_size <= sh_name) {  // FIXME: weak
1736             char msg[50]; snprintf(msg, sizeof(msg),
1737                 "bad Elf32_Shdr[%d].sh_name %#x",
1738                 -1+ e_shnum -j, sh_name);
1739             throwCantPack(msg);
1740         }
1741         if (0==strcmp(name, &shstrtab[sh_name])) {
1742             return shdr;
1743         }
1744     }
1745     return 0;
1746 }
1747 
elf_find_section_name(char const * const name) const1748 Elf64_Shdr const *PackLinuxElf64::elf_find_section_name(
1749     char const *const name
1750 ) const
1751 {
1752     Elf64_Shdr const *shdr = shdri;
1753     if (!shdr) {
1754         return 0;
1755     }
1756     int j = e_shnum;
1757     for (; 0 <=--j; ++shdr) {
1758         unsigned const sh_name = get_te32(&shdr->sh_name);
1759         if ((u32_t)file_size <= sh_name) {  // FIXME: weak
1760             char msg[50]; snprintf(msg, sizeof(msg),
1761                 "bad Elf64_Shdr[%d].sh_name %#x",
1762                 -1+ e_shnum -j, sh_name);
1763             throwCantPack(msg);
1764         }
1765         if (0==strcmp(name, &shstrtab[sh_name])) {
1766             return shdr;
1767         }
1768     }
1769     return 0;
1770 }
1771 
elf_find_section_type(unsigned const type) const1772 Elf32_Shdr const *PackLinuxElf32::elf_find_section_type(
1773     unsigned const type
1774 ) const
1775 {
1776     Elf32_Shdr const *shdr = shdri;
1777     if (!shdr) {
1778         return 0;
1779     }
1780     int j = e_shnum;
1781     for (; 0 <=--j; ++shdr) {
1782         if (type==get_te32(&shdr->sh_type)) {
1783             return shdr;
1784         }
1785     }
1786     return 0;
1787 }
1788 
elf_find_section_type(unsigned const type) const1789 Elf64_Shdr const *PackLinuxElf64::elf_find_section_type(
1790     unsigned const type
1791 ) const
1792 {
1793     Elf64_Shdr const *shdr = shdri;
1794     if (!shdr) {
1795         return 0;
1796     }
1797     int j = e_shnum;
1798     for (; 0 <=--j; ++shdr) {
1799         if (type==get_te32(&shdr->sh_type)) {
1800             return shdr;
1801         }
1802     }
1803     return 0;
1804 }
1805 
get_str_name(unsigned st_name,unsigned symnum) const1806 char const *PackLinuxElf64::get_str_name(unsigned st_name, unsigned symnum) const
1807 {
1808     if (strtab_end <= st_name) {
1809         char msg[70]; snprintf(msg, sizeof(msg),
1810             "bad .st_name %#x in DT_SYMTAB[%d]", st_name, symnum);
1811         throwCantPack(msg);
1812     }
1813     return &dynstr[st_name];
1814 }
1815 
get_dynsym_name(unsigned symnum,unsigned relnum) const1816 char const *PackLinuxElf64::get_dynsym_name(unsigned symnum, unsigned relnum) const
1817 {
1818     if (symnum_end <= symnum) {
1819         char msg[70]; snprintf(msg, sizeof(msg),
1820             "bad symnum %#x in Elf64_Rel[%d]", symnum, relnum);
1821         throwCantPack(msg);
1822     }
1823     return get_str_name(get_te32(&dynsym[symnum].st_name), symnum);
1824 }
1825 
calls_crt1(Elf64_Rela const * rela,int sz)1826 bool PackLinuxElf64::calls_crt1(Elf64_Rela const *rela, int sz)
1827 {
1828     if (!dynsym || !dynstr || !rela) {
1829         return false;
1830     }
1831     for (unsigned relnum= 0; 0 < sz; (sz -= sizeof(Elf64_Rela)), ++rela, ++relnum) {
1832         unsigned const symnum = get_te64(&rela->r_info) >> 32;
1833         char const *const symnam = get_dynsym_name(symnum, relnum);
1834         if (0==strcmp(symnam, "__libc_start_main")  // glibc
1835         ||  0==strcmp(symnam, "__libc_init")  // Android
1836         ||  0==strcmp(symnam, "__uClibc_main")
1837         ||  0==strcmp(symnam, "__uClibc_start_main"))
1838             return true;
1839     }
1840     return false;
1841 }
1842 
get_str_name(unsigned st_name,unsigned symnum) const1843 char const *PackLinuxElf32::get_str_name(unsigned st_name, unsigned symnum) const
1844 {
1845     if (strtab_end <= st_name) {
1846         char msg[70]; snprintf(msg, sizeof(msg),
1847             "bad .st_name %#x in DT_SYMTAB[%d]\n", st_name, symnum);
1848         throwCantPack(msg);
1849     }
1850     return &dynstr[st_name];
1851 }
1852 
get_dynsym_name(unsigned symnum,unsigned relnum) const1853 char const *PackLinuxElf32::get_dynsym_name(unsigned symnum, unsigned relnum) const
1854 {
1855     if (symnum_end <= symnum) {
1856         char msg[70]; snprintf(msg, sizeof(msg),
1857             "bad symnum %#x in Elf32_Rel[%d]\n", symnum, relnum);
1858         throwCantPack(msg);
1859     }
1860     return get_str_name(get_te32(&dynsym[symnum].st_name), symnum);
1861 }
1862 
calls_crt1(Elf32_Rel const * rel,int sz)1863 bool PackLinuxElf32::calls_crt1(Elf32_Rel const *rel, int sz)
1864 {
1865     if (!dynsym || !dynstr || !rel) {
1866         return false;
1867     }
1868     for (unsigned relnum= 0; 0 < sz; (sz -= sizeof(Elf32_Rel)), ++rel, ++relnum) {
1869         unsigned const symnum = get_te32(&rel->r_info) >> 8;
1870         char const *const symnam = get_dynsym_name(symnum, relnum);
1871         if (0==strcmp(symnam, "__libc_start_main")  // glibc
1872         ||  0==strcmp(symnam, "__libc_init")  // Android
1873         ||  0==strcmp(symnam, "__uClibc_main")
1874         ||  0==strcmp(symnam, "__uClibc_start_main"))
1875             return true;
1876     }
1877     return false;
1878 }
1879 
1880 #define WANT_REL_ENUM
1881 #include "p_elf_enum.h"
1882 #undef WANT_REL_ENUM
1883 
canPack()1884 bool PackLinuxElf32::canPack()
1885 {
1886     union {
1887         unsigned char buf[sizeof(Elf32_Ehdr) + 14*sizeof(Elf32_Phdr)];
1888         //struct { Elf32_Ehdr ehdr; Elf32_Phdr phdr; } e;
1889     } u;
1890     COMPILE_TIME_ASSERT(sizeof(u.buf) <= 512)
1891 
1892     fi->seek(0, SEEK_SET);
1893     fi->readx(u.buf, sizeof(u.buf));
1894     fi->seek(0, SEEK_SET);
1895     Elf32_Ehdr const *const ehdr = (Elf32_Ehdr *) u.buf;
1896 
1897     // now check the ELF header
1898     if (checkEhdr(ehdr) != 0)
1899         return false;
1900 
1901     // additional requirements for linux/elf386
1902     if (get_te16(&ehdr->e_ehsize) != sizeof(*ehdr)) {
1903         throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
1904         return false;
1905     }
1906     if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
1907         throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
1908         return false;
1909     }
1910 
1911     unsigned char osabi0 = u.buf[Elf32_Ehdr::EI_OSABI];
1912     // The first PT_LOAD32 must cover the beginning of the file (0==p_offset).
1913     Elf32_Phdr const *phdr = phdri;
1914     note_size = 0;
1915     for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
1916         if (j >= 14) {
1917             throwCantPack("too many ElfXX_Phdr; try '--force-execve'");
1918             return false;
1919         }
1920         unsigned const p_type = get_te32(&phdr->p_type);
1921         unsigned const p_offset = get_te32(&phdr->p_offset);
1922         if (1!=exetype && PT_LOAD32 == p_type) { // 1st PT_LOAD
1923             exetype = 1;
1924             load_va = get_te32(&phdr->p_vaddr);  // class data member
1925 
1926             // Cast on next line is to avoid a compiler bug (incorrect complaint) in
1927             // Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
1928             // error C4319: '~': zero extending 'unsigned int' to 'upx_uint64_t' of greater size
1929             unsigned const off = ~page_mask & (unsigned)load_va;
1930 
1931             if (off && off == p_offset) { // specific hint
1932                 throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
1933                 // Fixing it inside upx fails because packExtent() reads original file.
1934                 return false;
1935             }
1936             if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
1937                 throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
1938                 return false;
1939             }
1940             hatch_off = ~3u & (3+ get_te32(&phdr->p_memsz));
1941         }
1942         if (PT_NOTE32 == p_type) {
1943             unsigned const x = get_te32(&phdr->p_memsz);
1944             if ( sizeof(elfout.notes) < x  // beware overflow of note_size
1945             ||  (sizeof(elfout.notes) < (note_size += x)) ) {
1946                 throwCantPack("PT_NOTEs too big; try '--force-execve'");
1947                 return false;
1948             }
1949             if (osabi_note && Elf32_Ehdr::ELFOSABI_NONE==osabi0) { // Still seems to be generic.
1950                 struct {
1951                     struct Elf32_Nhdr nhdr;
1952                     char name[8];
1953                     unsigned body;
1954                 } note;
1955                 memset(&note, 0, sizeof(note));
1956                 fi->seek(p_offset, SEEK_SET);
1957                 fi->readx(&note, sizeof(note));
1958                 fi->seek(0, SEEK_SET);
1959                 if (4==get_te32(&note.nhdr.descsz)
1960                 &&  1==get_te32(&note.nhdr.type)
1961                 // &&  0==note.end
1962                 &&  (1+ strlen(osabi_note))==get_te32(&note.nhdr.namesz)
1963                 &&  0==strcmp(osabi_note, (char const *)&note.name[0])
1964                 ) {
1965                     osabi0 = ei_osabi;  // Specified by PT_NOTE.
1966                 }
1967             }
1968         }
1969     }
1970     if (Elf32_Ehdr::ELFOSABI_NONE ==osabi0
1971     ||  Elf32_Ehdr::ELFOSABI_LINUX==osabi0) { // No EI_OSBAI, no PT_NOTE.
1972         unsigned const arm_eabi = 0xff000000u & get_te32(&ehdr->e_flags);
1973         if (Elf32_Ehdr::EM_ARM==e_machine
1974         &&   (EF_ARM_EABI_VER5==arm_eabi
1975           ||  EF_ARM_EABI_VER4==arm_eabi ) ) {
1976             // armel-eabi armeb-eabi ARM Linux EABI version 4 is a mess.
1977             ei_osabi = osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
1978         }
1979         else {
1980             osabi0 = opt->o_unix.osabi0;  // Possibly specified by command-line.
1981         }
1982     }
1983     if (osabi0!=ei_osabi) {
1984         return false;
1985     }
1986 
1987     // We want to compress position-independent executable (gcc -pie)
1988     // main programs, but compressing a shared library must be avoided
1989     // because the result is no longer usable.  In theory, there is no way
1990     // to tell them apart: both are just ET_DYN.  Also in theory,
1991     // neither the presence nor the absence of any particular symbol name
1992     // can be used to tell them apart; there are counterexamples.
1993     // However, we will use the following heuristic suggested by
1994     // Peter S. Mazinger <ps.m@gmx.net> September 2005:
1995     // If a ET_DYN has __libc_start_main as a global undefined symbol,
1996     // then the file is a position-independent executable main program
1997     // (that depends on libc.so.6) and is eligible to be compressed.
1998     // Otherwise (no __libc_start_main as global undefined): skip it.
1999     // Also allow  __uClibc_main  and  __uClibc_start_main .
2000 
2001     if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) {
2002         // The DT_SYMTAB has no designated length.  Read the whole file.
2003         alloc_file_image(file_image, file_size);
2004         fi->seek(0, SEEK_SET);
2005         fi->readx(file_image, file_size);
2006         memcpy(&ehdri, ehdr, sizeof(Elf32_Ehdr));
2007         phdri= (Elf32_Phdr *)((size_t)e_phoff + file_image);  // do not free() !!
2008         shdri= (Elf32_Shdr *)((size_t)e_shoff + file_image);  // do not free() !!
2009 
2010         sec_strndx = NULL;
2011         shstrtab = NULL;
2012         if (e_shnum) {
2013             unsigned const e_shstrndx = get_te16(&ehdr->e_shstrndx);
2014             if (e_shstrndx) {
2015                 if (e_shnum <= e_shstrndx) {
2016                     char msg[40]; snprintf(msg, sizeof(msg),
2017                         "bad e_shstrndx %#x >= e_shnum %d", e_shstrndx, e_shnum);
2018                     throwCantPack(msg);
2019                 }
2020                 sec_strndx = &shdri[e_shstrndx];
2021                 unsigned const sh_offset = get_te32(&sec_strndx->sh_offset);
2022                 if ((u32_t)file_size <= sh_offset) {
2023                     char msg[50]; snprintf(msg, sizeof(msg),
2024                         "bad .e_shstrndx->sh_offset %#x", sh_offset);
2025                     throwCantPack(msg);
2026                 }
2027                 shstrtab = (char const *)(sh_offset + file_image);
2028             }
2029             sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);
2030             if (sec_dynsym) {
2031                 unsigned const sh_link = get_te32(&sec_dynsym->sh_link);
2032                 if (e_shnum <= sh_link) {
2033                     char msg[50]; snprintf(msg, sizeof(msg),
2034                         "bad SHT_DYNSYM.sh_link %#x", sh_link);
2035                 }
2036                 sec_dynstr = &shdri[sh_link];
2037             }
2038 
2039             if (sec_strndx) {
2040                 unsigned const sh_name = get_te32(&sec_strndx->sh_name);
2041                 if (Elf32_Shdr::SHT_STRTAB != get_te32(&sec_strndx->sh_type)
2042                 || (u32_t)file_size <= (sizeof(".shstrtab")
2043                     + sh_name + (shstrtab - (const char *)&file_image[0]))
2044                 || (sh_name
2045                   && 0!=strcmp((char const *)".shstrtab", &shstrtab[sh_name]))
2046                 ) {
2047                     throwCantPack("bad e_shstrtab");
2048                 }
2049             }
2050         }
2051 
2052         Elf32_Phdr const *pload_x0(0);  // first eXecutable PT_LOAD
2053         phdr= phdri;
2054         for (int j= e_phnum; --j>=0; ++phdr)
2055         if (Elf32_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
2056             dynseg= (Elf32_Dyn const *)(check_pt_dynamic(phdr) + file_image);
2057             invert_pt_dynamic(dynseg);
2058         }
2059         else if (PT_LOAD32==get_te32(&phdr->p_type)) {
2060             if (!pload_x0
2061             &&  Elf32_Phdr::PF_X & get_te32(&phdr->p_flags)
2062             ) {
2063                 pload_x0 = phdr;
2064             }
2065             check_pt_load(phdr);
2066         }
2067         // elf_find_dynamic() returns 0 if 0==dynseg.
2068         dynstr=          (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);
2069         dynsym=     (Elf32_Sym const *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB);
2070 
2071         if (opt->o_unix.force_pie
2072         ||      Elf32_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf32_Dyn::DT_FLAGS_1)
2073         ||  calls_crt1((Elf32_Rel const *)elf_find_dynamic(Elf32_Dyn::DT_REL),
2074                                  (int)elf_unsigned_dynamic(Elf32_Dyn::DT_RELSZ))
2075         ||  calls_crt1((Elf32_Rel const *)elf_find_dynamic(Elf32_Dyn::DT_JMPREL),
2076                                  (int)elf_unsigned_dynamic(Elf32_Dyn::DT_PLTRELSZ))) {
2077             is_pie = true;
2078             goto proceed;  // calls C library init for main program
2079         }
2080 
2081         // Heuristic HACK for shared libraries (compare Darwin (MacOS) Dylib.)
2082         // If there is an existing DT_INIT, and if everything that the dynamic
2083         // linker ld-linux needs to perform relocations before calling DT_INIT
2084         // resides below the first SHT_EXECINSTR Section in one PT_LOAD, then
2085         // compress from the first executable Section to the end of that PT_LOAD.
2086         // We must not alter anything that ld-linux might touch before it calls
2087         // the DT_INIT function.
2088         //
2089         // Obviously this hack requires that the linker script put pieces
2090         // into good positions when building the original shared library,
2091         // and also requires ld-linux to behave.
2092 
2093         // Apparently glibc-2.13.90 insists on 0==e_ident[EI_PAD..15],
2094         // so compressing shared libraries may be doomed anyway.
2095         // 2011-06-01: stub.shlib-init.S works around by installing hatch
2096         // at end of .text.
2097 
2098         if (/*jni_onload_sym ||*/ elf_find_dynamic(upx_dt_init)) {
2099             if (this->e_machine!=Elf32_Ehdr::EM_386
2100             &&  this->e_machine!=Elf32_Ehdr::EM_MIPS
2101             &&  this->e_machine!=Elf32_Ehdr::EM_ARM)
2102                 goto abandon;  // need stub: EM_PPC
2103             if (elf_has_dynamic(Elf32_Dyn::DT_TEXTREL)) {
2104                 throwCantPack("DT_TEXTREL found; re-compile with -fPIC");
2105                 goto abandon;
2106             }
2107             if (!(Elf32_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf32_Dyn::DT_FLAGS_1))) {
2108                 // not explicitly PIE main program
2109                 if (Elf32_Ehdr::EM_ARM == e_machine  // Android is common
2110                 &&  !opt->o_unix.android_shlib  // but not explicit
2111                 ) {
2112                     opt->info_mode++;
2113                     info("note: use --android-shlib if appropriate");
2114                     opt->info_mode--;
2115                 }
2116             }
2117             Elf32_Shdr const *shdr = shdri;
2118             xct_va = ~0u;
2119             if (e_shnum) {
2120                 for (int j= e_shnum; --j>=0; ++shdr) {
2121                     unsigned const sh_type = get_te32(&shdr->sh_type);
2122                     if (Elf32_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
2123                         xct_va = umin(xct_va, get_te32(&shdr->sh_addr));
2124                     }
2125                     // Hook the first slot of DT_PREINIT_ARRAY or DT_INIT_ARRAY.
2126                     if ((     Elf32_Dyn::DT_PREINIT_ARRAY==upx_dt_init
2127                         &&  Elf32_Shdr::SHT_PREINIT_ARRAY==sh_type)
2128                     ||  (     Elf32_Dyn::DT_INIT_ARRAY   ==upx_dt_init
2129                         &&  Elf32_Shdr::SHT_INIT_ARRAY   ==sh_type) ) {
2130                         unsigned user_init_ava = get_te32(&shdr->sh_addr);
2131                         user_init_off = get_te32(&shdr->sh_offset);
2132                         if ((u32_t)file_size <= user_init_off) {
2133                             char msg[70]; snprintf(msg, sizeof(msg),
2134                                 "bad Elf32_Shdr[%d].sh_offset %#x",
2135                                 -1+ e_shnum - j, user_init_off);
2136                             throwCantPack(msg);
2137                         }
2138                         // Check that &file_image[user_init_off] has
2139                         // *_RELATIVE relocation, and fetch user_init_va.
2140                         // If Elf32_Rela then the actual value is in Rela.r_addend.
2141                         int z_rel = dt_table[Elf32_Dyn::DT_REL];
2142                         int z_rsz = dt_table[Elf32_Dyn::DT_RELSZ];
2143                         if (z_rel && z_rsz) {
2144                             unsigned rel_off = get_te32(&dynseg[-1+ z_rel].d_val);
2145                             Elf32_Rel *rp = (Elf32_Rel *)&file_image[rel_off];
2146                             unsigned relsz   = get_te32(&dynseg[-1+ z_rsz].d_val);
2147                             Elf32_Rel *last = (Elf32_Rel *)(relsz + (char *)rp);
2148                             for (; rp < last; ++rp) {
2149                                 unsigned r_va = get_te32(&rp->r_offset);
2150                                 if (r_va == user_init_ava) { // found the Elf32_Rel
2151                                     unsigned r_info = get_te32(&rp->r_info);
2152                                     unsigned r_type = ELF32_R_TYPE(r_info);
2153                                     if (Elf32_Ehdr::EM_ARM == e_machine
2154                                     &&  R_ARM_RELATIVE == r_type) {
2155                                         user_init_va = get_te32(&file_image[user_init_off]);
2156                                     }
2157                                     else {
2158                                         char msg[50]; snprintf(msg, sizeof(msg),
2159                                             "bad relocation %#x DT_INIT_ARRAY[0]",
2160                                             r_info);
2161                                         throwCantPack(msg);
2162                                     }
2163                                     break;
2164                                 }
2165                             }
2166                         }
2167                         unsigned const p_filesz = get_te32(&pload_x0->p_filesz);
2168                         if (!((user_init_va - xct_va) < p_filesz)) {
2169                             // Not in executable portion of first executable PT_LOAD.
2170                             if (0==user_init_va && opt->o_unix.android_shlib) {
2171                                 // Android allows (0 ==> skip) ?
2172                                 upx_dt_init = 0;  // force steal of 'extra' DT_NULL
2173                                 // XXX: FIXME: depends on SHT_DYNAMIC coming later
2174                             }
2175                             else {
2176                                 char msg[70]; snprintf(msg, sizeof(msg),
2177                                     "bad init address %#x in Elf32_Shdr[%d].%#x\n",
2178                                     (unsigned)user_init_va, -1+ e_shnum - j, user_init_off);
2179                                 throwCantPack(msg);
2180                             }
2181                         }
2182                     }
2183                     // By default /usr/bin/ld leaves 4 extra DT_NULL to support pre-linking.
2184                     // Take one as a last resort.
2185                     if ((Elf32_Dyn::DT_INIT==upx_dt_init || !upx_dt_init)
2186                     &&  Elf32_Shdr::SHT_DYNAMIC == sh_type) {
2187                         unsigned const n = get_te32(&shdr->sh_size) / sizeof(Elf32_Dyn);
2188                         Elf32_Dyn *dynp = (Elf32_Dyn *)&file_image[get_te32(&shdr->sh_offset)];
2189                         for (; Elf32_Dyn::DT_NULL != dynp->d_tag; ++dynp) {
2190                             if (upx_dt_init == get_te32(&dynp->d_tag)) {
2191                                 break;  // re-found DT_INIT
2192                             }
2193                         }
2194                         if ((1+ dynp) < (n+ dynseg)) { // not the terminator, so take it
2195                             user_init_va = get_te32(&dynp->d_val);  // 0 if (0==upx_dt_init)
2196                             set_te32(&dynp->d_tag, upx_dt_init = Elf32_Dyn::DT_INIT);
2197                             user_init_off = (char const *)&dynp->d_val - (char const *)&file_image[0];
2198                         }
2199                     }
2200                 }
2201             }
2202             else { // no Sections; use heuristics
2203                 unsigned const strsz  = elf_unsigned_dynamic(Elf32_Dyn::DT_STRSZ);
2204                 unsigned const strtab = elf_unsigned_dynamic(Elf32_Dyn::DT_STRTAB);
2205                 unsigned const relsz  = elf_unsigned_dynamic(Elf32_Dyn::DT_RELSZ);
2206                 unsigned const rel    = elf_unsigned_dynamic(Elf32_Dyn::DT_REL);
2207                 unsigned const init   = elf_unsigned_dynamic(upx_dt_init);
2208                 if ((init == (relsz + rel   ) && rel    == (strsz + strtab))
2209                 ||  (init == (strsz + strtab) && strtab == (relsz + rel   ))
2210                 ) {
2211                     xct_va = init;
2212                     user_init_va = init;
2213                     user_init_off = elf_get_offset_from_address(init);
2214                 }
2215             }
2216             // Rely on 0==elf_unsigned_dynamic(tag) if no such tag.
2217             unsigned const va_gash = elf_unsigned_dynamic(Elf32_Dyn::DT_GNU_HASH);
2218             unsigned const va_hash = elf_unsigned_dynamic(Elf32_Dyn::DT_HASH);
2219             unsigned y = 0;
2220             if ((y=1, xct_va < va_gash)  ||  (y=2, (0==va_gash && xct_va < va_hash))
2221             ||  (y=3, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_STRTAB))
2222             ||  (y=4, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_SYMTAB))
2223             ||  (y=5, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_REL))
2224             ||  (y=6, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_RELA))
2225             ||  (y=7, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_JMPREL))
2226             ||  (y=8, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERDEF))
2227             ||  (y=9, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERSYM))
2228             ||  (y=10, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERNEEDED)) ) {
2229                 static char const *which[] = {
2230                     "unknown",
2231                     "DT_GNU_HASH",
2232                     "DT_HASH",
2233                     "DT_STRTAB",
2234                     "DT_SYMTAB",
2235                     "DT_REL",
2236                     "DT_RELA",
2237                     "DT_JMPREL",
2238                     "DT_VERDEF",
2239                     "DT_VERSYM",
2240                     "DT_VERNEEDED",
2241                 };
2242                 char buf[30]; snprintf(buf, sizeof(buf), "%s above stub", which[y]);
2243                 throwCantPack(buf);
2244                 goto abandon;
2245             }
2246             if (!opt->o_unix.android_shlib) {
2247                 phdr = phdri;
2248                 for (unsigned j= 0; j < e_phnum; ++phdr, ++j) {
2249                     unsigned const vaddr = get_te32(&phdr->p_vaddr);
2250                     if (PT_NOTE32 == get_te32(&phdr->p_type)
2251                     && xct_va < vaddr) {
2252                         char buf[40]; snprintf(buf, sizeof(buf),
2253                            "PT_NOTE %#x above stub", vaddr);
2254                         throwCantPack(buf);
2255                         goto abandon;
2256                     }
2257                 }
2258             }
2259             xct_off = elf_get_offset_from_address(xct_va);
2260             if (opt->debug.debug_level) {
2261                 fprintf(stderr, "shlib canPack: xct_va=%#lx  xct_off=%#lx\n",
2262                     (long)xct_va, (long)xct_off);
2263             }
2264             goto proceed;  // But proper packing depends on checking xct_va.
2265         }
2266         else
2267             throwCantPack("need DT_INIT; try \"void _init(void){}\"");
2268 abandon:
2269         return false;
2270 proceed: ;
2271     }
2272     // XXX Theoretically the following test should be first,
2273     // but PackUnix::canPack() wants 0!=exetype ?
2274     if (!super::canPack())
2275         return false;
2276     assert(exetype == 1);
2277     exetype = 0;
2278 
2279     // set options
2280     opt->o_unix.blocksize = blocksize = file_size;
2281     return true;
2282 }
2283 
2284 bool
canPack()2285 PackLinuxElf64::canPack()
2286 {
2287     union {
2288         unsigned char buf[sizeof(Elf64_Ehdr) + 14*sizeof(Elf64_Phdr)];
2289         //struct { Elf64_Ehdr ehdr; Elf64_Phdr phdr; } e;
2290     } u;
2291     COMPILE_TIME_ASSERT(sizeof(u) <= 1024)
2292 
2293     fi->readx(u.buf, sizeof(u.buf));
2294     fi->seek(0, SEEK_SET);
2295     Elf64_Ehdr const *const ehdr = (Elf64_Ehdr *) u.buf;
2296 
2297     // now check the ELF header
2298     if (checkEhdr(ehdr) != 0)
2299         return false;
2300 
2301     // additional requirements for linux/elf386
2302     if (get_te16(&ehdr->e_ehsize) != sizeof(*ehdr)) {
2303         throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
2304         return false;
2305     }
2306     if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
2307         throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
2308         return false;
2309     }
2310 
2311     // The first PT_LOAD64 must cover the beginning of the file (0==p_offset).
2312     Elf64_Phdr const *phdr = phdri;
2313     for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
2314         if (j >= 14) {
2315             throwCantPack("too many ElfXX_Phdr; try '--force-execve'");
2316             return false;
2317         }
2318         unsigned const p_type = get_te32(&phdr->p_type);
2319         if (1!=exetype && PT_LOAD64 == p_type) { // 1st PT_LOAD
2320             exetype = 1;
2321             load_va = get_te64(&phdr->p_vaddr);  // class data member
2322             upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
2323             upx_uint64_t const off = ~page_mask & load_va;
2324             if (off && off == p_offset) { // specific hint
2325                 throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
2326                 // Fixing it inside upx fails because packExtent() reads original file.
2327                 return false;
2328             }
2329             if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
2330                 throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
2331                 return false;
2332             }
2333             hatch_off = ~3ul & (3+ get_te64(&phdr->p_memsz));
2334             break;
2335         }
2336     }
2337     // We want to compress position-independent executable (gcc -pie)
2338     // main programs, but compressing a shared library must be avoided
2339     // because the result is no longer usable.  In theory, there is no way
2340     // to tell them apart: both are just ET_DYN.  Also in theory,
2341     // neither the presence nor the absence of any particular symbol name
2342     // can be used to tell them apart; there are counterexamples.
2343     // However, we will use the following heuristic suggested by
2344     // Peter S. Mazinger <ps.m@gmx.net> September 2005:
2345     // If a ET_DYN has __libc_start_main as a global undefined symbol,
2346     // then the file is a position-independent executable main program
2347     // (that depends on libc.so.6) and is eligible to be compressed.
2348     // Otherwise (no __libc_start_main as global undefined): skip it.
2349     // Also allow  __uClibc_main  and  __uClibc_start_main .
2350 
2351     if (Elf64_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) {
2352         // The DT_SYMTAB has no designated length.  Read the whole file.
2353         alloc_file_image(file_image, file_size);
2354         fi->seek(0, SEEK_SET);
2355         fi->readx(file_image, file_size);
2356         memcpy(&ehdri, ehdr, sizeof(Elf64_Ehdr));
2357         phdri= (Elf64_Phdr *)((size_t)e_phoff + file_image);  // do not free() !!
2358         shdri= (Elf64_Shdr *)((size_t)e_shoff + file_image);  // do not free() !!
2359 
2360         sec_strndx = NULL;
2361         shstrtab = NULL;
2362         if (e_shnum) {
2363             unsigned const e_shstrndx = get_te16(&ehdr->e_shstrndx);
2364             if (e_shstrndx) {
2365                 if (e_shnum <= e_shstrndx) {
2366                     char msg[40]; snprintf(msg, sizeof(msg),
2367                         "bad e_shstrndx %#x >= e_shnum %d", e_shstrndx, e_shnum);
2368                     throwCantPack(msg);
2369                 }
2370                 sec_strndx = &shdri[e_shstrndx];
2371                 upx_uint64_t sh_offset = get_te64(&sec_strndx->sh_offset);
2372                 if ((u64_t)file_size <= sh_offset) {
2373                     char msg[50]; snprintf(msg, sizeof(msg),
2374                         "bad .e_shstrndx->sh_offset %#lx", (long unsigned)sh_offset);
2375                     throwCantPack(msg);
2376                 }
2377                 shstrtab = (char const *)(sh_offset + file_image);
2378             }
2379             sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
2380             if (sec_dynsym) {
2381                 upx_uint64_t const sh_link = get_te64(&sec_dynsym->sh_link);
2382                 if (e_shnum <= sh_link) {
2383                     char msg[50]; snprintf(msg, sizeof(msg),
2384                         "bad SHT_DYNSYM.sh_link %#lx", (long unsigned)sh_link);
2385                 }
2386                 sec_dynstr = &shdri[sh_link];
2387             }
2388 
2389             if (sec_strndx) {
2390                 unsigned const sh_name = get_te32(&sec_strndx->sh_name);
2391                 if (Elf64_Shdr::SHT_STRTAB != get_te32(&sec_strndx->sh_type)
2392                 || (u32_t)file_size <= (sizeof(".shstrtab")
2393                     + sh_name + (shstrtab - (const char *)&file_image[0]))
2394                 || (sh_name
2395                   && 0!=strcmp((char const *)".shstrtab", &shstrtab[sh_name]))
2396                 ) {
2397                     throwCantPack("bad e_shstrtab");
2398                 }
2399             }
2400         }
2401 
2402         Elf64_Phdr const *pload_x0(0);  // first eXecutable PT_LOAD
2403         phdr= phdri;
2404         for (int j= e_phnum; --j>=0; ++phdr)
2405         if (Elf64_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
2406             dynseg= (Elf64_Dyn const *)(check_pt_dynamic(phdr) + file_image);
2407             invert_pt_dynamic(dynseg);
2408         }
2409         else if (PT_LOAD64==get_te32(&phdr->p_type)) {
2410             if (!pload_x0
2411             &&  Elf32_Phdr::PF_X & get_te32(&phdr->p_flags)
2412             ) {
2413                 pload_x0 = phdr;
2414             }
2415             check_pt_load(phdr);
2416         }
2417         // elf_find_dynamic() returns 0 if 0==dynseg.
2418         dynstr=          (char const *)elf_find_dynamic(Elf64_Dyn::DT_STRTAB);
2419         dynsym=     (Elf64_Sym const *)elf_find_dynamic(Elf64_Dyn::DT_SYMTAB);
2420 
2421         if (opt->o_unix.force_pie
2422         ||       Elf64_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf64_Dyn::DT_FLAGS_1)
2423         ||  calls_crt1((Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_RELA),
2424                                   (int)elf_unsigned_dynamic(Elf64_Dyn::DT_RELASZ))
2425         ||  calls_crt1((Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_JMPREL),
2426                                   (int)elf_unsigned_dynamic(Elf64_Dyn::DT_PLTRELSZ))) {
2427             is_pie = true;
2428             goto proceed;  // calls C library init for main program
2429         }
2430 
2431         // Heuristic HACK for shared libraries (compare Darwin (MacOS) Dylib.)
2432         // If there is an existing DT_INIT, and if everything that the dynamic
2433         // linker ld-linux needs to perform relocations before calling DT_INIT
2434         // resides below the first SHT_EXECINSTR Section in one PT_LOAD, then
2435         // compress from the first executable Section to the end of that PT_LOAD.
2436         // We must not alter anything that ld-linux might touch before it calls
2437         // the DT_INIT function.
2438         //
2439         // Obviously this hack requires that the linker script put pieces
2440         // into good positions when building the original shared library,
2441         // and also requires ld-linux to behave.
2442 
2443         if (elf_find_dynamic(upx_dt_init)) {
2444             if (elf_has_dynamic(Elf64_Dyn::DT_TEXTREL)) {
2445                 throwCantPack("DT_TEXTREL found; re-compile with -fPIC");
2446                 goto abandon;
2447             }
2448             if (!(Elf64_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf64_Dyn::DT_FLAGS_1))) {
2449                 // not explicitly PIE main program
2450                 if (Elf64_Ehdr::EM_AARCH64 == e_machine  // Android is common
2451                 &&  !opt->o_unix.android_shlib  // but not explicit
2452                 ) {
2453                     opt->info_mode++;
2454                     info("note: use --android-shlib if appropriate");
2455                     opt->info_mode--;
2456                 }
2457             }
2458             Elf64_Shdr const *shdr = shdri;
2459             xct_va = ~0ull;
2460             if (e_shnum) {
2461                 for (int j= e_shnum; --j>=0; ++shdr) {
2462                     unsigned const sh_type = get_te32(&shdr->sh_type);
2463                     if (Elf64_Shdr::SHF_EXECINSTR & get_te64(&shdr->sh_flags)) {
2464                         xct_va = umin(xct_va, get_te64(&shdr->sh_addr));
2465                     }
2466                     // Hook the first slot of DT_PREINIT_ARRAY or DT_INIT_ARRAY.
2467                     if ((     Elf64_Dyn::DT_PREINIT_ARRAY==upx_dt_init
2468                         &&  Elf64_Shdr::SHT_PREINIT_ARRAY==sh_type)
2469                     ||  (     Elf64_Dyn::DT_INIT_ARRAY   ==upx_dt_init
2470                         &&  Elf64_Shdr::SHT_INIT_ARRAY   ==sh_type) ) {
2471                         unsigned user_init_ava = get_te32(&shdr->sh_addr);
2472                         user_init_off = get_te64(&shdr->sh_offset);
2473                         if ((u64_t)file_size <= user_init_off) {
2474                             char msg[70]; snprintf(msg, sizeof(msg),
2475                                 "bad Elf64_Shdr[%d].sh_offset %#x",
2476                                 -1+ e_shnum - j, user_init_off);
2477                             throwCantPack(msg);
2478                         }
2479                         // Check that &file_image[user_init_off] has
2480                         // *_RELATIVE relocation, and fetch user_init_va.
2481                         // If Elf64_Rela then the actual value is in Rela.r_addend.
2482                         int z_rel = dt_table[Elf64_Dyn::DT_RELA];
2483                         int z_rsz = dt_table[Elf64_Dyn::DT_RELASZ];
2484                         if (z_rel && z_rsz) {
2485                             unsigned rel_off = get_te64(&dynseg[-1+ z_rel].d_val);
2486                             Elf64_Rela *rp = (Elf64_Rela *)&file_image[rel_off];
2487                             unsigned relsz   = get_te64(&dynseg[-1+ z_rsz].d_val);
2488                             Elf64_Rela *last = (Elf64_Rela *)(relsz + (char *)rp);
2489                             for (; rp < last; ++rp) {
2490                                 unsigned r_va = get_te64(&rp->r_offset);
2491                                 if (r_va == user_init_ava) { // found the Elf64_Rela
2492                                     unsigned r_info = get_te64(&rp->r_info);
2493                                     unsigned r_type = ELF64_R_TYPE(r_info);
2494                                     if (Elf64_Ehdr::EM_AARCH64 == e_machine
2495                                     &&  R_AARCH64_RELATIVE == r_type) {
2496                                         user_init_va = get_te64(&rp->r_addend);
2497                                     }
2498                                     else if (Elf64_Ehdr::EM_AARCH64 == e_machine
2499                                     &&  R_AARCH64_ABS64 == r_type) {
2500                                         user_init_va = get_te64(&file_image[user_init_off]);
2501                                     }
2502                                     else {
2503                                         char msg[50]; snprintf(msg, sizeof(msg),
2504                                             "bad relocation %#x DT_INIT_ARRAY[0]",
2505                                             r_info);
2506                                         throwCantPack(msg);
2507                                     }
2508                                     break;
2509                                 }
2510                             }
2511                         }
2512                         unsigned const p_filesz = get_te64(&pload_x0->p_filesz);
2513                         if (!((user_init_va - xct_va) < p_filesz)) {
2514                             // Not in executable portion of first executable PT_LOAD.
2515                             if (0==user_init_va && opt->o_unix.android_shlib) {
2516                                 // Android allows (0 ==> skip) ?
2517                                 upx_dt_init = 0;  // force steal of 'extra' DT_NULL
2518                                 // XXX: FIXME: depends on SHT_DYNAMIC coming later
2519                             }
2520                             else {
2521                                 char msg[70]; snprintf(msg, sizeof(msg),
2522                                     "bad init address %#x in Elf64_Shdr[%d].%#x\n",
2523                                     (unsigned)user_init_va, -1+ e_shnum - j, user_init_off);
2524                                 throwCantPack(msg);
2525                             }
2526                         }
2527                     }
2528                     // By default /usr/bin/ld leaves 4 extra DT_NULL to support pre-linking.
2529                     // Take one as a last resort.
2530                     if ((Elf64_Dyn::DT_INIT==upx_dt_init || !upx_dt_init)
2531                     &&  Elf64_Shdr::SHT_DYNAMIC == sh_type) {
2532                         unsigned const n = get_te64(&shdr->sh_size) / sizeof(Elf64_Dyn);
2533                         Elf64_Dyn *dynp = (Elf64_Dyn *)&file_image[get_te64(&shdr->sh_offset)];
2534                         for (; Elf64_Dyn::DT_NULL != dynp->d_tag; ++dynp) {
2535                             if (upx_dt_init == get_te64(&dynp->d_tag)) {
2536                                 break;  // re-found DT_INIT
2537                             }
2538                         }
2539                         if ((1+ dynp) < (n+ dynseg)) { // not the terminator, so take it
2540                             user_init_va = get_te64(&dynp->d_val);  // 0 if (0==upx_dt_init)
2541                             set_te64(&dynp->d_tag, upx_dt_init = Elf64_Dyn::DT_INIT);
2542                             user_init_off = (char const *)&dynp->d_val - (char const *)&file_image[0];
2543                         }
2544                     }
2545                 }
2546             }
2547             else { // no Sections; use heuristics
2548                 upx_uint64_t const strsz  = elf_unsigned_dynamic(Elf64_Dyn::DT_STRSZ);
2549                 upx_uint64_t const strtab = elf_unsigned_dynamic(Elf64_Dyn::DT_STRTAB);
2550                 upx_uint64_t const relsz  = elf_unsigned_dynamic(Elf64_Dyn::DT_RELSZ);
2551                 upx_uint64_t const rel    = elf_unsigned_dynamic(Elf64_Dyn::DT_REL);
2552                 upx_uint64_t const init   = elf_unsigned_dynamic(upx_dt_init);
2553                 if ((init == (relsz + rel   ) && rel    == (strsz + strtab))
2554                 ||  (init == (strsz + strtab) && strtab == (relsz + rel   ))
2555                 ) {
2556                     xct_va = init;
2557                     user_init_va = init;
2558                     user_init_off = elf_get_offset_from_address(init);
2559                 }
2560             }
2561             // Rely on 0==elf_unsigned_dynamic(tag) if no such tag.
2562             upx_uint64_t const va_gash = elf_unsigned_dynamic(Elf64_Dyn::DT_GNU_HASH);
2563             upx_uint64_t const va_hash = elf_unsigned_dynamic(Elf64_Dyn::DT_HASH);
2564             unsigned y = 0;
2565             if ((y=1, xct_va < va_gash)  ||  (y=2, (0==va_gash && xct_va < va_hash))
2566             ||  (y=3, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_STRTAB))
2567             ||  (y=4, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_SYMTAB))
2568             ||  (y=5, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_REL))
2569             ||  (y=6, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_RELA))
2570             ||  (y=7, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_JMPREL))
2571             ||  (y=8, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERDEF))
2572             ||  (y=9, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERSYM))
2573             ||  (y=10, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERNEEDED)) ) {
2574                 static char const *which[] = {
2575                     "unknown",
2576                     "DT_GNU_HASH",
2577                     "DT_HASH",
2578                     "DT_STRTAB",
2579                     "DT_SYMTAB",
2580                     "DT_REL",
2581                     "DT_RELA",
2582                     "DT_JMPREL",
2583                     "DT_VERDEF",
2584                     "DT_VERSYM",
2585                     "DT_VERNEEDED",
2586                 };
2587                 char buf[30]; snprintf(buf, sizeof(buf), "%s above stub", which[y]);
2588                 throwCantPack(buf);
2589                 goto abandon;
2590             }
2591             if (!opt->o_unix.android_shlib) {
2592                 phdr = phdri;
2593                 for (unsigned j= 0; j < e_phnum; ++phdr, ++j) {
2594                     upx_uint64_t const vaddr = get_te64(&phdr->p_vaddr);
2595                     if (PT_NOTE64 == get_te32(&phdr->p_type)
2596                     && xct_va < vaddr) {
2597                         char buf[40]; snprintf(buf, sizeof(buf),
2598                            "PT_NOTE %#lx above stub", (unsigned long)vaddr);
2599                         throwCantPack(buf);
2600                         goto abandon;
2601                     }
2602                 }
2603             }
2604             xct_off = elf_get_offset_from_address(xct_va);
2605             if (opt->debug.debug_level) {
2606                 fprintf(stderr, "shlib canPack: xct_va=%#lx  xct_off=%#lx\n",
2607                     (long)xct_va, (long)xct_off);
2608             }
2609             goto proceed;  // But proper packing depends on checking xct_va.
2610         }
2611         else
2612             throwCantPack("need DT_INIT; try \"void _init(void){}\"");
2613 abandon:
2614         return false;
2615 proceed: ;
2616     }
2617     // XXX Theoretically the following test should be first,
2618     // but PackUnix::canPack() wants 0!=exetype ?
2619     if (!super::canPack())
2620         return false;
2621     assert(exetype == 1);
2622     exetype = 0;
2623 
2624     // set options
2625     opt->o_unix.blocksize = blocksize = file_size;
2626     return true;
2627 }
2628 
2629 off_t
getbrk(const Elf32_Phdr * phdr,int nph) const2630 PackLinuxElf32::getbrk(const Elf32_Phdr *phdr, int nph) const
2631 {
2632     off_t brka = 0;
2633     for (int j = 0; j < nph; ++phdr, ++j) {
2634         if (PT_LOAD32 == get_te32(&phdr->p_type)) {
2635             off_t b = get_te32(&phdr->p_vaddr) + get_te32(&phdr->p_memsz);
2636             if (b > brka)
2637                 brka = b;
2638         }
2639     }
2640     return brka;
2641 }
2642 
2643 off_t
getbase(const Elf32_Phdr * phdr,int nph) const2644 PackLinuxElf32::getbase(const Elf32_Phdr *phdr, int nph) const
2645 {
2646     off_t base = ~0u;
2647     for (int j = 0; j < nph; ++phdr, ++j) {
2648         if (PT_LOAD32 == get_te32(&phdr->p_type)) {
2649             unsigned const vaddr = get_te32(&phdr->p_vaddr);
2650             if (vaddr < (unsigned) base)
2651                 base = vaddr;
2652         }
2653     }
2654     if (0!=base) {
2655         return base;
2656     }
2657     return 0x12000;
2658 }
2659 
2660 off_t
getbrk(const Elf64_Phdr * phdr,int nph) const2661 PackLinuxElf64::getbrk(const Elf64_Phdr *phdr, int nph) const
2662 {
2663     off_t brka = 0;
2664     for (int j = 0; j < nph; ++phdr, ++j) {
2665         if (PT_LOAD64 == get_te32(&phdr->p_type)) {
2666             off_t b = get_te64(&phdr->p_vaddr) + get_te64(&phdr->p_memsz);
2667             if (b > brka)
2668                 brka = b;
2669         }
2670     }
2671     return brka;
2672 }
2673 
2674 void
generateElfHdr(OutputFile * fo,void const * proto,unsigned const brka)2675 PackLinuxElf32::generateElfHdr(
2676     OutputFile *fo,
2677     void const *proto,
2678     unsigned const brka
2679 )
2680 {
2681     cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
2682     cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
2683     memcpy(h3, proto, sizeof(*h3));  // reads beyond, but OK
2684     h3->ehdr.e_type = ehdri.e_type;  // ET_EXEC vs ET_DYN (gcc -pie -fPIC)
2685     h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;
2686     unsigned phnum_o = get_te16(&h2->ehdr.e_phnum);
2687     if (Elf32_Ehdr::EM_MIPS==e_machine) { // MIPS R3000  FIXME
2688         h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = Elf32_Ehdr::ELFOSABI_NONE;
2689         h3->ehdr.e_flags = ehdri.e_flags;
2690     }
2691 
2692     assert(get_te32(&h2->ehdr.e_phoff)     == sizeof(Elf32_Ehdr));
2693                          h2->ehdr.e_shoff = 0;
2694     assert(get_te16(&h2->ehdr.e_ehsize)    == sizeof(Elf32_Ehdr));
2695     assert(get_te16(&h2->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
2696            set_te16(&h2->ehdr.e_shentsize, sizeof(Elf32_Shdr));
2697     if (o_elf_shnum) {
2698                         h2->ehdr.e_shnum = o_elf_shnum;
2699                         h2->ehdr.e_shstrndx = o_elf_shnum - 1;
2700     }
2701     else {
2702                         h2->ehdr.e_shnum = 0;
2703                         h2->ehdr.e_shstrndx = 0;
2704     }
2705 
2706     sz_elf_hdrs = sizeof(*h2) - sizeof(linfo);  // default
2707     if (gnu_stack) {
2708         sz_elf_hdrs += sizeof(Elf32_Phdr);
2709         memcpy(&h2->phdr[phnum_o++], gnu_stack, sizeof(*gnu_stack));
2710         set_te16(&h2->ehdr.e_phnum, phnum_o);
2711     }
2712     o_binfo =  sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr)*phnum_o + sizeof(l_info) + sizeof(p_info);
2713     set_te32(&h2->phdr[0].p_filesz, sizeof(*h2));  // + identsize;
2714               h2->phdr[0].p_memsz = h2->phdr[0].p_filesz;
2715 
2716     for (unsigned j=0; j < phnum_o; ++j) {
2717         if (PT_LOAD32==get_te32(&h3->phdr[j].p_type)) {
2718             set_te32(&h3->phdr[j].p_align, page_size);
2719         }
2720     }
2721 
2722     // Info for OS kernel to set the brk()
2723     if (brka) {
2724         // linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
2725         upx_uint32_t lo_va_user = ~0u;  // infinity
2726         upx_uint32_t memsz(0);
2727         for (int j= e_phnum; --j>=0; ) {
2728             if (PT_LOAD32 == get_te32(&phdri[j].p_type)) {
2729                 upx_uint32_t const vaddr = get_te32(&phdri[j].p_vaddr);
2730                 lo_va_user = umin(lo_va_user, vaddr);
2731                 if (vaddr == lo_va_user) {
2732                     memsz = get_te32(&phdri[j].p_memsz);
2733                 }
2734             }
2735         }
2736         set_te32(&h2->phdr[0].p_paddr, lo_va_user);
2737         set_te32(&h2->phdr[0].p_vaddr, lo_va_user);
2738         unsigned const brkb = page_mask & (~page_mask +
2739             get_te32(&h2->phdr[0].p_vaddr) + memsz);
2740         set_te32(&h2->phdr[1].p_type, PT_LOAD32);  // be sure
2741         h2->phdr[1].p_offset = 0;
2742         set_te32(&h2->phdr[1].p_vaddr, brkb);
2743         set_te32(&h2->phdr[1].p_paddr, brkb);
2744         h2->phdr[1].p_filesz = 0;
2745         set_te32(&h2->phdr[1].p_memsz, brka - brkb);
2746         set_te32(&h2->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);
2747     }
2748     if (ph.format==getFormat()) {
2749         assert((2u+ !!gnu_stack) == phnum_o);
2750         set_te32(&h2->phdr[0].p_flags, ~Elf32_Phdr::PF_W & get_te32(&h2->phdr[0].p_flags));
2751         if (!gnu_stack) {
2752             memset(&h2->linfo, 0, sizeof(h2->linfo));
2753             fo->write(h2, sizeof(*h2));
2754         }
2755         else {
2756             memset(&h3->linfo, 0, sizeof(h3->linfo));
2757             fo->write(h3, sizeof(*h3));
2758         }
2759     }
2760     else {
2761         assert(false);  // unknown ph.format, PackLinuxElf32
2762     }
2763 }
2764 
2765 void
generateElfHdr(OutputFile * fo,void const * proto,unsigned const brka)2766 PackNetBSDElf32x86::generateElfHdr(
2767     OutputFile *fo,
2768     void const *proto,
2769     unsigned const brka
2770 )
2771 {
2772     super::generateElfHdr(fo, proto, brka);
2773     cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
2774 
2775     sz_elf_hdrs = sizeof(*h2) - sizeof(linfo);
2776     unsigned note_offset = sz_elf_hdrs;
2777 
2778     // Find the NetBSD PT_NOTE and the PaX PT_NOTE.
2779     Elf32_Nhdr const *np_NetBSD = 0;  unsigned sz_NetBSD = 0;
2780     Elf32_Nhdr const *np_PaX    = 0;  unsigned sz_PaX    = 0;
2781     unsigned char *cp = note_body;
2782     unsigned j;
2783     for (j=0; j < note_size; ) {
2784         Elf32_Nhdr const *const np = (Elf32_Nhdr const *)(void *)cp;
2785         int k = sizeof(*np) + up4(get_te32(&np->namesz))
2786             + up4(get_te32(&np->descsz));
2787 
2788         if (NHDR_NETBSD_TAG == np->type && 7== np->namesz
2789         &&  NETBSD_DESCSZ == np->descsz
2790         &&  0==strcmp(ELF_NOTE_NETBSD_NAME,
2791                 /* &np->body */ (char const *)(1+ np))) {
2792             np_NetBSD = np;
2793             sz_NetBSD = k;
2794         }
2795         if (NHDR_PAX_TAG == np->type && 4== np->namesz
2796         &&  PAX_DESCSZ==np->descsz
2797         &&  0==strcmp(ELF_NOTE_PAX_NAME,
2798                 /* &np->body */ (char const *)(1+ np))) {
2799             np_PaX = np;
2800             sz_PaX = k;
2801         }
2802         cp += k;
2803         j += k;
2804     }
2805 
2806     // Add PT_NOTE for the NetBSD note and PaX note, if any.
2807     note_offset += (np_NetBSD ? sizeof(Elf32_Phdr) : 0);
2808     note_offset += (np_PaX    ? sizeof(Elf32_Phdr) : 0);
2809     Elf32_Phdr *phdr = &elfout.phdr[2];
2810     if (np_NetBSD) {
2811         set_te32(&phdr->p_type, PT_NOTE32);
2812         set_te32(&phdr->p_offset, note_offset);
2813         set_te32(&phdr->p_vaddr, note_offset);
2814         set_te32(&phdr->p_paddr, note_offset);
2815         set_te32(&phdr->p_filesz, sz_NetBSD);
2816         set_te32(&phdr->p_memsz,  sz_NetBSD);
2817         set_te32(&phdr->p_flags, Elf32_Phdr::PF_R);
2818         set_te32(&phdr->p_align, 4);
2819 
2820         sz_elf_hdrs += sz_NetBSD + sizeof(*phdr);
2821         note_offset += sz_NetBSD;
2822         ++phdr;
2823     }
2824     if (np_PaX) {
2825         set_te32(&phdr->p_type, PT_NOTE32);
2826         set_te32(&phdr->p_offset, note_offset);
2827         set_te32(&phdr->p_vaddr, note_offset);
2828         set_te32(&phdr->p_paddr, note_offset);
2829         set_te32(&phdr->p_filesz, sz_PaX);
2830         set_te32(&phdr->p_memsz,  sz_PaX);
2831         set_te32(&phdr->p_flags, Elf32_Phdr::PF_R);
2832         set_te32(&phdr->p_align, 4);
2833 
2834         /* &np_PaX->body[4] */
2835         const unsigned char *p4 =  &(ACC_CCAST(const unsigned char *, (1+ np_PaX)))[4];
2836         unsigned bits = get_te32(p4);
2837         bits &= ~PAX_MPROTECT;
2838         bits |=  PAX_NOMPROTECT;
2839         set_te32(ACC_UNCONST_CAST(unsigned char *, p4), bits);
2840 
2841         sz_elf_hdrs += sz_PaX + sizeof(*phdr);
2842         note_offset += sz_PaX;
2843         ++phdr;
2844     }
2845     set_te32(&h2->phdr[0].p_filesz, note_offset);
2846               h2->phdr[0].p_memsz = h2->phdr[0].p_filesz;
2847 
2848     if (ph.format==getFormat()) {
2849         set_te16(&h2->ehdr.e_phnum, !!sz_NetBSD + !!sz_PaX +
2850         get_te16(&h2->ehdr.e_phnum));
2851         fo->seek(0, SEEK_SET);
2852         fo->rewrite(h2, sizeof(*h2) - sizeof(h2->linfo));
2853 
2854         // The 'if' guards on these two calls to memcpy are required
2855         // because the C Standard Committee did not debug the Standard
2856         // before publishing.  An empty region (0==size) must nevertheless
2857         // have a valid (non-NULL) pointer.
2858         if (sz_NetBSD) memcpy(&((char *)phdr)[0],         np_NetBSD, sz_NetBSD);
2859         if (sz_PaX)    memcpy(&((char *)phdr)[sz_NetBSD], np_PaX,    sz_PaX);
2860 
2861         fo->write(&elfout.phdr[2],
2862             &((char *)phdr)[sz_PaX + sz_NetBSD] - (char *)&elfout.phdr[2]);
2863 
2864         l_info foo; memset(&foo, 0, sizeof(foo));
2865         fo->rewrite(&foo, sizeof(foo));
2866     }
2867     else {
2868         assert(false);  // unknown ph.format, PackLinuxElf32
2869     }
2870 }
2871 
2872 void
generateElfHdr(OutputFile * fo,void const * proto,unsigned const brka)2873 PackOpenBSDElf32x86::generateElfHdr(
2874     OutputFile *fo,
2875     void const *proto,
2876     unsigned const brka
2877 )
2878 {
2879     cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
2880     memcpy(h3, proto, sizeof(*h3));  // reads beyond, but OK
2881     h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;
2882     assert(2==get_te16(&h3->ehdr.e_phnum));
2883     set_te16(&h3->ehdr.e_phnum, 3);
2884 
2885     assert(get_te32(&h3->ehdr.e_phoff)     == sizeof(Elf32_Ehdr));
2886                          h3->ehdr.e_shoff = 0;
2887     assert(get_te16(&h3->ehdr.e_ehsize)    == sizeof(Elf32_Ehdr));
2888     assert(get_te16(&h3->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
2889            set_te16(&h3->ehdr.e_shentsize, sizeof(Elf32_Shdr));
2890                          h3->ehdr.e_shnum = 0;
2891                          h3->ehdr.e_shstrndx = 0;
2892 
2893     struct {
2894         Elf32_Nhdr nhdr;
2895         char name[8];
2896         unsigned body;
2897     } elfnote;
2898 
2899     unsigned const note_offset = sizeof(*h3) - sizeof(linfo);
2900     sz_elf_hdrs = sizeof(elfnote) + note_offset;
2901 
2902     set_te32(&h3->phdr[2].p_type, PT_NOTE32);
2903     set_te32(&h3->phdr[2].p_offset, note_offset);
2904     set_te32(&h3->phdr[2].p_vaddr, note_offset);
2905     set_te32(&h3->phdr[2].p_paddr, note_offset);
2906     set_te32(&h3->phdr[2].p_filesz, sizeof(elfnote));
2907     set_te32(&h3->phdr[2].p_memsz,  sizeof(elfnote));
2908     set_te32(&h3->phdr[2].p_flags, Elf32_Phdr::PF_R);
2909     set_te32(&h3->phdr[2].p_align, 4);
2910 
2911     // Q: Same as this->note_body[0 .. this->note_size-1] ?
2912     set_te32(&elfnote.nhdr.namesz, 8);
2913     set_te32(&elfnote.nhdr.descsz, OPENBSD_DESCSZ);
2914     set_te32(&elfnote.nhdr.type,   NHDR_OPENBSD_TAG);
2915     memcpy(elfnote.name, "OpenBSD", sizeof(elfnote.name));
2916     elfnote.body = 0;
2917 
2918     set_te32(&h3->phdr[0].p_filesz, sz_elf_hdrs);
2919               h3->phdr[0].p_memsz = h3->phdr[0].p_filesz;
2920 
2921     unsigned const brkb = brka | ((0==(~page_mask & brka)) ? 0x20 : 0);
2922     set_te32(&h3->phdr[1].p_type, PT_LOAD32);  // be sure
2923     set_te32(&h3->phdr[1].p_offset, ~page_mask & brkb);
2924     set_te32(&h3->phdr[1].p_vaddr, brkb);
2925     set_te32(&h3->phdr[1].p_paddr, brkb);
2926     h3->phdr[1].p_filesz = 0;
2927     // Too many kernels have bugs when 0==.p_memsz
2928     set_te32(&h3->phdr[1].p_memsz, 1);
2929     set_te32(&h3->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);
2930 
2931     if (ph.format==getFormat()) {
2932         memset(&h3->linfo, 0, sizeof(h3->linfo));
2933         fo->write(h3, sizeof(*h3) - sizeof(h3->linfo));
2934         fo->write(&elfnote, sizeof(elfnote));
2935         fo->write(&h3->linfo, sizeof(h3->linfo));
2936     }
2937     else {
2938         assert(false);  // unknown ph.format, PackLinuxElf32
2939     }
2940 }
2941 
2942 void
generateElfHdr(OutputFile * fo,void const * proto,unsigned const brka)2943 PackLinuxElf64::generateElfHdr(
2944     OutputFile *fo,
2945     void const *proto,
2946     unsigned const brka
2947 )
2948 {
2949     cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
2950     cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
2951     memcpy(h3, proto, sizeof(*h3));  // reads beyond, but OK
2952     h3->ehdr.e_type = ehdri.e_type;  // ET_EXEC vs ET_DYN (gcc -pie -fPIC)
2953     h3->ehdr.e_ident[Elf64_Ehdr::EI_OSABI] = ei_osabi;
2954     if (Elf64_Ehdr::ELFOSABI_LINUX == ei_osabi  // proper
2955     &&  Elf64_Ehdr::ELFOSABI_NONE  == ehdri.e_ident[Elf64_Ehdr::EI_OSABI]  // sloppy
2956     ) { // propagate sloppiness so that decompression does not complain
2957         h3->ehdr.e_ident[Elf64_Ehdr::EI_OSABI] = ehdri.e_ident[Elf64_Ehdr::EI_OSABI];
2958     }
2959     if (Elf64_Ehdr::EM_PPC64 == get_te16(&ehdri.e_machine)) {
2960         h3->ehdr.e_flags = ehdri.e_flags;  // "0x1, abiv1" vs "0x2, abiv2"
2961     }
2962 
2963     unsigned phnum_o = get_te16(&h2->ehdr.e_phnum);
2964 
2965     assert(get_te64(&h2->ehdr.e_phoff)     == sizeof(Elf64_Ehdr));
2966                          h2->ehdr.e_shoff = 0;
2967     assert(get_te16(&h2->ehdr.e_ehsize)    == sizeof(Elf64_Ehdr));
2968     assert(get_te16(&h2->ehdr.e_phentsize) == sizeof(Elf64_Phdr));
2969            set_te16(&h2->ehdr.e_shentsize, sizeof(Elf64_Shdr));
2970     if (o_elf_shnum) {
2971                         h2->ehdr.e_shnum = o_elf_shnum;
2972                         h2->ehdr.e_shstrndx = o_elf_shnum - 1;
2973     }
2974     else {
2975                         h2->ehdr.e_shnum = 0;
2976                         h2->ehdr.e_shstrndx = 0;
2977     }
2978 
2979     sz_elf_hdrs = sizeof(*h2) - sizeof(linfo);  // default
2980     if (gnu_stack) {
2981         sz_elf_hdrs += sizeof(Elf64_Phdr);
2982         memcpy(&h2->phdr[phnum_o++], gnu_stack, sizeof(*gnu_stack));
2983         set_te16(&h2->ehdr.e_phnum, phnum_o);
2984     }
2985     o_binfo =  sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr)*phnum_o + sizeof(l_info) + sizeof(p_info);
2986     set_te64(&h2->phdr[0].p_filesz, sizeof(*h2));  // + identsize;
2987                   h2->phdr[0].p_memsz = h2->phdr[0].p_filesz;
2988 
2989     for (unsigned j=0; j < 4; ++j) {
2990         if (PT_LOAD64==get_te32(&h3->phdr[j].p_type)) {
2991             set_te64(&h3->phdr[j].p_align, page_size);
2992         }
2993     }
2994 
2995     // Info for OS kernel to set the brk()
2996     if (brka) {
2997         // linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
2998         upx_uint64_t lo_va_user(~(upx_uint64_t)0);  // infinity
2999         for (int j= e_phnum; --j>=0; ) {
3000             if (PT_LOAD64 == get_te32(&phdri[j].p_type)) {
3001                 upx_uint64_t const vaddr = get_te64(&phdri[j].p_vaddr);
3002                 lo_va_user = umin64(lo_va_user, vaddr);
3003             }
3004         }
3005         set_te64(&h2->phdr[0].p_paddr, lo_va_user);
3006         set_te64(&h2->phdr[0].p_vaddr, lo_va_user);
3007         set_te32(&h2->phdr[1].p_type, PT_LOAD64);  // be sure
3008         h2->phdr[1].p_offset = 0;
3009         h2->phdr[1].p_filesz = 0;
3010         // .p_memsz = brka;  temporary until sz_pack2
3011         set_te64(&h2->phdr[1].p_memsz, brka);
3012         set_te32(&h2->phdr[1].p_flags, Elf64_Phdr::PF_R | Elf64_Phdr::PF_W);
3013     }
3014     if (ph.format==getFormat()) {
3015         assert((2u+ !!gnu_stack) == phnum_o);
3016         set_te32(&h2->phdr[0].p_flags, ~Elf64_Phdr::PF_W & get_te32(&h2->phdr[0].p_flags));
3017         if (!gnu_stack) {
3018             memset(&h2->linfo, 0, sizeof(h2->linfo));
3019             fo->write(h2, sizeof(*h2));
3020         }
3021         else {
3022             memset(&h3->linfo, 0, sizeof(h3->linfo));
3023             fo->write(h3, sizeof(*h3));
3024         }
3025     }
3026     else {
3027         assert(false);  // unknown ph.format, PackLinuxElf64
3028     }
3029 }
3030 
3031 // Android shlib has ABS symbols that actually are relative.
3032 static char const abs_symbol_names[][14] = {
3033       "__bss_end__"
3034     ,  "_bss_end__"
3035     , "__bss_start"
3036     , "__bss_start__"
3037     ,  "_edata"
3038     ,  "_end"
3039     , "__end__"
3040     , ""
3041 };
3042 
3043 int
adjABS(Elf32_Sym * sym,unsigned delta)3044 PackLinuxElf32::adjABS(Elf32_Sym *sym, unsigned delta)
3045 {
3046     for (int j = 0; abs_symbol_names[j][0]; ++j) {
3047         unsigned st_name = get_te32(&sym->st_name);
3048         if (!strcmp(abs_symbol_names[j], get_str_name(st_name, (unsigned)-1))) {
3049             sym->st_value += delta;
3050             return 1;
3051         }
3052     }
3053     return 0;
3054 }
3055 
3056 int
adjABS(Elf64_Sym * sym,unsigned delta)3057 PackLinuxElf64::adjABS(Elf64_Sym *sym, unsigned delta)
3058 {
3059     for (int j = 0; abs_symbol_names[j][0]; ++j) {
3060         unsigned st_name = get_te32(&sym->st_name);
3061         if (!strcmp(abs_symbol_names[j], get_str_name(st_name, (unsigned)-1))) {
3062             sym->st_value += delta;
3063             return 1;
3064         }
3065     }
3066     return 0;
3067 }
3068 
pack1(OutputFile * fo,Filter &)3069 void PackLinuxElf32::pack1(OutputFile *fo, Filter & /*ft*/)
3070 {
3071     fi->seek(0, SEEK_SET);
3072     fi->readx(&ehdri, sizeof(ehdri));
3073     assert(e_phoff == sizeof(Elf32_Ehdr));  // checked by canPack()
3074     sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
3075 
3076     // Remember all PT_NOTE, and find lg2_page from PT_LOAD.
3077     Elf32_Phdr *phdr = phdri;
3078     note_size = 0;
3079     for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
3080         if (PT_NOTE32 == get_te32(&phdr->p_type)) {
3081             note_size += up4(get_te32(&phdr->p_filesz));
3082         }
3083     }
3084     if (note_size) {
3085         note_body = New(unsigned char, note_size);
3086         note_size = 0;
3087     }
3088     phdr = phdri;
3089     for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
3090         unsigned const type = get_te32(&phdr->p_type);
3091         if (PT_NOTE32 == type) {
3092             unsigned const len = get_te32(&phdr->p_filesz);
3093             fi->seek(get_te32(&phdr->p_offset), SEEK_SET);
3094             fi->readx(&note_body[note_size], len);
3095             note_size += up4(len);
3096         }
3097         if (PT_LOAD32 == type) {
3098             unsigned x = get_te32(&phdr->p_align) >> lg2_page;
3099             while (x>>=1) {
3100                 ++lg2_page;
3101             }
3102         }
3103         if (PT_GNU_STACK32 == type) {
3104             // MIPS stub cannot handle GNU_STACK yet.
3105             if (Elf32_Ehdr::EM_MIPS != this->e_machine) {
3106                 gnu_stack = phdr;
3107             }
3108         }
3109     }
3110     page_size =  1u<<lg2_page;
3111     page_mask = ~0u<<lg2_page;
3112 
3113     progid = 0;  // getRandomId();  not useful, so do not clutter
3114     sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
3115     if (0!=xct_off) {  // shared library
3116         sz_elf_hdrs = xct_off;
3117         lowmem.alloc(xct_off + (!opt->o_unix.android_shlib
3118             ? 0
3119             : e_shnum * sizeof(Elf32_Shdr)));
3120         memcpy(lowmem, file_image, xct_off);  // android omits Shdr here
3121         fo->write(lowmem, xct_off);  // < SHF_EXECINSTR (typ: in .plt or .init)
3122         if (opt->o_unix.android_shlib) {
3123             // In order to pacify the runtime linker on Android "O" ("Oreo"),
3124             // we will splice-in a 4KiB page that contains an "extra" copy
3125             // of the Shdr, any PT_NOTE above xct_off, and shstrtab.
3126             // File order: Ehdr, Phdr[], section contents below xct_off,
3127             //    Shdr_copy[], PT_NOTEs.hi, shstrtab.
3128             xct_va  += asl_delta;
3129             //xct_off += asl_delta;  // not yet
3130 
3131             // Relocate PT_DYNAMIC (in 2nd PT_LOAD)
3132             Elf32_Dyn *dyn = const_cast<Elf32_Dyn *>(dynseg);
3133             for (; dyn->d_tag; ++dyn) {
3134                 unsigned d_tag = get_te32(&dyn->d_tag);
3135                 if (Elf32_Dyn::DT_FINI       == d_tag
3136                 ||  Elf32_Dyn::DT_FINI_ARRAY == d_tag
3137                 ||  Elf32_Dyn::DT_INIT_ARRAY == d_tag
3138                 ||  Elf32_Dyn::DT_PREINIT_ARRAY == d_tag
3139                 ||  Elf32_Dyn::DT_PLTGOT     == d_tag) {
3140                     unsigned d_val = get_te32(&dyn->d_val);
3141                     set_te32(&dyn->d_val, asl_delta + d_val);
3142                 }
3143             }
3144 
3145             // Relocate dynsym (DT_SYMTAB) which is below xct_va
3146             unsigned const off_dynsym = get_te32(&sec_dynsym->sh_offset);
3147             unsigned const sz_dynsym  = get_te32(&sec_dynsym->sh_size);
3148             Elf32_Sym *dyntym = (Elf32_Sym *)lowmem.subref(
3149                 "bad dynsym", off_dynsym, sz_dynsym);
3150             Elf32_Sym *sym = dyntym;
3151             for (int j = sz_dynsym / sizeof(Elf32_Sym); --j>=0; ++sym) {
3152                 unsigned symval = get_te32(&sym->st_value);
3153                 unsigned symsec = get_te16(&sym->st_shndx);
3154                 if (Elf32_Sym::SHN_UNDEF != symsec
3155                 &&  Elf32_Sym::SHN_ABS   != symsec
3156                 &&  xct_off <= symval) {
3157                     set_te32(&sym->st_value, asl_delta + symval);
3158                 }
3159                 if (Elf32_Sym::SHN_ABS == symsec && xct_off <= symval) {
3160                     adjABS(sym, asl_delta);
3161                 }
3162             }
3163 
3164             // Relocate Phdr virtual addresses, but not physical offsets and sizes
3165             unsigned char buf_notes[512]; memset(buf_notes, 0, sizeof(buf_notes));
3166             unsigned len_notes = 0;
3167             phdr = (Elf32_Phdr *)lowmem.subref(
3168                 "bad e_phoff", e_phoff, e_phnum * sizeof(Elf32_Phdr));
3169             for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
3170                 upx_uint32_t offset = get_te32(&phdr->p_offset);
3171                 if (xct_off <= offset) { // above the extra page
3172                     if (PT_NOTE32 == get_te32(&phdr->p_type)) {
3173                         upx_uint32_t memsz = get_te32(&phdr->p_memsz);
3174                         if (sizeof(buf_notes) < (memsz + len_notes)) {
3175                             throwCantPack("PT_NOTEs too big");
3176                         }
3177                         set_te32(&phdr->p_vaddr,
3178                             len_notes + (e_shnum * sizeof(Elf32_Shdr)) + xct_off);
3179                         phdr->p_offset = phdr->p_paddr = phdr->p_vaddr;
3180                         memcpy(&buf_notes[len_notes], &file_image[offset], memsz);
3181                         len_notes += memsz;
3182                     }
3183                     else {
3184                         //set_te32(&phdr->p_offset, asl_delta + offset);  // physical
3185                         upx_uint32_t addr = get_te32(&phdr->p_paddr);
3186                         set_te32(&phdr->p_paddr, asl_delta + addr);
3187                                      addr = get_te32(&phdr->p_vaddr);
3188                         set_te32(&phdr->p_vaddr, asl_delta + addr);
3189                     }
3190                 }
3191                 // .p_filesz,.p_memsz are updated in ::pack3
3192             }
3193 
3194             Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)&lowmem[0];
3195             upx_uint32_t e_entry = get_te32(&ehdr->e_entry);
3196             if (xct_off < e_entry) {
3197                 set_te32(&ehdr->e_entry, asl_delta + e_entry);
3198             }
3199             // Relocate Shdr; and Rela, Rel (below xct_off)
3200             set_te32(&ehdr->e_shoff, xct_off);
3201             memcpy(&lowmem[xct_off], shdri, e_shnum * sizeof(Elf32_Shdr));
3202             Elf32_Shdr *const shdro = (Elf32_Shdr *)&lowmem[xct_off];
3203             Elf32_Shdr *shdr = shdro;
3204             unsigned sz_shstrtab  = get_te32(&sec_strndx->sh_size);
3205             for (unsigned j = 0; j < e_shnum; ++j, ++shdr) {
3206 
3207                 unsigned sh_type = get_te32(&shdr->sh_type);
3208                 unsigned sh_size = get_te32(&shdr->sh_size);
3209                 unsigned  sh_offset = get_te32(&shdr->sh_offset);
3210                 unsigned sh_entsize = get_te32(&shdr->sh_entsize);
3211                 if (xct_off <= sh_offset) {
3212                     //set_te32(&shdr->sh_offset, asl_delta + sh_offset);  // FIXME ??
3213                     upx_uint32_t addr = get_te32(&shdr->sh_addr);
3214                     set_te32(&shdr->sh_addr, asl_delta + addr);
3215                 }
3216                 if (Elf32_Shdr::SHT_RELA== sh_type) {
3217                     if (sizeof(Elf32_Rela) != sh_entsize) {
3218                         char msg[50];
3219                         snprintf(msg, sizeof(msg), "bad Rela.sh_entsize %u", sh_entsize);
3220                         throwCantPack(msg);
3221                     }
3222                     n_jmp_slot = 0;
3223                     plt_off = ~0u;
3224                     Elf32_Rela *const relb = (Elf32_Rela *)lowmem.subref(
3225                          "bad Rela offset", sh_offset, sh_size);
3226                     Elf32_Rela *rela = relb;
3227                     for (int k = sh_size / sh_entsize; --k >= 0; ++rela) {
3228                         unsigned r_addend = get_te32(&rela->r_addend);
3229                         unsigned r_offset = get_te32(&rela->r_offset);
3230                         unsigned r_info   = get_te32(&rela->r_info);
3231                         unsigned r_type = ELF32_R_TYPE(r_info);
3232                         if (xct_off <= r_offset) {
3233                             set_te32(&rela->r_offset, asl_delta + r_offset);
3234                         }
3235                         if (Elf32_Ehdr::EM_ARM == e_machine) {
3236                             if (R_ARM_RELATIVE == r_type) {
3237                                 if (xct_off <= r_addend) {
3238                                     set_te32(&rela->r_addend, asl_delta + r_addend);
3239                                 }
3240                             }
3241                             if (R_ARM_JUMP_SLOT == r_type) {
3242                                 // .rela.plt contains offset of the "first time" target
3243                                 if (plt_off > r_offset) {
3244                                     plt_off = r_offset;
3245                                 }
3246                                 unsigned d = elf_get_offset_from_address(r_offset);
3247                                 unsigned w = get_te32(&file_image[d]);
3248                                 if (xct_off <= w) {
3249                                     set_te32(&file_image[d], asl_delta + w);
3250                                 }
3251                                 ++n_jmp_slot;
3252                             }
3253                         }
3254                     }
3255                     fo->seek(sh_offset, SEEK_SET);
3256                     fo->rewrite(relb, sh_size);
3257                 }
3258                 if (Elf32_Shdr::SHT_REL == sh_type) {
3259                     if (sizeof(Elf32_Rel) != sh_entsize) {
3260                         char msg[50];
3261                         snprintf(msg, sizeof(msg), "bad Rel.sh_entsize %u", sh_entsize);
3262                         throwCantPack(msg);
3263                     }
3264                     n_jmp_slot = 0;
3265                     plt_off = ~0u;
3266                     Elf32_Rel *const rel0 = (Elf32_Rel *)lowmem.subref(
3267                          "bad Rel offset", sh_offset, sh_size);
3268                     Elf32_Rel *rel = rel0;
3269                     for (int k = sh_size / sh_entsize; --k >= 0; ++rel) {
3270                         unsigned r_offset = get_te32(&rel->r_offset);
3271                         unsigned r_info = get_te32(&rel->r_info);
3272                         unsigned r_type = ELF32_R_TYPE(r_info);
3273                         unsigned d = elf_get_offset_from_address(r_offset);
3274                         unsigned w = get_te32(&file_image[d]);
3275                         if (xct_off <= r_offset) {
3276                             set_te32(&rel->r_offset, asl_delta + r_offset);
3277                         }
3278                         if (Elf32_Ehdr::EM_ARM == e_machine) switch (r_type) {
3279                             default: {
3280                                 char msg[90]; snprintf(msg, sizeof(msg),
3281                                     "unexpected relocation %#x [%#x]",
3282                                     r_type, -1 + (sh_size / sh_entsize) - k);
3283                                 throwCantPack(msg);
3284                             } break;
3285                             case R_ARM_ABS32:  // FALL THROUGH
3286                             case R_ARM_GLOB_DAT: // FALL THROUGH
3287                             case R_ARM_RELATIVE: {
3288                                 if (xct_off <= w) {
3289                                     set_te32(&file_image[d], asl_delta + w);
3290                                 }
3291                             } break;
3292                             case R_ARM_JUMP_SLOT: {
3293                                 if (plt_off > r_offset) {
3294                                     plt_off = r_offset;
3295                                 }
3296                                 if (xct_off <= w) {
3297                                     set_te32(&file_image[d], asl_delta + w);
3298                                 }
3299                                 ++n_jmp_slot;
3300                             }; break;
3301                         }
3302                     }
3303                     fo->seek(sh_offset, SEEK_SET);
3304                     fo->rewrite(rel0, sh_size);
3305                 }
3306                 if (Elf32_Shdr::SHT_NOTE == sh_type) {
3307                     if (!(Elf32_Shdr::SHF_ALLOC & get_te32(&shdr->sh_flags))) {
3308                         // example: version number of 'gold' linker (static binder)
3309                         if (sizeof(buf_notes) < (sh_size + len_notes)) {
3310                             throwCantPack("SHT_NOTEs too big");
3311                         }
3312                         set_te32(&shdro[j].sh_offset,
3313                             len_notes + (e_shnum * sizeof(Elf32_Shdr)) + xct_off);
3314                         memcpy(&buf_notes[len_notes], &file_image[sh_offset], sh_size);
3315                         len_notes += sh_size;
3316                     }
3317                     else { // SHF_ALLOC, thus already in PT_LOAD
3318                         // Not sure why we need this conditional.
3319                         // Anyway, some Android have multiple SHT_NOTE sections.
3320                         if (xct_off <= sh_offset) {
3321                             upx_uint32_t pos = xct_off + e_shnum * sizeof(Elf32_Shdr);
3322                             set_te32(&shdr->sh_addr,   pos);
3323                             set_te32(&shdr->sh_offset, pos);
3324                         }
3325                     }
3326                 }
3327             }
3328             // shstrndx will move
3329             set_te32(&shdro[get_te16(&ehdri.e_shstrndx)].sh_offset,
3330                 len_notes + e_shnum * sizeof(Elf32_Shdr) + xct_off);
3331 
3332             // (Re-)write all changes below xct_off
3333             fo->seek(0, SEEK_SET);
3334             fo->rewrite(lowmem, xct_off);
3335 
3336             // New copy of Shdr
3337             Elf32_Shdr blank; memset(&blank, 0, sizeof(blank));
3338             set_te32(&blank.sh_offset, xct_off);  // hint for "upx -d"
3339             fo->write(&blank, sizeof(blank));
3340             fo->write(&shdro[1], (-1+ e_shnum) * sizeof(Elf32_Shdr));
3341 
3342             if (len_notes) {
3343                 fo->write(buf_notes, len_notes);
3344             }
3345 
3346             // New copy of Shdr[.e_shstrndx].[ sh_offset, +.sh_size )
3347             fo->write(shstrtab,  sz_shstrtab);
3348 
3349             sz_elf_hdrs = fpad4(fo);
3350             //xct_off += asl_delta;  // wait until ::pack3
3351         }
3352         memset(&linfo, 0, sizeof(linfo));
3353         fo->write(&linfo, sizeof(linfo));
3354     }
3355 
3356     // if the preserve build-id option was specified
3357     if (opt->o_unix.preserve_build_id) {
3358         // set this so we can use elf_find_section_name
3359         e_shnum = get_te16(&ehdri.e_shnum);
3360         if (!shdri) {
3361             shdri = (Elf32_Shdr *)&file_image[get_te32(&ehdri.e_shoff)];
3362         }
3363         //set the shstrtab
3364         sec_strndx = &shdri[get_te16(&ehdri.e_shstrndx)];
3365 
3366         char *strtab = New(char, sec_strndx->sh_size);
3367         fi->seek(0,SEEK_SET);
3368         fi->seek(sec_strndx->sh_offset,SEEK_SET);
3369         fi->readx(strtab,sec_strndx->sh_size);
3370 
3371         shstrtab = (const char*)strtab;
3372 
3373         Elf32_Shdr const *buildid = elf_find_section_name(".note.gnu.build-id");
3374         if (buildid) {
3375             unsigned char *data = New(unsigned char, buildid->sh_size);
3376             memset(data,0,buildid->sh_size);
3377             fi->seek(0,SEEK_SET);
3378             fi->seek(buildid->sh_offset,SEEK_SET);
3379             fi->readx(data,buildid->sh_size);
3380 
3381             buildid_data  = data;
3382 
3383             o_elf_shnum = 3;
3384             memset(&shdrout,0,sizeof(shdrout));
3385 
3386             //setup the build-id
3387             memcpy(&shdrout.shdr[1], buildid, sizeof(shdrout.shdr[1]));
3388             shdrout.shdr[1].sh_name = 1;
3389 
3390             //setup the shstrtab
3391             memcpy(&shdrout.shdr[2], sec_strndx, sizeof(shdrout.shdr[2]));
3392             shdrout.shdr[2].sh_name = 20;
3393             shdrout.shdr[2].sh_size = 29; //size of our static shstrtab
3394         }
3395     }
3396 }
3397 
pack1(OutputFile * fo,Filter & ft)3398 void PackLinuxElf32x86::pack1(OutputFile *fo, Filter &ft)
3399 {
3400     super::pack1(fo, ft);
3401     if (0!=xct_off)  // shared library
3402         return;
3403     generateElfHdr(fo, stub_i386_linux_elf_fold, getbrk(phdri, e_phnum) );
3404 }
3405 
pack1(OutputFile * fo,Filter & ft)3406 void PackBSDElf32x86::pack1(OutputFile *fo, Filter &ft)
3407 {
3408     PackLinuxElf32::pack1(fo, ft);
3409     if (0!=xct_off) // shared library
3410         return;
3411     generateElfHdr(fo, stub_i386_bsd_elf_fold, getbrk(phdri, e_phnum) );
3412 }
3413 
pack1(OutputFile * fo,Filter & ft)3414 void PackLinuxElf32armLe::pack1(OutputFile *fo, Filter &ft)
3415 {
3416     super::pack1(fo, ft);
3417     if (0!=xct_off)  // shared library
3418         return;
3419     unsigned const e_flags = get_te32(&ehdri.e_flags);
3420     cprElfHdr3 h3;
3421     if (Elf32_Ehdr::ELFOSABI_LINUX==ei_osabi) {
3422         memcpy(&h3, stub_arm_v5a_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
3423 
3424         h3.ehdr.e_ident[Elf32_Ehdr::EI_ABIVERSION] = e_flags>>24;
3425     }
3426     else {
3427         memcpy(&h3, stub_arm_v4a_linux_elf_fold,        sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
3428     }
3429     // Fighting over .e_ident[EI_ABIVERSION]: Debian armhf is latest culprit.
3430     // So copy from input to output; but see PackLinuxElf32::generateElfHdr
3431     memcpy(&h3.ehdr.e_ident[0], &ehdri.e_ident[0], sizeof(ehdri.e_ident));
3432     set_te32(&h3.ehdr.e_flags, e_flags);
3433     generateElfHdr(fo, &h3, getbrk(phdri, e_phnum) );
3434 }
3435 
pack1(OutputFile * fo,Filter & ft)3436 void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft)
3437 {
3438     super::pack1(fo, ft);
3439     if (0!=xct_off)  // shared library
3440         return;
3441     unsigned const e_flags = get_te32(&ehdri.e_flags);
3442     cprElfHdr3 h3;
3443     memcpy(&h3, stub_armeb_v4a_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
3444     set_te32(&h3.ehdr.e_flags, e_flags);
3445     generateElfHdr(fo, &h3, getbrk(phdri, e_phnum) );
3446 }
3447 
pack1(OutputFile * fo,Filter & ft)3448 void PackLinuxElf32mipsel::pack1(OutputFile *fo, Filter &ft)
3449 {
3450     super::pack1(fo, ft);
3451     if (0!=xct_off)  // shared library
3452         return;
3453     cprElfHdr3 h3;
3454     memcpy(&h3, stub_mipsel_r3000_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
3455     generateElfHdr(fo, &h3, getbrk(phdri, e_phnum) );
3456 }
3457 
pack1(OutputFile * fo,Filter & ft)3458 void PackLinuxElf32mipseb::pack1(OutputFile *fo, Filter &ft)
3459 {
3460     super::pack1(fo, ft);
3461     if (0!=xct_off)  // shared library
3462         return;
3463     cprElfHdr3 h3;
3464     memcpy(&h3, stub_mips_r3000_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
3465     generateElfHdr(fo, &h3, getbrk(phdri, e_phnum) );
3466 }
3467 
pack1(OutputFile * fo,Filter & ft)3468 void PackLinuxElf32ppc::pack1(OutputFile *fo, Filter &ft)
3469 {
3470     super::pack1(fo, ft);
3471     if (0!=xct_off)  // shared library
3472         return;
3473     generateElfHdr(fo, stub_powerpc_linux_elf_fold, getbrk(phdri, e_phnum) );
3474 }
3475 
pack1(OutputFile * fo,Filter & ft)3476 void PackLinuxElf64ppcle::pack1(OutputFile *fo, Filter &ft)
3477 {
3478     super::pack1(fo, ft);
3479     if (0!=xct_off)  // shared library
3480         return;
3481     generateElfHdr(fo, stub_powerpc64le_linux_elf_fold, getbrk(phdri, e_phnum) );
3482 }
3483 
pack1(OutputFile * fo,Filter & ft)3484 void PackLinuxElf64ppc::pack1(OutputFile *fo, Filter &ft)
3485 {
3486     super::pack1(fo, ft);
3487     if (0!=xct_off)  // shared library
3488         return;
3489     generateElfHdr(fo, stub_powerpc64_linux_elf_fold, getbrk(phdri, e_phnum) );
3490 }
3491 
pack1(OutputFile * fo,Filter &)3492 void PackLinuxElf64::pack1(OutputFile *fo, Filter & /*ft*/)
3493 {
3494     fi->seek(0, SEEK_SET);
3495     fi->readx(&ehdri, sizeof(ehdri));
3496     assert(e_phoff == sizeof(Elf64_Ehdr));  // checked by canPack()
3497     sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
3498 
3499     Elf64_Phdr *phdr = phdri;
3500     note_size = 0;
3501     for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
3502         if (PT_NOTE64 == get_te32(&phdr->p_type)) {
3503             note_size += up4(get_te64(&phdr->p_filesz));
3504         }
3505     }
3506     if (note_size) {
3507         note_body = New(unsigned char, note_size);
3508         note_size = 0;
3509     }
3510     phdr = phdri;
3511     for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
3512         unsigned const type = get_te32(&phdr->p_type);
3513         if (PT_NOTE64 == type) {
3514             unsigned const len = get_te64(&phdr->p_filesz);
3515             fi->seek(get_te64(&phdr->p_offset), SEEK_SET);
3516             fi->readx(&note_body[note_size], len);
3517             note_size += up4(len);
3518         }
3519         if (PT_LOAD64 == type) {
3520             unsigned x = get_te64(&phdr->p_align) >> lg2_page;
3521             while (x>>=1) {
3522                 ++lg2_page;
3523             }
3524         }
3525         if (PT_GNU_STACK64 == type) {
3526             gnu_stack = phdr;
3527         }
3528     }
3529     page_size =  1u  <<lg2_page;
3530     page_mask = ~0ull<<lg2_page;
3531 
3532     progid = 0;  // getRandomId();  not useful, so do not clutter
3533     sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
3534     if (0!=xct_off) {  // shared library
3535         sz_elf_hdrs = xct_off;
3536         lowmem.alloc(xct_off + (!opt->o_unix.android_shlib
3537             ? 0
3538             : e_shnum * sizeof(Elf64_Shdr)));
3539         memcpy(lowmem, file_image, xct_off);  // android omits Shdr here
3540         fo->write(lowmem, xct_off);  // < SHF_EXECINSTR (typ: in .plt or .init)
3541         if (opt->o_unix.android_shlib) {
3542             // In order to pacify the runtime linker on Android "O" ("Oreo"),
3543             // we will splice-in a 4KiB page that contains an "extra" copy
3544             // of the Shdr, any PT_NOTE above xct_off, and shstrtab.
3545             // File order: Ehdr, Phdr[], section contents below xct_off,
3546             //    Shdr_copy[], PT_NOTEs.hi, shstrtab.
3547             xct_va  += asl_delta;
3548             //xct_off += asl_delta;  // not yet
3549 
3550             // Relocate PT_DYNAMIC (in 2nd PT_LOAD)
3551             Elf64_Dyn *dyn = const_cast<Elf64_Dyn *>(dynseg);
3552             for (; dyn->d_tag; ++dyn) {
3553                 upx_uint64_t d_tag = get_te64(&dyn->d_tag);
3554                 if (Elf64_Dyn::DT_FINI       == d_tag
3555                 ||  Elf64_Dyn::DT_FINI_ARRAY == d_tag
3556                 ||  Elf64_Dyn::DT_INIT_ARRAY == d_tag
3557                 ||  Elf64_Dyn::DT_PREINIT_ARRAY == d_tag
3558                 ||  Elf64_Dyn::DT_PLTGOT      == d_tag) {
3559                     upx_uint64_t d_val = get_te64(&dyn->d_val);
3560                     set_te64(&dyn->d_val, asl_delta + d_val);
3561                 }
3562             }
3563 
3564             // Relocate dynsym (DT_SYMTAB) which is below xct_va
3565             upx_uint64_t const off_dynsym = get_te64(&sec_dynsym->sh_offset);
3566             upx_uint64_t const sz_dynsym  = get_te64(&sec_dynsym->sh_size);
3567             Elf64_Sym *dyntym = (Elf64_Sym *)lowmem.subref(
3568                 "bad dynsym", off_dynsym, sz_dynsym);
3569             Elf64_Sym *sym = dyntym;
3570             for (int j = sz_dynsym / sizeof(Elf64_Sym); --j>=0; ++sym) {
3571                 upx_uint64_t symval = get_te64(&sym->st_value);
3572                 unsigned symsec = get_te16(&sym->st_shndx);
3573                 if (Elf64_Sym::SHN_UNDEF != symsec
3574                 &&  Elf64_Sym::SHN_ABS   != symsec
3575                 &&  xct_off <= symval) {
3576                     set_te64(&sym->st_value, asl_delta + symval);
3577                 }
3578                 if (Elf64_Sym::SHN_ABS == symsec && xct_off <= symval) {
3579                     adjABS(sym, asl_delta);
3580                 }
3581             }
3582 
3583             // Relocate Phdr virtual addresses, but not physical offsets and sizes
3584             unsigned char buf_notes[512]; memset(buf_notes, 0, sizeof(buf_notes));
3585             unsigned len_notes = 0;
3586             phdr = (Elf64_Phdr *)lowmem.subref(
3587                 "bad e_phoff", e_phoff, e_phnum * sizeof(Elf64_Phdr));
3588             for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
3589                 upx_uint64_t offset = get_te64(&phdr->p_offset);
3590                 if (xct_off <= offset) { // above the extra page
3591                     if (PT_NOTE64 == get_te32(&phdr->p_type)) {
3592                         upx_uint64_t memsz = get_te64(&phdr->p_memsz);
3593                         if (sizeof(buf_notes) < (memsz + len_notes)) {
3594                             throwCantPack("PT_NOTES too big");
3595                         }
3596                         set_te64(&phdr->p_vaddr,
3597                             len_notes + (e_shnum * sizeof(Elf64_Shdr)) + xct_off);
3598                         phdr->p_offset = phdr->p_paddr = phdr->p_vaddr;
3599                         memcpy(&buf_notes[len_notes], &file_image[offset], memsz);
3600                         len_notes += memsz;
3601                     }
3602                     else {
3603                         //set_te64(&phdr->p_offset, asl_delta + offset);  // physical
3604                         upx_uint64_t addr = get_te64(&phdr->p_paddr);
3605                         set_te64(&phdr->p_paddr, asl_delta + addr);
3606                                      addr = get_te64(&phdr->p_vaddr);
3607                         set_te64(&phdr->p_vaddr, asl_delta + addr);
3608                     }
3609                 }
3610                 // .p_filesz,.p_memsz are updated in ::pack3
3611             }
3612 
3613             Elf64_Ehdr *const ehdr = (Elf64_Ehdr *)&lowmem[0];
3614             upx_uint64_t e_entry = get_te64(&ehdr->e_entry);
3615             if (xct_off < e_entry) {
3616                 set_te64(&ehdr->e_entry, asl_delta + e_entry);
3617             }
3618             // Relocate Shdr; and Rela, Rel (below xct_off)
3619             set_te64(&ehdr->e_shoff, xct_off);
3620             memcpy(&lowmem[xct_off], shdri, e_shnum * sizeof(Elf64_Shdr));
3621             Elf64_Shdr *const shdro = (Elf64_Shdr *)&lowmem[xct_off];
3622             Elf64_Shdr *shdr = shdro;
3623             upx_uint64_t sz_shstrtab  = get_te64(&sec_strndx->sh_size);
3624             for (unsigned j = 0; j < e_shnum; ++j, ++shdr) {
3625                 unsigned sh_type = get_te32(&shdr->sh_type);
3626                 upx_uint64_t sh_size = get_te64(&shdr->sh_size);
3627                 upx_uint64_t sh_offset = get_te64(&shdr->sh_offset);
3628                 upx_uint64_t sh_entsize = get_te64(&shdr->sh_entsize);
3629 
3630                 if (xct_off <= sh_offset) {
3631                     upx_uint64_t addr = get_te64(&shdr->sh_addr);
3632                     set_te64(&shdr->sh_addr, asl_delta + addr);
3633                 }
3634                 if (Elf64_Shdr::SHT_RELA == sh_type) {
3635                     if (sizeof(Elf64_Rela) != sh_entsize) {
3636                         char msg[50];
3637                         snprintf(msg, sizeof(msg), "bad Rela.sh_entsize %lu", (long)sh_entsize);
3638                         throwCantPack(msg);
3639                     }
3640                     n_jmp_slot = 0;
3641                     plt_off = ~0ull;
3642                     Elf64_Rela *const relb = (Elf64_Rela *)lowmem.subref(
3643                          "bad Rela offset", sh_offset, sh_size);
3644                     Elf64_Rela *rela = relb;
3645                     for (int k = sh_size / sh_entsize; --k >= 0; ++rela) {
3646                         upx_uint64_t r_addend = get_te64(&rela->r_addend);
3647                         upx_uint64_t r_offset = get_te64(&rela->r_offset);
3648                         upx_uint64_t r_info   = get_te64(&rela->r_info);
3649                         unsigned r_type = ELF64_R_TYPE(r_info);
3650                         if (xct_off <= r_offset) {
3651                             set_te64(&rela->r_offset, asl_delta + r_offset);
3652                         }
3653                         if (Elf64_Ehdr::EM_AARCH64 == e_machine) switch (r_type) {
3654                             default: {
3655                                 char msg[90]; snprintf(msg, sizeof(msg),
3656                                     "unexpected relocation %#x [%#x]",
3657                                     r_type, -1 + (unsigned)(sh_size / sh_entsize) - k);
3658                                 throwCantPack(msg);
3659                             } break;
3660                             case R_AARCH64_ABS64: // FALL THROUGH
3661                             case R_AARCH64_GLOB_DAT: // FALL THROUGH
3662                             case R_AARCH64_RELATIVE: {
3663                                 if (xct_off <= r_addend) {
3664                                     set_te64(&rela->r_addend, asl_delta + r_addend);
3665                                 }
3666                             } break;
3667                             case R_AARCH64_JUMP_SLOT: {
3668                                 // .rela.plt contains offset of the "first time" target
3669                                 if (plt_off > r_offset) {
3670                                     plt_off = r_offset;
3671                                 }
3672                                 upx_uint64_t d = elf_get_offset_from_address(r_offset);
3673                                 upx_uint64_t w = get_te64(&file_image[d]);
3674                                 if (xct_off <= w) {
3675                                     set_te64(&file_image[d], asl_delta + w);
3676                                 }
3677                                 ++n_jmp_slot;
3678                             } break;
3679                         }
3680                     }
3681                     fo->seek(sh_offset, SEEK_SET);
3682                     fo->rewrite(relb, sh_size);
3683                 }
3684                 if (Elf64_Shdr::SHT_REL == sh_type) {
3685                     if (sizeof(Elf64_Rel) != sh_entsize) {
3686                         char msg[50];
3687                         snprintf(msg, sizeof(msg), "bad Rel.sh_entsize %lu", (long)sh_entsize);
3688                         throwCantPack(msg);
3689                     }
3690                     Elf64_Rel *rel = (Elf64_Rel *)lowmem.subref(
3691                             "bad Rel sh_offset", sh_offset, sh_size);
3692                     for (int k = sh_size / sh_entsize; --k >= 0; ++rel) {
3693                         upx_uint64_t r_offset = get_te64(&rel->r_offset);
3694                         if (xct_off <= r_offset) {
3695                             set_te64(&rel->r_offset, asl_delta + r_offset);
3696                         }
3697                         // r_offset must be in 2nd PT_LOAD; .p_vaddr was already relocated
3698                         upx_uint64_t d = elf_get_offset_from_address(asl_delta + r_offset);
3699                         upx_uint64_t w = get_te64(&file_image[d]);
3700                         upx_uint64_t r_info = get_te64(&rel->r_info);
3701                         unsigned r_type = ELF64_R_TYPE(r_info);
3702                         if (xct_off <= w
3703                         &&  Elf64_Ehdr::EM_AARCH64 == e_machine
3704                         &&  (  R_AARCH64_RELATIVE  == r_type
3705                             || R_AARCH64_JUMP_SLOT == r_type)) {
3706                             set_te64(&file_image[d], asl_delta + w);
3707                         }
3708                     }
3709                 }
3710                 if (Elf64_Shdr::SHT_NOTE == sh_type) {
3711                     if (!(Elf64_Shdr::SHF_ALLOC & get_te64(&shdr->sh_flags))) {
3712                         // example: version numer of 'gold' linker (static binder)
3713                         if (sizeof(buf_notes) < (sh_size + len_notes)) {
3714                             throwCantPack("SHT_NOTEs too big");
3715                         }
3716                         set_te64(&shdro[j].sh_offset,
3717                             len_notes + (e_shnum * sizeof(Elf64_Shdr)) + xct_off);
3718                         memcpy(&buf_notes[len_notes], &file_image[sh_offset], sh_size);
3719                         len_notes += sh_size;
3720                     }
3721                     else { // SHF_ALLOC: in PT_LOAD; but move sh_addr and sh_offset
3722                         // Not sure why we need this conditional.
3723                         // Anyway, some Android have multiple SHT_NOTE sections.
3724                         if (xct_off <= sh_offset) {
3725                             upx_uint64_t pos = xct_off + e_shnum * sizeof(Elf64_Shdr);
3726                             set_te64(&shdr->sh_addr,   pos);
3727                             set_te64(&shdr->sh_offset, pos);
3728                         }
3729                     }
3730                 }
3731             }
3732             // shstrndx will move
3733             set_te64(&shdro[get_te16(&ehdri.e_shstrndx)].sh_offset,
3734                 len_notes + e_shnum * sizeof(Elf64_Shdr) + xct_off);
3735 
3736             // (Re-)write all changes below xct_off
3737             fo->seek(0, SEEK_SET);
3738             fo->rewrite(lowmem, xct_off);
3739 
3740             // New copy of Shdr
3741             Elf64_Shdr blank; memset(&blank, 0, sizeof(blank));
3742             set_te64(&blank.sh_offset, xct_off);  // hint for "upx -d"
3743             fo->write(&blank, sizeof(blank));
3744             fo->write(&shdro[1], (-1+ e_shnum) * sizeof(Elf64_Shdr));
3745 
3746             if (len_notes) {
3747                 fo->write(buf_notes, len_notes);
3748             }
3749 
3750             // New copy of Shdr[.e_shstrndx].[ sh_offset, +.sh_size )
3751             fo->write(shstrtab,  sz_shstrtab);
3752 
3753             sz_elf_hdrs = fpad8(fo);
3754             //xct_off += asl_delta;  // wait until ::pack3
3755         }
3756         memset(&linfo, 0, sizeof(linfo));
3757         fo->write(&linfo, sizeof(linfo));
3758     }
3759 
3760     // only execute if option present
3761     if (opt->o_unix.preserve_build_id) {
3762         // set this so we can use elf_find_section_name
3763         e_shnum = get_te16(&ehdri.e_shnum);
3764         if (!shdri) {
3765             shdri = (Elf64_Shdr *)&file_image[get_te32(&ehdri.e_shoff)];
3766         }
3767         //set the shstrtab
3768         sec_strndx = &shdri[get_te16(&ehdri.e_shstrndx)];
3769 
3770         char *strtab = New(char, sec_strndx->sh_size);
3771         fi->seek(0,SEEK_SET);
3772         fi->seek(sec_strndx->sh_offset,SEEK_SET);
3773         fi->readx(strtab,sec_strndx->sh_size);
3774 
3775         shstrtab = (const char*)strtab;
3776 
3777         Elf64_Shdr const *buildid = elf_find_section_name(".note.gnu.build-id");
3778         if (buildid) {
3779             unsigned char *data = New(unsigned char, buildid->sh_size);
3780             memset(data,0,buildid->sh_size);
3781             fi->seek(0,SEEK_SET);
3782             fi->seek(buildid->sh_offset,SEEK_SET);
3783             fi->readx(data,buildid->sh_size);
3784 
3785             buildid_data  = data;
3786 
3787             o_elf_shnum = 3;
3788             memset(&shdrout,0,sizeof(shdrout));
3789 
3790             //setup the build-id
3791             memcpy(&shdrout.shdr[1], buildid, sizeof(shdrout.shdr[1]));
3792             shdrout.shdr[1].sh_name = 1;
3793 
3794             //setup the shstrtab
3795             memcpy(&shdrout.shdr[2], sec_strndx, sizeof(shdrout.shdr[2]));
3796             shdrout.shdr[2].sh_name = 20;
3797             shdrout.shdr[2].sh_size = 29; //size of our static shstrtab
3798         }
3799     }
3800 }
3801 
pack1(OutputFile * fo,Filter & ft)3802 void PackLinuxElf64amd::pack1(OutputFile *fo, Filter &ft)
3803 {
3804     super::pack1(fo, ft);
3805     if (0!=xct_off)  // shared library
3806         return;
3807     generateElfHdr(fo, stub_amd64_linux_elf_fold, getbrk(phdri, e_phnum) );
3808 }
3809 
pack1(OutputFile * fo,Filter & ft)3810 void PackLinuxElf64arm::pack1(OutputFile *fo, Filter &ft)
3811 {
3812     super::pack1(fo, ft);
3813     if (0!=xct_off)  // shared library
3814         return;
3815     generateElfHdr(fo, stub_arm64_linux_elf_fold, getbrk(phdri, e_phnum) );
3816 }
3817 
3818 // Determine length of gap between PT_LOAD phdr[k] and closest PT_LOAD
3819 // which follows in the file (or end-of-file).  Optimize for common case
3820 // where the PT_LOAD are adjacent ascending by .p_offset.  Assume no overlap.
3821 
find_LOAD_gap(Elf32_Phdr const * const phdr,unsigned const k,unsigned const nph)3822 unsigned PackLinuxElf32::find_LOAD_gap(
3823     Elf32_Phdr const *const phdr,
3824     unsigned const k,
3825     unsigned const nph
3826 )
3827 {
3828     if (PT_LOAD32!=get_te32(&phdr[k].p_type)) {
3829         return 0;
3830     }
3831     unsigned const hi = get_te32(&phdr[k].p_offset) +
3832                         get_te32(&phdr[k].p_filesz);
3833     unsigned lo = ph.u_file_size;
3834     if (lo < hi)
3835         throwCantPack("bad input: PT_LOAD beyond end-of-file");
3836     unsigned j = k;
3837     for (;;) { // circular search, optimize for adjacent ascending
3838         ++j;
3839         if (nph==j) {
3840             j = 0;
3841         }
3842         if (k==j) {
3843             break;
3844         }
3845         if (PT_LOAD32==get_te32(&phdr[j].p_type)) {
3846             unsigned const t = get_te32(&phdr[j].p_offset);
3847             if ((t - hi) < (lo - hi)) {
3848                 lo = t;
3849                 if (hi==lo) {
3850                     break;
3851                 }
3852             }
3853         }
3854     }
3855     return lo - hi;
3856 }
3857 
pack2(OutputFile * fo,Filter & ft)3858 int PackLinuxElf32::pack2(OutputFile *fo, Filter &ft)
3859 {
3860     Extent x;
3861     unsigned k;
3862     bool const is_shlib = (0!=xct_off);
3863 
3864     // count passes, set ptload vars
3865     uip->ui_total_passes = 0;
3866     for (k = 0; k < e_phnum; ++k) {
3867         if (PT_LOAD32==get_te32(&phdri[k].p_type)) {
3868             uip->ui_total_passes++;
3869             if (find_LOAD_gap(phdri, k, e_phnum)) {
3870                 uip->ui_total_passes++;
3871             }
3872         }
3873     }
3874     uip->ui_total_passes -= !!is_shlib;  // not .data of shlib
3875 
3876     // compress extents
3877     unsigned hdr_u_len = (is_shlib ? xct_off : (sizeof(Elf32_Ehdr) + sz_phdrs));
3878 
3879     unsigned total_in =  (is_shlib ?           0 : xct_off);
3880     unsigned total_out = (is_shlib ? sz_elf_hdrs : xct_off);
3881 
3882     uip->ui_pass = 0;
3883     ft.addvalue = 0;
3884 
3885     unsigned nk_f = 0; unsigned xsz_f = 0;
3886     for (k = 0; k < e_phnum; ++k)
3887     if (PT_LOAD32==get_te32(&phdri[k].p_type)
3888     &&  Elf32_Phdr::PF_X & get_te32(&phdri[k].p_flags)) {
3889         unsigned xsz =     get_te32(&phdri[k].p_filesz);
3890         if (xsz_f < xsz) {
3891             xsz_f = xsz;
3892             nk_f = k;
3893         }
3894     }
3895     int nx = 0;
3896     for (k = 0; k < e_phnum; ++k)
3897     if (PT_LOAD32==get_te32(&phdri[k].p_type)) {
3898         if (ft.id < 0x40) {
3899             // FIXME: ??    ft.addvalue = phdri[k].p_vaddr;
3900         }
3901         x.offset = get_te32(&phdri[k].p_offset);
3902         x.size   = get_te32(&phdri[k].p_filesz);
3903         if (!is_shlib || hdr_u_len < (u32_t)x.size) {
3904             if (0 == nx) { // 1st PT_LOAD32 must cover Ehdr at 0==p_offset
3905                 unsigned const delta = hdr_u_len;
3906                 if (ft.id < 0x40) {
3907                     // FIXME: ??     ft.addvalue += asl_delta;
3908                 }
3909                 if ((off_t)delta == x.size) { // PT_LOAD[0] with ElfXX.Ehdr only
3910                     // QBE backend - http://c9x.me/compile/
3911                     hdr_u_len = 0;  // no fiddling necessary!
3912                     // &ft arg to packExtent will be zero becaue (k != nk_f)
3913                 }
3914                 else {
3915                     x.offset += delta;
3916                     x.size   -= delta;
3917                 }
3918             }
3919             // compressWithFilters() always assumes a "loader", so would
3920             // throw NotCompressible for small .data Extents, which PowerPC
3921             // sometimes marks as PF_X anyway.  So filter only first segment.
3922             if (k == nk_f || !is_shlib) {
3923                 packExtent(x, total_in, total_out,
3924                     (k==nk_f ? &ft : 0 ), fo, hdr_u_len);
3925             }
3926             else {
3927                 total_in += x.size;
3928             }
3929         }
3930         else {
3931                 total_in += x.size;
3932         }
3933         hdr_u_len = 0;
3934         ++nx;
3935     }
3936     sz_pack2a = fpad4(fo);  // MATCH01
3937 
3938     // Accounting only; ::pack3 will do the compression and output
3939     for (k = 0; k < e_phnum; ++k) {
3940         total_in += find_LOAD_gap(phdri, k, e_phnum);
3941     }
3942 
3943     if (total_in != (u32_t)file_size)
3944         throwEOFException();
3945 
3946     return 0;  // omit end-of-compression bhdr for now
3947 }
3948 
3949 // Determine length of gap between PT_LOAD phdr[k] and closest PT_LOAD
3950 // which follows in the file (or end-of-file).  Optimize for common case
3951 // where the PT_LOAD are adjacent ascending by .p_offset.  Assume no overlap.
3952 
find_LOAD_gap(Elf64_Phdr const * const phdr,unsigned const k,unsigned const nph)3953 unsigned PackLinuxElf64::find_LOAD_gap(
3954     Elf64_Phdr const *const phdr,
3955     unsigned const k,
3956     unsigned const nph
3957 )
3958 {
3959     if (PT_LOAD64!=get_te32(&phdr[k].p_type)) {
3960         return 0;
3961     }
3962     unsigned const hi = get_te64(&phdr[k].p_offset) +
3963                         get_te64(&phdr[k].p_filesz);
3964     unsigned lo = ph.u_file_size;
3965     if (lo < hi)
3966         throwCantPack("bad input: PT_LOAD beyond end-of-file");
3967     unsigned j = k;
3968     for (;;) { // circular search, optimize for adjacent ascending
3969         ++j;
3970         if (nph==j) {
3971             j = 0;
3972         }
3973         if (k==j) {
3974             break;
3975         }
3976         if (PT_LOAD64==get_te32(&phdr[j].p_type)) {
3977             unsigned const t = get_te64(&phdr[j].p_offset);
3978             if ((t - hi) < (lo - hi)) {
3979                 lo = t;
3980                 if (hi==lo) {
3981                     break;
3982                 }
3983             }
3984         }
3985     }
3986     return lo - hi;
3987 }
3988 
pack2(OutputFile * fo,Filter & ft)3989 int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
3990 {
3991     Extent x;
3992     unsigned k;
3993     bool const is_shlib = (0!=xct_off);
3994 
3995     // count passes, set ptload vars
3996     uip->ui_total_passes = 0;
3997     for (k = 0; k < e_phnum; ++k) {
3998         if (PT_LOAD64==get_te32(&phdri[k].p_type)) {
3999             uip->ui_total_passes++;
4000             if (find_LOAD_gap(phdri, k, e_phnum)) {
4001                 uip->ui_total_passes++;
4002             }
4003         }
4004     }
4005     uip->ui_total_passes -= !!is_shlib;  // not .data of shlib
4006 
4007     // compress extents
4008     unsigned hdr_u_len = (is_shlib ? xct_off : (sizeof(Elf64_Ehdr) + sz_phdrs));
4009 
4010     unsigned total_in =  (is_shlib ?           0 : xct_off);
4011     unsigned total_out = (is_shlib ? sz_elf_hdrs : xct_off);
4012 
4013     uip->ui_pass = 0;
4014     ft.addvalue = 0;
4015 
4016     unsigned nk_f = 0; upx_uint64_t xsz_f = 0;
4017     for (k = 0; k < e_phnum; ++k)
4018     if (PT_LOAD64==get_te32(&phdri[k].p_type)
4019     &&  Elf64_Phdr::PF_X & get_te64(&phdri[k].p_flags)) {
4020         upx_uint64_t xsz = get_te64(&phdri[k].p_filesz);
4021         if (xsz_f < xsz) {
4022             xsz_f = xsz;
4023             nk_f = k;
4024         }
4025     }
4026     int nx = 0;
4027     for (k = 0; k < e_phnum; ++k)
4028     if (PT_LOAD64==get_te32(&phdri[k].p_type)) {
4029         if (ft.id < 0x40) {
4030             // FIXME: ??    ft.addvalue = phdri[k].p_vaddr;
4031         }
4032         x.offset = get_te64(&phdri[k].p_offset);
4033         x.size   = get_te64(&phdri[k].p_filesz);
4034         if (!is_shlib || hdr_u_len < (u64_t)x.size) {
4035             if (0 == nx) { // 1st PT_LOAD64 must cover Ehdr at 0==p_offset
4036                 unsigned const delta = hdr_u_len;
4037                 if (ft.id < 0x40) {
4038                     // FIXME: ??     ft.addvalue += asl_delta;
4039                 }
4040                 if ((off_t)delta == x.size) { // PT_LOAD[0] with ElfXX.Ehdr only
4041                     // QBE backend - http://c9x.me/compile/
4042                     hdr_u_len = 0;  // no fiddling necessary!
4043                     // &ft arg to packExtent will be zero becaue (k != nk_f)
4044                 }
4045                 else {
4046                     x.offset += delta;
4047                     x.size   -= delta;
4048                 }
4049             }
4050             // compressWithFilters() always assumes a "loader", so would
4051             // throw NotCompressible for small .data Extents, which PowerPC
4052             // sometimes marks as PF_X anyway.  So filter only first segment.
4053             if (k == nk_f || !is_shlib) {
4054                 packExtent(x, total_in, total_out,
4055                     (k==nk_f ? &ft : 0 ), fo, hdr_u_len);
4056             }
4057             else {
4058                 total_in += x.size;
4059             }
4060         }
4061         else {
4062                 total_in += x.size;
4063         }
4064         hdr_u_len = 0;
4065         ++nx;
4066     }
4067     sz_pack2a = fpad4(fo);  // MATCH01
4068 
4069     // Accounting only; ::pack3 will do the compression and output
4070     for (k = 0; k < e_phnum; ++k) {
4071         total_in += find_LOAD_gap(phdri, k, e_phnum);
4072     }
4073 
4074     if (total_in != (u32_t)file_size)
4075         throwEOFException();
4076 
4077     return 0;  // omit end-of-compression bhdr for now
4078 }
4079 
4080 // Filter 0x50, 0x51 assume HostPolicy::isLE
4081 static const int *
ARM_getFilters(bool const isBE)4082 ARM_getFilters(bool const isBE)
4083 {
4084     static const int f50[] = { 0x50, FT_END };
4085     static const int f51[] = { 0x51, FT_END };
4086     if (isBE)
4087         return f51;
4088     return f50;
4089 }
4090 
4091 const int *
getFilters() const4092 PackLinuxElf32armBe::getFilters() const
4093 {
4094     return ARM_getFilters(true);
4095 }
4096 
4097 const int *
getFilters() const4098 PackLinuxElf32armLe::getFilters() const
4099 {
4100     return ARM_getFilters(false);
4101 }
4102 
4103 const int *
getFilters() const4104 PackLinuxElf32mipseb::getFilters() const
4105 {
4106     static const int f_none[] = { FT_END };
4107     return f_none;
4108 }
4109 
4110 const int *
getFilters() const4111 PackLinuxElf32mipsel::getFilters() const
4112 {
4113     static const int f_none[] = { FT_END };
4114     return f_none;
4115 }
4116 
4117 // October 2011: QNX 6.3.0 has no unique signature?
ARM_is_QNX(void)4118 int PackLinuxElf32::ARM_is_QNX(void)
4119 {
4120     if (Elf32_Ehdr::EM_ARM==get_te16(&ehdri.e_machine)
4121     &&  Elf32_Ehdr::ELFDATA2MSB== ehdri.e_ident[Elf32_Ehdr::EI_DATA]
4122     &&  Elf32_Ehdr::ELFOSABI_ARM==ehdri.e_ident[Elf32_Ehdr::EI_OSABI]
4123     &&  0x100000==(page_mask & get_te32(&phdri[0].p_vaddr))) {
4124         Elf32_Phdr const *phdr = phdri;
4125         for (int j = get_te16(&ehdri.e_phnum); --j>=0; ++phdr) {
4126             if (Elf32_Phdr::PT_INTERP==get_te32(&phdr->p_type)) {
4127                 char interp[64];
4128                 unsigned const sz_interp = get_te32(&phdr->p_filesz);
4129                 unsigned const pos_interp = get_te32(&phdr->p_offset);
4130                 if (sz_interp <= sizeof(interp)
4131                 &&  (sz_interp + pos_interp) <= (unsigned)file_size) {
4132                     fi->seek(pos_interp, SEEK_SET);
4133                     fi->readx(interp, sz_interp);
4134                     for (int k = sz_interp - 5; k>=0; --k) {
4135                         if (0==memcmp("ldqnx", &interp[k], 5))
4136                             return 1;
4137                     }
4138                 }
4139             }
4140         }
4141     }
4142     return 0;
4143 }
4144 
ARM_defineSymbols(Filter const * ft)4145 void PackLinuxElf32::ARM_defineSymbols(Filter const *ft)
4146 {
4147     PackLinuxElf32::defineSymbols(ft);
4148 
4149 #define MAP_PRIVATE      2     /* UNIX standard */
4150 #define MAP_FIXED     0x10     /* UNIX standard */
4151 #define MAP_ANONYMOUS 0x20     /* UNIX standard */
4152 #define MAP_PRIVANON     3     /* QNX anonymous private memory */
4153     unsigned mflg = MAP_PRIVATE | MAP_ANONYMOUS;
4154     if (ARM_is_QNX())
4155         mflg = MAP_PRIVANON;
4156     linker->defineSymbol("MFLG", mflg);
4157 }
4158 
defineSymbols(Filter const * ft)4159 void PackLinuxElf32armLe::defineSymbols(Filter const *ft)
4160 {
4161     ARM_defineSymbols(ft);
4162 }
4163 
defineSymbols(Filter const * ft)4164 void PackLinuxElf32armBe::defineSymbols(Filter const *ft)
4165 {
4166     ARM_defineSymbols(ft);
4167 }
4168 
defineSymbols(Filter const * ft)4169 void PackLinuxElf64arm::defineSymbols(Filter const *ft)
4170 {
4171     PackLinuxElf64::defineSymbols(ft);
4172 
4173 #define MAP_PRIVATE      2     /* UNIX standard */
4174 #define MAP_FIXED     0x10     /* UNIX standard */
4175 #define MAP_ANONYMOUS 0x20     /* UNIX standard */
4176 #define MAP_PRIVANON     3     /* QNX anonymous private memory */
4177     unsigned mflg = MAP_PRIVATE | MAP_ANONYMOUS;
4178     //if (ARM_is_QNX())
4179     //    mflg = MAP_PRIVANON;
4180     linker->defineSymbol("MFLG", mflg);
4181 }
4182 
defineSymbols(Filter const * ft)4183 void PackLinuxElf32mipseb::defineSymbols(Filter const *ft)
4184 {
4185     PackLinuxElf32::defineSymbols(ft);
4186 }
4187 
defineSymbols(Filter const * ft)4188 void PackLinuxElf32mipsel::defineSymbols(Filter const *ft)
4189 {
4190     PackLinuxElf32::defineSymbols(ft);
4191 }
4192 
pack4(OutputFile * fo,Filter & ft)4193 void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
4194 {
4195     overlay_offset = sz_elf_hdrs + sizeof(linfo);
4196 
4197     if (opt->o_unix.preserve_build_id) {
4198         // calc e_shoff here and write shdrout, then o_shstrtab
4199         //NOTE: these are pushed last to ensure nothing is stepped on
4200         //for the UPX structure.
4201         unsigned const len = fpad4(fo);
4202         set_te32(&elfout.ehdr.e_shoff,len);
4203 
4204         int const ssize = sizeof(shdrout);
4205 
4206         shdrout.shdr[2].sh_offset = len+ssize;
4207         shdrout.shdr[1].sh_offset = shdrout.shdr[2].sh_offset+shdrout.shdr[2].sh_size;
4208 
4209         fo->write(&shdrout, ssize);
4210 
4211         fo->write(o_shstrtab,shdrout.shdr[2].sh_size);
4212         fo->write(buildid_data,shdrout.shdr[1].sh_size);
4213     }
4214 
4215     // Cannot pre-round .p_memsz.  If .p_filesz < .p_memsz, then kernel
4216     // tries to make .bss, which requires PF_W.
4217     // But strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X.
4218     set_te32(&elfout.phdr[0].p_filesz, sz_pack2 + lsize);
4219               elfout.phdr[0].p_memsz = elfout.phdr[0].p_filesz;
4220     super::pack4(fo, ft);  // write PackHeader and overlay_offset
4221 
4222     fo->seek(0, SEEK_SET);
4223     if (0!=xct_off) {  // shared library
4224         fo->rewrite(&lowmem[0], sizeof(ehdri) + e_phnum * sizeof(*phdri));
4225         fo->seek(sz_elf_hdrs, SEEK_SET);
4226         fo->rewrite(&linfo, sizeof(linfo));
4227 
4228         if (jni_onload_va) {
4229             unsigned tmp = sz_pack2 + get_te32(&elfout.phdr[0].p_vaddr);
4230             tmp |= (Elf32_Ehdr::EM_ARM==e_machine);  // THUMB mode
4231             set_te32(&tmp, tmp);
4232             fo->seek(ptr_udiff(&jni_onload_sym->st_value, file_image), SEEK_SET);
4233             fo->rewrite(&tmp, sizeof(tmp));
4234         }
4235     }
4236     else {
4237         unsigned const reloc = get_te32(&elfout.phdr[0].p_vaddr);
4238         Elf32_Phdr *phdr = &elfout.phdr[2];
4239         unsigned const o_phnum = get_te16(&elfout.ehdr.e_phnum);
4240         for (unsigned j = 2; j < o_phnum; ++j, ++phdr) {
4241             if (PT_NOTE32 == get_te32(&phdr->p_type)) {
4242                 set_te32(            &phdr->p_vaddr,
4243                     reloc + get_te32(&phdr->p_vaddr));
4244                 set_te32(            &phdr->p_paddr,
4245                     reloc + get_te32(&phdr->p_paddr));
4246             }
4247         }
4248         fo->rewrite(&elfout, sizeof(Elf32_Phdr) * o_phnum + sizeof(Elf32_Ehdr));
4249         fo->seek(sz_elf_hdrs, SEEK_SET);  // skip over PT_NOTE bodies, if any
4250         fo->rewrite(&linfo, sizeof(linfo));
4251     }
4252 }
4253 
pack4(OutputFile * fo,Filter & ft)4254 void PackLinuxElf64::pack4(OutputFile *fo, Filter &ft)
4255 {
4256     overlay_offset = sz_elf_hdrs + sizeof(linfo);
4257 
4258     if (opt->o_unix.preserve_build_id) {
4259         // calc e_shoff here and write shdrout, then o_shstrtab
4260         //NOTE: these are pushed last to ensure nothing is stepped on
4261         //for the UPX structure.
4262         unsigned const len = fpad4(fo);
4263         set_te64(&elfout.ehdr.e_shoff,len);
4264 
4265         int const ssize = sizeof(shdrout);
4266 
4267         shdrout.shdr[2].sh_offset = len+ssize;
4268         shdrout.shdr[1].sh_offset = shdrout.shdr[2].sh_offset+shdrout.shdr[2].sh_size;
4269 
4270         fo->write(&shdrout, ssize);
4271 
4272         fo->write(o_shstrtab,shdrout.shdr[2].sh_size);
4273         fo->write(buildid_data,shdrout.shdr[1].sh_size);
4274     }
4275 
4276     // Cannot pre-round .p_memsz.  If .p_filesz < .p_memsz, then kernel
4277     // tries to make .bss, which requires PF_W.
4278     // But strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X.
4279     set_te64(&elfout.phdr[0].p_filesz, sz_pack2 + lsize);
4280               elfout.phdr[0].p_memsz = elfout.phdr[0].p_filesz;
4281     super::pack4(fo, ft);  // write PackHeader and overlay_offset
4282 
4283     fo->seek(0, SEEK_SET);
4284     if (0!=xct_off) {  // shared library
4285         fo->rewrite(&lowmem[0], sizeof(ehdri) + e_phnum * sizeof(Elf64_Phdr));
4286         fo->seek(sz_elf_hdrs, SEEK_SET);
4287         fo->rewrite(&linfo, sizeof(linfo));
4288     }
4289     else {
4290         if (PT_NOTE64 == get_te64(&elfout.phdr[2].p_type)) {
4291             upx_uint64_t const reloc = get_te64(&elfout.phdr[0].p_vaddr);
4292             set_te64(            &elfout.phdr[2].p_vaddr,
4293                 reloc + get_te64(&elfout.phdr[2].p_vaddr));
4294             set_te64(            &elfout.phdr[2].p_paddr,
4295                 reloc + get_te64(&elfout.phdr[2].p_paddr));
4296             fo->rewrite(&elfout, sz_elf_hdrs);
4297             // FIXME   fo->rewrite(&elfnote, sizeof(elfnote));
4298         }
4299         else {
4300             fo->rewrite(&elfout, sz_elf_hdrs);
4301         }
4302         fo->rewrite(&linfo, sizeof(linfo));
4303     }
4304 }
4305 
4306 void
unRel32(unsigned dt_rel,Elf32_Rel * rel0,unsigned relsz,MemBuffer & ptload1,unsigned const load_off,OutputFile * fo)4307 PackLinuxElf32::unRel32(
4308     unsigned dt_rel,
4309     Elf32_Rel *rel0,
4310     unsigned relsz,
4311     MemBuffer &ptload1,
4312     unsigned const load_off,
4313     OutputFile *fo
4314 )
4315 {
4316     Elf32_Rel *rel = rel0;
4317     for (int k = relsz / sizeof(Elf32_Rel); --k >= 0; ++rel) {
4318         unsigned r_offset = get_te32(&rel->r_offset);
4319         unsigned r_info   = get_te32(&rel->r_info);
4320         unsigned r_type = ELF32_R_TYPE(r_info);
4321         if (xct_off <= r_offset) {
4322             set_te32(&rel->r_offset, r_offset - asl_delta);
4323         }
4324         if (Elf32_Ehdr::EM_ARM == e_machine) {
4325             if (R_ARM_RELATIVE == r_type) {
4326                 unsigned d = r_offset - load_off - asl_delta;
4327                 unsigned w = get_te32(&ptload1[d]);
4328                 if (xct_off <= w) {
4329                     set_te32(&ptload1[d], w - asl_delta);
4330                 }
4331             }
4332             if (R_ARM_JUMP_SLOT == r_type) {
4333                 ++n_jmp_slot;
4334                 // .rel.plt contains offset of the "first time" target
4335                 unsigned d = r_offset - load_off - asl_delta;
4336                 if (plt_off > d) {
4337                     plt_off = d;
4338                 }
4339                 unsigned w = get_te32(&ptload1[d]);
4340                 if (xct_off <= w) {
4341                     set_te32(&ptload1[d], w - asl_delta);
4342                 }
4343             }
4344         }
4345     }
4346     fo->seek(dt_rel, SEEK_SET);
4347     fo->rewrite(rel0, relsz);
4348 }
4349 
4350 void
unRela64(upx_uint64_t dt_rela,Elf64_Rela * rela0,unsigned relasz,MemBuffer & ptload1,upx_uint64_t const load_off,upx_uint64_t old_dtinit,OutputFile * fo)4351 PackLinuxElf64::unRela64(
4352     upx_uint64_t dt_rela,
4353     Elf64_Rela *rela0,
4354     unsigned relasz,
4355     MemBuffer &ptload1,
4356     upx_uint64_t const load_off,
4357     upx_uint64_t old_dtinit,
4358     OutputFile *fo
4359 )
4360 {
4361     Elf64_Rela *rela = rela0;
4362     for (int k = relasz / sizeof(Elf64_Rela); --k >= 0; ++rela) {
4363         upx_uint64_t r_addend = get_te64(&rela->r_addend);
4364         if (xct_off <= r_addend) {
4365             r_addend -= asl_delta;
4366             set_te64(&rela->r_addend, r_addend);
4367         }
4368 
4369         upx_uint64_t r_offset = get_te64(&rela->r_offset);
4370         if (xct_off <= r_offset) {
4371             r_offset -= asl_delta;
4372             set_te64(&rela->r_offset, r_offset);
4373         }
4374 
4375         upx_uint64_t r_info   = get_te64(&rela->r_info);
4376         unsigned r_type = ELF64_R_TYPE(r_info);
4377         if (Elf64_Ehdr::EM_AARCH64 == e_machine) {
4378             if (R_AARCH64_RELATIVE == r_type) {
4379                 if (old_dtinit == r_addend) {
4380                     set_te64(&ptload1[r_offset - load_off], r_addend);
4381                 }
4382             }
4383             if (R_AARCH64_JUMP_SLOT == r_type) {
4384                 ++n_jmp_slot;
4385                 // .rela.plt contains offset of the "first time" target
4386                 upx_uint64_t d = r_offset - load_off;
4387                 if (plt_off > d) {
4388                     plt_off = d;
4389                 }
4390                 upx_uint64_t w = get_te64(&ptload1[d]);
4391                 if (xct_off <= w) {
4392                     set_te64(&ptload1[d], w - asl_delta);
4393                 }
4394             }
4395         }
4396     }
4397     fo->seek(dt_rela, SEEK_SET);
4398     fo->rewrite(rela0, relasz);
4399 }
4400 
unpack(OutputFile * fo)4401 void PackLinuxElf64::unpack(OutputFile *fo)
4402 {
4403     if (e_phoff != sizeof(Elf64_Ehdr)) {// Phdrs not contiguous with Ehdr
4404         throwCantUnpack("bad e_phoff");
4405     }
4406     unsigned const c_phnum = get_te16(&ehdri.e_phnum);
4407     upx_uint64_t old_data_off = 0;
4408     upx_uint64_t old_data_len = 0;
4409     upx_uint64_t old_dtinit = 0;
4410     unsigned is_asl = 0;  // is Android Shared Library
4411 
4412     unsigned szb_info = sizeof(b_info);
4413     {
4414         upx_uint64_t const e_entry = get_te64(&ehdri.e_entry);
4415         if (e_entry < 0x401180
4416         &&  get_te16(&ehdri.e_machine)==Elf64_Ehdr::EM_386) { /* old style, 8-byte b_info */
4417             szb_info = 2*sizeof(unsigned);
4418         }
4419     }
4420 
4421     fi->seek(overlay_offset - sizeof(l_info), SEEK_SET);
4422     fi->readx(&linfo, sizeof(linfo));
4423     lsize = get_te16(&linfo.l_lsize);
4424     if (UPX_MAGIC_LE32 != get_le32(&linfo.l_magic)) {
4425         throwCantUnpack("l_info corrupted");
4426     }
4427     p_info hbuf;  fi->readx(&hbuf, sizeof(hbuf));
4428     unsigned orig_file_size = get_te32(&hbuf.p_filesize);
4429     blocksize = get_te32(&hbuf.p_blocksize);
4430     if ((u32_t)file_size > orig_file_size || blocksize > orig_file_size
4431         || !mem_size_valid(1, blocksize, OVERHEAD))
4432         throwCantUnpack("p_info corrupted");
4433 
4434     ibuf.alloc(blocksize + OVERHEAD);
4435     b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
4436     fi->readx(&bhdr, szb_info);
4437     ph.u_len = get_te32(&bhdr.sz_unc);
4438     ph.c_len = get_te32(&bhdr.sz_cpr);
4439     if (ph.c_len > (unsigned)file_size || ph.c_len == 0 || ph.u_len == 0
4440     ||  ph.u_len > orig_file_size)
4441         throwCantUnpack("b_info corrupted");
4442     ph.filter_cto = bhdr.b_cto8;
4443 
4444     MemBuffer u(ph.u_len);
4445     Elf64_Ehdr *const ehdr = (Elf64_Ehdr *)&u[0];
4446     Elf64_Phdr const *phdr = 0;
4447 
4448     // Uncompress Ehdr and Phdrs.
4449     if (ibuf.getSize() < ph.c_len)
4450         throwCompressedDataViolation();
4451     fi->readx(ibuf, ph.c_len);
4452     decompress(ibuf, (upx_byte *)ehdr, false);
4453     if (ehdr->e_type   !=ehdri.e_type
4454     ||  ehdr->e_machine!=ehdri.e_machine
4455     ||  ehdr->e_version!=ehdri.e_version
4456         // less strict for EM_PPC64 to workaround earlier bug
4457     ||  !( ehdr->e_flags==ehdri.e_flags
4458         || Elf64_Ehdr::EM_PPC64 == get_te16(&ehdri.e_machine))
4459     ||  ehdr->e_ehsize !=ehdri.e_ehsize
4460         // check EI_MAG[0-3], EI_CLASS, EI_DATA, EI_VERSION
4461     ||  memcmp(ehdr->e_ident, ehdri.e_ident, Elf64_Ehdr::EI_OSABI)) {
4462         throwCantUnpack("ElfXX_Ehdr corrupted");
4463     }
4464     fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
4465 
4466     unsigned const u_phnum = get_te16(&ehdr->e_phnum);
4467     unsigned total_in = 0;
4468     unsigned total_out = 0;
4469     unsigned c_adler = upx_adler32(NULL, 0);
4470     unsigned u_adler = upx_adler32(NULL, 0);
4471 #define MAX_ELF_HDR 1024
4472     if ((MAX_ELF_HDR - sizeof(Elf64_Ehdr))/sizeof(Elf64_Phdr) < u_phnum) {
4473         throwCantUnpack("bad compressed e_phnum");
4474     }
4475 #undef MAX_ELF_HDR
4476 
4477     // Packed ET_EXE has no PT_DYNAMIC.
4478     // Packed ET_DYN has original PT_DYNAMIC for info needed by rtld.
4479     Elf64_Phdr const *const dynhdr = elf_find_ptype(Elf64_Phdr::PT_DYNAMIC, phdri, c_phnum);
4480     bool const is_shlib = !!dynhdr;
4481     if (is_shlib) {
4482         // Unpack and output the Ehdr and Phdrs for real.
4483         // This depends on position within input file fi.
4484         unpackExtent(ph.u_len, fo, total_in, total_out,
4485             c_adler, u_adler, false, szb_info);
4486 
4487         // The first PT_LOAD.  Part is not compressed (for benefit of rtld.)
4488         fi->seek(0, SEEK_SET);
4489         fi->readx(ibuf, get_te64(&dynhdr->p_offset) + get_te64(&dynhdr->p_filesz));
4490         overlay_offset -= sizeof(linfo);
4491         xct_off = overlay_offset;
4492         e_shoff = get_te64(&ehdri.e_shoff);
4493         ibuf.subref("bad .e_shoff %#lx for %#lx", e_shoff, sizeof(Elf64_Shdr) * e_shnum);
4494         if (e_shoff && e_shnum) { // --android-shlib
4495             shdri = (Elf64_Shdr /*const*/ *)ibuf.subref(
4496                 "bad Shdr table", e_shoff, sizeof(Elf64_Shdr)*e_shnum);
4497             upx_uint64_t xct_off2 = get_te64(&shdri->sh_offset);
4498             if (e_shoff == xct_off2) {
4499                 xct_off = e_shoff;
4500             }
4501             // un-Relocate dynsym (DT_SYMTAB) which is below xct_off
4502             dynseg = (Elf64_Dyn const *)ibuf.subref(
4503                 "bad DYNAMIC", get_te64(&dynhdr->p_offset), get_te64(&dynhdr->p_filesz));
4504             dynstr = (char const *)elf_find_dynamic(Elf64_Dyn::DT_STRTAB);
4505             sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
4506             if (sec_dynsym) {
4507                 upx_uint64_t const off_dynsym = get_te64(&sec_dynsym->sh_offset);
4508                 upx_uint64_t const sz_dynsym  = get_te64(&sec_dynsym->sh_size);
4509                 Elf64_Sym *const sym0 = (Elf64_Sym *)ibuf.subref(
4510                     "bad dynsym", off_dynsym, sz_dynsym);
4511                 Elf64_Sym *sym = sym0;
4512                 for (int j = sz_dynsym / sizeof(Elf64_Sym); --j>=0; ++sym) {
4513                     upx_uint64_t symval = get_te64(&sym->st_value);
4514                     unsigned symsec = get_te16(&sym->st_shndx);
4515                     if (Elf64_Sym::SHN_UNDEF != symsec
4516                     &&  Elf64_Sym::SHN_ABS   != symsec
4517                     &&  xct_off <= symval) {
4518                         set_te64(&sym->st_value, symval - asl_delta);
4519                     }
4520                     if (Elf64_Sym::SHN_ABS == symsec && xct_off <= symval) {
4521                         adjABS(sym, 0u - asl_delta);
4522                     }
4523                 }
4524             }
4525         }
4526         if (fo) {
4527             fo->write(ibuf + ph.u_len, xct_off - ph.u_len);
4528         }
4529         // Search the Phdrs of compressed
4530         int n_ptload = 0;
4531         phdr = (Elf64_Phdr *) (void *) (1+ (Elf64_Ehdr *)(unsigned char *)ibuf);
4532         for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
4533             if (PT_LOAD64==get_te32(&phdr->p_type) && 0!=n_ptload++) {
4534                 old_data_off = get_te64(&phdr->p_offset);
4535                 old_data_len = get_te64(&phdr->p_filesz);
4536                 break;
4537             }
4538         }
4539 
4540         total_in  = xct_off;
4541         total_out = xct_off;
4542         ph.u_len = 0;
4543         // Position the input for next unpackExtent.
4544         fi->seek(sizeof(linfo) + overlay_offset + sizeof(hbuf) + szb_info + ph.c_len, SEEK_SET);
4545 
4546         // Decompress and unfilter the tail of first PT_LOAD.
4547         phdr = (Elf64_Phdr *) (void *) (1+ ehdr);
4548         for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
4549             if (PT_LOAD64==get_te32(&phdr->p_type)) {
4550                 ph.u_len = get_te64(&phdr->p_filesz) - xct_off;
4551                 break;
4552             }
4553         }
4554         unpackExtent(ph.u_len, fo, total_in, total_out,
4555             c_adler, u_adler, false, szb_info);
4556     }
4557     else {  // main executable
4558         // Decompress each PT_LOAD.
4559         bool first_PF_X = true;
4560         phdr = (Elf64_Phdr *) (void *) (1+ ehdr);  // uncompressed
4561         for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
4562             if (PT_LOAD64==get_te32(&phdr->p_type)) {
4563                 unsigned const filesz = get_te64(&phdr->p_filesz);
4564                 unsigned const offset = get_te64(&phdr->p_offset);
4565                 if (fo)
4566                     fo->seek(offset, SEEK_SET);
4567                 if (Elf64_Phdr::PF_X & get_te32(&phdr->p_flags)) {
4568                     unpackExtent(filesz, fo, total_in, total_out,
4569                         c_adler, u_adler, first_PF_X, szb_info);
4570                     first_PF_X = false;
4571                 }
4572                 else {
4573                     unpackExtent(filesz, fo, total_in, total_out,
4574                         c_adler, u_adler, false, szb_info);
4575                 }
4576             }
4577         }
4578     }
4579     phdr = phdri;
4580     load_va = 0;
4581     for (unsigned j=0; j < c_phnum; ++j) {
4582         if (PT_LOAD64==get_te32(&phdr->p_type)) {
4583             load_va = get_te64(&phdr->p_vaddr);
4584             break;
4585         }
4586     }
4587     if (is_shlib
4588     ||  ((unsigned)(get_te64(&ehdri.e_entry) - load_va) + up4(lsize) +
4589                 ph.getPackHeaderSize() + sizeof(overlay_offset))
4590             < up4(file_size)) {
4591         // Loader is not at end; skip past it.
4592         funpad4(fi);  // MATCH01
4593         unsigned d_info[6]; fi->readx(d_info, sizeof(d_info));
4594         if (0==old_dtinit) {
4595             old_dtinit = get_te32(&d_info[2 + (0==d_info[0])]);
4596             is_asl = 1u& get_te32(&d_info[0 + (0==d_info[0])]);
4597         }
4598         fi->seek(lsize - sizeof(d_info), SEEK_CUR);
4599     }
4600 
4601     // The gaps between PT_LOAD and after last PT_LOAD
4602     phdr = (Elf64_Phdr *)&u[sizeof(*ehdr)];
4603     upx_uint64_t hi_offset(0);
4604     for (unsigned j = 0; j < u_phnum; ++j) {
4605         if (PT_LOAD64==phdr[j].p_type
4606         &&  hi_offset < phdr[j].p_offset)
4607             hi_offset = phdr[j].p_offset;
4608     }
4609     for (unsigned j = 0; j < u_phnum; ++j) {
4610         unsigned const size = find_LOAD_gap(phdr, j, u_phnum);
4611         if (size) {
4612             unsigned const where = get_te64(&phdr[j].p_offset) +
4613                                    get_te64(&phdr[j].p_filesz);
4614             if (fo)
4615                 fo->seek(where, SEEK_SET);
4616             unpackExtent(size, fo, total_in, total_out,
4617                 c_adler, u_adler, false, szb_info,
4618                 (phdr[j].p_offset != hi_offset));
4619         }
4620     }
4621 
4622     // check for end-of-file
4623     fi->readx(&bhdr, szb_info);
4624     unsigned const sz_unc = ph.u_len = get_te32(&bhdr.sz_unc);
4625 
4626     if (sz_unc == 0) { // uncompressed size 0 -> EOF
4627         // note: magic is always stored le32
4628         unsigned const sz_cpr = get_le32(&bhdr.sz_cpr);
4629         if (sz_cpr != UPX_MAGIC_LE32)  // sz_cpr must be h->magic
4630             throwCompressedDataViolation();
4631     }
4632     else { // extra bytes after end?
4633         throwCompressedDataViolation();
4634     }
4635 
4636     if (is_shlib) {
4637         // DT_INIT must be restored.
4638         // If android_shlib, then the asl_delta relocations must be un-done.
4639         int n_ptload = 0;
4640         upx_uint64_t load_off = 0;
4641         phdr = (Elf64_Phdr *)&u[sizeof(*ehdr)];
4642         for (unsigned j= 0; j < u_phnum; ++j, ++phdr) {
4643             if (PT_LOAD64==get_te32(&phdr->p_type) && 0!=n_ptload++) {
4644                 load_off = get_te64(&phdr->p_offset);
4645                 load_va = get_te64(&phdr->p_vaddr);
4646                 fi->seek(old_data_off, SEEK_SET);
4647                 fi->readx(ibuf, old_data_len);
4648                 total_in  += old_data_len;
4649                 total_out += old_data_len;
4650 
4651                 Elf64_Phdr const *udynhdr = (Elf64_Phdr *)&u[sizeof(*ehdr)];
4652                 for (unsigned j3= 0; j3 < u_phnum; ++j3, ++udynhdr)
4653                 if (Elf64_Phdr::PT_DYNAMIC==get_te32(&udynhdr->p_type)) {
4654                     upx_uint64_t dt_pltrelsz(0), dt_jmprel(0);
4655                     upx_uint64_t dt_relasz(0), dt_rela(0);
4656                     upx_uint64_t const dyn_len = get_te64(&udynhdr->p_filesz);
4657                     upx_uint64_t const dyn_off = get_te64(&udynhdr->p_offset);
4658                     if (dyn_off < load_off) {
4659                         continue;  // Oops.  Not really is_shlib ?  [built by 'rust' ?]
4660                     }
4661                     Elf64_Dyn *dyn = (Elf64_Dyn *)((unsigned char *)ibuf +
4662                         (dyn_off - load_off));
4663                     dynseg = dyn; invert_pt_dynamic(dynseg);
4664                     for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
4665                         upx_uint64_t const tag = get_te64(&dyn->d_tag);
4666                         upx_uint64_t       val = get_te64(&dyn->d_val);
4667                         if (is_asl) switch (tag) {
4668                         case Elf64_Dyn::DT_RELASZ:   { dt_relasz   = val; } break;
4669                         case Elf64_Dyn::DT_RELA:     { dt_rela     = val; } break;
4670                         case Elf64_Dyn::DT_PLTRELSZ: { dt_pltrelsz = val; } break;
4671                         case Elf64_Dyn::DT_JMPREL:   { dt_jmprel   = val; } break;
4672 
4673                         case Elf64_Dyn::DT_PLTGOT:
4674                         case Elf64_Dyn::DT_PREINIT_ARRAY:
4675                         case Elf64_Dyn::DT_INIT_ARRAY:
4676                         case Elf64_Dyn::DT_FINI_ARRAY:
4677                         case Elf64_Dyn::DT_FINI: {
4678                             set_te64(&dyn->d_val, val - asl_delta);
4679                         }; break;
4680                         } // end switch()
4681                         if (upx_dt_init == tag) {
4682                             if (Elf64_Dyn::DT_INIT == tag) {
4683                                 set_te64(&dyn->d_val, old_dtinit);
4684                                 if (!old_dtinit) { // compressor took the slot
4685                                     dyn->d_tag = Elf64_Dyn::DT_NULL;
4686                                     dyn->d_val = 0;
4687                                 }
4688                             }
4689                             else { // DT_INIT_ARRAY, DT_PREINIT_ARRAY
4690                                 set_te64(&ibuf[val - load_va], old_dtinit
4691                                     + (is_asl ? asl_delta : 0));  // counter-act unRel64
4692                             }
4693                         }
4694                         // Modified DT_*.d_val are re-written later from ibuf[]
4695                     }
4696                     if (is_asl) {
4697                         lowmem.alloc(xct_off);
4698                         fi->seek(0, SEEK_SET);
4699                         fi->read(lowmem, xct_off);  // contains relocation tables
4700                         if (dt_relasz && dt_rela) {
4701                             Elf64_Rela *const rela0 = (Elf64_Rela *)lowmem.subref(
4702                                 "bad Rela offset", dt_rela, dt_relasz);
4703                             unRela64(dt_rela, rela0, dt_relasz, ibuf, load_va, old_dtinit, fo);
4704                         }
4705                         if (dt_pltrelsz && dt_jmprel) { // FIXME:  overlap w/ DT_REL ?
4706                             Elf64_Rela *const jmp0 = (Elf64_Rela *)lowmem.subref(
4707                                 "bad Jmprel offset", dt_jmprel, dt_pltrelsz);
4708                             unRela64(dt_jmprel, jmp0, dt_pltrelsz, ibuf, load_va, old_dtinit, fo);
4709                         }
4710                         // Modified relocation tables are re-written by unRela64
4711                     }
4712                 }
4713                 if (fo) {
4714                     fo->seek(get_te64(&phdr->p_offset), SEEK_SET);
4715                     fo->rewrite(ibuf, old_data_len);
4716                 }
4717             }
4718         }
4719     }
4720 
4721     // update header with totals
4722     ph.c_len = total_in;
4723     ph.u_len = total_out;
4724 
4725     // all bytes must be written
4726     if (total_out != orig_file_size)
4727         throwEOFException();
4728 
4729     // finally test the checksums
4730     if (ph.c_adler != c_adler || ph.u_adler != u_adler)
4731         throwChecksumError();
4732 }
4733 
4734 
4735 /*************************************************************************
4736 //
4737 **************************************************************************/
4738 
PackLinuxElf32x86(InputFile * f)4739 PackLinuxElf32x86::PackLinuxElf32x86(InputFile *f) : super(f)
4740 {
4741     e_machine = Elf32_Ehdr::EM_386;
4742     ei_class  = Elf32_Ehdr::ELFCLASS32;
4743     ei_data   = Elf32_Ehdr::ELFDATA2LSB;
4744     ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
4745 }
4746 
~PackLinuxElf32x86()4747 PackLinuxElf32x86::~PackLinuxElf32x86()
4748 {
4749 }
4750 
newLinker() const4751 Linker* PackLinuxElf32x86::newLinker() const
4752 {
4753     return new ElfLinkerX86;
4754 }
4755 
PackBSDElf32x86(InputFile * f)4756 PackBSDElf32x86::PackBSDElf32x86(InputFile *f) : super(f)
4757 {
4758     e_machine = Elf32_Ehdr::EM_386;
4759     ei_class  = Elf32_Ehdr::ELFCLASS32;
4760     ei_data   = Elf32_Ehdr::ELFDATA2LSB;
4761 }
4762 
~PackBSDElf32x86()4763 PackBSDElf32x86::~PackBSDElf32x86()
4764 {
4765 }
4766 
PackFreeBSDElf32x86(InputFile * f)4767 PackFreeBSDElf32x86::PackFreeBSDElf32x86(InputFile *f) : super(f)
4768 {
4769     ei_osabi  = Elf32_Ehdr::ELFOSABI_FREEBSD;
4770 }
4771 
~PackFreeBSDElf32x86()4772 PackFreeBSDElf32x86::~PackFreeBSDElf32x86()
4773 {
4774 }
4775 
PackNetBSDElf32x86(InputFile * f)4776 PackNetBSDElf32x86::PackNetBSDElf32x86(InputFile *f) : super(f)
4777 {
4778     ei_osabi  = Elf32_Ehdr::ELFOSABI_NETBSD;
4779     osabi_note = "NetBSD";
4780 }
4781 
~PackNetBSDElf32x86()4782 PackNetBSDElf32x86::~PackNetBSDElf32x86()
4783 {
4784 }
4785 
PackOpenBSDElf32x86(InputFile * f)4786 PackOpenBSDElf32x86::PackOpenBSDElf32x86(InputFile *f) : super(f)
4787 {
4788     ei_osabi  = Elf32_Ehdr::ELFOSABI_OPENBSD;
4789     osabi_note = "OpenBSD";
4790 }
4791 
~PackOpenBSDElf32x86()4792 PackOpenBSDElf32x86::~PackOpenBSDElf32x86()
4793 {
4794 }
4795 
4796 int const *
getFilters() const4797 PackLinuxElf32x86::getFilters() const
4798 {
4799     static const int filters[] = {
4800         0x49, 0x46,
4801 // FIXME 2002-11-11: We use stub/fold_elf86.asm, which calls the
4802 // decompressor multiple times, and unfilter is independent of decompress.
4803 // Currently only filters 0x49, 0x46, 0x80..0x87 can handle this;
4804 // and 0x80..0x87 are regarded as "untested".
4805 #if 0
4806         0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
4807 #endif
4808 #if 0
4809         0x83, 0x36, 0x26,
4810               0x86, 0x80,
4811         0x84, 0x87, 0x81,
4812         0x82, 0x85,
4813         0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
4814 #endif
4815     FT_END };
4816     return filters;
4817 }
4818 
PackLinuxElf32armLe(InputFile * f)4819 PackLinuxElf32armLe::PackLinuxElf32armLe(InputFile *f) : super(f)
4820 {
4821     e_machine = Elf32_Ehdr::EM_ARM;
4822     ei_class  = Elf32_Ehdr::ELFCLASS32;
4823     ei_data   = Elf32_Ehdr::ELFDATA2LSB;
4824     ei_osabi  = Elf32_Ehdr::ELFOSABI_ARM;
4825 }
4826 
~PackLinuxElf32armLe()4827 PackLinuxElf32armLe::~PackLinuxElf32armLe()
4828 {
4829 }
4830 
PackLinuxElf32mipseb(InputFile * f)4831 PackLinuxElf32mipseb::PackLinuxElf32mipseb(InputFile *f) : super(f)
4832 {
4833     e_machine = Elf32_Ehdr::EM_MIPS;
4834     ei_class  = Elf32_Ehdr::ELFCLASS32;
4835     ei_data   = Elf32_Ehdr::ELFDATA2MSB;
4836     ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
4837 }
4838 
~PackLinuxElf32mipseb()4839 PackLinuxElf32mipseb::~PackLinuxElf32mipseb()
4840 {
4841 }
4842 
PackLinuxElf32mipsel(InputFile * f)4843 PackLinuxElf32mipsel::PackLinuxElf32mipsel(InputFile *f) : super(f)
4844 {
4845     e_machine = Elf32_Ehdr::EM_MIPS;
4846     ei_class  = Elf32_Ehdr::ELFCLASS32;
4847     ei_data   = Elf32_Ehdr::ELFDATA2LSB;
4848     ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
4849 }
4850 
~PackLinuxElf32mipsel()4851 PackLinuxElf32mipsel::~PackLinuxElf32mipsel()
4852 {
4853 }
4854 
newLinker() const4855 Linker* PackLinuxElf32armLe::newLinker() const
4856 {
4857     return new ElfLinkerArmLE();
4858 }
4859 
newLinker() const4860 Linker* PackLinuxElf32mipseb::newLinker() const
4861 {
4862     return new ElfLinkerMipsBE();
4863 }
4864 
newLinker() const4865 Linker* PackLinuxElf32mipsel::newLinker() const
4866 {
4867     return new ElfLinkerMipsLE();
4868 }
4869 
PackLinuxElf32armBe(InputFile * f)4870 PackLinuxElf32armBe::PackLinuxElf32armBe(InputFile *f) : super(f)
4871 {
4872     e_machine = Elf32_Ehdr::EM_ARM;
4873     ei_class  = Elf32_Ehdr::ELFCLASS32;
4874     ei_data   = Elf32_Ehdr::ELFDATA2MSB;
4875     ei_osabi  = Elf32_Ehdr::ELFOSABI_ARM;
4876 }
4877 
~PackLinuxElf32armBe()4878 PackLinuxElf32armBe::~PackLinuxElf32armBe()
4879 {
4880 }
4881 
newLinker() const4882 Linker* PackLinuxElf32armBe::newLinker() const
4883 {
4884     return new ElfLinkerArmBE();
4885 }
4886 
4887 unsigned
elf_get_offset_from_address(unsigned addr) const4888 PackLinuxElf32::elf_get_offset_from_address(unsigned addr) const
4889 {
4890     Elf32_Phdr const *phdr = phdri;
4891     int j = e_phnum;
4892     for (; --j>=0; ++phdr) if (PT_LOAD32 == get_te32(&phdr->p_type)) {
4893         unsigned const t = addr - get_te32(&phdr->p_vaddr);
4894         if (t < get_te32(&phdr->p_filesz)) {
4895             unsigned const p_offset = get_te32(&phdr->p_offset);
4896             if ((u32_t)file_size <= p_offset) { // FIXME: weak
4897                 char msg[40]; snprintf(msg, sizeof(msg),
4898                     "bad Elf32_Phdr[%d].p_offset %x",
4899                     -1+ e_phnum - j, p_offset);
4900                 throwCantPack(msg);
4901             }
4902             return t + p_offset;
4903         }
4904     }
4905     return 0;
4906 }
4907 
4908 u32_t  // returns .p_offset
check_pt_load(Elf32_Phdr const * const phdr)4909 PackLinuxElf32::check_pt_load(Elf32_Phdr const *const phdr)
4910 {
4911     u32_t filesz = get_te32(&phdr->p_filesz);
4912     u32_t offset = get_te32(&phdr->p_offset), offend = filesz + offset;
4913     u32_t vaddr  = get_te32(&phdr->p_vaddr);
4914     u32_t paddr  = get_te32(&phdr->p_paddr);
4915     u32_t align  = get_te32(&phdr->p_align);
4916 
4917     if ((-1+ align) & (paddr ^ vaddr)
4918     ||  (u32_t)file_size <= (u32_t)offset
4919     ||  (u32_t)file_size <  (u32_t)offend
4920     ||  (u32_t)file_size <= (u32_t)filesz) {
4921         char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
4922             (unsigned)(phdr - phdri));
4923         throwCantPack(msg);
4924     }
4925     return offset;
4926 }
4927 
4928 Elf32_Dyn const *
elf_has_dynamic(unsigned int key) const4929 PackLinuxElf32::elf_has_dynamic(unsigned int key) const
4930 {
4931     Elf32_Dyn const *dynp= dynseg;
4932     if (dynp)
4933     for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te32(&dynp->d_tag)==key) {
4934         return dynp;
4935     }
4936     return 0;
4937 }
4938 
4939 unsigned  // checked .p_offset; sz_dynseg set
check_pt_dynamic(Elf32_Phdr const * const phdr)4940 PackLinuxElf32::check_pt_dynamic(Elf32_Phdr const *const phdr)
4941 {
4942     unsigned t = get_te32(&phdr->p_offset), s = sizeof(Elf32_Dyn) + t;
4943     unsigned vaddr = get_te32(&phdr->p_vaddr);
4944     unsigned filesz = get_te32(&phdr->p_filesz), memsz = get_te32(&phdr->p_memsz);
4945     unsigned align = get_te32(&phdr->p_align);
4946     if (s < t || (u32_t)file_size < s
4947     ||  (3 & t) || (7 & (filesz | memsz))  // .balign 4; 8==sizeof(Elf32_Dyn)
4948     ||  (-1+ align) & (t ^ vaddr)
4949     ||  filesz < sizeof(Elf32_Dyn)
4950     ||  memsz  < sizeof(Elf32_Dyn)
4951     ||  filesz < memsz) {
4952         char msg[50]; snprintf(msg, sizeof(msg), "bad PT_DYNAMIC phdr[%u]",
4953             (unsigned)(phdr - phdri));
4954         throwCantPack(msg);
4955     }
4956     sz_dynseg = memsz;
4957     return t;
4958 }
4959 
4960 void const *
elf_find_dynamic(unsigned int key) const4961 PackLinuxElf32::elf_find_dynamic(unsigned int key) const
4962 {
4963     Elf32_Dyn const *dynp= dynseg;
4964     if (dynp)
4965     for (; (unsigned)((char const *)dynp - (char const *)dynseg) < sz_dynseg
4966             && Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te32(&dynp->d_tag)==key) {
4967         unsigned const t= elf_get_offset_from_address(get_te32(&dynp->d_val));
4968         if (t && t < (unsigned)file_size) {
4969             return t + file_image;
4970         }
4971         break;
4972     }
4973     return 0;
4974 }
4975 
4976 upx_uint64_t
elf_unsigned_dynamic(unsigned int key) const4977 PackLinuxElf32::elf_unsigned_dynamic(unsigned int key) const
4978 {
4979     Elf32_Dyn const *dynp= dynseg;
4980     if (dynp)
4981     for (; (unsigned)((char const *)dynp - (char const *)dynseg) < sz_dynseg
4982             && Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te32(&dynp->d_tag)==key) {
4983         return get_te32(&dynp->d_val);
4984     }
4985     return 0;
4986 }
4987 
4988 upx_uint64_t
elf_get_offset_from_address(upx_uint64_t addr) const4989 PackLinuxElf64::elf_get_offset_from_address(upx_uint64_t addr) const
4990 {
4991     Elf64_Phdr const *phdr = phdri;
4992     int j = e_phnum;
4993     for (; --j>=0; ++phdr) if (PT_LOAD64 == get_te32(&phdr->p_type)) {
4994         upx_uint64_t const t = addr - get_te64(&phdr->p_vaddr);
4995         if (t < get_te64(&phdr->p_filesz)) {
4996             upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
4997             if ((u64_t)file_size <= p_offset) { // FIXME: weak
4998                 char msg[40]; snprintf(msg, sizeof(msg),
4999                     "bad Elf64_Phdr[%d].p_offset %#lx",
5000                     -1+ e_phnum - j, (long unsigned)p_offset);
5001                 throwCantPack(msg);
5002             }
5003             return t + p_offset;
5004         }
5005     }
5006     return 0;
5007 }
5008 
5009 u64_t  // returns .p_offset
check_pt_load(Elf64_Phdr const * const phdr)5010 PackLinuxElf64::check_pt_load(Elf64_Phdr const *const phdr)
5011 {
5012     u64_t filesz = get_te64(&phdr->p_filesz);
5013     u64_t offset = get_te64(&phdr->p_offset), offend = filesz + offset;
5014     u64_t vaddr  = get_te64(&phdr->p_vaddr);
5015     u64_t paddr  = get_te64(&phdr->p_paddr);
5016     u64_t align  = get_te64(&phdr->p_align);
5017 
5018     if ((-1+ align) & (paddr ^ vaddr)
5019     ||  (u64_t)file_size <= (u64_t)offset
5020     ||  (u64_t)file_size <  (u64_t)offend
5021     ||  (u64_t)file_size <= (u64_t)filesz) {
5022         char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
5023             (unsigned)(phdr - phdri));
5024         throwCantPack(msg);
5025     }
5026     return offset;
5027 }
5028 
5029 Elf64_Dyn const *
elf_has_dynamic(unsigned int key) const5030 PackLinuxElf64::elf_has_dynamic(unsigned int key) const
5031 {
5032     Elf64_Dyn const *dynp= dynseg;
5033     if (dynp)
5034     for (; Elf64_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te64(&dynp->d_tag)==key) {
5035         return dynp;
5036     }
5037     return 0;
5038 }
5039 
5040 upx_uint64_t  // checked .p_offset; sz_dynseg set
check_pt_dynamic(Elf64_Phdr const * const phdr)5041 PackLinuxElf64::check_pt_dynamic(Elf64_Phdr const *const phdr)
5042 {
5043     upx_uint64_t t = get_te64(&phdr->p_offset), s = sizeof(Elf64_Dyn) + t;
5044     upx_uint64_t vaddr = get_te64(&phdr->p_vaddr);
5045     upx_uint64_t filesz = get_te64(&phdr->p_filesz), memsz = get_te64(&phdr->p_memsz);
5046     upx_uint64_t align = get_te64(&phdr->p_align);
5047     if (s < t || (upx_uint64_t)file_size < s
5048     ||  (7 & t) || (0xf & (filesz | memsz))  // .balign 8; 16==sizeof(Elf64_Dyn)
5049     ||  (-1+ align) & (t ^ vaddr)
5050     ||  filesz < sizeof(Elf64_Dyn)
5051     ||  memsz  < sizeof(Elf64_Dyn)
5052     ||  filesz < memsz) {
5053         char msg[50]; snprintf(msg, sizeof(msg), "bad PT_DYNAMIC phdr[%u]",
5054             (unsigned)(phdr - phdri));
5055         throwCantPack(msg);
5056     }
5057     sz_dynseg = memsz;
5058     return t;
5059 }
5060 
5061 void
invert_pt_dynamic(Elf64_Dyn const * dynp)5062 PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp)
5063 {
5064     if (dt_table[Elf64_Dyn::DT_NULL]) {
5065         return;  // not 1st time; do not change upx_dt_init
5066     }
5067     Elf64_Dyn const *const dynp0 = dynp;
5068     unsigned ndx = 1+ 0;
5069     if (dynp)
5070     for (; ; ++ndx, ++dynp) {
5071         upx_uint64_t const d_tag = get_te64(&dynp->d_tag);
5072         if (d_tag>>32) { // outrageous
5073             char msg[50]; snprintf(msg, sizeof(msg),
5074                 "bad Elf64_Dyn[%d].d_tag %#lx", -1+ ndx, (long unsigned)d_tag);
5075             throwCantPack(msg);
5076         }
5077         if (d_tag < DT_NUM) {
5078             if (Elf64_Dyn::DT_NEEDED != d_tag
5079             &&  dt_table[d_tag]
5080             &&    get_te64(&dynp->d_val)
5081                != get_te64(&dynp0[-1+ dt_table[d_tag]].d_val)) {
5082                 char msg[50]; snprintf(msg, sizeof(msg),
5083                     "duplicate DT_%#x: [%#x] [%#x]",
5084                     (unsigned)d_tag, -1+ dt_table[d_tag], -1+ ndx);
5085                 throwCantPack(msg);
5086             }
5087             dt_table[d_tag] = ndx;
5088         }
5089         if (Elf64_Dyn::DT_NULL == d_tag) {
5090             break;  // check here so that dt_table[DT_NULL] is set
5091         }
5092     }
5093     upx_dt_init = 0;
5094          if (dt_table[Elf64_Dyn::DT_INIT])          upx_dt_init = Elf64_Dyn::DT_INIT;
5095     else if (dt_table[Elf64_Dyn::DT_PREINIT_ARRAY]) upx_dt_init = Elf64_Dyn::DT_PREINIT_ARRAY;
5096     else if (dt_table[Elf64_Dyn::DT_INIT_ARRAY])    upx_dt_init = Elf64_Dyn::DT_INIT_ARRAY;
5097 
5098     unsigned const z_str = dt_table[Elf64_Dyn::DT_STRSZ];
5099     if (z_str) {
5100         strtab_end = get_te64(&dynp0[-1+ z_str].d_val);
5101         if ((u64_t)file_size <= strtab_end) { // FIXME: weak
5102             char msg[50]; snprintf(msg, sizeof(msg),
5103                 "bad DT_STRSZ %#x", strtab_end);
5104             throwCantPack(msg);
5105         }
5106     }
5107     // DT_SYMTAB has no designated length.
5108     // End it when next area else starts; often DT_STRTAB.  (FIXME)
5109     unsigned const x_sym = dt_table[Elf64_Dyn::DT_SYMTAB];
5110     unsigned const x_str = dt_table[Elf64_Dyn::DT_STRTAB];
5111     if (x_sym && x_str) {
5112         upx_uint64_t const v_sym = get_te64(&dynp0[-1+ x_sym].d_val);
5113         upx_uint64_t const v_str = get_te64(&dynp0[-1+ x_str].d_val);
5114         unsigned const  z_sym = dt_table[Elf64_Dyn::DT_SYMENT];
5115         unsigned const sz_sym = !z_sym ? sizeof(Elf64_Sym)
5116             : get_te64(&dynp0[-1+ z_sym].d_val);
5117         if (sz_sym < sizeof(Elf64_Sym)) {
5118             char msg[50]; snprintf(msg, sizeof(msg),
5119                 "bad DT_SYMENT %x", sz_sym);
5120             throwCantPack(msg);
5121         }
5122         if (v_sym < v_str) {
5123             symnum_end = (v_str - v_sym) / sz_sym;
5124         }
5125         if (symnum_end < 1) {
5126             throwCantPack("bad DT_SYMTAB");
5127         }
5128     }
5129     // DT_HASH often ends at DT_SYMTAB
5130     unsigned const v_hsh = elf_unsigned_dynamic(Elf64_Dyn::DT_HASH);
5131     if (v_hsh && file_image) {
5132         hashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_HASH);
5133         if (!hashtab) {
5134             char msg[40]; snprintf(msg, sizeof(msg),
5135                "bad DT_HASH %#x", v_hsh);
5136             throwCantPack(msg);
5137         }
5138         unsigned const nbucket = get_te32(&hashtab[0]);
5139         unsigned const *const buckets = &hashtab[2];
5140         unsigned const *const chains = &buckets[nbucket]; (void)chains;
5141 
5142         unsigned const v_sym = !x_sym ? 0 : get_te32(&dynp0[-1+ x_sym].d_val);
5143         if (!nbucket || !v_sym
5144         || (nbucket>>31) || (file_size/sizeof(unsigned)) <= (2*nbucket)  // FIXME: weak
5145         || ((v_hsh < v_sym) && (v_sym - v_hsh) < (sizeof(unsigned)*2  // headers
5146                 + sizeof(*buckets)*nbucket  // buckets
5147                 + sizeof(*chains) *nbucket  // chains
5148            ))
5149         ) {
5150             char msg[90]; snprintf(msg, sizeof(msg),
5151                 "bad DT_HASH nbucket=%#x  len=%#x",
5152                 nbucket, (v_sym - v_hsh));
5153             throwCantPack(msg);
5154         }
5155     }
5156     // DT_GNU_HASH often ends at DT_SYMTAB;  FIXME: not for Android?
5157     unsigned const v_gsh = elf_unsigned_dynamic(Elf64_Dyn::DT_GNU_HASH);
5158     if (v_gsh && file_image) {
5159         gashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_GNU_HASH);
5160         if (!gashtab) {
5161             char msg[40]; snprintf(msg, sizeof(msg),
5162                "bad DT_GNU_HASH %#x", v_gsh);
5163             throwCantPack(msg);
5164         }
5165         unsigned const n_bucket = get_te32(&gashtab[0]);
5166         unsigned const n_bitmask = get_te32(&gashtab[2]);
5167         unsigned const gnu_shift = get_te32(&gashtab[3]);
5168         upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4];
5169         unsigned     const *const buckets = (unsigned const *)&bitmask[n_bitmask];
5170         unsigned     const *const hasharr = &buckets[n_bucket]; (void)hasharr;
5171       //unsigned     const *const gashend = &hasharr[n_bucket];  // minimum
5172 
5173         upx_uint64_t const v_sym = !x_sym ? 0 : get_te64(&dynp0[-1+ x_sym].d_val);
5174         if (!n_bucket || !n_bitmask || !v_sym
5175         || (-1+ n_bitmask) & n_bitmask  // not a power of 2
5176         || 8*sizeof(upx_uint64_t) <= gnu_shift  // shifted result always == 0
5177         || (n_bucket>>30)  // fie on fuzzers
5178         || (n_bitmask>>30)
5179         || (file_size/sizeof(unsigned)) <= ((sizeof(*bitmask)/sizeof(unsigned))*n_bitmask + 2*n_bucket)  // FIXME: weak
5180         // FIXME: next test does work for Android?
5181         || ((v_gsh < v_sym) && (v_sym - v_gsh) < (sizeof(unsigned)*4  // headers
5182                 + sizeof(*bitmask)*n_bitmask  // bitmask
5183                 + sizeof(*buckets)*n_bucket  // buckets
5184                 + sizeof(*hasharr)*n_bucket  // hasharr
5185             ))
5186         ) {
5187             char msg[90]; snprintf(msg, sizeof(msg),
5188                 "bad DT_GNU_HASH n_bucket=%#x  n_bitmask=%#x  len=%#lx",
5189                 n_bucket, n_bitmask, (long unsigned)(v_sym - v_gsh));
5190             throwCantPack(msg);
5191         }
5192     }
5193     unsigned const e_shstrndx = get_te16(&ehdri.e_shstrndx);
5194     if (e_shnum <= e_shstrndx
5195     &&  !(0==e_shnum && 0==e_shstrndx) ) {
5196         char msg[40]; snprintf(msg, sizeof(msg),
5197             "bad .e_shstrndx %d >= .e_shnum %d", e_shstrndx, e_shnum);
5198         throwCantPack(msg);
5199     }
5200 }
5201 
5202 void const *
elf_find_dynamic(unsigned int key) const5203 PackLinuxElf64::elf_find_dynamic(unsigned int key) const
5204 {
5205     Elf64_Dyn const *dynp= dynseg;
5206     if (dynp)
5207     for (; (unsigned)((char const *)dynp - (char const *)dynseg) < sz_dynseg
5208             && Elf64_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te64(&dynp->d_tag)==key) {
5209         upx_uint64_t const t= elf_get_offset_from_address(get_te64(&dynp->d_val));
5210         if (t && t < (upx_uint64_t)file_size) {
5211             return t + file_image;
5212         }
5213         break;
5214     }
5215     return 0;
5216 }
5217 
5218 upx_uint64_t
elf_unsigned_dynamic(unsigned int key) const5219 PackLinuxElf64::elf_unsigned_dynamic(unsigned int key) const
5220 {
5221     Elf64_Dyn const *dynp= dynseg;
5222     if (dynp)
5223     for (; (unsigned)((char const *)dynp - (char const *)dynseg) < sz_dynseg
5224             && Elf64_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te64(&dynp->d_tag)==key) {
5225         return get_te64(&dynp->d_val);
5226     }
5227     return 0;
5228 }
5229 
gnu_hash(char const * q)5230 unsigned PackLinuxElf::gnu_hash(char const *q)
5231 {
5232     unsigned char const *p = (unsigned char const *)q;
5233     unsigned h;
5234 
5235     for (h= 5381; 0!=*p; ++p) {
5236         h += *p + (h << 5);
5237     }
5238     return h;
5239 }
5240 
elf_hash(char const * p)5241 unsigned PackLinuxElf::elf_hash(char const *p)
5242 {
5243     unsigned h;
5244     for (h= 0; 0!=*p; ++p) {
5245         h = *p + (h<<4);
5246         {
5247             unsigned const t = 0xf0000000u & h;
5248             h &= ~t;
5249             h ^= t>>24;
5250         }
5251     }
5252     return h;
5253 }
5254 
elf_lookup(char const * name) const5255 Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
5256 {
5257     if (hashtab && dynsym && dynstr) {
5258         unsigned const nbucket = get_te32(&hashtab[0]);
5259         unsigned const *const buckets = &hashtab[2];
5260         unsigned const *const chains = &buckets[nbucket];
5261         unsigned const m = elf_hash(name) % nbucket;
5262         unsigned si;
5263         for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) {
5264             char const *const p= get_dynsym_name(si, (unsigned)-1);
5265             if (0==strcmp(name, p)) {
5266                 return &dynsym[si];
5267             }
5268         }
5269     }
5270     if (gashtab && dynsym && dynstr) {
5271         unsigned const n_bucket = get_te32(&gashtab[0]);
5272         unsigned const symbias  = get_te32(&gashtab[1]);
5273         unsigned const n_bitmask = get_te32(&gashtab[2]);
5274         unsigned const gnu_shift = get_te32(&gashtab[3]);
5275         unsigned const *const bitmask = &gashtab[4];
5276         unsigned const *const buckets = &bitmask[n_bitmask];
5277         unsigned const *const hasharr = &buckets[n_bucket];
5278 
5279         unsigned const h = gnu_hash(name);
5280         unsigned const hbit1 = 037& h;
5281         unsigned const hbit2 = 037& (h>>gnu_shift);
5282         unsigned const w = get_te32(&bitmask[(n_bitmask -1) & (h>>5)]);
5283 
5284         if (1& (w>>hbit1) & (w>>hbit2)) {
5285             unsigned bucket = get_te32(&buckets[h % n_bucket]);
5286             if (0!=bucket) {
5287                 Elf32_Sym const *dsp = &dynsym[bucket];
5288                 unsigned const *hp = &hasharr[bucket - symbias];
5289 
5290                 do if (0==((h ^ get_te32(hp))>>1)) {
5291                     unsigned st_name = get_te32(&dsp->st_name);
5292                     char const *const p = get_str_name(st_name, (unsigned)-1);
5293                     if (0==strcmp(name, p)) {
5294                         return dsp;
5295                     }
5296                 } while (++dsp, 0==(1u& get_te32(hp++)));
5297             }
5298         }
5299     }
5300     return 0;
5301 
5302 }
5303 
elf_lookup(char const * name) const5304 Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const
5305 {
5306     if (hashtab && dynsym && dynstr) {
5307         unsigned const nbucket = get_te32(&hashtab[0]);
5308         unsigned const *const buckets = &hashtab[2];
5309         unsigned const *const chains = &buckets[nbucket];
5310         unsigned const m = elf_hash(name) % nbucket;
5311         unsigned si;
5312         for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) {
5313             char const *const p= get_dynsym_name(si, (unsigned)-1);
5314             if (0==strcmp(name, p)) {
5315                 return &dynsym[si];
5316             }
5317         }
5318     }
5319     if (gashtab && dynsym && dynstr) {
5320         unsigned const n_bucket = get_te32(&gashtab[0]);
5321         unsigned const symbias  = get_te32(&gashtab[1]);
5322         unsigned const n_bitmask = get_te32(&gashtab[2]);
5323         unsigned const gnu_shift = get_te32(&gashtab[3]);
5324         upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4];
5325         unsigned     const *const buckets = (unsigned const *)&bitmask[n_bitmask];
5326         unsigned     const *const hasharr = &buckets[n_bucket];
5327 
5328         unsigned const h = gnu_hash(name);
5329         unsigned const hbit1 = 077& h;
5330         unsigned const hbit2 = 077& (h>>gnu_shift);
5331         upx_uint64_t const w = get_te64(&bitmask[(n_bitmask -1) & (h>>6)]);
5332 
5333         if (1& (w>>hbit1) & (w>>hbit2)) {
5334             unsigned bucket = get_te32(&buckets[h % n_bucket]);
5335             if (0!=bucket) {
5336                 Elf64_Sym const *dsp = &dynsym[bucket];
5337                 unsigned const *hp = &hasharr[bucket - symbias];
5338 
5339                 do if (0==((h ^ get_te32(hp))>>1)) {
5340                     unsigned st_name = get_te32(&dsp->st_name);
5341                     char const *const p = get_str_name(st_name, (unsigned)-1);
5342                     if (0==strcmp(name, p)) {
5343                         return dsp;
5344                     }
5345                 } while (++dsp, 0==(1u& get_te32(hp++)));
5346             }
5347         }
5348     }
5349     return 0;
5350 
5351 }
5352 
unpack(OutputFile * fo)5353 void PackLinuxElf32::unpack(OutputFile *fo)
5354 {
5355     if (e_phoff != sizeof(Elf32_Ehdr)) {// Phdrs not contiguous with Ehdr
5356         throwCantUnpack("bad e_phoff");
5357     }
5358     unsigned const c_phnum = get_te16(&ehdri.e_phnum);
5359     unsigned old_data_off = 0;
5360     unsigned old_data_len = 0;
5361     unsigned old_dtinit = 0;
5362     unsigned is_asl = 0;  // is Android Shared Library
5363 
5364     unsigned szb_info = sizeof(b_info);
5365     {
5366         if (get_te32(&ehdri.e_entry) < 0x401180
5367         &&  Elf32_Ehdr::EM_386 ==get_te16(&ehdri.e_machine)
5368         &&  Elf32_Ehdr::ET_EXEC==get_te16(&ehdri.e_type)) {
5369             // Beware ET_DYN.e_entry==0x10f0 (or so) does NOT qualify here.
5370             /* old style, 8-byte b_info */
5371             szb_info = 2*sizeof(unsigned);
5372         }
5373     }
5374 
5375     fi->seek(overlay_offset - sizeof(l_info), SEEK_SET);
5376     fi->readx(&linfo, sizeof(linfo));
5377     lsize = get_te16(&linfo.l_lsize);
5378     if (UPX_MAGIC_LE32 != get_le32(&linfo.l_magic)) {
5379         throwCantUnpack("l_info corrupted");
5380     }
5381     p_info hbuf;  fi->readx(&hbuf, sizeof(hbuf));
5382     unsigned orig_file_size = get_te32(&hbuf.p_filesize);
5383     blocksize = get_te32(&hbuf.p_blocksize);
5384     if ((u32_t)file_size > orig_file_size || blocksize > orig_file_size
5385         || !mem_size_valid(1, blocksize, OVERHEAD))
5386         throwCantUnpack("p_info corrupted");
5387 
5388     ibuf.alloc(blocksize + OVERHEAD);
5389     b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
5390     fi->readx(&bhdr, szb_info);
5391     ph.u_len = get_te32(&bhdr.sz_unc);
5392     ph.c_len = get_te32(&bhdr.sz_cpr);
5393     if (ph.c_len > (unsigned)file_size || ph.c_len == 0 || ph.u_len == 0
5394     ||  ph.u_len > orig_file_size)
5395         throwCantUnpack("b_info corrupted");
5396     ph.filter_cto = bhdr.b_cto8;
5397 
5398     MemBuffer u(ph.u_len);
5399     Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)&u[0];
5400     Elf32_Phdr const *phdr = 0;
5401 
5402     // Uncompress Ehdr and Phdrs.
5403     if (ibuf.getSize() < ph.c_len) {
5404         throwCompressedDataViolation();
5405     }
5406     fi->readx(ibuf, ph.c_len);
5407     decompress(ibuf, (upx_byte *)ehdr, false);
5408     if (ehdr->e_type   !=ehdri.e_type
5409     ||  ehdr->e_machine!=ehdri.e_machine
5410     ||  ehdr->e_version!=ehdri.e_version
5411     ||  ehdr->e_flags  !=ehdri.e_flags
5412     ||  ehdr->e_ehsize !=ehdri.e_ehsize
5413         // check EI_MAG[0-3], EI_CLASS, EI_DATA, EI_VERSION
5414     ||  memcmp(ehdr->e_ident, ehdri.e_ident, Elf32_Ehdr::EI_OSABI)) {
5415         throwCantUnpack("ElfXX_Ehdr corrupted");
5416     }
5417     fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
5418 
5419     unsigned const u_phnum = get_te16(&ehdr->e_phnum);
5420     unsigned total_in = 0;
5421     unsigned total_out = 0;
5422     unsigned c_adler = upx_adler32(NULL, 0);
5423     unsigned u_adler = upx_adler32(NULL, 0);
5424 #define MAX_ELF_HDR 512
5425     if ((MAX_ELF_HDR - sizeof(Elf32_Ehdr))/sizeof(Elf32_Phdr) < u_phnum) {
5426         throwCantUnpack("bad compressed e_phnum");
5427     }
5428 #undef MAX_ELF_HDR
5429 
5430     // Packed ET_EXE has no PT_DYNAMIC.
5431     // Packed ET_DYN has original PT_DYNAMIC for info needed by rtld.
5432     Elf32_Phdr const *const dynhdr = elf_find_ptype(Elf32_Phdr::PT_DYNAMIC, phdri, c_phnum);
5433     bool const is_shlib = !!dynhdr;
5434     if (is_shlib) {
5435         // Unpack and output the Ehdr and Phdrs for real.
5436         // This depends on position within input file fi.
5437         unpackExtent(ph.u_len, fo, total_in, total_out,
5438             c_adler, u_adler, false, szb_info);
5439 
5440         // The first PT_LOAD.  Part is not compressed (for benefit of rtld.)
5441         fi->seek(0, SEEK_SET);
5442         fi->readx(ibuf, get_te32(&dynhdr->p_offset) + get_te32(&dynhdr->p_filesz));
5443         overlay_offset -= sizeof(linfo);
5444         xct_off = overlay_offset;
5445         e_shoff = get_te32(&ehdri.e_shoff);
5446         ibuf.subref("bad .e_shoff %#x for %#x", e_shoff, sizeof(Elf32_Shdr) * e_shnum);
5447         if (e_shoff && e_shnum) { // --android-shlib
5448             shdri = (Elf32_Shdr /*const*/ *)ibuf.subref(
5449                 "bad Shdr table", e_shoff, sizeof(Elf32_Shdr)*e_shnum);
5450             unsigned xct_off2 = get_te32(&shdri->sh_offset);
5451             if (e_shoff == xct_off2) {
5452                 xct_off = e_shoff;
5453             }
5454             // un-Relocate dynsym (DT_SYMTAB) which is below xct_off
5455             dynseg = (Elf32_Dyn const *)ibuf.subref(
5456                 "bad DYNAMIC", get_te32(&dynhdr->p_offset), get_te32(&dynhdr->p_filesz));
5457             dynstr = (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);
5458             sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);
5459             if (sec_dynsym) {
5460                 unsigned const off_dynsym = get_te32(&sec_dynsym->sh_offset);
5461                 unsigned const sz_dynsym  = get_te32(&sec_dynsym->sh_size);
5462                 Elf32_Sym *const sym0 = (Elf32_Sym *)ibuf.subref(
5463                     "bad dynsym", off_dynsym, sz_dynsym);
5464                 Elf32_Sym *sym = sym0;
5465                 for (int j = sz_dynsym / sizeof(Elf32_Sym); --j>=0; ++sym) {
5466                     unsigned symval = get_te32(&sym->st_value);
5467                     unsigned symsec = get_te16(&sym->st_shndx);
5468                     if (Elf32_Sym::SHN_UNDEF != symsec
5469                     &&  Elf32_Sym::SHN_ABS   != symsec
5470                     &&  xct_off <= symval) {
5471                         set_te32(&sym->st_value, symval - asl_delta);
5472                     }
5473                     if (Elf32_Sym::SHN_ABS == symsec && xct_off <= symval) {
5474                         adjABS(sym, 0u - asl_delta);
5475                     }
5476                 }
5477             }
5478         }
5479         if (fo) {
5480             fo->write(ibuf + ph.u_len, xct_off - ph.u_len);
5481         }
5482         // Search the Phdrs of compressed
5483         int n_ptload = 0;
5484         phdr = (Elf32_Phdr *) (void *) (1+ (Elf32_Ehdr *)(unsigned char *)ibuf);
5485         for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
5486             if (PT_LOAD32==get_te32(&phdr->p_type) && 0!=n_ptload++) {
5487                 old_data_off = get_te32(&phdr->p_offset);
5488                 old_data_len = get_te32(&phdr->p_filesz);
5489                 break;
5490             }
5491         }
5492 
5493         total_in  = xct_off;
5494         total_out = xct_off;
5495         ph.u_len = 0;
5496         // Position the input for next unpackExtent.
5497         fi->seek(sizeof(linfo) + overlay_offset + sizeof(hbuf) + szb_info + ph.c_len, SEEK_SET);
5498 
5499         // Decompress and unfilter the tail of first PT_LOAD.
5500         phdr = (Elf32_Phdr *) (void *) (1+ ehdr);
5501         for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
5502             if (PT_LOAD32==get_te32(&phdr->p_type)) {
5503                 ph.u_len = get_te32(&phdr->p_filesz) - xct_off;
5504                 break;
5505             }
5506         }
5507         unpackExtent(ph.u_len, fo, total_in, total_out,
5508             c_adler, u_adler, false, szb_info);
5509     }
5510     else {  // main executable
5511         // Decompress each PT_LOAD.
5512         bool first_PF_X = true;
5513         phdr = (Elf32_Phdr *) (void *) (1+ ehdr);  // uncompressed
5514         for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
5515             if (PT_LOAD32==get_te32(&phdr->p_type)) {
5516                 unsigned const filesz = get_te32(&phdr->p_filesz);
5517                 unsigned const offset = get_te32(&phdr->p_offset);
5518                 if (fo)
5519                     fo->seek(offset, SEEK_SET);
5520                 if (Elf32_Phdr::PF_X & get_te32(&phdr->p_flags)) {
5521                     unpackExtent(filesz, fo, total_in, total_out,
5522                         c_adler, u_adler, first_PF_X, szb_info);
5523                     first_PF_X = false;
5524                 }
5525                 else {
5526                     unpackExtent(filesz, fo, total_in, total_out,
5527                         c_adler, u_adler, false, szb_info);
5528                 }
5529             }
5530         }
5531     }
5532     phdr = phdri;
5533     load_va = 0;
5534     for (unsigned j=0; j < c_phnum; ++j) {
5535         if (PT_LOAD32==get_te32(&phdr->p_type)) {
5536             load_va = get_te32(&phdr->p_vaddr);
5537             break;
5538         }
5539     }
5540     if (is_shlib
5541     ||  ((unsigned)(get_te32(&ehdri.e_entry) - load_va) + up4(lsize) +
5542                 ph.getPackHeaderSize() + sizeof(overlay_offset))
5543             < up4(file_size)) {
5544         // Loader is not at end; skip past it.
5545         funpad4(fi);  // MATCH01
5546         unsigned d_info[4]; fi->readx(d_info, sizeof(d_info));
5547         if (0==old_dtinit) {
5548             old_dtinit = get_te32(&d_info[2 + (0==d_info[0])]);
5549             is_asl = 1u& get_te32(&d_info[0 + (0==d_info[0])]);
5550         }
5551         fi->seek(lsize - sizeof(d_info), SEEK_CUR);
5552     }
5553 
5554     // The gaps between PT_LOAD and after last PT_LOAD
5555     phdr = (Elf32_Phdr *)&u[sizeof(*ehdr)];
5556     unsigned hi_offset(0);
5557     for (unsigned j = 0; j < u_phnum; ++j) {
5558         if (PT_LOAD32==phdr[j].p_type
5559         &&  hi_offset < phdr[j].p_offset)
5560             hi_offset = phdr[j].p_offset;
5561     }
5562     for (unsigned j = 0; j < u_phnum; ++j) {
5563         unsigned const size = find_LOAD_gap(phdr, j, u_phnum);
5564         if (size) {
5565             unsigned const where = get_te32(&phdr[j].p_offset) +
5566                                    get_te32(&phdr[j].p_filesz);
5567             if (fo)
5568                 fo->seek(where, SEEK_SET);
5569             unpackExtent(size, fo, total_in, total_out,
5570                 c_adler, u_adler, false, szb_info,
5571                 (phdr[j].p_offset != hi_offset));
5572         }
5573     }
5574 
5575     // check for end-of-file
5576     fi->readx(&bhdr, szb_info);
5577     unsigned const sz_unc = ph.u_len = get_te32(&bhdr.sz_unc);
5578 
5579     if (sz_unc == 0) { // uncompressed size 0 -> EOF
5580         // note: magic is always stored le32
5581         unsigned const sz_cpr = get_le32(&bhdr.sz_cpr);
5582         if (sz_cpr != UPX_MAGIC_LE32)  // sz_cpr must be h->magic
5583             throwCompressedDataViolation();
5584     }
5585     else { // extra bytes after end?
5586         throwCompressedDataViolation();
5587     }
5588 
5589     if (is_shlib) {
5590         // DT_INIT must be restored.
5591         // If android_shlib, then the asl_delta relocations must be un-done.
5592         int n_ptload = 0;
5593         unsigned load_off = 0;
5594         phdr = (Elf32_Phdr *)&u[sizeof(*ehdr)];
5595         for (unsigned j= 0; j < u_phnum; ++j, ++phdr) {
5596             if (PT_LOAD32==get_te32(&phdr->p_type) && 0!=n_ptload++) {
5597                 load_off = get_te32(&phdr->p_offset);
5598                 load_va  = get_te32(&phdr->p_vaddr);
5599                 fi->seek(old_data_off, SEEK_SET);
5600                 fi->readx(ibuf, old_data_len);
5601                 total_in  += old_data_len;
5602                 total_out += old_data_len;
5603 
5604                 Elf32_Phdr const *udynhdr = (Elf32_Phdr *)&u[sizeof(*ehdr)];
5605                 for (unsigned j3= 0; j3 < u_phnum; ++j3, ++udynhdr)
5606                 if (Elf32_Phdr::PT_DYNAMIC==get_te32(&udynhdr->p_type)) {
5607                     unsigned dt_pltrelsz(0), dt_jmprel(0);
5608                     unsigned dt_relsz(0), dt_rel(0);
5609                     unsigned const dyn_len = get_te32(&udynhdr->p_filesz);
5610                     unsigned const dyn_off = get_te32(&udynhdr->p_offset);
5611                     if (dyn_off < load_off) {
5612                         continue;  // Oops.  Not really is_shlib ?  [built by 'rust' ?]
5613                     }
5614                     Elf32_Dyn *dyn = (Elf32_Dyn *)((unsigned char *)ibuf +
5615                         (dyn_off - load_off));
5616                     dynseg = dyn; invert_pt_dynamic(dynseg);
5617                     for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
5618                         unsigned const tag = get_te32(&dyn->d_tag);
5619                         unsigned       val = get_te32(&dyn->d_val);
5620                         if (is_asl) switch (tag) {
5621                         case Elf32_Dyn::DT_RELSZ:    { dt_relsz    = val; } break;
5622                         case Elf32_Dyn::DT_REL:      { dt_rel      = val; } break;
5623                         case Elf32_Dyn::DT_PLTRELSZ: { dt_pltrelsz = val; } break;
5624                         case Elf32_Dyn::DT_JMPREL:   { dt_jmprel   = val; } break;
5625 
5626                         case Elf32_Dyn::DT_PLTGOT:
5627                         case Elf32_Dyn::DT_PREINIT_ARRAY:
5628                         case Elf32_Dyn::DT_INIT_ARRAY:
5629                         case Elf32_Dyn::DT_FINI_ARRAY:
5630                         case Elf32_Dyn::DT_FINI: {
5631                             set_te32(&dyn->d_val, val -= asl_delta);
5632                         }; break;
5633                         } // end switch()
5634                         if (upx_dt_init == tag) {
5635                             if (Elf32_Dyn::DT_INIT == tag) {
5636                                 set_te32(&dyn->d_val, old_dtinit);
5637                                 if (!old_dtinit) { // compressor took the slot
5638                                     dyn->d_tag = Elf32_Dyn::DT_NULL;
5639                                     dyn->d_val = 0;
5640                                 }
5641                             }
5642                             else { // DT_INIT_ARRAY, DT_PREINIT_ARRAY
5643                                 set_te32(&ibuf[val - load_va], old_dtinit
5644                                     + (is_asl ? asl_delta : 0));  // counter-act unRel32
5645                             }
5646                         }
5647                         // Modified DT_*.d_val are re-written later from ibuf[]
5648                     }
5649                     if (is_asl) {
5650                         lowmem.alloc(xct_off);
5651                         fi->seek(0, SEEK_SET);
5652                         fi->read(lowmem, xct_off);  // contains relocation tables
5653                         if (dt_relsz && dt_rel) {
5654                             Elf32_Rel *const rel0 = (Elf32_Rel *)lowmem.subref(
5655                                 "bad Rel offset", dt_rel, dt_relsz);
5656                             unRel32(dt_rel, rel0, dt_relsz, ibuf, load_va, fo);
5657                         }
5658                         if (dt_pltrelsz && dt_jmprel) { // FIXME:  overlap w/ DT_REL ?
5659                             Elf32_Rel *const jmp0 = (Elf32_Rel *)lowmem.subref(
5660                                 "bad Jmprel offset", dt_jmprel, dt_pltrelsz);
5661                             unRel32(dt_jmprel, jmp0, dt_pltrelsz, ibuf, load_va, fo);
5662                         }
5663                         // Modified relocation tables are re-written by unRel32
5664                     }
5665                 }
5666                 if (fo) {
5667                     fo->seek(get_te32(&phdr->p_offset), SEEK_SET);
5668                     fo->rewrite(ibuf, old_data_len);
5669                 }
5670             }
5671         }
5672     }
5673 
5674     // update header with totals
5675     ph.c_len = total_in;
5676     ph.u_len = total_out;
5677 
5678     // all bytes must be written
5679     if (total_out != orig_file_size)
5680         throwEOFException();
5681 
5682     // finally test the checksums
5683     if (ph.c_adler != c_adler || ph.u_adler != u_adler)
5684         throwChecksumError();
5685 }
5686 
unpack(OutputFile *)5687 void PackLinuxElf::unpack(OutputFile * /*fo*/)
5688 {
5689     throwCantUnpack("internal error");
5690 }
5691 
5692 /* vim:set ts=4 sw=4 et: */
5693