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(¬e, 0, sizeof(note));
1956 fi->seek(p_offset, SEEK_SET);
1957 fi->readx(¬e, sizeof(note));
1958 fi->seek(0, SEEK_SET);
1959 if (4==get_te32(¬e.nhdr.descsz)
1960 && 1==get_te32(¬e.nhdr.type)
1961 // && 0==note.end
1962 && (1+ strlen(osabi_note))==get_te32(¬e.nhdr.namesz)
1963 && 0==strcmp(osabi_note, (char const *)¬e.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(¬e_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(¬e_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