Coverage Report

Created: 2025-11-03 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/upx/src/p_lx_elf.cpp
Line
Count
Source
1
/* p_lx_elf.cpp --
2
3
   This file is part of the UPX executable compressor.
4
5
   Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
6
   Copyright (C) 1996-2025 Laszlo Molnar
7
   Copyright (C) 2000-2025 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
#define ALLOW_INT_PLUS_MEMBUFFER 1
34
#include "conf.h"
35
36
#include "file.h"
37
#include "filter.h"
38
#include "linker.h"
39
#include "packer.h"
40
#include "p_elf.h"
41
#include "p_unix.h"
42
#include "p_lx_exc.h"
43
#include "p_lx_elf.h"
44
#include "ui.h"
45
46
// NOLINTBEGIN(clang-analyzer-core.CallAndMessage)
47
// NOLINTBEGIN(clang-analyzer-deadcode.DeadStores)
48
49
#if defined(__CHERI__) && defined(__CHERI_PURE_CAPABILITY__)
50
#  pragma clang diagnostic ignored "-Wcheri-capability-misuse" // TODO later
51
#  pragma clang diagnostic ignored "-Wcheri-provenance" // TODO later
52
#endif
53
54
using upx::umin;
55
56
323k
#define PT_LOAD Elf32_Phdr::PT_LOAD  /* 64-bit PT_LOAD is the same */
57
0
#define PT_NOTE32   Elf32_Phdr::PT_NOTE
58
0
#define PT_NOTE64   Elf64_Phdr::PT_NOTE
59
0
#define PT_GNU_STACK32  Elf32_Phdr::PT_GNU_STACK
60
0
#define PT_GNU_STACK64  Elf64_Phdr::PT_GNU_STACK
61
0
#define PT_GNU_RELRO32  Elf32_Phdr::PT_GNU_RELRO
62
0
#define PT_GNU_RELRO64  Elf64_Phdr::PT_GNU_RELRO
63
64
// also see stub/src/MAX_ELF_HDR.[Sc]
65
static constexpr unsigned MAX_ELF_HDR_32 = 512;
66
static constexpr unsigned MAX_ELF_HDR_64 = 1024;
67
68
//static unsigned const EF_ARM_HASENTRY = 0x02;
69
static unsigned const EF_ARM_EABI_VER4 = 0x04000000;
70
static unsigned const EF_ARM_EABI_VER5 = 0x05000000;
71
72
/*static*/ const unsigned char PackLinuxElf::o_shstrtab[] = {  \
73
/*start*/       '\0',
74
/*offset  1*/   '.','n','o','t','e','.','g','n','u','.','b','u','i','l','d','-','i','d','\0',
75
/*offset 20*/   '.','s','h','s','t','r','t','a','b','\0'
76
};
77
78
static unsigned
79
up4(unsigned x)
80
500
{
81
500
    return ~3u & (3+ x);
82
500
}
83
84
static unsigned
85
up8(unsigned x)
86
0
{
87
0
    return ~7u & (7+ x);
88
0
}
89
90
static off_t
91
fpadN(OutputFile *fo, unsigned len)
92
0
{
93
0
    if (len) {
94
0
        MemBuffer pad(len); pad.clear();
95
0
        fo->write(pad, len);
96
0
    }
97
0
    return fo->st_size();
98
0
}
99
100
static off_t
101
fpad4(OutputFile *fo, unsigned pos)
102
0
{
103
0
    (void)pos;  // debug: compare 'pos' with "shell grep pos /proc/PID/fdinfo/FD"
104
0
    if (!fo) { // --test, --list
105
0
        return 0;
106
0
    }
107
0
    off_t len = fo->st_size();
108
0
    unsigned d = 3u & (0 - len);
109
0
    if (d) {
110
0
        unsigned zero = 0;
111
0
        fo->write(&zero, d);
112
0
    }
113
0
    return d + len;
114
0
}
115
116
static off_t
117
fpad8(OutputFile *fo, unsigned pos)
118
0
{
119
0
    (void)pos;  // debug: compare 'pos' with "shell grep pos /proc/PID/fdinfo/FD"
120
0
    if (!fo) { // --test, --list
121
0
        return 0;
122
0
    }
123
0
    off_t len = fo->st_size();
124
0
    unsigned d = 7u & (0 - len);
125
0
    if (d) {
126
0
        upx_uint64_t zero = 0;
127
0
        fo->write(&zero, d);
128
0
    }
129
0
    return d + len;
130
0
}
131
132
static unsigned
133
funpad4(InputFile *fi)
134
134
{
135
134
    unsigned d = 3u & (0 - fi->tell());
136
134
    if (d)
137
131
        fi->seek(d, SEEK_CUR);
138
134
    return d;
139
134
}
140
141
static void alloc_file_image(MemBuffer &mb, off_t size)
142
23.6k
{
143
23.6k
    assert(mem_size_valid_bytes(size));
144
23.6k
    if (mb.getVoidPtr() == nullptr) {
145
22.5k
        mb.alloc(size);
146
22.5k
    } else {
147
1.08k
        assert((u32_t)size <= mb.getSize());
148
1.08k
    }
149
23.6k
}
150
151
int
152
PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const
153
169k
{
154
169k
    const unsigned char * const buf = ehdr->e_ident;
155
156
169k
    if (0!=memcmp(buf, "\x7f\x45\x4c\x46", 4)  // "\177ELF"
157
85.4k
    ||  buf[Elf32_Ehdr::EI_CLASS]!=ei_class
158
40.1k
    ||  buf[Elf32_Ehdr::EI_DATA] !=ei_data
159
169k
    ) {
160
151k
        return -1;
161
151k
    }
162
17.2k
    if (!memcmp(buf+8, "FreeBSD", 7))                   // branded
163
51
        return 1;
164
165
17.1k
    int const type = get_te16(&ehdr->e_type);
166
17.1k
    if (type != Elf32_Ehdr::ET_EXEC && type != Elf32_Ehdr::ET_DYN)
167
2.54k
        return 2;
168
14.6k
    if (get_te16(&ehdr->e_machine) != (unsigned) e_machine)
169
5.92k
        return 3;
170
8.70k
    if (get_te32(&ehdr->e_version) != Elf32_Ehdr::EV_CURRENT)
171
1.08k
        return 4;
172
7.61k
    if (e_phnum < 1)
173
680
        return 5;
174
6.93k
    if (get_te16(&ehdr->e_phentsize) != sizeof(Elf32_Phdr))
175
613
        return 6;
176
177
6.32k
    if (type == Elf32_Ehdr::ET_EXEC) {
178
        // check for Linux kernels
179
5.53k
        unsigned const entry = get_te32(&ehdr->e_entry);
180
5.53k
        if (entry == 0xC0100000)    // uncompressed vmlinux
181
10
            return 1000;
182
5.52k
        if (entry == 0x00001000)    // compressed vmlinux
183
15
            return 1001;
184
5.50k
        if (entry == 0x00100000)    // compressed bvmlinux
185
15
            return 1002;
186
5.50k
    }
187
188
    // FIXME: add more checks for kernels
189
190
    // FIXME: add special checks for other ELF i386 formats, like
191
    //        NetBSD, OpenBSD, Solaris, ....
192
193
    // success
194
6.28k
    return 0;
195
6.32k
}
196
197
int
198
PackLinuxElf64::checkEhdr(Elf64_Ehdr const *ehdr) const
199
65.2k
{
200
65.2k
    const unsigned char * const buf = ehdr->e_ident;
201
65.2k
    unsigned char osabi0 = buf[Elf32_Ehdr::EI_OSABI];
202
65.2k
    if (0==osabi0) {
203
25.3k
        osabi0 = opt->o_unix.osabi0;
204
25.3k
    }
205
206
65.2k
    if (0!=memcmp(buf, "\x7f\x45\x4c\x46", 4)  // "\177ELF"
207
28.0k
    ||  buf[Elf64_Ehdr::EI_CLASS]!=ei_class
208
13.5k
    ||  buf[Elf64_Ehdr::EI_DATA] !=ei_data
209
6.80k
    ||                     osabi0!=ei_osabi
210
65.2k
    ) {
211
60.5k
        return -1;
212
60.5k
    }
213
4.74k
    if (!memcmp(buf+8, "FreeBSD", 7))                   // branded
214
22
        return 1;
215
216
4.72k
    int const type = get_te16(&ehdr->e_type);
217
4.72k
    if (type != Elf64_Ehdr::ET_EXEC && type != Elf64_Ehdr::ET_DYN)
218
1.41k
        return 2;
219
3.31k
    if (get_te16(&ehdr->e_machine) != (unsigned) e_machine)
220
1.75k
        return 3;
221
1.55k
    if (get_te32(&ehdr->e_version) != Elf64_Ehdr::EV_CURRENT)
222
154
        return 4;
223
1.40k
    if (e_phnum < 1)
224
5
        return 5;
225
1.39k
    if (get_te16(&ehdr->e_phentsize) != sizeof(Elf64_Phdr))
226
34
        return 6;
227
228
1.36k
    if (type == Elf64_Ehdr::ET_EXEC) {
229
        // check for Linux kernels
230
1.06k
        upx_uint64_t const entry = get_te64(&ehdr->e_entry);
231
1.06k
        if (entry == 0xC0100000)    // uncompressed vmlinux
232
3
            return 1000;
233
1.05k
        if (entry == 0x00001000)    // compressed vmlinux
234
3
            return 1001;
235
1.05k
        if (entry == 0x00100000)    // compressed bvmlinux
236
3
            return 1002;
237
1.05k
    }
238
239
    // FIXME: add more checks for kernels
240
241
    // FIXME: add special checks for other ELF i386 formats, like
242
    //        NetBSD, OpenBSD, Solaris, ....
243
244
    // success
245
1.35k
    return 0;
246
1.36k
}
247
248
PackLinuxElf::PackLinuxElf(InputFile *f)
249
241k
    : super(f), e_phnum(0), dynstr(nullptr),
250
241k
    sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), sz_pack2a(0),
251
241k
    lg2_page(12), page_size(1u<<lg2_page), is_pie(0), is_asl(0),
252
241k
    xct_off(0), o_binfo(0), so_slide(0), xct_va(0), jni_onload_va(0),
253
241k
    user_init_va(0), user_init_off(0),
254
241k
    e_machine(0), ei_class(0), ei_data(0), ei_osabi(0), osabi_note(nullptr),
255
241k
    shstrtab(nullptr),
256
241k
    o_elf_shnum(0)
257
241k
{
258
241k
    memset(dt_table, 0, sizeof(dt_table));
259
241k
    symnum_max = 0;
260
241k
    user_init_rp = nullptr;
261
241k
}
262
263
PackLinuxElf::~PackLinuxElf()
264
241k
{
265
241k
}
266
267
int PackLinuxElf32::is_LOAD(Elf32_Phdr const *phdr) const
268
169k
{
269
    // (1+ PT_LOPROC) can confuse!
270
169k
    return PT_LOAD == get_te32(&phdr->p_type);
271
169k
}
272
273
int PackLinuxElf64::is_LOAD(Elf64_Phdr const *phdr) const
274
153k
{
275
    // (1+ PT_LOPROC) can confuse!
276
153k
    return PT_LOAD == get_te32(&phdr->p_type);
277
153k
}
278
279
void
280
PackLinuxElf32::PackLinuxElf32help1(InputFile *f)
281
172k
{
282
172k
    e_type  = get_te16(&ehdri.e_type);
283
172k
    e_phnum = get_te16(&ehdri.e_phnum);
284
172k
    e_shnum = get_te16(&ehdri.e_shnum);
285
172k
    unsigned const e_phentsize = get_te16(&ehdri.e_phentsize);
286
172k
    if (memcmp((char const *)&ehdri, "\x7f\x45\x4c\x46", 4)  // "\177ELF"
287
89.2k
    || ehdri.e_ident[Elf32_Ehdr::EI_CLASS]!=Elf32_Ehdr::ELFCLASS32
288
43.9k
    || sizeof(Elf32_Phdr) != e_phentsize
289
17.1k
    || (Elf32_Ehdr::ELFDATA2MSB == ehdri.e_ident[Elf32_Ehdr::EI_DATA]
290
3.52k
            && &N_BELE_RTP::be_policy != bele)
291
17.1k
    || (Elf32_Ehdr::ELFDATA2LSB == ehdri.e_ident[Elf32_Ehdr::EI_DATA]
292
155k
            && &N_BELE_RTP::le_policy != bele)) {
293
155k
        e_phoff = 0;
294
155k
        e_shoff = 0;
295
155k
        sz_phdrs = 0;
296
155k
        return;
297
155k
    }
298
17.0k
    if (0==e_phnum) throwCantUnpack("0==e_phnum");
299
17.0k
    e_phoff = get_te32(&ehdri.e_phoff);
300
17.0k
    unsigned const last_Phdr = e_phoff + e_phnum * usizeof(Elf32_Phdr);
301
17.0k
    if (last_Phdr < e_phoff  // wrap-around
302
16.9k
    ||  e_phoff != sizeof(Elf32_Ehdr)  // must be contiguous
303
16.0k
    ||  (unsigned long)file_size < last_Phdr) {
304
954
        throwCantUnpack("bad e_phoff %#x", e_phoff);
305
954
    }
306
16.0k
    e_shoff = get_te32(&ehdri.e_shoff);
307
16.0k
    e_shstrndx = get_te16(&ehdri.e_shstrndx);
308
16.0k
    unsigned const last_Shdr = e_shoff + e_shnum * usizeof(Elf32_Shdr);
309
16.0k
    if (last_Shdr < e_shoff  // wrap-around
310
15.6k
    ||  (e_shnum && e_shoff < last_Phdr)
311
14.0k
    ||  (unsigned long)file_size < last_Shdr) {
312
7.18k
        if (opt->cmd == CMD_COMPRESS) {
313
0
            throwCantUnpack("bad e_shoff %#x", e_shoff);
314
0
        }
315
7.18k
    }
316
16.0k
    sz_phdrs = e_phnum * e_phentsize;
317
16.0k
    sz_elf_hdrs = sz_phdrs + sizeof(Elf32_Ehdr) +
318
16.0k
        n_phdrx * sizeof(Elf32_Phdr);  // phdrx bodies later: ::generateElfHdr
319
320
16.0k
    if (f && Elf32_Ehdr::ET_DYN!=e_type) {
321
10.5k
        unsigned const len = file_size;  // (sz_phdrs + e_phoff) except --preserve-build-id
322
10.5k
        alloc_file_image(file_image, len);
323
10.5k
        f->seek(0, SEEK_SET);
324
10.5k
        f->readx(file_image, len);
325
10.5k
        phdri= (Elf32_Phdr       *)(e_phoff + file_image);  // do not free() !!
326
10.5k
    }
327
16.0k
    if (f && Elf32_Ehdr::ET_DYN==e_type) {
328
        // The DT_SYMTAB has no designated length.  Read the whole file.
329
5.53k
        alloc_file_image(file_image, file_size);
330
5.53k
        f->seek(0, SEEK_SET);
331
5.53k
        f->readx(file_image, file_size);
332
5.53k
        phdri= (Elf32_Phdr *)(e_phoff + file_image);  // do not free() !!
333
5.53k
        if (opt->cmd != CMD_COMPRESS || !e_shoff ||  file_size < e_shoff) {
334
5.53k
            shdri = nullptr;
335
5.53k
        }
336
0
        else {  // FIXME: copy from file_image ?
337
0
            fi->seek(e_shoff, SEEK_SET);
338
0
            if (mb_shdr.getSize() != sizeof(Elf32_Shdr) * e_shnum) {
339
0
                mb_shdr.alloc(   sizeof(Elf32_Shdr) * e_shnum);
340
0
            }
341
0
            shdri = (Elf32_Shdr *)mb_shdr.getVoidPtr();
342
0
            fi->readx(shdri, sizeof(Elf32_Shdr) * e_shnum);
343
0
        }
344
5.53k
        sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);
345
5.53k
        if (sec_dynsym) {
346
0
            unsigned t = get_te32(&sec_dynsym->sh_link);
347
0
            if (e_shnum <= t)
348
0
                throwCantPack("bad dynsym->sh_link");
349
0
            sec_dynstr = &shdri[t];
350
0
        }
351
352
5.53k
        Elf32_Phdr const *phdr= phdri;
353
65.4k
        for (int j = e_phnum; --j>=0; ++phdr)
354
59.9k
        if (Elf32_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
355
4.22k
            unsigned offset = check_pt_dynamic(phdr);
356
4.22k
            dynseg= (Elf32_Dyn *)(offset + file_image);
357
4.22k
            invert_pt_dynamic(dynseg,
358
4.22k
                umin(get_te32(&phdr->p_filesz), (unsigned)(file_size_u - offset)));
359
4.22k
        }
360
55.6k
        else if (is_LOAD(phdr)) {
361
6.59k
            check_pt_load(phdr);
362
6.59k
        }
363
        // elf_find_dynamic() returns 0 if 0==dynseg.
364
5.53k
        dynstr =          (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);
365
5.53k
        dynsym = (Elf32_Sym /*const*/ *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB);
366
5.53k
        gashtab =     (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_GNU_HASH);
367
5.53k
        hashtab =     (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_HASH);
368
5.53k
        if (3& ((upx_uintptr_t)dynsym | (upx_uintptr_t)gashtab | (upx_uintptr_t)hashtab)) {
369
19
            throwCantPack("unaligned DT_SYMTAB, DT_GNU_HASH, or DT_HASH/n");
370
19
        }
371
5.51k
        jni_onload_sym = elf_lookup("JNI_OnLoad");
372
5.51k
        if (jni_onload_sym) {
373
32
            jni_onload_va = get_te32(&jni_onload_sym->st_value);
374
32
            jni_onload_va = 0;  // FIXME not understood; need example
375
32
        }
376
5.51k
    }
377
16.0k
}
378
379
#define WANT_EHDR_ENUM
380
#define WANT_REL_ENUM
381
#include "p_elf_enum.h"
382
#undef WANT_REL_ENUM
383
#undef WANT_EHDR_ENUM
384
385
off_t PackLinuxElf::pack3(OutputFile *fo, Filter &ft) // return length of output
386
0
{
387
0
    if (!fo) {
388
0
        return 0;
389
0
    }
390
0
    unsigned disp;
391
0
    unsigned len = sz_pack2a;  // after headers and all PT_LOAD
392
393
0
    unsigned const t = (4 & len) ^ ((!!xct_off)<<2);  // 0 or 4
394
0
    if (t) {
395
0
        if (fo) {
396
0
            unsigned const zero = 0;
397
0
            fo->write(&zero, t);
398
0
        }
399
0
        len += t;  // force sz_pack2 (0 mod 8)  [see below]
400
0
    }
401
402
0
    set_te32(&disp, sz_elf_hdrs + usizeof(p_info) + usizeof(l_info) +
403
0
        (!!xct_off & !!is_asl));  // |1 iff android shlib
404
0
    fo->write(&disp, sizeof(disp));  // offset(b_info)
405
        // FIXME: If is_shlib then that is useful only for the is_asl bit.
406
        // Better info is the word below with (overlay_offset - sizeof(linfo)).
407
408
0
    len += sizeof(disp);
409
0
    set_te32(&disp, len);  // distance back to beginning (detect dynamic reloc)
410
0
    fo->write(&disp, sizeof(disp));
411
0
    len += sizeof(disp);
412
413
0
    if (xct_off) {  // is_shlib
414
0
        upx_uint64_t const firstpc_va = (jni_onload_va
415
0
            ? jni_onload_va
416
0
            : user_init_va);
417
0
        set_te32(&disp, firstpc_va - load_va);
418
0
        fo->write(&disp, sizeof(disp));  // DT_INIT.d_val or DT_INIT_ARRAY[0]
419
0
        len += sizeof(disp);
420
421
0
        set_te32(&disp, xct_off);
422
0
        fo->write(&disp, sizeof(disp));  // offset(lowest_executable_instr)
423
0
        len += sizeof(disp);
424
425
0
        if (is_asl) {
426
0
            xct_off += asl_delta;  // the extra page
427
0
        }
428
0
        set_te32(&disp, overlay_offset - sizeof(linfo));
429
0
        fo->write(&disp, sizeof(disp));  // &{l_info; p_info; b_info}
430
0
        len += sizeof(disp);
431
0
    }
432
0
    total_out += len - sz_pack2a;
433
0
    sz_pack2 = len;  // 0 mod 8  [see above]
434
435
    // FIXME: debugging aid: entry to decompressor
436
0
    if (lowmem.getSize()) {
437
0
        Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)&lowmem[0];
438
0
        set_te32(&ehdr->e_entry, sz_pack2);  // hint for decompressor
439
0
    }
440
    // end debugging aid
441
442
0
    super::pack3(fo, ft);  // append the decompressor
443
0
    set_te16(&linfo.l_lsize, up4(  // MATCH03: up4
444
0
    get_te16(&linfo.l_lsize) + len - sz_pack2a));
445
0
    total_out = fpad4(fo, total_out);  // MATCH03
446
0
    return total_out;
447
0
}
448
449
static unsigned
450
is_pow2(u64_t x)
451
42.1k
{
452
42.1k
    return !((-1+ x) & x);
453
42.1k
}
454
455
Elf32_Phdr const *
456
PackLinuxElf32::elf_find_Phdr_for_va(upx_uint32_t addr, Elf32_Phdr const *phdr, unsigned phnum)
457
19.2k
{
458
57.4k
    for (unsigned j = 0; j < phnum; ++j, ++phdr) {
459
57.2k
        u32_t align = get_te32(&phdr->p_align);
460
57.2k
        if (is_LOAD(phdr)
461
24.2k
        && is_pow2(align) && !((-1+ align) &
462
23.0k
            (get_te32(&phdr->p_vaddr) ^ get_te32(&phdr->p_offset)))
463
21.9k
        &&  (addr - get_te32(&phdr->p_vaddr)) < get_te32(&phdr->p_filesz)) {
464
19.0k
            return phdr;
465
19.0k
        }
466
57.2k
    }
467
231
    return nullptr;
468
19.2k
}
469
470
Elf64_Phdr const *
471
PackLinuxElf64::elf_find_Phdr_for_va(upx_uint64_t addr, Elf64_Phdr const *phdr, unsigned phnum)
472
13.4k
{
473
55.8k
    for (unsigned j = 0; j < phnum; ++j, ++phdr) {
474
55.5k
        u64_t align = get_te64(&phdr->p_align);
475
55.5k
        if (is_LOAD(phdr)
476
17.8k
        && is_pow2(align) && !((-1+ align) &
477
15.7k
            (get_te64(&phdr->p_vaddr) ^ get_te64(&phdr->p_offset)))
478
15.0k
        &&  (addr - get_te64(&phdr->p_vaddr)) < get_te64(&phdr->p_filesz)) {
479
13.1k
            return phdr;
480
13.1k
        }
481
55.5k
    }
482
313
    return nullptr;
483
13.4k
}
484
485
unsigned
486
PackLinuxElf32::slide_sh_offset(Elf32_Shdr *shdr)
487
0
{
488
0
    unsigned sh_offset = get_te32(&shdr->sh_offset);
489
0
    unsigned sh_addr   = get_te32(&shdr->sh_addr);
490
0
    if (Elf32_Shdr::SHF_WRITE & get_te32(&shdr->sh_flags)
491
0
      || (sh_offset && !sh_addr))
492
0
    {
493
0
        unsigned newoff = so_slide + sh_offset + (is_asl ? asl_delta : 0);
494
0
        if ((unsigned)this->file_size < newoff) {
495
0
            throwInternalError("bad slide %p %#x", shdr, (unsigned)so_slide);
496
0
        }
497
0
        set_te32(&shdr->sh_offset, newoff);
498
0
        if (sh_addr) // change only if non-zero
499
0
            set_te32(&shdr->sh_addr,
500
0
                so_slide + sh_addr + (is_asl ? asl_delta : 0));
501
0
        return newoff;
502
0
    }
503
0
    return sh_offset;
504
0
}
505
506
void
507
PackLinuxElf32::asl_slide_Shdrs()
508
0
{
509
0
    Elf32_Shdr *shdr = shdro;
510
0
    for (unsigned j = 0; j < e_shnum; ++shdr, ++j) {
511
0
        unsigned sh_offset = get_te32(&shdr->sh_offset);
512
0
        if (xct_off < sh_offset) {
513
0
            slide_sh_offset(shdr);
514
0
        }
515
0
    }
516
0
}
517
518
unsigned
519
PackLinuxElf64::slide_sh_offset(Elf64_Shdr *shdr)
520
0
{
521
0
    unsigned sh_offset = get_te64(&shdr->sh_offset);
522
0
    unsigned sh_addr   = get_te64(&shdr->sh_addr);
523
0
    if (Elf64_Shdr::SHF_WRITE & get_te64(&shdr->sh_flags)
524
0
      || (sh_offset && !sh_addr))
525
0
    {
526
0
        unsigned newoff = so_slide + sh_offset + (is_asl ? asl_delta : 0);
527
0
        if ((unsigned)this->file_size < newoff) {
528
0
            throwInternalError("bad slide %p %#x", shdr, (unsigned)so_slide);
529
0
        }
530
0
        set_te64(&shdr->sh_offset, newoff);
531
0
        if (sh_addr) // change only if non-zero
532
0
            set_te64(&shdr->sh_addr,
533
0
                so_slide + sh_addr + (is_asl ? asl_delta : 0));
534
0
        return newoff;
535
0
    }
536
0
    return sh_offset;
537
0
}
538
539
void
540
PackLinuxElf64::asl_slide_Shdrs()
541
0
{
542
0
    Elf64_Shdr *shdr = shdro;
543
0
    for (unsigned j = 0; j < e_shnum; ++shdr, ++j) {
544
0
        unsigned sh_offset = get_te64_32(&shdr->sh_offset);
545
0
        if (xct_off < sh_offset) {
546
0
            slide_sh_offset(shdr);
547
0
        }
548
0
    }
549
0
}
550
551
// C_BASE covers the convex hull of the PT_LOAD of the uncompressed module.
552
// It has (PF_W & .p_flags), and is ".bss": empty (0==.p_filesz, except a bug
553
// in Linux kernel forces 0x1000==.p_filesz) with .p_memsz equal to the brk(0).
554
// It is first in order to reserve all // pages, in particular so that if
555
// (64K == .p_align) but at runtime (4K == PAGE_SIZE) then the Linux kernel
556
// does not put [vdso] and [vvar] into alignment holes that the UPX runtime stub
557
// will overwrite.
558
//
559
// Note that C_TEXT[.p_vaddr, +.p_memsz) is a subset of C_BASE.
560
// This requires that the kernel process the ELFxx_Phdr in ascending order,
561
// and does not mind the overlap.  The UPX runtime stub will "re-program"
562
// the memory regions anyway.
563
enum { // ordinals in ELFxx_Phdr[] of compressed output
564
      C_BASE = 0  // reserve address space
565
    , C_TEXT = 1  // compressed data and stub
566
    , C_NOTE = 2  // PT_NOTE copied from input
567
    , C_GSTK = 3  // PT_GNU_STACK; will be 2 if no PT_NOTE
568
};
569
570
off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
571
0
{
572
0
    if (!overlay_offset) {
573
0
        overlay_offset = sizeof(linfo) + (xct_off ? xct_off : sz_elf_hdrs);
574
0
    }
575
576
0
    total_out = super::pack3(fo, ft);  // loader follows compressed PT_LOADs
577
0
    if (fo && xct_off  && !is_asl && Elf32_Dyn::DT_INIT != upx_dt_init) {
578
        // Patch user_init_rp.  is_asl has done this already in asl_pack2_Shdrs()
579
        // Section .init_array[0] must have R_$(ARCH)_RELATIVE relocation.
580
0
        fo->seek((char *)user_init_rp - (char *)&file_image[0], SEEK_SET);
581
0
        Elf32_Rel rel(*(Elf32_Rel const *)user_init_rp);
582
0
        u32_t r_info = get_te32(&((Elf32_Rel const *)user_init_rp)->r_info);
583
0
        u32_t r_type = (Elf32_Ehdr::EM_386  == e_machine) ? R_386_RELATIVE
584
0
                     : (Elf32_Ehdr::EM_ARM  == e_machine) ? R_ARM_RELATIVE
585
0
                     : (Elf32_Ehdr::EM_PPC  == e_machine) ? R_PPC_RELATIVE
586
0
                     : (Elf32_Ehdr::EM_MIPS == e_machine) ? R_MIPS_32
587
0
                     : 0;
588
0
        set_te32(&rel.r_info, ELF32_R_INFO(ELF32_R_SYM(r_info), r_type));
589
0
        if (is_asl) {
590
0
            u32_t r_offset = get_te32(&((Elf32_Rel const *)user_init_rp)->r_offset);
591
0
            set_te32(&rel.r_offset, asl_delta + r_offset);
592
0
        }
593
0
        fo->rewrite(&rel, sizeof(rel));
594
0
        fo->seek(0, SEEK_END);
595
596
        // Value of init_array[0] will be changed later.
597
        // See write() of 'cpr_entry' below.
598
0
    }
599
    // NOTE: PackLinuxElf::pack3  adjusted xct_off for the extra page
600
601
    // Then compressed gaps (including debuginfo.)
602
0
    for (unsigned k = 0; k < e_phnum; ++k) {
603
0
        Extent x;
604
0
        x.size = find_LOAD_gap(phdri, k, e_phnum);
605
0
        if (x.size) {
606
0
            x.offset = get_te32(&phdri[k].p_offset) +
607
0
                       get_te32(&phdri[k].p_filesz);
608
0
            packExtent(x, nullptr, fo);
609
0
        }
610
0
    }
611
    // write block end marker (uncompressed size 0)
612
0
    b_info hdr; memset(&hdr, 0, sizeof(hdr));
613
0
    set_le32(&hdr.sz_cpr, UPX_MAGIC_LE32);
614
0
    fo->write(&hdr, sizeof(hdr));
615
0
    total_out = fpad4(fo, total_out);
616
617
0
    if (0==xct_off) { // not shared library
618
0
        set_te32(&elfout.phdr[C_BASE].p_align, 0u - page_mask);
619
0
        elfout.phdr[C_BASE].p_paddr = elfout.phdr[C_BASE].p_vaddr;
620
0
        elfout.phdr[C_BASE].p_offset = 0;
621
0
        unsigned abrk = getbrk(phdri, e_phnum);
622
        // vbase handles ET_EXEC.  FIXME: pre-linking?
623
0
        unsigned vbase = get_te32(&elfout.phdr[C_BASE].p_vaddr);
624
0
        set_te32(&elfout.phdr[C_BASE].p_filesz, 0x1000);  // Linux kernel SIGSEGV if (0==.p_filesz)
625
0
        set_te32(&elfout.phdr[C_BASE].p_memsz, abrk - vbase);
626
0
        set_te32(&elfout.phdr[C_BASE].p_flags, Elf32_Phdr::PF_W|Elf32_Phdr::PF_R);
627
0
        set_te32(&elfout.phdr[C_TEXT].p_filesz, sz_pack2 + lsize);
628
0
        set_te32(&elfout.phdr[C_TEXT].p_memsz,  sz_pack2 + lsize);
629
0
        set_te32(&elfout.phdr[C_TEXT].p_vaddr, abrk= (page_mask & (~page_mask + abrk)));
630
0
        elfout.phdr[C_TEXT].p_paddr = elfout.phdr[C_TEXT].p_vaddr;
631
0
        set_te32(&elfout.ehdr.e_entry, abrk + get_te32(&elfout.ehdr.e_entry) - vbase);
632
0
    }
633
0
    if (0!=xct_off) { // shared library
634
0
        unsigned const cpr_entry = load_va + sz_pack2;
635
0
        set_te32(&file_image[user_init_off], cpr_entry);  // set the hook
636
637
0
        if (user_init_rp) { // decompressor needs hint for DT_INIT_ARRAY
638
0
            Elf32_Dyn *dynp = (Elf32_Dyn *)elf_find_dynptr(Elf32_Dyn::DT_NULL);
639
0
            set_te32(&dynp->d_val, (char *)user_init_rp - (char *)&file_image[0]);
640
0
        }
641
642
0
        Elf32_Phdr *const phdr0 = (Elf32_Phdr *)lowmem.subref(
643
0
                "bad e_phoff", e_phoff, e_phnum * sizeof(Elf32_Phdr));
644
0
        Elf32_Phdr *phdr = phdr0;
645
0
        upx_off_t off = fo->st_size();  // 64 bits
646
0
        so_slide = 0;
647
0
        for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
648
            // p_vaddr and p_paddr do not change!
649
0
            unsigned const len  = get_te32(&phdr->p_filesz);
650
0
            unsigned const ioff = get_te32(&phdri[j].p_offset);  // without asl_delta
651
0
            unsigned       align= get_te32(&phdr->p_align);
652
0
            unsigned const type = get_te32(&phdr->p_type);
653
0
            if (Elf32_Phdr::PT_INTERP==type) {
654
                // Rotate to highest position, so it can be lopped
655
                // by decrementing e_phnum.
656
0
                memcpy((unsigned char *)ibuf, phdr, sizeof(*phdr));  // extract
657
0
                memmove(phdr, 1+phdr, (e_phnum - (1+ j))*sizeof(*phdr));  // overlapping
658
0
                memcpy(&phdr[e_phnum - (1+ j)], (unsigned char *)ibuf, sizeof(*phdr));  // to top
659
0
                --phdr; --e_phnum;
660
0
                set_te16(&ehdri.e_phnum, e_phnum);
661
0
                set_te16(&((Elf32_Ehdr *)(unsigned char *)lowmem)->e_phnum, e_phnum);
662
0
                continue;
663
0
            }
664
0
            if (PT_LOAD == type) {
665
0
                if (!ioff) { // first PT_LOAD must contain everything written so far
666
0
                    set_te32(&phdr->p_filesz, sz_pack2 + lsize);  // is this correct?
667
0
                    set_te32(&phdr->p_memsz,  sz_pack2 + lsize);
668
                    // so_entry._start is in 1st PT_LOAD, and must be eXecutable
669
0
                    unsigned p_flags = get_te32(&phdr->p_flags);
670
0
                    set_te32(&phdr->p_flags, Elf32_Phdr::PF_X | p_flags);
671
0
                }
672
0
                else if ((xct_off - ioff) < len) { // Change length of compressed PT_LOAD.
673
0
                    set_te32(&phdr->p_filesz, total_out - ioff);  // FIXME  (sz_pack2 + lsize - ioff) ?
674
0
                    set_te32(&phdr->p_memsz,  total_out - ioff);
675
0
                    if (user_init_off < xct_off) { // MIPS puts PT_DYNAMIC here
676
                        // Allow for DT_INIT in a new [stolen] slot
677
0
                        unsigned off2 = user_init_off - sizeof(unsigned);
678
0
                        fo->seek(off2, SEEK_SET);
679
0
                        fo->rewrite(&file_image[off2], 2*sizeof(unsigned));
680
0
                    }
681
0
                }
682
0
                else if (xct_off < ioff) { // Slide subsequent PT_LOAD.
683
0
                    if ((1u<<12) < align
684
0
                    &&  (  Elf32_Ehdr::EM_386 == e_machine
685
0
                        || Elf32_Ehdr::EM_ARM == e_machine)  // FIXME: other $ARCH ?
686
0
                    ) {
687
0
                        align = 1u<<12;
688
0
                        set_te32(&phdr->p_align, align);
689
0
                    }
690
0
                    off = fpadN(fo, (-1 + align) & (ioff - off));
691
0
                    if (!so_slide) { // only once
692
0
                        so_slide = off - ((is_asl ? asl_delta : 0) + ioff);
693
                        //fprintf(stderr, "\nso_slide = %#x\n", (unsigned)so_slide);
694
                        //asl_slide_Shdrs();
695
0
                    }
696
0
                    set_te32(&phdr->p_offset, off);
697
0
                    fo->seek(off, SEEK_SET);
698
0
                    fo->write(&file_image[ioff], len);
699
0
                    off += len;
700
0
                    total_out = off;
701
702
0
                    if ((user_init_off - ioff) < len) {
703
0
                        fo->seek(user_init_off + so_slide, SEEK_SET);
704
0
                        unsigned word = cpr_entry;
705
0
                        set_te32(&word, cpr_entry);
706
0
                        fo->rewrite(&word, sizeof(word));
707
0
                        fo->seek(0, SEEK_END);
708
0
                    }
709
0
                }
710
0
                continue;  // all done with this PT_LOAD
711
0
            }
712
0
            if (xct_off < ioff) {
713
0
                set_te32(&phdr->p_offset, so_slide + (is_asl ? asl_delta : 0) + ioff);
714
0
            }
715
0
        }  // end each Phdr
716
717
0
        if (sec_arm_attr || is_asl) { // must update Shdr.sh_offset for so_slide
718
0
            Elf32_Shdr *shdr = shdri;
719
0
            for (unsigned j = 0; j < e_shnum; ++shdr, ++j) {
720
0
                unsigned sh_type = get_te32(&shdr->sh_type);
721
0
                if (Elf32_Shdr::SHT_REL == sh_type
722
0
                &&  n_jmp_slot  // FIXME  who sets this?
723
0
                &&  !strcmp(".rel.plt", get_te32(&shdr->sh_name) + shstrtab)) {
724
0
                    unsigned va = elf_unsigned_dynamic(Elf32_Dyn::DT_PLTGOT)
725
0
                        - (is_asl ? asl_delta : 0);
726
                    // Now use the old Phdrs (phdri)
727
0
                    Elf32_Phdr const *phva;
728
0
                    phva = elf_find_Phdr_for_va(va, phdri, e_phnum);
729
0
                    unsigned old_off = (va - get_te32(&phva->p_vaddr))
730
0
                        + get_te32(&phva->p_offset);
731
732
                    // Now use the new Phdrs (phdr0)
733
0
                    va += (is_asl ? asl_delta : 0);
734
0
                    phva = elf_find_Phdr_for_va(va, phdr0, e_phnum);
735
0
                    unsigned new_off = (va - get_te32(&phva->p_vaddr))
736
0
                        + get_te32(&phva->p_offset);
737
738
0
                    if (fo && n_jmp_slot) {
739
0
                        fo->seek(new_off, SEEK_SET);
740
0
                        fo->rewrite(&file_image[old_off], n_jmp_slot * 4);
741
0
                    }
742
0
                }
743
0
                if (j && shdr->sh_addr == 0
744
0
                &&  get_te32(&shdr->sh_offset) < xct_off) {
745
                    // Try to be nice by sliding; but still fails if compressed.
746
                    // So don't do it unless appending plain text of shstrtab.
747
0
                    unsigned sh_off = get_te32(&shdr->sh_offset);
748
0
                    if (xct_off < sh_off) {
749
0
                        slide_sh_offset(shdr);
750
0
                    }
751
0
                }
752
0
            }
753
            // Maybe: append plain text of shstrtab strings?
754
0
            fo->seek(total_out, SEEK_SET);
755
0
            if (xct_off < e_shoff) {
756
0
                set_te32(&((Elf32_Ehdr *)lowmem.getVoidPtr())->e_shoff, total_out);
757
0
                if (fo) {
758
0
                    fo->write(shdri, e_shnum * sizeof(*shdr));
759
0
                    total_out += e_shnum * sizeof(*shdr);
760
0
                }
761
0
            }
762
0
        }
763
0
        else { // output has no Shdr
764
0
            ehdri.e_shnum = 0;
765
0
            ehdri.e_shoff = 0;
766
0
            ehdri.e_shstrndx = 0;
767
0
        }
768
0
    }
769
0
    return total_out;
770
0
}
771
772
off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft)
773
0
{
774
0
    if (!overlay_offset) {
775
0
        overlay_offset = sizeof(linfo) + (xct_off ? xct_off : sz_elf_hdrs);
776
0
    }
777
778
0
    total_out = super::pack3(fo, ft);  // loader follows compressed PT_LOADs
779
0
    if (fo && xct_off && Elf64_Dyn::DT_INIT != upx_dt_init) { // patch user_init_rp
780
0
        fo->seek((char *)user_init_rp - (char *)&file_image[0], SEEK_SET);
781
0
        Elf64_Rela rela(*(Elf64_Rela const *)user_init_rp);
782
        //u64_t r_info = get_te64(&((Elf64_Rela const *)user_init_rp)->r_info);
783
0
        u32_t r_type = (Elf64_Ehdr::EM_AARCH64 == e_machine) ? R_AARCH64_RELATIVE
784
0
                     : (Elf64_Ehdr::EM_X86_64  == e_machine) ? R_X86_64_RELATIVE
785
0
                     : (Elf64_Ehdr::EM_PPC64   == e_machine) ? R_PPC64_RELATIVE
786
0
                     : 0;
787
0
        set_te64(&rela.r_info, ELF64_R_INFO(0 /*ELF64_R_SYM(r_info)*/, r_type));
788
0
        set_te64(&rela.r_addend, sz_pack2);  // entry to decompressor
789
0
        fo->rewrite(&rela, sizeof(rela));
790
791
0
        fo->seek(0, SEEK_END);
792
0
    }
793
    // NOTE: PackLinuxElf::pack3  adjusted xct_off for the extra page
794
795
    // Then compressed gaps (including debuginfo.)
796
0
    for (unsigned k = 0; k < e_phnum; ++k) {
797
0
        Extent x;
798
0
        x.size = find_LOAD_gap(phdri, k, e_phnum);
799
0
        if (x.size) {
800
0
            x.offset = get_te64(&phdri[k].p_offset) +
801
0
                       get_te64(&phdri[k].p_filesz);
802
0
            packExtent(x, nullptr, fo);
803
0
        }
804
0
    }
805
    // write block end marker (uncompressed size 0)
806
0
    b_info hdr; memset(&hdr, 0, sizeof(hdr));
807
0
    set_le32(&hdr.sz_cpr, UPX_MAGIC_LE32);
808
0
    fo->write(&hdr, sizeof(hdr));
809
0
    total_out = fpad4(fo, total_out);
810
811
0
    if (0==xct_off) { // not shared library
812
0
        set_te64(&elfout.phdr[C_BASE].p_align, ((u64_t)0) - page_mask);
813
0
        elfout.phdr[C_BASE].p_paddr = elfout.phdr[C_BASE].p_vaddr;
814
0
        elfout.phdr[C_BASE].p_offset = 0;
815
0
        u64_t abrk = getbrk(phdri, e_phnum);
816
        // vbase handles ET_EXEC.  FIXME: pre-linking?
817
0
        u64_t const vbase = get_te64(&elfout.phdr[C_BASE].p_vaddr);
818
0
        set_te64(&elfout.phdr[C_BASE].p_filesz, 0x1000);  // Linux kernel SIGSEGV if (0==.p_filesz)
819
0
        set_te64(&elfout.phdr[C_BASE].p_memsz, abrk - vbase);
820
0
        set_te32(&elfout.phdr[C_BASE].p_flags, Elf64_Phdr::PF_W|Elf64_Phdr::PF_R);
821
0
        set_te64(&elfout.phdr[C_TEXT].p_filesz, sz_pack2 + lsize);
822
0
        set_te64(&elfout.phdr[C_TEXT].p_memsz,  sz_pack2 + lsize);
823
0
        set_te64(&elfout.phdr[C_TEXT].p_vaddr, abrk= (page_mask & (~page_mask + abrk)));
824
0
        elfout.phdr[C_TEXT].p_paddr = elfout.phdr[C_TEXT].p_vaddr;
825
0
        set_te64(&elfout.ehdr.e_entry, abrk + get_te64(&elfout.ehdr.e_entry) - vbase);
826
0
    }
827
0
    if (0!=xct_off) { // shared library
828
0
        u64_t const cpr_entry = load_va + sz_pack2;
829
0
        set_te64(&file_image[user_init_off], cpr_entry);  // set the hook
830
831
0
        if (user_init_rp) { // decompressor needs hint for DT_INIT_ARRAY
832
0
            Elf64_Dyn *dynp = (Elf64_Dyn *)elf_find_dynptr(Elf64_Dyn::DT_NULL);
833
0
            set_te64(&dynp->d_val, (char *)user_init_rp - (char *)&file_image[0]);
834
0
        }
835
836
0
        Elf64_Phdr *const phdr0 = (Elf64_Phdr *)lowmem.subref(
837
0
                "bad e_phoff", e_phoff, e_phnum * sizeof(Elf64_Phdr));
838
0
        Elf64_Phdr *phdr = phdr0;
839
0
        upx_off_t off = fo->st_size();  // 64 bits
840
0
        so_slide = 0;
841
0
        for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
842
            // p_vaddr and p_paddr do not change!
843
0
            u64_t const len  = get_te64(&phdr->p_filesz);
844
0
            u64_t const ioff = get_te64(&phdri[j].p_offset);  // without asl_delta
845
0
            u64_t       align= get_te64(&phdr->p_align);
846
0
            unsigned const type = get_te32(&phdr->p_type);
847
0
            if (Elf64_Phdr::PT_INTERP==type) {
848
                // Rotate to highest position, so it can be lopped
849
                // by decrementing e_phnum.
850
0
                memcpy((unsigned char *)ibuf, phdr, sizeof(*phdr));  // extract
851
0
                memmove(phdr, 1+phdr, (e_phnum - (1+ j))*sizeof(*phdr));  // overlapping
852
0
                memcpy(&phdr[e_phnum - (1+ j)], (unsigned char *)ibuf, sizeof(*phdr));  // to top
853
0
                --phdr; --e_phnum;
854
0
                set_te16(&ehdri.e_phnum, e_phnum);
855
0
                set_te16(&((Elf64_Ehdr *)(unsigned char *)lowmem)->e_phnum, e_phnum);
856
0
                continue;
857
0
            }
858
0
            if (PT_LOAD == type) {
859
0
                if (!ioff) { // first PT_LOAD must contain everything written so far
860
0
                    set_te64(&phdr->p_filesz, sz_pack2 + lsize);  // is this correct?
861
0
                    set_te64(&phdr->p_memsz,  sz_pack2 + lsize);
862
0
                }
863
0
                else if ((xct_off - ioff) < len) { // Change length of compressed PT_LOAD.
864
0
                    set_te64(&phdr->p_filesz, total_out - ioff);  // FIXME  (sz_pack2 + lsize - ioff) ?
865
0
                    set_te64(&phdr->p_memsz,  total_out - ioff);
866
0
                    if (user_init_off < xct_off) { // MIPS puts PT_DYNAMIC here
867
                        // Allow for DT_INIT in a new [stolen] slot
868
0
                        unsigned off2 = user_init_off - sizeof(u64_t);
869
0
                        fo->seek(off2, SEEK_SET);
870
0
                        fo->rewrite(&file_image[off2], 2*sizeof(u64_t));
871
0
                    }
872
0
                }
873
0
                else if (xct_off < ioff) { // Slide subsequent PT_LOAD.
874
0
                    if ((1u<<12) < align
875
0
                    &&  Elf64_Ehdr::EM_X86_64 == e_machine  // FIXME: other $ARCH ?
876
0
                    ) {
877
0
                        align = 1u<<12;
878
0
                        set_te64(&phdr->p_align, align);
879
0
                    }
880
0
                    off = fpadN(fo, (-1 + align) & (ioff - off));
881
0
                    if (!so_slide) { // only once
882
0
                        so_slide = off - ((is_asl ? asl_delta : 0) + ioff);
883
                        //fprintf(stderr, "\nso_slide = %#x\n", (unsigned)so_slide);
884
                        //asl_slide_Shdrs();
885
0
                    }
886
0
                    set_te64(&phdr->p_offset, off);
887
0
                    fo->seek(off, SEEK_SET);
888
0
                    fo->write(&file_image[ioff], len);
889
0
                    off += len;
890
0
                    total_out = off;
891
892
0
                    if ((user_init_off - ioff) < len) {
893
0
                        fo->seek(user_init_off + so_slide, SEEK_SET);
894
0
                        u64_t word = cpr_entry;
895
0
                        set_te64(&word, cpr_entry);
896
0
                        fo->rewrite(&word, sizeof(word));
897
0
                        fo->seek(0, SEEK_END);
898
0
                    }
899
0
                }
900
0
                continue;  // all done with this PT_LOAD
901
0
            }
902
0
            if (xct_off < ioff) {
903
0
                set_te64(&phdr->p_offset, so_slide + (is_asl ? asl_delta : 0) + ioff);
904
0
            }
905
0
        }  // end each Phdr
906
907
0
        if (sec_arm_attr || is_asl) { // must update Shdr.sh_offset for so_slide
908
            // Update {DYNAMIC}.sh_offset by so_slide.
909
0
            Elf64_Shdr *shdr = (Elf64_Shdr *)lowmem.subref(  // FIXME: use shdri ?
910
0
                    "bad e_shoff", xct_off - (is_asl ? asl_delta : 0), e_shnum * sizeof(Elf64_Shdr));
911
0
            for (unsigned j = 0; j < e_shnum; ++shdr, ++j) {
912
0
                unsigned sh_type = get_te32(&shdr->sh_type);
913
0
                unsigned sh_flags = get_te64(&shdr->sh_flags);  // all SHF_ are 32-bit anyway
914
0
                unsigned sh_offset = get_te64(&shdr->sh_offset); // already asl_delta
915
0
                if (Elf64_Shdr::SHF_ALLOC & sh_flags
916
0
                &&  Elf64_Shdr::SHF_WRITE & sh_flags
917
0
                &&  xct_off < sh_offset) {
918
0
                    set_te64(&shdr->sh_offset, so_slide + sh_offset);
919
0
                }
920
0
                if (Elf64_Shdr::SHT_RELA == sh_type
921
0
                &&  n_jmp_slot  // FIXME: does this apply to SHT_RELA ?
922
0
                &&  !strcmp(".rel.plt", get_te32(&shdr->sh_name) + shstrtab)) {
923
0
                    u64_t va = elf_unsigned_dynamic(Elf64_Dyn::DT_PLTGOT) - (is_asl ? asl_delta : 0);
924
                    // Now use the old Phdrs (phdri)
925
0
                    Elf64_Phdr const *phva;
926
0
                    phva = elf_find_Phdr_for_va(va, phdri, e_phnum);
927
0
                    u64_t old_off = (va - get_te64(&phva->p_vaddr))
928
0
                        + get_te64(&phva->p_offset);
929
930
                    // Now use the new Phdrs (phdr0)
931
0
                    va += (is_asl ? asl_delta : 0);
932
0
                    phva = elf_find_Phdr_for_va(va, phdr0, e_phnum);
933
0
                    u64_t new_off = (va - get_te64(&phva->p_vaddr))
934
0
                        + get_te64(&phva->p_offset);
935
936
0
                    if (fo && n_jmp_slot) {
937
0
                        fo->seek(new_off, SEEK_SET);
938
0
                        fo->rewrite(&file_image[old_off], n_jmp_slot * 8);
939
0
                    }
940
0
                }
941
0
                if (j && shdr->sh_addr == 0
942
0
                &&  get_te64_32(&shdr->sh_offset) < xct_off) { // UPX_RSIZE_MAX_MEM protects us
943
                    // Try to be nice by sliding; but still fails if compressed.
944
                    // So don't do it unless appending plain text of shstrtab.
945
0
                    unsigned sh_off = get_te64_32(&shdr->sh_offset);  // UPX_RSIZE_MAX_MEM protects us
946
0
                    if (xct_off < sh_off) {
947
0
                        set_te64(&shdr->sh_offset, sh_off + so_slide);
948
0
                    }
949
0
                }
950
0
            }
951
            // Maybe: append plain text of shstrtab strings?
952
0
            fo->seek(total_out, SEEK_SET);
953
0
            if (xct_off < e_shoff) {
954
0
                set_te32(&((Elf32_Ehdr *)lowmem.getVoidPtr())->e_shoff, total_out);
955
0
                if (fo) {
956
0
                    fo->write(shdri, e_shnum * sizeof(*shdr));
957
0
                    total_out += e_shnum * sizeof(*shdr);
958
0
                }
959
0
            }
960
0
        }
961
0
        else { // output has no Shdr
962
0
            ehdri.e_shnum = 0;
963
0
            ehdri.e_shoff = 0;
964
0
            ehdri.e_shstrndx = 0;
965
0
        }
966
0
    }
967
0
    return total_out;
968
0
}
969
970
void
971
PackLinuxElf::addStubEntrySections(Filter const *, unsigned m_decompr)
972
0
{
973
0
    (void)m_decompr;  // FIXME
974
0
    if (hasLoaderSection("ELFMAINX")) {
975
0
        addLoader("ELFMAINX", nullptr);
976
0
    }
977
0
    if (hasLoaderSection("ELFMAINXu")) {
978
            // brk() trouble if static
979
0
        addLoader("ELFMAINXu", nullptr);
980
0
    }
981
0
    addLoader(
982
0
        ( M_IS_NRV2E(ph_forced_method(ph.method)) ? "NRV_HEAD,NRV2E,NRV_TAIL"
983
0
        : M_IS_NRV2D(ph_forced_method(ph.method)) ? "NRV_HEAD,NRV2D,NRV_TAIL"
984
0
        : M_IS_NRV2B(ph_forced_method(ph.method)) ? "NRV_HEAD,NRV2B,NRV_TAIL"
985
0
        : M_IS_LZMA(ph_forced_method(ph.method))  ? "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"
986
0
        : nullptr), nullptr);
987
0
    if (hasLoaderSection("CFLUSH"))
988
0
        addLoader("CFLUSH");
989
0
    addLoader("ELFMAINY,IDENTSTR", nullptr);
990
0
    if (hasLoaderSection("ELFMAINZe")) { // ppc64 big-endian only
991
0
        addLoader("ELFMAINZe", nullptr);
992
0
    }
993
0
    addLoader("+40,ELFMAINZ", nullptr);
994
0
    if (hasLoaderSection("ANDMAJNZ")) { // Android trouble with args to DT_INIT
995
0
        if (is_asl) {
996
0
            addLoader("ANDMAJNZ", nullptr);  // constant PAGE_SIZE
997
0
        }
998
0
        else {
999
0
            addLoader("ELFMAJNZ", nullptr);  // PAGE_SIZE from AT_PAGESZ
1000
0
        }
1001
0
        addLoader("ELFMAKNZ", nullptr);
1002
0
    }
1003
0
    if (hasLoaderSection("ELFMAINZu")) {
1004
0
        addLoader("ELFMAINZu", nullptr);
1005
0
    }
1006
0
    addLoader("FOLDEXEC", nullptr);
1007
0
}
1008
1009
1010
void PackLinuxElf::defineSymbols(Filter const *)
1011
0
{
1012
0
    linker->defineSymbol("O_BINFO", o_binfo
1013
0
       | ((!!opt->o_unix.is_ptinterp)     << 0)
1014
0
       | ((!!opt->o_unix.unmap_all_pages) << 1) );
1015
0
}
1016
1017
void PackLinuxElf32::defineSymbols(Filter const *ft)
1018
0
{
1019
0
    PackLinuxElf::defineSymbols(ft);
1020
0
}
1021
1022
void PackLinuxElf64::defineSymbols(Filter const *ft)
1023
0
{
1024
0
    PackLinuxElf::defineSymbols(ft);
1025
0
}
1026
1027
PackLinuxElf32::PackLinuxElf32(InputFile *f)
1028
172k
    : super(f), phdri(nullptr), shdri(nullptr),
1029
172k
    n_phdrx(0), sz_phdrx(0),
1030
172k
    page_mask(~0u<<lg2_page),
1031
172k
    dynseg(nullptr), hashtab(nullptr), hashend(nullptr),
1032
172k
                     gashtab(nullptr), gashend(nullptr), dynsym(nullptr),
1033
172k
    jni_onload_sym(nullptr),
1034
172k
    sec_strndx(nullptr), sec_dynsym(nullptr), sec_dynstr(nullptr)
1035
172k
    , sec_arm_attr(nullptr)
1036
172k
{
1037
172k
    memset(&ehdri, 0, sizeof(ehdri));
1038
172k
    n_jmp_slot = 0;
1039
172k
    if (f) {
1040
172k
        f->seek(0, SEEK_SET);
1041
172k
        f->readx(&ehdri, sizeof(ehdri));
1042
172k
    }
1043
172k
}
1044
1045
PackLinuxElf32::~PackLinuxElf32()
1046
{
1047
}
1048
1049
void PackLinuxElf32::add_phdrx(Elf32_Phdr const *phdr)
1050
0
{
1051
0
    if (END_PHDRX <= n_phdrx) {
1052
0
        throwCantPack("too many Phdr %u", (unsigned)(phdr - phdri));
1053
0
    }
1054
0
    phdrx[n_phdrx++] = phdr;
1055
0
}
1056
1057
PackLinuxElf64::PackLinuxElf64(InputFile *f)
1058
69.1k
    : super(f), phdri(nullptr), shdri(nullptr),
1059
69.1k
    n_phdrx(0), sz_phdrx(0),
1060
69.1k
    page_mask(~0ull<<lg2_page),
1061
69.1k
    dynseg(nullptr), hashtab(nullptr), hashend(nullptr),
1062
69.1k
                     gashtab(nullptr), gashend(nullptr), dynsym(nullptr),
1063
69.1k
    jni_onload_sym(nullptr),
1064
69.1k
    sec_strndx(nullptr), sec_dynsym(nullptr), sec_dynstr(nullptr)
1065
69.1k
    , sec_arm_attr(nullptr)
1066
69.1k
{
1067
69.1k
    memset(&ehdri, 0, sizeof(ehdri));
1068
69.1k
    n_jmp_slot = 0;
1069
69.1k
    if (f) {
1070
69.1k
        f->seek(0, SEEK_SET);
1071
69.1k
        f->readx(&ehdri, sizeof(ehdri));
1072
69.1k
    }
1073
69.1k
}
1074
1075
PackLinuxElf64::~PackLinuxElf64()
1076
{
1077
}
1078
1079
void PackLinuxElf64::add_phdrx(Elf64_Phdr const *phdr)
1080
0
{
1081
0
    if (END_PHDRX <= n_phdrx) {
1082
0
        throwCantPack("too many Phdr %u", (unsigned)(phdr - phdri));
1083
0
    }
1084
0
    phdrx[n_phdrx++] = phdr;
1085
0
}
1086
1087
// FIXME: should be templated with PackLinuxElf32help1
1088
void
1089
PackLinuxElf64::PackLinuxElf64help1(InputFile *f)
1090
69.4k
{
1091
69.4k
    e_type  = get_te16(&ehdri.e_type);
1092
69.4k
    e_phnum = get_te16(&ehdri.e_phnum);
1093
69.4k
    e_shnum = get_te16(&ehdri.e_shnum);
1094
69.4k
    unsigned const e_phentsize = get_te16(&ehdri.e_phentsize);
1095
69.4k
    if (memcmp((char const *)&ehdri, "\x7f\x45\x4c\x46", 4)  // "\177ELF"
1096
32.2k
    || ehdri.e_ident[Elf64_Ehdr::EI_CLASS]!=Elf64_Ehdr::ELFCLASS64
1097
17.6k
    || sizeof(Elf64_Phdr) != e_phentsize
1098
7.97k
    || (Elf64_Ehdr::ELFDATA2MSB == ehdri.e_ident[Elf64_Ehdr::EI_DATA]
1099
1.96k
            && &N_BELE_RTP::be_policy != bele)
1100
7.95k
    || (Elf64_Ehdr::ELFDATA2LSB == ehdri.e_ident[Elf64_Ehdr::EI_DATA]
1101
61.4k
            && &N_BELE_RTP::le_policy != bele)) {
1102
61.4k
        e_phoff = 0;
1103
61.4k
        e_shoff = 0;
1104
61.4k
        sz_phdrs = 0;
1105
61.4k
        return;
1106
61.4k
    }
1107
7.94k
    if (0==e_phnum) throwCantUnpack("0==e_phnum");
1108
7.94k
    e_phoff = get_te64(&ehdri.e_phoff);
1109
7.94k
    upx_uint64_t const last_Phdr = e_phoff + e_phnum * sizeof(Elf64_Phdr);
1110
7.94k
    if (last_Phdr < e_phoff  // wrap-around
1111
7.91k
    ||  e_phoff != sizeof(Elf64_Ehdr)  // must be contiguous
1112
7.61k
    ||  (unsigned long)file_size < last_Phdr) {
1113
347
        throwCantUnpack("bad e_phoff %p", (void *)e_phoff);
1114
347
    }
1115
7.59k
    e_shoff = get_te64(&ehdri.e_shoff);
1116
7.59k
    upx_uint64_t const last_Shdr = e_shoff + e_shnum * sizeof(Elf64_Shdr);
1117
7.59k
    if (last_Shdr < e_shoff  // wrap-around
1118
7.38k
    ||  (e_shnum && e_shoff < last_Phdr)
1119
7.08k
    ||  (unsigned long)file_size < last_Shdr) {
1120
5.99k
        if (opt->cmd == CMD_COMPRESS) {
1121
0
            throwCantUnpack("bad e_shoff %p", (void *)e_shoff);
1122
0
        }
1123
5.99k
    }
1124
7.59k
    sz_phdrs = e_phnum * e_phentsize;
1125
7.59k
    sz_elf_hdrs = sz_phdrs + sizeof(Elf64_Ehdr) +
1126
7.59k
        n_phdrx * sizeof(Elf32_Phdr);  // phdrx bodies later: ::generateElfHdr
1127
1128
7.59k
    if (f && Elf64_Ehdr::ET_DYN!=e_type) {
1129
2.33k
        unsigned const len = file_size;  // (sz_phdrs + e_phoff) except --preserve-build-id
1130
2.33k
        alloc_file_image(file_image, len);
1131
2.33k
        f->seek(0, SEEK_SET);
1132
2.33k
        f->readx(file_image, len);
1133
2.33k
        phdri= (Elf64_Phdr       *)(e_phoff + file_image);  // do not free() !!
1134
2.33k
    }
1135
7.59k
    if (f && Elf64_Ehdr::ET_DYN==e_type) {
1136
        // The DT_SYMTAB has no designated length.  Read the whole file.
1137
5.26k
        alloc_file_image(file_image, file_size);
1138
5.26k
        f->seek(0, SEEK_SET);
1139
5.26k
        f->readx(file_image, file_size);
1140
5.26k
        phdri= (file_size <= (unsigned)e_phoff) ? nullptr : (Elf64_Phdr *)(e_phoff + file_image);  // do not free() !!
1141
5.26k
        if (!(opt->cmd == CMD_COMPRESS && e_shoff < (upx_uint64_t)file_size && mb_shdr.getSize() == 0)) {
1142
5.26k
            shdri = nullptr;
1143
5.26k
        }
1144
0
        else if (e_shnum && e_shoff && ehdri.e_shentsize) {
1145
0
            fi->seek(e_shoff, SEEK_SET);
1146
0
            mb_shdr.alloc(   sizeof(Elf64_Shdr) * e_shnum);
1147
0
            shdri = (Elf64_Shdr *)mb_shdr.getVoidPtr();
1148
0
            fi->readx(shdri, sizeof(Elf64_Shdr) * e_shnum);
1149
0
        }
1150
0
        else {
1151
0
            shdri = nullptr;
1152
0
        }
1153
5.26k
        sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
1154
5.26k
        if (sec_dynsym) {
1155
0
            unsigned t = get_te32(&sec_dynsym->sh_link);
1156
0
            if (e_shnum <= t)
1157
0
                throwCantPack("bad dynsym->sh_link");
1158
0
            sec_dynstr = &shdri[t];
1159
0
        }
1160
1161
5.26k
        Elf64_Phdr const *phdr= phdri;
1162
37.7k
        for (int j = e_phnum; --j>=0; ++phdr)
1163
32.4k
        if (Elf64_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
1164
4.17k
            upx_uint64_t offset = check_pt_dynamic(phdr);
1165
4.17k
            dynseg= (Elf64_Dyn *)(offset + file_image);
1166
4.17k
            invert_pt_dynamic(dynseg,
1167
4.17k
                umin(get_te64(&phdr->p_filesz), file_size_u - offset));
1168
4.17k
        }
1169
28.2k
        else if (is_LOAD(phdr)) {
1170
4.85k
            check_pt_load(phdr);
1171
4.85k
        }
1172
        // elf_find_dynamic() returns 0 if 0==dynseg.
1173
5.26k
        dynstr =          (char const *)elf_find_dynamic(Elf64_Dyn::DT_STRTAB);
1174
5.26k
        dynsym = (Elf64_Sym /*const*/ *)elf_find_dynamic(Elf64_Dyn::DT_SYMTAB);
1175
5.26k
        gashtab =     (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_GNU_HASH);
1176
5.26k
        hashtab =     (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_HASH);
1177
5.26k
        if (3& ((upx_uintptr_t)dynsym | (upx_uintptr_t)gashtab | (upx_uintptr_t)hashtab)) {
1178
16
            throwCantPack("unaligned DT_SYMTAB, DT_GNU_HASH, or DT_HASH/n");
1179
16
        }
1180
5.25k
        jni_onload_sym = elf_lookup("JNI_OnLoad");
1181
5.25k
        if (jni_onload_sym) {
1182
10
            jni_onload_va = get_te64(&jni_onload_sym->st_value);
1183
10
            jni_onload_va = 0;  // FIXME not understood; need example
1184
10
        }
1185
5.25k
    }
1186
7.59k
}
1187
1188
Linker* PackLinuxElf64amd::newLinker() const
1189
0
{
1190
0
    return new ElfLinkerAMD64;
1191
0
}
1192
1193
Linker* PackLinuxElf64arm::newLinker() const
1194
0
{
1195
0
    return new ElfLinkerArm64LE;
1196
0
}
1197
1198
int const *
1199
PackLinuxElf::getCompressionMethods(int method, int level) const
1200
0
{
1201
    // No real dependency on LE32.
1202
0
    return Packer::getDefaultCompressionMethods_le32(method, level);
1203
0
}
1204
1205
int const *
1206
PackLinuxElf32armLe::getCompressionMethods(int method, int level) const
1207
0
{
1208
0
    return Packer::getDefaultCompressionMethods_8(method, level);
1209
0
}
1210
1211
int const *
1212
PackLinuxElf32armBe::getCompressionMethods(int method, int level) const
1213
0
{
1214
0
    return Packer::getDefaultCompressionMethods_8(method, level);
1215
0
}
1216
1217
int const *
1218
PackLinuxElf32ppc::getFilters() const
1219
0
{
1220
0
    static const int filters[] = {
1221
0
        0xd0,
1222
0
    FT_END };
1223
0
    return filters;
1224
0
}
1225
1226
int const *
1227
PackLinuxElf64ppcle::getFilters() const
1228
0
{
1229
0
    static const int filters[] = {
1230
0
        0xd0,
1231
0
    FT_END };
1232
0
    return filters;
1233
0
}
1234
1235
int const *
1236
PackLinuxElf64ppc::getFilters() const
1237
0
{
1238
0
    static const int filters[] = {
1239
0
        0xd0,
1240
0
    FT_END };
1241
0
    return filters;
1242
0
}
1243
1244
int const *
1245
PackLinuxElf64amd::getFilters() const
1246
0
{
1247
0
    static const int filters[] = {
1248
0
        0x49,
1249
0
    FT_END };
1250
0
    return filters;
1251
0
}
1252
1253
int const *
1254
PackLinuxElf64arm::getFilters() const
1255
0
{
1256
0
    static const int filters[] = {
1257
0
        0x52,
1258
0
    FT_END };
1259
0
    return filters;
1260
0
}
1261
1262
void PackLinuxElf32::patchLoader()
1263
0
{
1264
0
}
1265
1266
void PackLinuxElf64::patchLoader()
1267
0
{
1268
0
}
1269
1270
void PackLinuxElf32::ARM_updateLoader(OutputFile * /*fo*/)
1271
0
{
1272
0
    set_te32(&elfout.ehdr.e_entry, sz_pack2 +
1273
0
        linker->getSymbolOffset("_start") +
1274
0
        get_te32(&elfout.phdr[C_TEXT].p_vaddr));
1275
0
}
1276
1277
void PackLinuxElf32armLe::updateLoader(OutputFile *fo)
1278
0
{
1279
0
    ARM_updateLoader(fo);
1280
0
}
1281
1282
void PackLinuxElf32armBe::updateLoader(OutputFile *fo)
1283
0
{
1284
0
    ARM_updateLoader(fo);
1285
0
}
1286
1287
void PackLinuxElf32mipsel::updateLoader(OutputFile *fo)
1288
0
{
1289
0
    ARM_updateLoader(fo);  // not ARM specific; (no 32-bit immediates)
1290
0
}
1291
1292
void PackLinuxElf32mipseb::updateLoader(OutputFile *fo)
1293
0
{
1294
0
    ARM_updateLoader(fo);  // not ARM specific; (no 32-bit immediates)
1295
0
}
1296
1297
void PackLinuxElf32::updateLoader(OutputFile * /*fo*/)
1298
0
{
1299
0
    unsigned start = linker->getSymbolOffset("_start");
1300
0
    unsigned vbase = get_te32(&elfout.phdr[C_TEXT].p_vaddr);
1301
0
    set_te32(&elfout.ehdr.e_entry, start + sz_pack2 + vbase);
1302
0
}
1303
1304
void PackLinuxElf64::updateLoader(OutputFile * /*fo*/)
1305
0
{
1306
0
    if (xct_off) {
1307
0
        return;  // FIXME elfout has no values at all
1308
0
    }
1309
0
    upx_uint64_t const vbase = get_te64(&elfout.phdr[C_TEXT].p_vaddr);
1310
0
    unsigned start = linker->getSymbolOffset("_start");
1311
1312
0
    if (get_te16(&elfout.ehdr.e_machine)==Elf64_Ehdr::EM_PPC64
1313
0
    &&  elfout.ehdr.e_ident[Elf64_Ehdr::EI_DATA]==Elf64_Ehdr::ELFDATA2MSB) {
1314
0
        unsigned descr = linker->getSymbolOffset("entry_descr");
1315
1316
        // External relocation of PPC64 function descriptor.
1317
0
        upx_uint64_t dot_entry = start + sz_pack2 + vbase;
1318
0
        upx_byte *p = getLoader();
1319
1320
0
        set_te64(&p[descr], dot_entry);
1321
        // Kernel 3.16.0 (2017-09-19) uses start, not descr
1322
0
        set_te64(&elfout.ehdr.e_entry, start + sz_pack2 + vbase);
1323
0
    }
1324
0
    else {
1325
0
        set_te64(&elfout.ehdr.e_entry, start + sz_pack2 + vbase);
1326
0
    }
1327
0
}
1328
1329
PackLinuxElf32ppc::PackLinuxElf32ppc(InputFile *f)
1330
16.4k
    : super(f)
1331
16.4k
{
1332
16.4k
    e_machine = Elf32_Ehdr::EM_PPC;
1333
16.4k
    ei_class  = Elf32_Ehdr::ELFCLASS32;
1334
16.4k
    ei_data   = Elf32_Ehdr::ELFDATA2MSB;
1335
16.4k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
1336
16.4k
}
1337
1338
PackLinuxElf32ppc::~PackLinuxElf32ppc()
1339
16.4k
{
1340
16.4k
}
1341
1342
Linker* PackLinuxElf32ppc::newLinker() const
1343
0
{
1344
0
    return new ElfLinkerPpc32;
1345
0
}
1346
1347
PackLinuxElf64ppcle::PackLinuxElf64ppcle(InputFile *f)
1348
14.5k
    : super(f), lg2_page(16), page_size(1u<<lg2_page)
1349
14.5k
{
1350
14.5k
    e_machine = Elf64_Ehdr::EM_PPC64;
1351
14.5k
    ei_class  = Elf64_Ehdr::ELFCLASS64;
1352
14.5k
    ei_data   = Elf64_Ehdr::ELFDATA2LSB;
1353
14.5k
    ei_osabi  = Elf64_Ehdr::ELFOSABI_LINUX;
1354
14.5k
}
1355
1356
PackLinuxElf64ppc::PackLinuxElf64ppc(InputFile *f)
1357
16.3k
    : super(f), lg2_page(16), page_size(1u<<lg2_page)
1358
16.3k
{
1359
16.3k
    e_machine = Elf64_Ehdr::EM_PPC64;
1360
16.3k
    ei_class  = Elf64_Ehdr::ELFCLASS64;
1361
16.3k
    ei_data   = Elf64_Ehdr::ELFDATA2MSB;
1362
16.3k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
1363
16.3k
}
1364
1365
PackLinuxElf64ppcle::~PackLinuxElf64ppcle()
1366
14.5k
{
1367
14.5k
}
1368
1369
PackLinuxElf64ppc::~PackLinuxElf64ppc()
1370
14.5k
{
1371
14.5k
}
1372
1373
Linker* PackLinuxElf64ppcle::newLinker() const
1374
0
{
1375
0
    return new ElfLinkerPpc64le;
1376
0
}
1377
1378
Linker* PackLinuxElf64ppc::newLinker() const
1379
0
{
1380
0
    return new ElfLinkerPpc64;
1381
0
}
1382
1383
PackLinuxElf64amd::PackLinuxElf64amd(InputFile *f)
1384
21.6k
    : super(f)
1385
21.6k
{
1386
    // Why did PackLinuxElf64Le set lg2_page = 16 ?
1387
    // It causes trouble for check_pt_dynamic() from canPack().
1388
21.6k
    lg2_page = 12;  page_size = 1u<<lg2_page;
1389
21.6k
    e_machine = Elf64_Ehdr::EM_X86_64;
1390
21.6k
    ei_class = Elf64_Ehdr::ELFCLASS64;
1391
21.6k
    ei_data = Elf64_Ehdr::ELFDATA2LSB;
1392
21.6k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
1393
21.6k
}
1394
1395
PackLinuxElf64arm::PackLinuxElf64arm(InputFile *f)
1396
16.6k
    : super(f)
1397
16.6k
{
1398
16.6k
    e_machine = Elf64_Ehdr::EM_AARCH64;
1399
16.6k
    ei_class = Elf64_Ehdr::ELFCLASS64;
1400
16.6k
    ei_data = Elf64_Ehdr::ELFDATA2LSB;
1401
16.6k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
1402
16.6k
}
1403
1404
PackLinuxElf64amd::~PackLinuxElf64amd()
1405
19.5k
{
1406
19.5k
}
1407
1408
PackLinuxElf64arm::~PackLinuxElf64arm()
1409
16.6k
{
1410
16.6k
}
1411
1412
void PackLinuxElf32x86::addStubEntrySections(Filter const *ft, unsigned m_decompr)
1413
0
{
1414
0
    (void)m_decompr;  // FIXME
1415
0
    int const n_mru = ft->n_mru;  // FIXME: belongs to filter? packerf?
1416
1417
// Rely on "+80CXXXX" [etc] in getDecompressorSections() packer_c.cpp */
1418
//    // Here is a quick summary of the format of the output file:
1419
//    linker->setLoaderAlignOffset(
1420
//            // Elf32_Ehdr
1421
//        sizeof(elfout.ehdr) +
1422
//            // Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
1423
//        (get_te16(&elfout.ehdr.e_phentsize) * get_te16(&elfout.ehdr.e_phnum)) +
1424
//            // checksum UPX! lsize version format
1425
//        sizeof(l_info) +
1426
//            // PT_DYNAMIC with DT_NEEDED "forwarded" from original file
1427
//        ((get_te16(&elfout.ehdr.e_phnum)==3)
1428
//            ? (unsigned) get_te32(&elfout.phdr[C_NOTE].p_memsz)
1429
//            : 0) +
1430
//            // p_progid, p_filesize, p_blocksize
1431
//        sizeof(p_info) +
1432
//            // compressed data
1433
//        b_len + ph.c_len );
1434
1435
            // entry to stub
1436
0
    addLoader("LEXEC000", nullptr);
1437
1438
0
    if (ft->id) {
1439
0
        { // decompr, unfilter are separate
1440
0
            addLoader("LXUNF000", nullptr);
1441
0
            addLoader("LXUNF002", nullptr);
1442
0
                if (0x80==(ft->id & 0xF0)) {
1443
0
                    if (256==n_mru) {
1444
0
                        addLoader("MRUBYTE0", nullptr);
1445
0
                    }
1446
0
                    else if (n_mru) {
1447
0
                        addLoader("LXMRU005", nullptr);
1448
0
                    }
1449
0
                    if (n_mru) {
1450
0
                        addLoader("LXMRU006", nullptr);
1451
0
                    }
1452
0
                    else {
1453
0
                        addLoader("LXMRU007", nullptr);
1454
0
                    }
1455
0
            }
1456
0
            else if (0x40==(ft->id & 0xF0)) {
1457
0
                addLoader("LXUNF008", nullptr);
1458
0
            }
1459
0
            addLoader("LXUNF010", nullptr);
1460
0
        }
1461
0
        if (n_mru) {
1462
0
            addLoader("LEXEC009", nullptr);
1463
0
        }
1464
0
    }
1465
0
    addLoader("LEXEC010", nullptr);
1466
0
    addLoader(getDecompressorSections(), nullptr);
1467
0
    addLoader("LEXEC015", nullptr);
1468
0
    if (ft->id) {
1469
0
        {  // decompr, unfilter are separate
1470
0
            if (0x80!=(ft->id & 0xF0)) {
1471
0
                addLoader("LXUNF042", nullptr);
1472
0
            }
1473
0
        }
1474
0
        addFilter32(ft->id);
1475
0
        { // decompr, unfilter are separate
1476
0
            if (0x80==(ft->id & 0xF0)) {
1477
0
                if (0==n_mru) {
1478
0
                    addLoader("LXMRU058", nullptr);
1479
0
                }
1480
0
            }
1481
0
            addLoader("LXUNF035", nullptr);
1482
0
        }
1483
0
    }
1484
0
    else {
1485
0
        addLoader("LEXEC017", nullptr);
1486
0
    }
1487
1488
0
    addLoader("IDENTSTR", nullptr);
1489
0
    addLoader("+40,LEXEC020", nullptr);
1490
0
    addLoader("FOLDEXEC", nullptr);
1491
0
}
1492
1493
void PackLinuxElf32x86::defineSymbols(Filter const *const ft)
1494
0
{
1495
0
    PackLinuxElf32::defineSymbols(ft);
1496
1497
0
    if (0x80==(ft->id & 0xF0)) {
1498
0
        int const mru = ft->n_mru ? 1+ ft->n_mru : 0;
1499
0
        if (mru && mru!=256) {
1500
0
            unsigned const is_pwr2 = (0==((mru -1) & mru));
1501
0
            linker->defineSymbol("NMRU", mru - is_pwr2);
1502
0
        }
1503
0
    }
1504
0
}
1505
1506
void
1507
PackLinuxElf32::buildLinuxLoader(
1508
    upx_byte const *const proto,
1509
    unsigned        const szproto,
1510
    upx_byte const *const fold,
1511
    unsigned        const szfold,
1512
    Filter const *ft
1513
)
1514
0
{
1515
0
    MemBuffer mb_cprLoader;
1516
0
    unsigned sz_cpr = 0;
1517
0
    unsigned sz_unc = 0;
1518
0
    unsigned method = 0;
1519
0
    upx_byte const *uncLoader = nullptr;
1520
1521
0
  if (0 < szfold) {
1522
0
    if (xct_off // shlib
1523
0
      && (  this->e_machine==Elf32_Ehdr::EM_ARM
1524
0
         || this->e_machine==Elf32_Ehdr::EM_386)
1525
0
    ) {
1526
0
        initLoader(fold, szfold);
1527
// Typical layout of 'sections' in compressed stub code for shared library:
1528
//   SO_HEAD
1529
//   ptr_NEXT
1530
//   EXP_HEAD  NRV getbit(), copy
1531
//   NRV2B etc: daisy chain of de-compressor for each method used
1532
//   EXP_TAIL  FIXME: unfilter
1533
//   SO_TAIL
1534
//   SO_MAIN  C-language supervision based on PT_LOADs
1535
0
        char sec[200]; memset(sec, 0, sizeof(sec));  // debug convenience
1536
0
        int len = 0;
1537
0
        unsigned m_decompr = methods_used | (1u << (0xFF & ph_forced_method(ph.method)));
1538
0
        len += snprintf(sec, sizeof(sec), "%s", "SO_HEAD,ptr_NEXT,EXP_HEAD");
1539
1540
        // Start of dasiy-chain fall-through.
1541
0
        if (((1u<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) {
1542
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B");
1543
0
        }
1544
0
        if (((1u<<M_NRV2D_LE32)|(1u<<M_NRV2D_8)|(1u<<M_NRV2D_LE16)) & m_decompr) {
1545
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2D");
1546
0
        }
1547
0
        if (((1u<<M_NRV2E_LE32)|(1u<<M_NRV2E_8)|(1u<<M_NRV2E_LE16)) & m_decompr) {
1548
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2E");
1549
0
        }
1550
0
        if (((1u<<M_LZMA)) & m_decompr) {
1551
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s",
1552
0
                "LZMA_DAISY,LZMA_ELF00,LZMA_DEC20,LZMA_DEC30");
1553
0
        }
1554
0
        len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "EXP_TAIL");
1555
        // End of daisy-chain fall-through.
1556
1557
        // MIPS directly calls memfd_create
1558
0
        if (this->e_machine != Elf32_Ehdr::EM_MIPS) {
1559
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s",
1560
0
                (sec_arm_attr || is_asl)
1561
0
                    ? "HUMF_A,UMF_ANDROID"
1562
0
                    : "HUMF_L,UMF_LINUX");
1563
0
        }
1564
0
        if (hasLoaderSection("STRCON")) {
1565
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "STRCON");
1566
0
        }
1567
0
        len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "SO_TAIL,SO_MAIN");
1568
0
        (void)len;  // Pacify the anal-retentive static analyzer which hates a good idiom.
1569
0
        NO_printf("\n%s\n", sec);
1570
0
        addLoader(sec, nullptr);
1571
0
        relocateLoader();
1572
0
        {
1573
0
            int sz_unc_int;
1574
0
            uncLoader = linker->getLoader(&sz_unc_int);
1575
0
            sz_unc = sz_unc_int;
1576
0
        }
1577
0
        method = M_NRV2B_LE32;  // requires unaligned fetch
1578
0
        if (this->e_machine==Elf32_Ehdr::EM_ARM)
1579
0
            method = M_NRV2B_8;  //only ARM v6 and above has unaligned fetch
1580
0
    } // end shlib (folded portion)
1581
0
    else if (this->e_machine==Elf32_Ehdr::EM_386
1582
0
         ||  this->e_machine==Elf32_Ehdr::EM_ARM
1583
0
         ||  this->e_machine==Elf32_Ehdr::EM_PPC
1584
0
         ||  this->e_machine==Elf32_Ehdr::EM_MIPS
1585
0
         ) { // main program with ELF2 de-compressor (folded portion)
1586
0
        initLoader(fold, szfold);
1587
0
        char sec[200]; memset(sec, 0, sizeof(sec));  // debug convenience
1588
0
        int len = 0;
1589
0
        unsigned m_decompr = methods_used | (1u << (0xFF & ph_forced_method(ph.method)));
1590
0
        len += snprintf(sec, sizeof(sec), "%s", ".text,EXP_HEAD");
1591
0
        if (((1u<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) {
1592
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B");
1593
0
        }
1594
0
        if (((1u<<M_NRV2D_LE32)|(1u<<M_NRV2D_8)|(1u<<M_NRV2D_LE16)) & m_decompr) {
1595
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2D");
1596
0
        }
1597
0
        if (((1u<<M_NRV2E_LE32)|(1u<<M_NRV2E_8)|(1u<<M_NRV2E_LE16)) & m_decompr) {
1598
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2E");
1599
0
        }
1600
0
        if (((1u<<M_LZMA)) & m_decompr) {
1601
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s",
1602
0
                "LZMA_DAISY,LZMA_ELF00,LZMA_DEC20,LZMA_DEC30");
1603
0
        }
1604
0
        len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "EXP_TAIL");
1605
1606
        // $ARCH-linux.elf-main2.c calls upx_mmap_and_fd, not direct memfd_create
1607
0
        len += snprintf(&sec[len], sizeof(sec) - len, ",%s",
1608
0
            (sec_arm_attr || is_asl)
1609
0
                ? "HUMF_A,UMF_ANDROID"
1610
0
                : "HUMF_L,UMF_LINUX");
1611
0
        if (hasLoaderSection("SYSCALLS")) {
1612
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "SYSCALLS");
1613
0
        }
1614
0
        (void)len;  // Pacify the anal-retentive static analyzer which hates a good idiom.
1615
0
        NO_printf("\n%s\n", sec);
1616
0
        addLoader(sec, nullptr);
1617
0
        relocateLoader();
1618
0
        {
1619
0
            int sz_unc_int;
1620
0
            uncLoader = linker->getLoader(&sz_unc_int);
1621
0
            sz_unc = sz_unc_int;
1622
0
        }
1623
0
        method = M_NRV2B_LE32;  // requires unaligned fetch
1624
0
        if (this->e_machine==Elf32_Ehdr::EM_ARM)
1625
0
            method = M_NRV2B_8;  //only ARM v6 and above has unaligned fetch
1626
0
    }
1627
0
    else { // main program with ELF1 de-compressor (folded portion)
1628
0
        cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
1629
0
        unsigned fold_hdrlen = usizeof(hf->ehdr) +
1630
0
            get_te16(&hf->ehdr.e_phentsize) * get_te16(&hf->ehdr.e_phnum);
1631
0
        if (this->e_machine==Elf32_Ehdr::EM_MIPS) {
1632
0
            fold_hdrlen = upx::umax(fold_hdrlen, (unsigned)0x80);
1633
0
        }
1634
0
        uncLoader = fold_hdrlen + fold;
1635
0
        sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen));
1636
0
        method = ph.method;
1637
0
    }
1638
1639
0
    struct b_info h; memset(&h, 0, sizeof(h));
1640
0
    h.b_method = method;
1641
    // _Ehdr and _Phdr are NOT filtered, so Leave h.b_ftid and h.b_cto8 as zero.
1642
1643
0
    mb_cprLoader.allocForCompression(sizeof(h) + sz_unc);
1644
0
    unsigned char *const cprLoader = (unsigned char *)mb_cprLoader;  // less typing
1645
1646
0
    h.sz_unc = sz_unc;
1647
0
    h.sz_cpr = mb_cprLoader.getSize();  // max that upx_compress may use
1648
0
    {
1649
0
        int r = upx_compress(uncLoader, sz_unc, sizeof(h) + cprLoader, &sz_cpr,
1650
0
            nullptr, ph_forced_method(method), 10, nullptr, nullptr );
1651
0
        h.sz_cpr = sz_cpr;  // actual length used
1652
0
        if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
1653
0
            throwInternalError("loader compression failed");
1654
0
    }
1655
0
    set_te32(&h.sz_cpr, h.sz_cpr);
1656
0
    set_te32(&h.sz_unc, h.sz_unc);
1657
0
    memcpy(cprLoader, &h, sizeof(h)); // cprLoader will become FOLDEXEC
1658
0
  }  // end (0 < szfold)
1659
1660
0
    initLoader(proto, szproto, -1, sz_cpr);
1661
0
    NO_printf("FOLDEXEC unc=%#x  cpr=%#x\n", sz_unc, sz_cpr);
1662
0
    linker->addSection("FOLDEXEC", mb_cprLoader, sizeof(b_info) + sz_cpr, 0);
1663
0
    if (xct_off  // shlib
1664
0
       && (this->e_machine==Elf32_Ehdr::EM_NONE
1665
0
          || this->e_machine==Elf32_Ehdr::EM_386
1666
0
          || this->e_machine==Elf32_Ehdr::EM_ARM
1667
0
          || this->e_machine==Elf32_Ehdr::EM_PPC
1668
0
          || this->e_machine==Elf32_Ehdr::EM_MIPS
1669
0
          )
1670
0
    ) { // shlib with ELF2 de-compressor
1671
0
        addLoader("ELFMAINX");
1672
0
        addLoader((sec_arm_attr || is_asl)
1673
0
            ? "HUMF_A,UMF_ANDROID"
1674
0
            : "HUMF_L,UMF_LINUX");
1675
0
        addLoader("ELFMAINZ,FOLDEXEC,IDENTSTR");
1676
0
    }
1677
0
    else if (this->e_machine==Elf32_Ehdr::EM_NONE
1678
0
          || this->e_machine==Elf32_Ehdr::EM_386
1679
0
          || this->e_machine==Elf32_Ehdr::EM_ARM
1680
0
          || this->e_machine==Elf32_Ehdr::EM_PPC
1681
0
          || this->e_machine==Elf32_Ehdr::EM_MIPS
1682
0
      ) { // main program with ELF2 de-compressor
1683
0
        addLoader("ELFMAINX");
1684
0
        if (this->e_machine==Elf32_Ehdr::EM_ARM) { // hardware is more problematic
1685
0
            if (opt->o_unix.catch_sigsegv && hasLoaderSection("ELFSIGSEGV"))
1686
0
                addLoader("ELFSIGSEGV");
1687
0
            addLoader("ELFMAINX2");
1688
0
        }
1689
        // Only if $ARCH-linux.elf-entry.S calls upx_mmap_and_fd instead of memfd_create
1690
0
        if (this->e_machine != Elf32_Ehdr::EM_PPC
1691
0
        &&  this->e_machine != Elf32_Ehdr::EM_MIPS)
1692
0
            addLoader((sec_arm_attr || is_asl)
1693
0
                ? "HUMF_A,UMF_ANDROID"
1694
0
                : "HUMF_L,UMF_LINUX");
1695
0
        addLoader("ELFMAINZ,FOLDEXEC,IDENTSTR");
1696
0
            defineSymbols(ft);
1697
0
    }
1698
0
    else { // main program with ELF1 de-compressor
1699
0
        addStubEntrySections(ft, methods_used | (1u << (0xFF & ph_forced_method(ph.method))) );
1700
0
        if (!xct_off) { // main program
1701
0
            defineSymbols(ft);
1702
0
        }
1703
0
    }
1704
0
    relocateLoader();
1705
0
}
1706
1707
void
1708
PackLinuxElf64::buildLinuxLoader(
1709
    upx_byte const *const proto,
1710
    unsigned        const szproto,
1711
    upx_byte const *const fold,
1712
    unsigned        const szfold,
1713
    Filter const *ft
1714
)
1715
0
{
1716
0
    MemBuffer mb_cprLoader;
1717
0
    unsigned sz_cpr = 0;
1718
0
    unsigned sz_unc = 0;
1719
0
    unsigned method = 0;
1720
0
    upx_byte const *uncLoader = nullptr;
1721
1722
0
  if (0 < szfold) {
1723
0
    if (xct_off // shlib
1724
0
      && (  this->e_machine==Elf64_Ehdr::EM_X86_64
1725
0
         || this->e_machine==Elf64_Ehdr::EM_AARCH64)
1726
0
    ) {
1727
0
        initLoader(fold, szfold);
1728
// Typical layout of 'sections' in compressed stub code for shared library:
1729
//   SO_HEAD
1730
//   ptr_NEXT
1731
//   EXP_HEAD  NRV getbit(), copy
1732
//   NRV2B etc: daisy chain of de-compressor for each method used
1733
//   EXP_TAIL  FIXME: unfilter
1734
//   SO_TAIL
1735
//   SO_MAIN  C-language supervision based on PT_LOADs
1736
0
        char sec[200]; memset(sec, 0, sizeof(sec));  // debug convenience
1737
0
        int len = 0;
1738
0
        unsigned m_decompr = methods_used | (1u << (0xFF & ph_forced_method(ph.method)));
1739
0
        len += snprintf(sec, sizeof(sec), "%s", "SO_HEAD,ptr_NEXT,EXP_HEAD");
1740
1741
        // Start of dasiy-chain fall-through.
1742
0
        if (((1u<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) {
1743
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B");
1744
0
        }
1745
0
        if (((1u<<M_NRV2D_LE32)|(1u<<M_NRV2D_8)|(1u<<M_NRV2D_LE16)) & m_decompr) {
1746
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2D");
1747
0
        }
1748
0
        if (((1u<<M_NRV2E_LE32)|(1u<<M_NRV2E_8)|(1u<<M_NRV2E_LE16)) & m_decompr) {
1749
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2E");
1750
0
        }
1751
0
        if (((1u<<M_LZMA)) & m_decompr) {
1752
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s",
1753
0
                "LZMA_DAISY,LZMA_ELF00,LZMA_DEC20,LZMA_DEC30");
1754
0
        }
1755
0
        len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "EXP_TAIL");
1756
        // End of daisy-chain fall-through.
1757
1758
        // Android on EM_AARCH64 has memfd_create(), so UMF_ANDROID not needed.
1759
0
        len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "HUMF_L,UMF_LINUX");
1760
0
        if (hasLoaderSection("STRCON")) {
1761
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "STRCON");
1762
0
        }
1763
0
        len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "SO_TAIL,SO_MAIN");
1764
0
        (void)len;  // Pacify the anal-retentive static analyzer which hates a good idiom.
1765
0
        NO_printf("\n%s\n", sec);
1766
0
        addLoader(sec, nullptr);
1767
0
        relocateLoader();
1768
0
        {
1769
0
            int sz_unc_int;
1770
0
            uncLoader = linker->getLoader(&sz_unc_int);
1771
0
            sz_unc = sz_unc_int;
1772
0
        }
1773
0
        method = M_NRV2B_LE32;  // requires unaligned fetch
1774
0
    }
1775
0
    else if (this->e_machine==Elf32_Ehdr::EM_NONE
1776
0
         ||  this->e_machine==Elf64_Ehdr::EM_X86_64
1777
0
         ||  this->e_machine==Elf64_Ehdr::EM_AARCH64
1778
0
         ||  this->e_machine==Elf64_Ehdr::EM_PPC64
1779
0
         ) { // main program with ELF2 de-compressor (folded portion)
1780
0
        initLoader(fold, szfold);
1781
0
        char sec[200]; memset(sec, 0, sizeof(sec));  // debug convenience
1782
0
        int len = 0;
1783
0
        unsigned m_decompr = methods_used | (1u << (0xFF & ph_forced_method(ph.method)));
1784
0
        len += snprintf(sec, sizeof(sec), "%s", ".text,EXP_HEAD");
1785
0
        if (((1u<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) {
1786
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B");
1787
0
        }
1788
0
        if (((1u<<M_NRV2D_LE32)|(1u<<M_NRV2D_8)|(1u<<M_NRV2D_LE16)) & m_decompr) {
1789
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2D");
1790
0
        }
1791
0
        if (((1u<<M_NRV2E_LE32)|(1u<<M_NRV2E_8)|(1u<<M_NRV2E_LE16)) & m_decompr) {
1792
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2E");
1793
0
        }
1794
0
        if (((1u<<M_LZMA)) & m_decompr) {
1795
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s",
1796
0
                "LZMA_DAISY,LZMA_ELF00,LZMA_DEC20,LZMA_DEC30");
1797
0
        }
1798
0
        len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "EXP_TAIL");
1799
0
        if (hasLoaderSection("SYSCALLS")) {
1800
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "SYSCALLS");
1801
0
        }
1802
0
        if (hasLoaderSection("STRCON")) {
1803
0
            len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "STRCON");
1804
0
        }
1805
0
        (void)len;
1806
0
        NO_printf("\n%s\n", sec);
1807
0
        addLoader(sec, nullptr);
1808
0
        relocateLoader();
1809
0
        {
1810
0
            int sz_unc_int;
1811
0
            uncLoader = linker->getLoader(&sz_unc_int);
1812
0
            sz_unc = sz_unc_int;
1813
0
        }
1814
0
        method = M_NRV2B_LE32;  // requires unaligned fetch
1815
0
    }
1816
0
    else { // not shlib: main program with ELF1 de-compressor
1817
0
        cprElfHdr1 const *hf = (cprElfHdr1 const *)fold;
1818
0
        e_type = get_te16(&hf->ehdr.e_type);
1819
0
        if (ET_REL == e_type) {
1820
0
            initLoader(fold, szfold);
1821
0
            addLoader(".text", nullptr);
1822
0
            relocateLoader();
1823
0
            int sz_unc_int(0);
1824
0
            uncLoader = linker->getLoader(&sz_unc_int);
1825
0
            sz_unc = sz_unc_int;
1826
0
        }
1827
0
        else if (ET_EXEC == e_type) {
1828
0
            hf = (cprElfHdr1 const *)fold;
1829
0
            unsigned fold_hdrlen = usizeof(hf->ehdr) +
1830
0
                get_te16(&hf->ehdr.e_phentsize) * get_te16(&hf->ehdr.e_phnum);
1831
0
            if (this->e_machine==Elf64_Ehdr::EM_X86_64) {
1832
0
                fold_hdrlen = get_te64(&hf->ehdr.e_entry);
1833
0
            }
1834
0
            uncLoader = &fold[fold_hdrlen];
1835
0
            sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen));
1836
0
        }
1837
0
        method = ph.method;
1838
0
    }
1839
1840
0
    struct b_info h; memset(&h, 0, sizeof(h));
1841
0
    h.b_method = method;
1842
    // _Ehdr and _Phdr are NOT filtered, so Leave h.b_ftid and h.b_cto8 as zero.
1843
1844
0
    mb_cprLoader.allocForCompression(sizeof(h) + sz_unc);
1845
0
    unsigned char *const cprLoader = (unsigned char *)mb_cprLoader;  // less typing
1846
1847
0
    h.sz_unc = sz_unc;
1848
0
    h.sz_cpr = mb_cprLoader.getSize();  // max that upx_compress may use
1849
0
    {
1850
0
        int r = upx_compress(uncLoader, sz_unc, sizeof(h) + cprLoader, &sz_cpr,
1851
0
            nullptr, ph_forced_method(method), 10, nullptr, nullptr );
1852
0
        h.sz_cpr = sz_cpr;  // actual length used
1853
0
        if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
1854
0
            throwInternalError("loader compression failed");
1855
0
    }
1856
0
    set_te32(&h.sz_cpr, h.sz_cpr);
1857
0
    set_te32(&h.sz_unc, h.sz_unc);
1858
0
    memcpy(cprLoader, &h, sizeof(h)); // cprLoader will become FOLDEXEC
1859
0
  }  // end (0 < szfold)
1860
1861
0
    initLoader(proto, szproto, -1, sz_cpr);
1862
0
    NO_printf("FOLDEXEC unc=%#x  cpr=%#x\n", sz_unc, sz_cpr);
1863
0
    linker->addSection("FOLDEXEC", mb_cprLoader, sizeof(b_info) + sz_cpr, 0);
1864
0
    if (xct_off
1865
0
       && (this->e_machine==Elf64_Ehdr::EM_NONE
1866
0
          || this->e_machine==Elf64_Ehdr::EM_X86_64
1867
0
          || this->e_machine==Elf64_Ehdr::EM_AARCH64
1868
0
          || this->e_machine==Elf64_Ehdr::EM_PPC64
1869
0
          )
1870
0
    ) {
1871
0
        addLoader("ELFMAINX,ELFMAINZ,FOLDEXEC,IDENTSTR");
1872
0
    } // shlib
1873
0
    else if (this->e_machine==Elf32_Ehdr::EM_NONE
1874
0
         ||  this->e_machine==Elf64_Ehdr::EM_X86_64
1875
0
         ||  this->e_machine==Elf64_Ehdr::EM_AARCH64
1876
0
         ||  this->e_machine==Elf64_Ehdr::EM_PPC64
1877
0
        ) { // main program with ELF2 de-compressor
1878
0
        addLoader("ELFMAINX");
1879
        // NYI for PPC64 {
1880
0
        if (opt->o_unix.catch_sigsegv && hasLoaderSection("ELFSIGSEGV"))
1881
0
            addLoader("ELFSIGSEGV");
1882
0
        if (this->e_machine!=Elf64_Ehdr::EM_PPC64)
1883
0
            addLoader("ELFMAINX2");
1884
        // } end NYI for PPC64
1885
0
        addLoader("ELFMAINZ,FOLDEXEC,IDENTSTR");
1886
0
        if (this->e_machine==Elf64_Ehdr::EM_PPC64
1887
0
        &&  ehdri.e_ident[Elf64_Ehdr::EI_DATA]==Elf64_Ehdr::ELFDATA2MSB) {
1888
0
            addLoader("ELFMAINZe");
1889
0
        }
1890
0
        if (!xct_off) { // main program
1891
0
            defineSymbols(ft);
1892
0
        }
1893
0
    }
1894
0
    else { // main program with ELF1 de-compressor
1895
0
        addStubEntrySections(ft, methods_used | (1u << (0xFF & ph_forced_method(ph.method))) );
1896
0
        if (!xct_off) { // main program
1897
0
            defineSymbols(ft);
1898
0
        }
1899
0
    }
1900
0
    relocateLoader();
1901
0
}
1902
1903
void
1904
PackLinuxElf64amd::defineSymbols(Filter const *ft)
1905
0
{
1906
0
    PackLinuxElf64::defineSymbols(ft);
1907
0
}
1908
1909
static const CLANG_FORMAT_DUMMY_STATEMENT
1910
#include "stub/i386-linux.elf-entry.h"
1911
static const CLANG_FORMAT_DUMMY_STATEMENT
1912
#include "stub/i386-linux.elf-so_entry.h"
1913
static const CLANG_FORMAT_DUMMY_STATEMENT
1914
#include "stub/i386-linux.elf-fold.h"
1915
static const CLANG_FORMAT_DUMMY_STATEMENT
1916
#include "stub/i386-linux.elf-so_fold.h"
1917
static const CLANG_FORMAT_DUMMY_STATEMENT
1918
#include "stub/i386-linux.shlib-init.h"
1919
1920
void
1921
PackLinuxElf32x86::buildLoader(const Filter *ft)
1922
0
{
1923
0
    if (0!=xct_off) {  // shared library
1924
0
        buildLinuxLoader(
1925
0
            stub_i386_linux_elf_so_entry, sizeof(stub_i386_linux_elf_so_entry),
1926
0
            stub_i386_linux_elf_so_fold,  sizeof(stub_i386_linux_elf_so_fold), ft);
1927
0
        return;
1928
0
    }
1929
0
    unsigned char tmp[sizeof(stub_i386_linux_elf_fold)];
1930
0
    memcpy(tmp, stub_i386_linux_elf_fold, sizeof(stub_i386_linux_elf_fold));
1931
0
    checkPatch(nullptr, 0, 0, 0);  // reset
1932
0
    if (opt->o_unix.is_ptinterp) {
1933
0
        unsigned j;
1934
0
        for (j = 0; j < sizeof(stub_i386_linux_elf_fold)-1; ++j) {
1935
0
            if (0x60==tmp[  j]
1936
0
            &&  0x47==tmp[1+j] ) {
1937
                /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
1938
0
                tmp[  j] = 0x47;
1939
0
                tmp[1+j] = 0x60;
1940
0
                break;
1941
0
            }
1942
0
        }
1943
0
    }
1944
0
    buildLinuxLoader(
1945
0
        stub_i386_linux_elf_entry, sizeof(stub_i386_linux_elf_entry),
1946
0
        tmp,                       sizeof(stub_i386_linux_elf_fold),  ft );
1947
0
}
1948
1949
static const CLANG_FORMAT_DUMMY_STATEMENT
1950
#include "stub/i386-bsd.elf-entry.h"
1951
static const CLANG_FORMAT_DUMMY_STATEMENT
1952
#include "stub/i386-bsd.elf-fold.h"
1953
1954
void
1955
PackBSDElf32x86::buildLoader(const Filter *ft)
1956
0
{
1957
0
    unsigned char tmp[sizeof(stub_i386_bsd_elf_fold)];
1958
0
    memcpy(tmp, stub_i386_bsd_elf_fold, sizeof(stub_i386_bsd_elf_fold));
1959
0
    checkPatch(nullptr, 0, 0, 0);  // reset
1960
0
    if (opt->o_unix.is_ptinterp) {
1961
0
        unsigned j;
1962
0
        for (j = 0; j < sizeof(stub_i386_bsd_elf_fold)-1; ++j) {
1963
0
            if (0x60==tmp[  j]
1964
0
            &&  0x47==tmp[1+j] ) {
1965
                /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
1966
0
                tmp[  j] = 0x47;
1967
0
                tmp[1+j] = 0x60;
1968
0
                break;
1969
0
            }
1970
0
        }
1971
0
    }
1972
0
    buildLinuxLoader(
1973
0
        stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
1974
0
        tmp,                     sizeof(stub_i386_bsd_elf_fold), ft);
1975
0
}
1976
1977
static const CLANG_FORMAT_DUMMY_STATEMENT
1978
#include "stub/i386-netbsd.elf-entry.h"
1979
1980
static const CLANG_FORMAT_DUMMY_STATEMENT
1981
#include "stub/i386-netbsd.elf-fold.h"
1982
1983
#define WANT_NHDR_ENUM
1984
#include "p_elf_enum.h"
1985
#undef WANT_NHDR_ENUM
1986
1987
void
1988
PackNetBSDElf32x86::buildLoader(const Filter *ft)
1989
0
{
1990
0
    unsigned char tmp[sizeof(stub_i386_netbsd_elf_fold)];
1991
0
    memcpy(tmp, stub_i386_netbsd_elf_fold, sizeof(stub_i386_netbsd_elf_fold));
1992
0
    checkPatch(nullptr, 0, 0, 0);  // reset
1993
0
    if (opt->o_unix.is_ptinterp) {
1994
0
        unsigned j;
1995
0
        for (j = 0; j < sizeof(stub_i386_netbsd_elf_fold)-1; ++j) {
1996
0
            if (0x60==tmp[  j]
1997
0
            &&  0x47==tmp[1+j] ) {
1998
                /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
1999
0
                tmp[  j] = 0x47;
2000
0
                tmp[1+j] = 0x60;
2001
0
                break;
2002
0
            }
2003
0
        }
2004
0
    }
2005
0
    buildLinuxLoader(
2006
0
        stub_i386_netbsd_elf_entry, sizeof(stub_i386_netbsd_elf_entry),
2007
0
        tmp,                        sizeof(stub_i386_netbsd_elf_fold), ft);
2008
0
}
2009
2010
static const CLANG_FORMAT_DUMMY_STATEMENT
2011
#include "stub/i386-openbsd.elf-fold.h"
2012
2013
void
2014
PackOpenBSDElf32x86::buildLoader(const Filter *ft)
2015
0
{
2016
0
    unsigned char tmp[sizeof(stub_i386_openbsd_elf_fold)];
2017
0
    memcpy(tmp, stub_i386_openbsd_elf_fold, sizeof(stub_i386_openbsd_elf_fold));
2018
0
    checkPatch(nullptr, 0, 0, 0);  // reset
2019
0
    if (opt->o_unix.is_ptinterp) {
2020
0
        unsigned j;
2021
0
        for (j = 0; j < sizeof(stub_i386_openbsd_elf_fold)-1; ++j) {
2022
0
            if (0x60==tmp[  j]
2023
0
            &&  0x47==tmp[1+j] ) {
2024
                /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
2025
0
                tmp[  j] = 0x47;
2026
0
                tmp[1+j] = 0x60;
2027
0
                break;
2028
0
            }
2029
0
        }
2030
0
    }
2031
0
    buildLinuxLoader(
2032
0
        stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
2033
0
        tmp,                     sizeof(stub_i386_openbsd_elf_fold), ft);
2034
0
}
2035
2036
static const CLANG_FORMAT_DUMMY_STATEMENT
2037
#include "stub/arm.v5a-linux.elf-entry.h"
2038
static const CLANG_FORMAT_DUMMY_STATEMENT
2039
#include "stub/arm.v5a-linux.elf-so_entry.h"
2040
static const CLANG_FORMAT_DUMMY_STATEMENT
2041
#include "stub/arm.v5a-linux.elf-fold.h"
2042
static const CLANG_FORMAT_DUMMY_STATEMENT
2043
#include "stub/arm.v5a-linux.elf-so_fold.h"
2044
static const CLANG_FORMAT_DUMMY_STATEMENT
2045
#include "stub/arm.v5t-linux.shlib-init.h"
2046
2047
static const CLANG_FORMAT_DUMMY_STATEMENT
2048
#include "stub/arm.v4a-linux.elf-entry.h"
2049
static const CLANG_FORMAT_DUMMY_STATEMENT
2050
#include "stub/arm.v4a-linux.elf-so_entry.h"
2051
static const CLANG_FORMAT_DUMMY_STATEMENT
2052
#include "stub/arm.v4a-linux.elf-fold.h"
2053
static const CLANG_FORMAT_DUMMY_STATEMENT
2054
#include "stub/arm.v4a-linux.elf-so_fold.h"
2055
#if 0
2056
static const CLANG_FORMAT_DUMMY_STATEMENT
2057
#include "stub/arm.v4a-linux.shlib-init.h"
2058
#endif
2059
2060
static const CLANG_FORMAT_DUMMY_STATEMENT
2061
#include "stub/armeb.v4a-linux.elf-entry.h"
2062
static const CLANG_FORMAT_DUMMY_STATEMENT
2063
#include "stub/armeb.v4a-linux.elf-fold.h"
2064
2065
void
2066
PackLinuxElf32armBe::buildLoader(Filter const *ft)
2067
0
{
2068
0
    buildLinuxLoader(
2069
0
        stub_armeb_v4a_linux_elf_entry, sizeof(stub_armeb_v4a_linux_elf_entry),
2070
0
        stub_armeb_v4a_linux_elf_fold,  sizeof(stub_armeb_v4a_linux_elf_fold), ft);
2071
0
}
2072
2073
void
2074
PackLinuxElf32armLe::buildLoader(Filter const *ft)
2075
0
{
2076
0
    if (Elf32_Ehdr::ELFOSABI_LINUX==ei_osabi) {
2077
0
        if (0!=xct_off) {  // shared library
2078
0
            buildLinuxLoader( // FIXME: 4 vs 5 ?
2079
0
                stub_arm_v5a_linux_elf_so_entry, sizeof(stub_arm_v5a_linux_elf_so_entry),
2080
0
                stub_arm_v5a_linux_elf_so_fold,  sizeof(stub_arm_v5a_linux_elf_so_fold), ft);
2081
0
            return;
2082
0
        }
2083
0
        buildLinuxLoader(
2084
0
            stub_arm_v5a_linux_elf_entry, sizeof(stub_arm_v5a_linux_elf_entry),
2085
0
            stub_arm_v5a_linux_elf_fold,  sizeof(stub_arm_v5a_linux_elf_fold), ft);
2086
0
    }
2087
0
    else {
2088
0
        buildLinuxLoader(
2089
0
            stub_arm_v4a_linux_elf_entry, sizeof(stub_arm_v4a_linux_elf_entry),
2090
0
            stub_arm_v4a_linux_elf_fold,  sizeof(stub_arm_v4a_linux_elf_fold), ft);
2091
0
    }
2092
0
}
2093
2094
static const CLANG_FORMAT_DUMMY_STATEMENT
2095
#include "stub/mipsel.r3000-linux.elf-entry.h"
2096
static const CLANG_FORMAT_DUMMY_STATEMENT
2097
#include "stub/mipsel.r3000-linux.elf-fold.h"
2098
static const CLANG_FORMAT_DUMMY_STATEMENT
2099
#include "stub/mipsel.r3000-linux.shlib-init.h"
2100
2101
void
2102
PackLinuxElf32mipsel::buildLoader(Filter const *ft)
2103
0
{
2104
0
    if (0!=xct_off) {  // shared library
2105
0
        buildLinuxLoader(
2106
0
            stub_mipsel_r3000_linux_shlib_init, sizeof(stub_mipsel_r3000_linux_shlib_init),
2107
0
            nullptr,                        0,                                 ft );
2108
0
        return;
2109
0
    }
2110
0
    buildLinuxLoader(
2111
0
        stub_mipsel_r3000_linux_elf_entry, sizeof(stub_mipsel_r3000_linux_elf_entry),
2112
0
        stub_mipsel_r3000_linux_elf_fold,  sizeof(stub_mipsel_r3000_linux_elf_fold), ft);
2113
0
}
2114
2115
static const CLANG_FORMAT_DUMMY_STATEMENT
2116
#include "stub/mips.r3000-linux.elf-entry.h"
2117
static const CLANG_FORMAT_DUMMY_STATEMENT
2118
#include "stub/mips.r3000-linux.elf-fold.h"
2119
static const CLANG_FORMAT_DUMMY_STATEMENT
2120
#include "stub/mips.r3000-linux.shlib-init.h"
2121
2122
void
2123
PackLinuxElf32mipseb::buildLoader(Filter const *ft)
2124
0
{
2125
0
    if (0!=xct_off) {  // shared library
2126
0
        buildLinuxLoader(
2127
0
            stub_mips_r3000_linux_shlib_init, sizeof(stub_mips_r3000_linux_shlib_init),
2128
0
            nullptr,                        0,                                 ft );
2129
0
        return;
2130
0
    }
2131
0
    buildLinuxLoader(
2132
0
        stub_mips_r3000_linux_elf_entry, sizeof(stub_mips_r3000_linux_elf_entry),
2133
0
        stub_mips_r3000_linux_elf_fold,  sizeof(stub_mips_r3000_linux_elf_fold), ft);
2134
0
}
2135
2136
static const CLANG_FORMAT_DUMMY_STATEMENT
2137
#include "stub/powerpc-linux.elf-entry.h"
2138
static const CLANG_FORMAT_DUMMY_STATEMENT
2139
#include "stub/powerpc-linux.elf-fold.h"
2140
2141
void
2142
PackLinuxElf32ppc::buildLoader(const Filter *ft)
2143
0
{
2144
0
    buildLinuxLoader(
2145
0
        stub_powerpc_linux_elf_entry, sizeof(stub_powerpc_linux_elf_entry),
2146
0
        stub_powerpc_linux_elf_fold,  sizeof(stub_powerpc_linux_elf_fold), ft);
2147
0
}
2148
2149
static const CLANG_FORMAT_DUMMY_STATEMENT
2150
#include "stub/powerpc64le-linux.elf-entry.h"
2151
static const CLANG_FORMAT_DUMMY_STATEMENT
2152
#include "stub/powerpc64le-linux.elf-fold.h"
2153
2154
void
2155
PackLinuxElf64ppcle::buildLoader(const Filter *ft)
2156
0
{
2157
0
    buildLinuxLoader(
2158
0
        stub_powerpc64le_linux_elf_entry, sizeof(stub_powerpc64le_linux_elf_entry),
2159
0
        stub_powerpc64le_linux_elf_fold,  sizeof(stub_powerpc64le_linux_elf_fold), ft);
2160
0
}
2161
2162
static const CLANG_FORMAT_DUMMY_STATEMENT
2163
#include "stub/powerpc64-linux.elf-entry.h"
2164
static const CLANG_FORMAT_DUMMY_STATEMENT
2165
#include "stub/powerpc64-linux.elf-fold.h"
2166
2167
void
2168
PackLinuxElf64ppc::buildLoader(const Filter *ft)
2169
0
{
2170
0
    buildLinuxLoader(
2171
0
        stub_powerpc64_linux_elf_entry, sizeof(stub_powerpc64_linux_elf_entry),
2172
0
        stub_powerpc64_linux_elf_fold,  sizeof(stub_powerpc64_linux_elf_fold), ft);
2173
0
}
2174
2175
static const CLANG_FORMAT_DUMMY_STATEMENT
2176
#include "stub/amd64-linux.elf-entry.h"
2177
static const CLANG_FORMAT_DUMMY_STATEMENT
2178
#include "stub/amd64-linux.elf-fold.h"
2179
static const CLANG_FORMAT_DUMMY_STATEMENT
2180
#include "stub/amd64-linux.elf-so_entry.h"
2181
static const CLANG_FORMAT_DUMMY_STATEMENT
2182
#include "stub/amd64-linux.elf-so_fold.h"
2183
static const CLANG_FORMAT_DUMMY_STATEMENT
2184
#include "stub/amd64-linux.shlib-init.h"
2185
2186
void
2187
PackLinuxElf64amd::buildLoader(const Filter *ft)
2188
0
{
2189
0
    if (0!=xct_off) {  // shared library
2190
0
        buildLinuxLoader(
2191
0
            stub_amd64_linux_elf_so_entry, sizeof(stub_amd64_linux_elf_so_entry),
2192
0
            stub_amd64_linux_elf_so_fold,  sizeof(stub_amd64_linux_elf_so_fold), ft);
2193
0
        return;
2194
0
    }
2195
0
    buildLinuxLoader(
2196
0
        stub_amd64_linux_elf_entry, sizeof(stub_amd64_linux_elf_entry),
2197
0
        stub_amd64_linux_elf_fold,  sizeof(stub_amd64_linux_elf_fold), ft);
2198
0
}
2199
2200
static const CLANG_FORMAT_DUMMY_STATEMENT
2201
#include "stub/arm64-linux.elf-entry.h"
2202
static const CLANG_FORMAT_DUMMY_STATEMENT
2203
#include "stub/arm64-linux.elf-so_entry.h"
2204
static const CLANG_FORMAT_DUMMY_STATEMENT
2205
#include "stub/arm64-linux.elf-fold.h"
2206
static const CLANG_FORMAT_DUMMY_STATEMENT
2207
#include "stub/arm64-linux.elf-so_fold.h"
2208
static const CLANG_FORMAT_DUMMY_STATEMENT
2209
#include "stub/arm64-linux.shlib-init.h"
2210
2211
void
2212
PackLinuxElf64arm::buildLoader(const Filter *ft)
2213
0
{
2214
0
    if (0!=xct_off) {  // shared library
2215
0
        buildLinuxLoader(
2216
0
            stub_arm64_linux_elf_so_entry, sizeof(stub_arm64_linux_elf_so_entry),
2217
0
            stub_arm64_linux_elf_so_fold,  sizeof(stub_arm64_linux_elf_so_fold), ft);
2218
0
        return;
2219
0
    }
2220
0
    buildLinuxLoader(
2221
0
        stub_arm64_linux_elf_entry, sizeof(stub_arm64_linux_elf_entry),
2222
0
        stub_arm64_linux_elf_fold,  sizeof(stub_arm64_linux_elf_fold), ft);
2223
0
}
2224
2225
    // DT_HASH, DT_GNU_HASH have no explicit length (except in ElfXX_Shdr),
2226
    // so it is hard to detect when the index of a hash chain is out-of-bounds.
2227
    // Workaround: Assume no overlap of DT_* tables (and often contiguous.)
2228
    // Then any given table ends at least as early as when another table begins.
2229
    // So find the tables, and sort the offsets.
2230
    // The 32-bit DT_xxxxx keys have the same values as 64-bit DT_xxxxx keys.
2231
static unsigned const dt_keys[] = {
2232
        Elf64_Dyn::DT_SYMTAB,
2233
        Elf64_Dyn::DT_VERSYM,  // not small integer
2234
        Elf64_Dyn::DT_VERNEED,  // not small integer
2235
        Elf64_Dyn::DT_HASH,
2236
        Elf64_Dyn::DT_GNU_HASH,  // not small integer
2237
        Elf64_Dyn::DT_STRTAB,
2238
        Elf64_Dyn::DT_VERDEF,  // not small integer
2239
        Elf64_Dyn::DT_REL,
2240
        Elf64_Dyn::DT_RELA,
2241
        Elf64_Dyn::DT_FINI_ARRAY,
2242
        Elf64_Dyn::DT_INIT_ARRAY,
2243
        Elf64_Dyn::DT_PREINIT_ARRAY,
2244
        0,
2245
};
2246
2247
static int __acc_cdecl_qsort
2248
qcmp_unsigned(void const *const aa, void const *const bb)
2249
37.9k
{
2250
37.9k
    unsigned a = *(unsigned const *)aa;
2251
37.9k
    unsigned b = *(unsigned const *)bb;
2252
37.9k
    if (a < b) return -1;
2253
9.91k
    if (a > b) return  1;
2254
88
    return  0;
2255
9.91k
}
2256
2257
void
2258
PackLinuxElf32::sort_DT32_offsets(Elf32_Dyn const *const dynp0)
2259
3.35k
{
2260
3.35k
    mb_dt_offsets.alloc(sizeof(unsigned) * sizeof(dt_keys)/sizeof(dt_keys[0]));
2261
3.35k
    mb_dt_offsets.clear();
2262
3.35k
    dt_offsets = (unsigned *)mb_dt_offsets.getVoidPtr();
2263
3.35k
    unsigned n_off = 0, k;
2264
41.9k
    for (unsigned j=0; ((k = dt_keys[j]),  k); ++j) {
2265
38.8k
        dt_offsets[n_off] = 0;  // default to "not found"
2266
38.8k
        u32_t rva = 0;
2267
38.8k
        if (k < DT_NUM) { // in range of easy table
2268
25.7k
            if (!dt_table[k]) {
2269
14.7k
                continue;  // not present in input
2270
14.7k
            }
2271
11.0k
            rva = get_te32(&dynp0[-1+ dt_table[k]].d_val);
2272
11.0k
        }
2273
13.0k
        else if (file_image) { // why is this guard necessary?
2274
13.0k
            rva = elf_unsigned_dynamic(k);  // zero if not found
2275
13.0k
        }
2276
24.1k
        if (!rva) {
2277
10.8k
            continue;  // not present in input
2278
10.8k
        }
2279
13.2k
        Elf32_Phdr const *phdr = elf_find_Phdr_for_va(rva, phdri, e_phnum);
2280
13.2k
        if (!phdr) {
2281
171
            char msg[60]; snprintf(msg, sizeof(msg), "bad  DT_{%#x} = %#x (no Phdr)",
2282
171
                k, rva);
2283
171
            throwCantPack(msg);
2284
171
        }
2285
13.0k
        dt_offsets[n_off] = (rva - get_te32(&phdr->p_vaddr)) + get_te32(&phdr->p_offset);
2286
2287
13.0k
        if (file_size <= dt_offsets[n_off]) {
2288
42
            char msg[60]; snprintf(msg, sizeof(msg), "bad DT_{%#x} = %#x (beyond EOF)",
2289
42
                k, dt_offsets[n_off]);
2290
42
                throwCantPack(msg);
2291
42
        }
2292
13.0k
        n_off += !!dt_offsets[n_off];
2293
13.0k
    }
2294
3.13k
    dt_offsets[n_off++] = file_size;  // sentinel
2295
3.13k
    upx_qsort(dt_offsets, n_off, sizeof(dt_offsets[0]), qcmp_unsigned);
2296
3.13k
}
2297
2298
unsigned PackLinuxElf32::find_dt_ndx(unsigned rva)
2299
6.00k
{
2300
6.00k
    unsigned *const dto = (unsigned *)mb_dt_offsets.getVoidPtr();
2301
6.00k
    unsigned const dto_size = mb_dt_offsets.getSize() / sizeof(*dto);
2302
12.8k
    for (unsigned j = 0; j < dto_size && dto[j]; ++j) { // linear search of short table
2303
12.6k
        if (rva == dto[j]) {
2304
5.85k
            return j;
2305
5.85k
        }
2306
12.6k
    }
2307
150
    return ~0u;
2308
6.00k
}
2309
2310
unsigned PackLinuxElf32::elf_find_table_size(unsigned dt_type, unsigned sh_type)
2311
6.44k
{
2312
6.44k
    Elf32_Shdr const *sec = elf_find_section_type(sh_type);
2313
6.44k
    if (sec) { // Cheat the easy way: use _Shdr.  (No _Shdr anyway for de-compression)
2314
0
        return get_te32(&sec->sh_size);
2315
0
    }
2316
    // Honest hard work: use _Phdr
2317
6.44k
    unsigned x_rva;
2318
6.44k
    if (dt_type < DT_NUM) {
2319
4.74k
        unsigned const x_ndx = dt_table[dt_type];
2320
4.74k
        if (!x_ndx) { // no such entry
2321
381
            return 0;
2322
381
        }
2323
4.36k
        x_rva = get_te32(&dynseg[-1+ x_ndx].d_val);
2324
4.36k
    }
2325
1.69k
    else {
2326
1.69k
        x_rva = elf_unsigned_dynamic(dt_type);
2327
1.69k
    }
2328
6.06k
    Elf32_Phdr const *const x_phdr = elf_find_Phdr_for_va(x_rva, phdri, e_phnum);
2329
6.06k
    if (!x_phdr)
2330
60
        return ~0u;  // corrupted Phdrs?
2331
6.00k
    unsigned const           d_off =             x_rva - get_te32(&x_phdr->p_vaddr);
2332
6.00k
    unsigned const           y_ndx = find_dt_ndx(d_off + get_te32(&x_phdr->p_offset));
2333
6.00k
    if (~0u != y_ndx) {
2334
5.85k
        return dt_offsets[1+ y_ndx] - dt_offsets[y_ndx];
2335
5.85k
    }
2336
150
    return ~0u;
2337
6.00k
}
2338
2339
void
2340
PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp, u32_t headway)
2341
3.97k
{
2342
3.97k
    if (dt_table[Elf32_Dyn::DT_NULL]) {
2343
553
        return;  // not 1st time; do not change upx_dt_init
2344
553
    }
2345
3.41k
    Elf32_Dyn const *const dynp0 = dynp;
2346
3.41k
    unsigned ndx = 0;
2347
3.41k
    unsigned const limit = headway / sizeof(*dynp);
2348
3.41k
    if (dynp)
2349
210k
    for (; ; ++ndx, ++dynp) {
2350
210k
        if (limit <= ndx) {
2351
41
            throwCantPack("DT_NULL not found");
2352
41
        }
2353
210k
        u32_t const d_tag = get_te32(&dynp->d_tag);
2354
210k
        if (d_tag < DT_NUM) {
2355
36.2k
            if (Elf32_Dyn::DT_NEEDED != d_tag
2356
33.9k
            &&  dt_table[d_tag]
2357
797
            &&    get_te32(&dynp->d_val)
2358
797
               != get_te32(&dynp0[-1+ dt_table[d_tag]].d_val)) {
2359
24
                throwCantPack("duplicate DT_%#x: [%#x] [%#x]",
2360
24
                    (unsigned)d_tag, -1+ dt_table[d_tag], ndx);
2361
24
            }
2362
36.2k
            dt_table[d_tag] = 1+ ndx;
2363
36.2k
        }
2364
210k
        if (Elf32_Dyn::DT_NULL == d_tag) {
2365
3.35k
            break;  // check here so that dt_table[DT_NULL] is set
2366
3.35k
        }
2367
210k
    }
2368
3.35k
    sort_DT32_offsets(dynp0);
2369
2370
3.35k
    upx_dt_init = 0;
2371
3.35k
         if (dt_table[Elf32_Dyn::DT_INIT])          upx_dt_init = Elf32_Dyn::DT_INIT;
2372
2.22k
    else if (dt_table[Elf32_Dyn::DT_PREINIT_ARRAY]) upx_dt_init = Elf32_Dyn::DT_PREINIT_ARRAY;
2373
2.17k
    else if (dt_table[Elf32_Dyn::DT_INIT_ARRAY])    upx_dt_init = Elf32_Dyn::DT_INIT_ARRAY;
2374
2375
3.35k
    unsigned const z_str = dt_table[Elf32_Dyn::DT_STRSZ];
2376
3.35k
    strtab_max = !z_str ? 0 : get_te32(&dynp0[-1+ z_str].d_val);
2377
3.35k
    unsigned const z_tab = dt_table[Elf32_Dyn::DT_STRTAB];
2378
3.35k
    unsigned const tmp1 = !z_tab ? 0 : get_te32(&dynp0[-1+ z_tab].d_val);
2379
3.35k
    if (tmp1 < sz_elf_hdrs) {
2380
118
        throwCantPack("bad DT_STRTAB %#x", tmp1);
2381
118
    }
2382
3.23k
    unsigned const strtab_beg = !z_tab ? 0 : elf_get_offset_from_address(tmp1);
2383
2384
3.23k
    if (!z_str || !z_tab || !(strtab_max + strtab_beg)
2385
3.00k
    || (this->file_size - strtab_beg) < strtab_max  // strtab overlaps EOF
2386
        // last string in table must have terminating NUL
2387
2.92k
    ||  '\0' != ((char *)file_image.getVoidPtr())[-1+ strtab_max + strtab_beg]
2388
3.23k
    ) {
2389
103
        throwCantPack("bad DT_STRSZ %#x", strtab_max);
2390
103
    }
2391
2392
3.13k
    { // Find end of DT_SYMTAB
2393
3.13k
        unsigned const tmp2 = elf_find_table_size(Elf32_Dyn::DT_SYMTAB,
2394
3.13k
            Elf32_Shdr::SHT_DYNSYM);
2395
3.13k
        symnum_max = (~0u == tmp2) ? 0 : tmp2 / sizeof(Elf32_Sym);
2396
3.13k
    }
2397
2398
3.13k
    unsigned v_sym = dt_table[Elf32_Dyn::DT_SYMTAB];
2399
3.13k
    if (v_sym) {
2400
2.52k
        v_sym = elf_get_offset_from_address(get_te32(&dynp0[-1+ v_sym].d_val));
2401
2.52k
    }
2402
3.13k
    unsigned v_hsh = dt_table[Elf32_Dyn::DT_HASH];
2403
3.13k
    if (v_hsh) {
2404
1.99k
        v_hsh = elf_get_offset_from_address(get_te32(&dynp0[-1+ v_hsh].d_val));
2405
1.99k
    }
2406
3.13k
    if (v_hsh && file_image) {
2407
1.88k
        hashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_HASH);
2408
1.88k
        if (!hashtab) {
2409
45
            throwCantPack("bad DT_HASH %#x", v_hsh);
2410
45
        }
2411
        // Find end of DT_HASH
2412
1.83k
        hashend = (unsigned const *)(void const *)(elf_find_table_size(
2413
1.83k
            Elf32_Dyn::DT_HASH, Elf32_Shdr::SHT_HASH) + (char const *)hashtab);
2414
1.83k
        if (!hashtab || (char const *)hashend <= (char const *)&hashtab[2]
2415
1.82k
        ||  file_image.getSizeInBytes()
2416
1.82k
            < (unsigned)((char const *)&hashtab[2] - (char *)&file_image[0]) )
2417
11
        {
2418
11
            throwCantPack("bad DT_HASH %#x", v_hsh);
2419
11
        }
2420
2421
1.82k
        unsigned const nbucket = get_te32(&hashtab[0]);
2422
1.82k
        unsigned const *const buckets = &hashtab[2];
2423
1.82k
        unsigned const *const chains = &buckets[nbucket]; (void)chains;
2424
1.82k
        if ((unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image))
2425
1.82k
                <= sizeof(unsigned)*nbucket ) {
2426
55
            throwCantPack("bad nbucket %#x\n", nbucket);
2427
55
        }
2428
2429
1.77k
        if ((unsigned)(hashend - buckets) < nbucket
2430
1.75k
        || !v_sym || (unsigned)file_size <= v_sym
2431
1.72k
        || ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket))
2432
1.77k
        ) {
2433
63
            throwCantPack("bad DT_HASH nbucket=%#x  len=%#x",
2434
63
                nbucket, (v_sym - v_hsh));
2435
63
        }
2436
1.70k
        unsigned chmax = 0;
2437
1.04M
        for (unsigned j= 0; j < nbucket; ++j) {
2438
1.04M
            unsigned x = get_te32(&buckets[j]);
2439
1.04M
            if (chmax < x) {
2440
6.80k
                chmax = x;
2441
6.80k
            }
2442
1.04M
        }
2443
1.70k
        if ((v_hsh < v_sym) && (v_sym - v_hsh) <
2444
1.33k
                (sizeof(*buckets)*(2+ nbucket) + sizeof(*chains)*(1+ chmax))) {
2445
89
            throwCantPack("bad DT_HASH nbucket=%#x  len=%#x",
2446
89
                nbucket, (v_sym - v_hsh));
2447
89
        }
2448
1.70k
    }
2449
2.86k
    unsigned const v_gsh = elf_unsigned_dynamic(Elf32_Dyn::DT_GNU_HASH);
2450
2.86k
    if (v_gsh && file_image) {
2451
        // Not similar to DT_HASH because DT_GNU_HASH is not small (0x6ffffef5).
2452
1.69k
        gashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_GNU_HASH);
2453
1.69k
        gashend = (unsigned const *)(void const *)(elf_find_table_size(
2454
1.69k
            Elf32_Dyn::DT_GNU_HASH, Elf32_Shdr::SHT_GNU_HASH) + (char const *)gashtab);
2455
1.69k
        if (!gashtab || (char const *)gashend <= (char const *)&gashtab[4]
2456
1.68k
        ||  file_image.getSizeInBytes()
2457
1.68k
            < (unsigned)((char const *)&gashtab[4] - (char *)&file_image[0]) )
2458
15
        {
2459
15
            throwCantPack("bad DT_GNU_HASH %#x", v_gsh);
2460
15
        }
2461
2462
1.68k
        unsigned const n_bucket = get_te32(&gashtab[0]);
2463
1.68k
        unsigned const symbias  = get_te32(&gashtab[1]);
2464
1.68k
        unsigned const n_bitmask = get_te32(&gashtab[2]);
2465
1.68k
        unsigned const gnu_shift = get_te32(&gashtab[3]);
2466
1.68k
        u32_t const *const bitmask = (u32_t const *)(void const *)&gashtab[4];
2467
1.68k
        unsigned     const *const buckets = (unsigned const *)&bitmask[n_bitmask];
2468
1.68k
        unsigned     const *const hasharr = &buckets[n_bucket]; (void)hasharr;
2469
1.68k
        if (!n_bucket || (1u<<31) <= n_bucket  /* fie on fuzzers */
2470
1.62k
        || (unsigned)(gashend - buckets) < n_bucket
2471
1.61k
        || (file_size + file_image) <= (void const *)hasharr) {
2472
89
            throwCantPack("bad n_bucket %#x\n", n_bucket);
2473
89
        }
2474
        // It would be better to detect zeroes shifted into low 5 bits of:
2475
        //    (037 & (hash_32 >> gnu_shift))
2476
        // but compilers can be stupid.
2477
1.59k
        if (31 < gnu_shift) {
2478
61
            throwCantPack("bad gnu_shift %#x", gnu_shift);
2479
61
        }
2480
        // unsigned const *const gashend = &hasharr[n_bucket];
2481
        // minimum, except:
2482
        // Rust and Android trim unused zeroes from high end of hasharr[]
2483
1.53k
        unsigned bmax = 0;
2484
269k
        for (unsigned j= 0; j < n_bucket; ++j) {
2485
267k
            unsigned bj = get_te32(&buckets[j]);
2486
267k
            if (bj) {
2487
149k
                if (bj < symbias) {
2488
22
                    throwCantPack("bad DT_GNU_HASH bucket[%d] < symbias{%#x}\n",
2489
22
                        bj, symbias);
2490
22
                }
2491
149k
                if (bmax < bj) {
2492
6.92k
                    bmax = bj;
2493
6.92k
                }
2494
149k
            }
2495
267k
        }
2496
1.50k
        if (1==n_bucket  && 0==buckets[0]
2497
247
        &&  1==n_bitmask && 0==bitmask[0]) {
2498
            // 2021-09-11 Rust on RaspberryPi apparently uses this to minimize space.
2499
            // But then the DT_GNU_HASH symbol lookup algorithm always fails?
2500
            // https://github.com/upx/upx/issues/525
2501
116
        } else
2502
1.39k
        if (bmax) {
2503
1.21k
            if ((1+ bmax) < symbias) {
2504
14
                throwCantPack("bad DT_GNU_HASH (1+ max_bucket)=%#x < symbias=%#x",
2505
14
                    1+ bmax, symbias);
2506
14
            }
2507
1.20k
            bmax -= symbias;
2508
1.20k
        }
2509
2510
1.49k
        unsigned r = 0;
2511
1.49k
        if (!n_bucket || !n_bitmask || !v_sym
2512
1.40k
        || (r=1, ((-1+ n_bitmask) & n_bitmask))  // not a power of 2
2513
1.40k
        || (r=2, (8*sizeof(u32_t) <= gnu_shift))  // shifted result always == 0
2514
1.40k
        || (r=3, (n_bucket>>30))  // fie on fuzzers
2515
1.40k
        || (r=4, (n_bitmask>>30))
2516
1.40k
        || (r=5, ((file_size/sizeof(unsigned))
2517
1.40k
                <= ((sizeof(*bitmask)/sizeof(unsigned))*n_bitmask + 2*n_bucket)))  // FIXME: weak
2518
1.39k
        || (r=6, ((v_gsh < v_sym) && (v_sym - v_gsh) < (sizeof(unsigned)*4  // headers
2519
1.01k
                + sizeof(*bitmask)*n_bitmask  // bitmask
2520
1.01k
                + sizeof(*buckets)*n_bucket  // buckets
2521
1.01k
                + sizeof(*hasharr)*(!bmax ? 0 : (1+ bmax))  // hasharr
2522
1.01k
            )) )
2523
1.49k
        ) {
2524
237
            char msg[90]; snprintf(msg, sizeof(msg),
2525
237
                "bad DT_GNU_HASH n_bucket=%#x  n_bitmask=%#x  len=%#lx  r=%d",
2526
237
                n_bucket, n_bitmask, (long unsigned)(v_sym - v_gsh), r);
2527
237
            throwCantPack(msg);
2528
237
        }
2529
1.49k
    }
2530
2.43k
    e_shstrndx = get_te16(&ehdri.e_shstrndx);  // who omitted this?
2531
2.43k
    if (e_shnum <= e_shstrndx
2532
244
    &&  !(0==e_shnum && 0==e_shstrndx) ) {
2533
37
        char msg[40]; snprintf(msg, sizeof(msg),
2534
37
            "bad .e_shstrndx %d >= .e_shnum %d", e_shstrndx, e_shnum);
2535
37
        throwCantPack(msg);
2536
37
    }
2537
2.43k
}
2538
2539
Elf32_Phdr const *
2540
PackLinuxElf32::elf_find_ptype(unsigned type, Elf32_Phdr const *phdr, unsigned phnum)
2541
549
{
2542
83.2k
    for (unsigned j = 0; j < phnum; ++j, ++phdr) {
2543
82.8k
        if (type == get_te32(&phdr->p_type)) {
2544
158
            return phdr;
2545
158
        }
2546
82.8k
    }
2547
391
    return nullptr;
2548
549
}
2549
2550
Elf64_Phdr const *
2551
PackLinuxElf64::elf_find_ptype(unsigned type, Elf64_Phdr const *phdr, unsigned phnum)
2552
571
{
2553
24.6k
    for (unsigned j = 0; j < phnum; ++j, ++phdr) {
2554
24.2k
        if (type == get_te32(&phdr->p_type)) {
2555
185
            return phdr;
2556
185
        }
2557
24.2k
    }
2558
386
    return nullptr;
2559
571
}
2560
2561
Elf32_Shdr const *PackLinuxElf32::elf_find_section_name(
2562
    char const *const name
2563
) const
2564
0
{
2565
0
    Elf32_Shdr const *shdr = shdri;
2566
0
    if (!shdr) {
2567
0
        return nullptr;
2568
0
    }
2569
0
    int j = e_shnum;
2570
0
    for (; 0 <=--j; ++shdr) {
2571
0
        unsigned const sh_name = get_te32(&shdr->sh_name);
2572
0
        if ((u32_t)file_size <= sh_name) {  // FIXME: weak
2573
0
            char msg[50]; snprintf(msg, sizeof(msg),
2574
0
                "bad Elf32_Shdr[%d].sh_name %#x",
2575
0
                -1+ e_shnum -j, sh_name);
2576
0
            throwCantPack(msg);
2577
0
        }
2578
0
        if (0==strcmp(name, &shstrtab[sh_name])) {
2579
0
            return shdr;
2580
0
        }
2581
0
    }
2582
0
    return nullptr;
2583
0
}
2584
2585
Elf64_Shdr const *PackLinuxElf64::elf_find_section_name(
2586
    char const *const name
2587
) const
2588
0
{
2589
0
    Elf64_Shdr const *shdr = shdri;
2590
0
    if (!shdr) {
2591
0
        return nullptr;
2592
0
    }
2593
0
    int j = e_shnum;
2594
0
    for (; 0 <=--j; ++shdr) {
2595
0
        unsigned const sh_name = get_te32(&shdr->sh_name);
2596
0
        if ((u32_t)file_size <= sh_name) {  // FIXME: weak
2597
0
            char msg[50]; snprintf(msg, sizeof(msg),
2598
0
                "bad Elf64_Shdr[%d].sh_name %#x",
2599
0
                -1+ e_shnum -j, sh_name);
2600
0
            throwCantPack(msg);
2601
0
        }
2602
0
        if (0==strcmp(name, &shstrtab[sh_name])) {
2603
0
            return shdr;
2604
0
        }
2605
0
    }
2606
0
    return nullptr;
2607
0
}
2608
2609
Elf32_Shdr *PackLinuxElf32::elf_find_section_type(
2610
    unsigned const type
2611
) const
2612
11.9k
{
2613
11.9k
    Elf32_Shdr *shdr = shdri;
2614
11.9k
    if (!shdr) {
2615
11.9k
        return nullptr;
2616
11.9k
    }
2617
0
    int j = e_shnum;
2618
0
    for (; 0 <=--j; ++shdr) {
2619
0
        if (type==get_te32(&shdr->sh_type)) {
2620
0
            return shdr;
2621
0
        }
2622
0
    }
2623
0
    return nullptr;
2624
0
}
2625
2626
Elf64_Shdr *PackLinuxElf64::elf_find_section_type(
2627
    unsigned const type
2628
) const
2629
9.72k
{
2630
9.72k
    Elf64_Shdr *shdr = shdri;
2631
9.72k
    if (!shdr) {
2632
9.72k
        return nullptr;
2633
9.72k
    }
2634
0
    int j = e_shnum;
2635
0
    for (; 0 <=--j; ++shdr) {
2636
0
        if (type==get_te32(&shdr->sh_type)) {
2637
0
            return shdr;
2638
0
        }
2639
0
    }
2640
0
    return nullptr;
2641
0
}
2642
2643
char const *PackLinuxElf64::get_str_name(unsigned st_name, unsigned symnum) const
2644
7.69k
{
2645
7.69k
    if (strtab_max <= st_name) {
2646
30
        char msg[70]; snprintf(msg, sizeof(msg),
2647
30
            "bad .st_name %#x in DT_SYMTAB[%d]", st_name, symnum);
2648
30
        throwCantPack(msg);
2649
30
    }
2650
7.66k
    return &dynstr[st_name];
2651
7.69k
}
2652
2653
char const *PackLinuxElf64::get_dynsym_name(unsigned symnum, unsigned relnum) const
2654
8.00k
{
2655
8.00k
    if (symnum_max <= symnum) {
2656
311
        (void)relnum;
2657
311
        return nullptr;
2658
311
    }
2659
7.69k
    return get_str_name(get_te32(&dynsym[symnum].st_name), symnum);
2660
8.00k
}
2661
2662
bool PackLinuxElf64::calls_crt1(Elf64_Rela const *rela, int sz)
2663
0
{
2664
0
    if (!dynsym || !dynstr || !rela) {
2665
0
        return false;
2666
0
    }
2667
0
    for (unsigned relnum= 0; 0 < sz; (sz -= sizeof(Elf64_Rela)), ++rela, ++relnum) {
2668
0
        unsigned const symnum = get_te64(&rela->r_info) >> 32;
2669
0
        char const *const symnam = get_dynsym_name(symnum, relnum);
2670
0
        if (0==strcmp(symnam, "__libc_start_main")  // glibc
2671
0
        ||  0==strcmp(symnam, "__libc_init")  // Android
2672
0
        ||  0==strcmp(symnam, "__uClibc_main")
2673
0
        ||  0==strcmp(symnam, "__uClibc_start_main"))
2674
0
            return true;
2675
0
    }
2676
0
    return false;
2677
0
}
2678
2679
char const *PackLinuxElf32::get_str_name(unsigned st_name, unsigned symnum) const
2680
3.06k
{
2681
3.06k
    if (strtab_max <= st_name) {
2682
54
        char msg[70]; snprintf(msg, sizeof(msg),
2683
54
            "bad .st_name %#x in DT_SYMTAB[%d]\n", st_name, symnum);
2684
54
        throwCantPack(msg);
2685
54
    }
2686
3.00k
    return &dynstr[st_name];
2687
3.06k
}
2688
2689
char const *PackLinuxElf32::get_dynsym_name(unsigned symnum, unsigned relnum) const
2690
3.30k
{
2691
3.30k
    if (symnum_max <= symnum) {
2692
239
        (void)relnum;
2693
239
        return nullptr;
2694
239
    }
2695
3.06k
    return get_str_name(get_te32(&dynsym[symnum].st_name), symnum);
2696
3.30k
}
2697
2698
bool PackLinuxElf32::calls_crt1(Elf32_Rel const *rel, int sz)
2699
0
{
2700
0
    if (!dynsym || !dynstr || !rel) {
2701
0
        return false;
2702
0
    }
2703
0
    for (unsigned relnum= 0; 0 < sz; (sz -= sizeof(Elf32_Rel)), ++rel, ++relnum) {
2704
0
        unsigned const symnum = get_te32(&rel->r_info) >> 8;
2705
0
        char const *const symnam = get_dynsym_name(symnum, relnum);
2706
0
        if (0==strcmp(symnam, "__libc_start_main")  // glibc
2707
0
        ||  0==strcmp(symnam, "__libc_init")  // Android
2708
0
        ||  0==strcmp(symnam, "__uClibc_main")
2709
0
        ||  0==strcmp(symnam, "__uClibc_start_main"))
2710
0
            return true;
2711
0
    }
2712
0
    return false;
2713
0
}
2714
2715
tribool PackLinuxElf32::canUnpack() // bool, except -1: format known, but not packed
2716
169k
{
2717
169k
    if (checkEhdr(&ehdri)) {
2718
162k
        return false;
2719
162k
    }
2720
6.28k
    if (get_te16(&ehdri.e_phnum) < 2) {
2721
20
        throwCantUnpack("e_phnum must be >= 2");
2722
20
    }
2723
6.26k
    if (Elf32_Ehdr::ET_DYN==get_te16(&ehdri.e_type)) {
2724
786
        PackLinuxElf32help1(fi);
2725
786
    }
2726
6.26k
    if (super::canUnpack()) {
2727
800
        return true;
2728
800
    }
2729
5.46k
    return false;
2730
6.26k
}
2731
2732
bool  // false [often throwCantPack]: some defect;  true: good so far
2733
PackLinuxElf32::canPackOSABI(Elf32_Ehdr const *ehdr)
2734
0
{
2735
0
    unsigned char osabi0 = ehdr->e_ident[Elf32_Ehdr::EI_OSABI];
2736
    // The first PT_LOAD must cover the beginning of the file (0==p_offset).
2737
0
    Elf32_Phdr const *phdr = phdri;
2738
0
    note_size = 0;
2739
0
    for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
2740
0
        if (j > ((MAX_ELF_HDR_32 - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))) {
2741
0
            throwCantPack("too many ElfXX_Phdr; try '--force-execve'");
2742
0
            return false;
2743
0
        }
2744
0
        unsigned const p_type = get_te32(&phdr->p_type);
2745
0
        unsigned const p_offset = get_te32(&phdr->p_offset);
2746
0
        if (1!=exetype && PT_LOAD == p_type) { // 1st PT_LOAD
2747
0
            exetype = 1;
2748
0
            load_va = get_te32(&phdr->p_vaddr);  // class data member
2749
2750
            // Cast on next line is to avoid a compiler bug (incorrect complaint) in
2751
            // Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
2752
            // error C4319: '~': zero extending 'unsigned int' to 'upx_uint64_t' of greater size
2753
0
            unsigned const off = ~page_mask & (unsigned)load_va;
2754
2755
0
            if (off && off == p_offset) { // specific hint
2756
0
                throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
2757
                // Fixing it inside upx fails because packExtent() reads original file.
2758
0
                return false;
2759
0
            }
2760
0
            if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
2761
0
                throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
2762
0
                return false;
2763
0
            }
2764
0
            hatch_off = ~3u & (3+ get_te32(&phdr->p_memsz));
2765
0
        }
2766
0
        if (EM_MIPS == e_machine
2767
0
        &&  (Elf32_Phdr::PT_MIPS_ABIFLAGS == p_type
2768
0
          || Elf32_Phdr::PT_MIPS_REGINFO  == p_type)
2769
0
        ) {
2770
0
            add_phdrx(phdr);  // PT_MIPS_*
2771
0
            unsigned mask = -1+ get_te32(&phdr->p_align);
2772
0
            sz_phdrx = ~mask & (mask + sz_phdrx);
2773
0
            sz_phdrx += get_te32(&phdr->p_memsz);
2774
2775
0
        }
2776
0
        if (PT_NOTE32 == p_type) {
2777
0
            if (osabi_note && Elf32_Ehdr::ELFOSABI_NONE==osabi0) { // Still seems to be generic.
2778
0
                struct {
2779
0
                    struct Elf32_Nhdr nhdr;
2780
0
                    char name[8];
2781
0
                    unsigned body;
2782
0
                } note;
2783
0
                memset(&note, 0, sizeof(note));
2784
0
                fi->seek(p_offset, SEEK_SET);
2785
0
                fi->readx(&note, sizeof(note));
2786
0
                fi->seek(0, SEEK_SET);
2787
0
                if (4==get_te32(&note.nhdr.descsz)
2788
0
                &&  1==get_te32(&note.nhdr.type)
2789
                // &&  0==note.end
2790
0
                &&  (1+ strlen(osabi_note))==get_te32(&note.nhdr.namesz)
2791
0
                &&  0==strcmp(osabi_note, (char const *)&note.name[0])
2792
0
                ) {
2793
0
                    osabi0 = ei_osabi;  // Specified by PT_NOTE.
2794
0
                }
2795
0
            }
2796
0
        }
2797
0
    }
2798
0
    if (Elf32_Ehdr::ELFOSABI_NONE ==osabi0
2799
0
    ||  Elf32_Ehdr::ELFOSABI_LINUX==osabi0) { // No EI_OSBAI, no PT_NOTE.
2800
0
        unsigned const arm_eabi = 0xff000000u & get_te32(&ehdr->e_flags);
2801
0
        if (Elf32_Ehdr::EM_ARM==e_machine
2802
0
        &&   (EF_ARM_EABI_VER5==arm_eabi
2803
0
          ||  EF_ARM_EABI_VER4==arm_eabi ) ) {
2804
            // armel-eabi armeb-eabi ARM Linux EABI version 4 is a mess.
2805
0
            ei_osabi = osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
2806
0
        }
2807
0
        else {
2808
0
            osabi0 = opt->o_unix.osabi0;  // Possibly specified by command-line.
2809
0
        }
2810
0
    }
2811
0
    if (osabi0!=ei_osabi) {
2812
0
        return false;
2813
0
    }
2814
0
    return true;  // good so far
2815
0
}
2816
2817
#define WANT_SHDR_ENUM
2818
#include "p_elf_enum.h"
2819
#undef  WANT_SHDR_ENUM
2820
2821
upx_uint64_t PackLinuxElf32::canPack_Shdr(Elf32_Phdr const *pload_x0)
2822
0
{
2823
0
    Elf32_Shdr const *shdr_xva = nullptr;
2824
0
    Elf32_Shdr const *shdr = shdri;
2825
0
  for (int j= e_shnum; --j>=0; ++shdr) {
2826
0
    unsigned const sh_type = get_te32(&shdr->sh_type);
2827
0
    if (!shdr_xva && Elf32_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
2828
0
        shdr_xva = shdr;
2829
0
        xct_va = get_te32(&shdr_xva->sh_addr);
2830
0
    }
2831
    // Hook the first slot of DT_PREINIT_ARRAY or DT_INIT_ARRAY.
2832
0
    if (!user_init_rp && (
2833
0
        (     Elf32_Dyn::DT_PREINIT_ARRAY==upx_dt_init
2834
0
        &&  Elf32_Shdr::SHT_PREINIT_ARRAY==sh_type)
2835
0
    ||  (     Elf32_Dyn::DT_INIT_ARRAY   ==upx_dt_init
2836
0
        &&  Elf32_Shdr::SHT_INIT_ARRAY   ==sh_type) )) {
2837
0
        unsigned user_init_ava = get_te32(&shdr->sh_addr);
2838
0
        user_init_off = get_te32(&shdr->sh_offset);
2839
0
        if ((u32_t)file_size <= user_init_off) {
2840
0
            char msg[70]; snprintf(msg, sizeof(msg),
2841
0
                "bad Elf32_Shdr[%d].sh_offset %#x",
2842
0
                -1+ e_shnum - j, user_init_off);
2843
0
            throwCantPack(msg);
2844
0
        }
2845
        // Check that &file_image[user_init_off] has
2846
        // *_RELATIVE or *_ABS* relocation, and fetch user_init_va.
2847
        // If Elf32_Rela then the actual value is in Rela.r_addend.
2848
0
        int z_rel = dt_table[Elf32_Dyn::DT_REL];
2849
0
        int z_rsz = dt_table[Elf32_Dyn::DT_RELSZ];
2850
0
        if (z_rel && z_rsz) {
2851
0
            unsigned rel_off = get_te32(&dynseg[-1+ z_rel].d_val);
2852
0
            if ((unsigned)file_size <= rel_off) {
2853
0
                char msg[70]; snprintf(msg, sizeof(msg),
2854
0
                     "bad Elf32_Dynamic[DT_REL] %#x\n",
2855
0
                     rel_off);
2856
0
                throwCantPack(msg);
2857
0
            }
2858
0
            Elf32_Rel *rp = (Elf32_Rel *)&file_image[rel_off];
2859
0
            unsigned relsz   = get_te32(&dynseg[-1+ z_rsz].d_val);
2860
0
            if ((unsigned)file_size <= relsz) {
2861
0
                char msg[70]; snprintf(msg, sizeof(msg),
2862
0
                     "bad Elf32_Dynamic[DT_RELSZ] %#x\n",
2863
0
                     relsz);
2864
0
                throwCantPack(msg);
2865
0
            }
2866
0
            Elf32_Rel *last = (Elf32_Rel *)(relsz + (char *)rp);
2867
0
            for (; rp < last; ++rp) {
2868
0
                unsigned r_va = get_te32(&rp->r_offset);
2869
0
                if (r_va == user_init_ava) { // found the Elf32_Rel
2870
0
                    user_init_rp = rp;
2871
0
                    unsigned r_info = get_te32(&rp->r_info);
2872
0
                    unsigned r_type = ELF32_R_TYPE(r_info);
2873
0
                    set_te32(&dynsym[0].st_name, r_va);  // for decompressor
2874
0
                    set_te32(&dynsym[0].st_value, r_info);
2875
0
                    if (Elf32_Ehdr::EM_ARM == e_machine) {
2876
0
                        if (R_ARM_RELATIVE == r_type) {
2877
0
                            user_init_va = get_te32(&file_image[user_init_off]);
2878
0
                        }
2879
0
                        else if (R_ARM_ABS32 == r_type) {
2880
0
                            unsigned symj = ELF32_R_SYM(r_info);
2881
0
                            user_init_va = get_te32(&dynsym[symj].st_value);
2882
0
                            set_te32(&rp->r_info, ELF32_R_INFO(0, R_ARM_RELATIVE));
2883
                            // pack3() will set &file_image[user_init_off]
2884
0
                        }
2885
0
                        else {
2886
0
                            goto bad;
2887
0
                        }
2888
0
                    }
2889
0
                    else if (Elf32_Ehdr::EM_386 == e_machine) {
2890
0
                        if (R_386_RELATIVE == r_type) {
2891
0
                            user_init_va = get_te32(&file_image[user_init_off]);
2892
0
                        }
2893
0
                        else if (R_386_32 == r_type) {
2894
0
                            unsigned symj = ELF32_R_SYM(r_info);
2895
0
                            user_init_va = get_te32(&dynsym[symj].st_value);
2896
0
                            set_te32(&rp->r_info, ELF32_R_INFO(0, R_386_RELATIVE));
2897
                            // pack3() will set &file_image[user_init_off]
2898
0
                        }
2899
0
                        else {
2900
0
                            goto bad;
2901
0
                        }
2902
0
                    }
2903
0
                    else {
2904
0
bad:
2905
0
                        char msg[50]; snprintf(msg, sizeof(msg),
2906
0
                            "bad relocation %#x DT_INIT_ARRAY[0]",
2907
0
                            r_info);
2908
0
                        throwCantPack(msg);
2909
0
                    }
2910
0
                    break;
2911
0
                }
2912
0
            }
2913
0
        }
2914
0
        unsigned const p_filesz = get_te32(&pload_x0->p_filesz);
2915
0
        if (!((user_init_va - xct_va) < p_filesz)) {
2916
            // Not in executable portion of first executable PT_LOAD.
2917
0
            if (0==user_init_va && is_asl) {
2918
                // Android allows (0 ==> skip) ?
2919
0
                upx_dt_init = 0;  // force steal of 'extra' DT_NULL
2920
                // XXX: FIXME: depends on SHT_DYNAMIC coming later
2921
0
            }
2922
0
            else {
2923
0
                char msg[70]; snprintf(msg, sizeof(msg),
2924
0
                    "bad init address %#x in Elf32_Shdr[%d].%#x\n",
2925
0
                    (unsigned)user_init_va, -1+ e_shnum - j, user_init_off);
2926
0
                throwCantPack(msg);
2927
0
            }
2928
0
        }
2929
0
    }
2930
    // By default /usr/bin/ld leaves 4 extra DT_NULL to support pre-linking.
2931
    // Take one as a last resort.
2932
0
    if ((Elf32_Dyn::DT_INIT==upx_dt_init || !upx_dt_init)
2933
0
    &&  Elf32_Shdr::SHT_DYNAMIC == sh_type) {
2934
0
        unsigned sh_offset = get_te32(&shdr->sh_offset);
2935
0
        unsigned sh_size = get_te32(&shdr->sh_size);
2936
0
        if ((unsigned)file_size < sh_size
2937
0
        ||  (unsigned)file_size < sh_offset
2938
0
        || ((unsigned)file_size - sh_offset) < sh_size) {
2939
0
            throwCantPack("bad SHT_DYNAMIC");
2940
0
        }
2941
0
        unsigned const n = get_te32(&shdr->sh_size) / sizeof(Elf32_Dyn);
2942
0
        Elf32_Dyn *dynp = (Elf32_Dyn *)&file_image[get_te32(&shdr->sh_offset)];
2943
0
        for (; Elf32_Dyn::DT_NULL != dynp->d_tag; ++dynp) {
2944
0
            if (upx_dt_init == get_te32(&dynp->d_tag)) {
2945
0
                break;  // re-found DT_INIT
2946
0
            }
2947
0
        }
2948
0
        if ((1+ dynp) < (n+ dynseg)) { // not the terminator, so take it
2949
0
            user_init_va = get_te32(&dynp->d_val);  // 0 if (0==upx_dt_init)
2950
0
            set_te32(&dynp->d_tag, upx_dt_init = Elf32_Dyn::DT_INIT);
2951
0
            user_init_off = (char const *)&dynp->d_val - (char const *)&file_image[0];
2952
0
        }
2953
0
    }
2954
0
  }
2955
0
    return xct_va;
2956
0
}
2957
2958
upx_uint64_t PackLinuxElf64::canPack_Shdr(Elf64_Phdr const *pload_x0)
2959
0
{
2960
0
    Elf64_Shdr const *shdr_xva = nullptr;
2961
0
    Elf64_Shdr const *shdr = shdri;
2962
0
  for (int j= e_shnum; --j>=0; ++shdr) {
2963
0
    unsigned const sh_type = get_te32(&shdr->sh_type);
2964
0
    if (!shdr_xva && Elf64_Shdr::SHF_EXECINSTR & get_te64(&shdr->sh_flags)) {
2965
0
        shdr_xva = shdr;
2966
0
        xct_va = get_te64_32(&shdr_xva->sh_addr);
2967
0
    }
2968
    // Hook the first slot of DT_PREINIT_ARRAY or DT_INIT_ARRAY.
2969
0
    if (!user_init_rp && (
2970
0
           (     Elf64_Dyn::DT_PREINIT_ARRAY==upx_dt_init
2971
0
           &&  Elf64_Shdr::SHT_PREINIT_ARRAY==sh_type)
2972
0
        || (     Elf64_Dyn::DT_INIT_ARRAY   ==upx_dt_init
2973
0
           &&  Elf64_Shdr::SHT_INIT_ARRAY   ==sh_type) )) {
2974
0
        unsigned user_init_ava = get_te64(&shdr->sh_addr);
2975
0
        user_init_off = get_te64(&shdr->sh_offset);
2976
0
        if ((u64_t)file_size <= user_init_off) {
2977
0
            char msg[70]; snprintf(msg, sizeof(msg),
2978
0
                "bad Elf64_Shdr[%d].sh_offset %#x",
2979
0
                -1+ e_shnum - j, user_init_off);
2980
0
            throwCantPack(msg);
2981
0
        }
2982
        // Check that &file_image[user_init_off] has
2983
        // *_RELATIVE or *_ABS* relocation, and fetch user_init_va.
2984
        // If Elf_Rela then the actual value is in Rela.r_addend.
2985
0
        int z_rel = dt_table[Elf64_Dyn::DT_RELA];
2986
0
        int z_rsz = dt_table[Elf64_Dyn::DT_RELASZ];
2987
0
        if (z_rel && z_rsz) {
2988
0
            upx_uint64_t rel_off = get_te64(&dynseg[-1+ z_rel].d_val);
2989
0
            if ((u64_t)file_size <= rel_off) {
2990
0
                char msg[70]; snprintf(msg, sizeof(msg),
2991
0
                     "bad Elf64_Dynamic[DT_RELA] %#llx\n",
2992
0
                     rel_off);
2993
0
                throwCantPack(msg);
2994
0
            }
2995
0
            Elf64_Rela *rp = (Elf64_Rela *)&file_image[rel_off];
2996
0
            upx_uint64_t relsz   = get_te64(&dynseg[-1+ z_rsz].d_val);
2997
0
            if ((u64_t)file_size <= relsz) {
2998
0
                char msg[70]; snprintf(msg, sizeof(msg),
2999
0
                     "bad Elf64_Dynamic[DT_RELASZ] %#llx\n",
3000
0
                     relsz);
3001
0
                throwCantPack(msg);
3002
0
            }
3003
0
            Elf64_Rela *last = (Elf64_Rela *)(relsz + (char *)rp);
3004
0
            for (; rp < last; ++rp) {
3005
0
                upx_uint64_t r_va = get_te64(&rp->r_offset);
3006
0
                if (r_va == user_init_ava) { // found the Elf64_Rela
3007
0
                    user_init_rp = rp;
3008
0
                    upx_uint64_t r_info = get_te64(&rp->r_info);
3009
0
                    unsigned r_type = ELF64_R_TYPE(r_info);
3010
0
                    set_te32(&dynsym[0].st_name, r_va);  // for decompressor
3011
0
                    set_te64(&dynsym[0].st_value, r_info);
3012
0
                    set_te64(&dynsym[0].st_size, get_te64(&rp->r_addend));
3013
0
                    if (Elf64_Ehdr::EM_AARCH64 == e_machine) {
3014
0
                        if (R_AARCH64_RELATIVE == r_type) {
3015
0
                            user_init_va = get_te64(&rp->r_addend);
3016
0
                        }
3017
0
                        else if (R_AARCH64_ABS64 == r_type) {
3018
0
                            user_init_va = get_te64(&dynsym[ELF64_R_SYM(r_info)].st_value);
3019
0
                        }
3020
0
                        else {
3021
0
                            char msg[50]; snprintf(msg, sizeof(msg),
3022
0
                                "bad relocation %#llx DT_INIT_ARRAY[0]",
3023
0
                                r_info);
3024
0
                            throwCantPack(msg);
3025
0
                        }
3026
0
                    }
3027
0
                    else if (Elf64_Ehdr::EM_X86_64 == e_machine) {
3028
0
                        if (R_X86_64_RELATIVE == r_type) {
3029
0
                            user_init_va = get_te64(&rp->r_addend);
3030
0
                        }
3031
0
                        else if (R_X86_64_64 == r_type) {
3032
0
                            user_init_va = get_te64(&dynsym[ELF64_R_SYM(r_info)].st_value);
3033
0
                        }
3034
0
                        else {
3035
0
                            char msg[50]; snprintf(msg, sizeof(msg),
3036
0
                                "bad relocation %#llx DT_INIT_ARRAY[0]",
3037
0
                                r_info);
3038
0
                            throwCantPack(msg);
3039
0
                        }
3040
0
                    }
3041
0
                    break;
3042
0
                }
3043
0
            }
3044
0
        }
3045
0
        unsigned const p_filesz = get_te64(&pload_x0->p_filesz);
3046
0
        if (!((user_init_va - xct_va) < p_filesz)) {
3047
            // Not in executable portion of first executable PT_LOAD.
3048
0
            if (0==user_init_va && is_asl) {
3049
                // Android allows (0 ==> skip) ?
3050
0
                upx_dt_init = 0;  // force steal of 'extra' DT_NULL
3051
                // XXX: FIXME: depends on SHT_DYNAMIC coming later
3052
0
            }
3053
0
            else {
3054
0
                char msg[70]; snprintf(msg, sizeof(msg),
3055
0
                    "bad init address %#x in Elf64_Shdr[%d].%#x\n",
3056
0
                    (unsigned)user_init_va, -1+ e_shnum - j, user_init_off);
3057
0
                throwCantPack(msg);
3058
0
            }
3059
0
        }
3060
0
    }
3061
    // By default /usr/bin/ld leaves 4 extra DT_NULL to support pre-linking.
3062
    // Take one as a last resort.
3063
0
    if ((Elf64_Dyn::DT_INIT==upx_dt_init || !upx_dt_init)
3064
0
    &&  Elf64_Shdr::SHT_DYNAMIC == sh_type) {
3065
0
        upx_uint64_t sh_offset = get_te64(&shdr->sh_offset);
3066
0
        upx_uint64_t sh_size = get_te64(&shdr->sh_size);
3067
0
        if ((upx_uint64_t)file_size < sh_size
3068
0
        ||  (upx_uint64_t)file_size < sh_offset
3069
0
        || ((upx_uint64_t)file_size - sh_offset) < sh_size) {
3070
0
            throwCantPack("bad SHT_DYNAMIC");
3071
0
        }
3072
0
        unsigned const n = sh_size / sizeof(Elf64_Dyn);
3073
0
        Elf64_Dyn *dynp = (Elf64_Dyn *)&file_image[sh_offset];
3074
0
        for (; Elf64_Dyn::DT_NULL != dynp->d_tag; ++dynp) {
3075
0
            if (upx_dt_init == get_te64(&dynp->d_tag)) {
3076
0
                break;  // re-found DT_INIT
3077
0
            }
3078
0
        }
3079
0
        if ((1+ dynp) < (n+ dynseg)) { // not the terminator, so take it
3080
0
            user_init_va = get_te64(&dynp->d_val);  // 0 if (0==upx_dt_init)
3081
0
            set_te64(&dynp->d_tag, upx_dt_init = Elf64_Dyn::DT_INIT);
3082
0
            user_init_off = (char const *)&dynp->d_val - (char const *)&file_image[0];
3083
0
        }
3084
0
    }
3085
0
  }
3086
0
    return xct_va;
3087
0
}
3088
3089
tribool PackLinuxElf32::canPack()
3090
0
{
3091
0
    union {
3092
0
        unsigned char buf[MAX_ELF_HDR_32];
3093
        //struct { Elf32_Ehdr ehdr; Elf32_Phdr phdr; } e;
3094
0
    } u;
3095
0
    COMPILE_TIME_ASSERT(sizeof(u.buf) <= (2*512))
3096
3097
// My earlier design with "extra" Shdrs in output at xct_off
3098
// DOES NOT WORK because code for EM_ARM has embedded relocations
3099
// that are not made visible, such as:
3100
//    ----- glibc-2.31/sysdeps/arm/crti.S
3101
//            .type call_weak_fn, %function
3102
//    call_weak_fn:
3103
//            ldr r3, .LGOT
3104
//            ldr r2, .LGOT+4
3105
//    .LPIC:
3106
//            add r3, pc, r3
3107
//            ldr r2, [r3, r2]
3108
//            cmp r2, #0
3109
//            bxeq lr
3110
//            b PREINIT_FUNCTION
3111
//            .p2align 2
3112
//    .LGOT:
3113
//            .word _GLOBAL_OFFSET_TABLE_-(.LPIC+8)  // unseen reloc!
3114
//            .word PREINIT_FUNCTION(GOT)
3115
//    -----
3116
// So, PackUnix::PackUnix() disables (but silently accepts) --android-shlib,
3117
// and see if appending ARM_ATTRIBUTES Shdr is good enough.
3118
3119
0
    fi->seek(0, SEEK_SET);
3120
0
    fi->readx(u.buf, sizeof(u.buf));
3121
0
    fi->seek(0, SEEK_SET);
3122
0
    Elf32_Ehdr const *const ehdr = (Elf32_Ehdr *) u.buf;
3123
3124
    // now check the ELF header
3125
0
    if (checkEhdr(ehdr) != 0)
3126
0
        return false;
3127
3128
    // additional requirements for linux/elf386
3129
0
    if (get_te16(&ehdr->e_ehsize) != sizeof(*ehdr)) {
3130
0
        throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
3131
0
        return false;
3132
0
    }
3133
0
    if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
3134
0
        throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
3135
0
        return false;
3136
0
    }
3137
3138
0
    if (!canPackOSABI((Elf32_Ehdr *)u.buf)) {
3139
0
        return false;
3140
0
    }
3141
0
    upx_uint32_t max_LOADsz = 0, max_offset = 0;
3142
0
    Elf32_Phdr *phdr = phdri;
3143
0
    for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
3144
0
        if (j > ((MAX_ELF_HDR_32 - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))) {
3145
0
            throwCantPack("too many ElfXX_Phdr; try '--force-execve'");
3146
0
            return false;
3147
0
        }
3148
0
        if (is_LOAD(phdr)) {
3149
            // The first PT_LOAD must cover the beginning of the file (0==p_offset).
3150
0
            upx_uint32_t const p_offset = get_te32(&phdr->p_offset);
3151
0
            if (1!= exetype) {
3152
0
                exetype = 1;
3153
0
                load_va = get_te32(&phdr->p_vaddr);  // class data member
3154
0
                upx_uint32_t const off = ~page_mask & (upx_uint32_t)load_va;
3155
0
                if (off && off == p_offset) { // specific hint
3156
0
                    throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
3157
                    // Fixing it inside upx fails because packExtent() reads original file.
3158
0
                    return false;
3159
0
                }
3160
0
                if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
3161
0
                    throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
3162
0
                    return false;
3163
0
                }
3164
                // FIXME: bad for shlib!
3165
0
                hatch_off = ~3ul & (3+ get_te32(&phdr->p_memsz));
3166
0
            }
3167
0
            max_LOADsz = UPX_MAX(max_LOADsz, UPX_MIN(0x200000u, get_te32(&phdr->p_align)));
3168
0
            unsigned filesz = get_te32(&phdr->p_filesz);
3169
0
            max_LOADsz = UPX_MAX(max_LOADsz, filesz);
3170
0
            max_offset = UPX_MAX(max_offset, filesz + p_offset);
3171
0
        }
3172
0
    }
3173
0
    if (canUnpack()) {
3174
0
        throwAlreadyPacked();
3175
0
    }
3176
    // Heuristic for lopped trailing PackHeader (packed and "hacked"!)
3177
0
    if (3 == e_phnum  // not shlib: PT_LOAD.C_BASE, PT_LOAD.C_TEXT, PT_GNU_STACK
3178
0
    && UPX_MAGIC_LE32 == get_le32(&((l_info *)&phdri[e_phnum])->l_magic)) {
3179
0
        throwAlreadyPacked();
3180
0
    }
3181
    // We want to compress position-independent executable (gcc -pie)
3182
    // main programs, but compressing a shared library must be avoided
3183
    // because the result is no longer usable.  In theory, there is no way
3184
    // to tell them apart: both are just ET_DYN.  Also in theory,
3185
    // neither the presence nor the absence of any particular symbol name
3186
    // can be used to tell them apart; there are counterexamples.
3187
    // However, we will use the following heuristic suggested by
3188
    // Peter S. Mazinger <ps.m@gmx.net> September 2005:
3189
    // If a ET_DYN has __libc_start_main as a global undefined symbol,
3190
    // then the file is a position-independent executable main program
3191
    // (that depends on libc.so.6) and is eligible to be compressed.
3192
    // Otherwise (no __libc_start_main as global undefined): skip it.
3193
    // Also allow  __uClibc_main  and  __uClibc_start_main .
3194
3195
0
    if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) {
3196
        // The DT_SYMTAB has no designated length.  Read the whole file.
3197
0
        alloc_file_image(file_image, file_size);
3198
0
        fi->seek(0, SEEK_SET);
3199
0
        fi->readx(file_image, file_size);
3200
0
        memcpy(&ehdri, ehdr, sizeof(Elf32_Ehdr));
3201
0
        phdri= (Elf32_Phdr *)((size_t)e_phoff + file_image);  // do not free() !!
3202
0
        shdri= (Elf32_Shdr *)((size_t)e_shoff + file_image);  // do not free() !!
3203
3204
0
        sec_strndx = nullptr;
3205
0
        shstrtab = nullptr;
3206
0
        if (e_shnum) {
3207
0
            e_shstrndx = get_te16(&ehdr->e_shstrndx);
3208
0
            if (e_shstrndx) {
3209
0
                if (e_shnum <= e_shstrndx) {
3210
0
                    char msg[40]; snprintf(msg, sizeof(msg),
3211
0
                        "bad e_shstrndx %#x >= e_shnum %d", e_shstrndx, e_shnum);
3212
0
                    throwCantPack(msg);
3213
0
                }
3214
0
                sec_strndx = &shdri[e_shstrndx];
3215
0
                unsigned const sh_offset = get_te32(&sec_strndx->sh_offset);
3216
0
                if ((u32_t)file_size <= sh_offset) {
3217
0
                    char msg[50]; snprintf(msg, sizeof(msg),
3218
0
                        "bad .e_shstrndx->sh_offset %#x", sh_offset);
3219
0
                    throwCantPack(msg);
3220
0
                }
3221
0
                shstrtab = (char const *)(sh_offset + file_image);
3222
0
            }
3223
0
            sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);
3224
0
            if (sec_dynsym) {
3225
0
                unsigned const sh_link = get_te32(&sec_dynsym->sh_link);
3226
0
                if (e_shnum <= sh_link) {
3227
0
                    char msg[50]; snprintf(msg, sizeof(msg),
3228
0
                        "bad SHT_DYNSYM.sh_link %#x", sh_link);
3229
0
                }
3230
0
                sec_dynstr = &shdri[sh_link];
3231
0
            }
3232
3233
0
            if (sec_strndx) {
3234
0
                unsigned const sh_name = get_te32(&sec_strndx->sh_name);
3235
0
                if (Elf32_Shdr::SHT_STRTAB != get_te32(&sec_strndx->sh_type)
3236
0
                || (u32_t)file_size <= (sizeof(".shstrtab")
3237
0
                    + sh_name + (shstrtab - (const char *)&file_image[0]))
3238
0
                || (sh_name
3239
0
                  && 0!=strcmp((char const *)".shstrtab", &shstrtab[sh_name]))
3240
0
                ) {
3241
0
                    throwCantPack("bad e_shstrtab");
3242
0
                }
3243
0
            }
3244
0
        }
3245
3246
0
        Elf32_Phdr const *pload_x0(nullptr);  // first eXecutable PT_LOAD
3247
0
        phdr= phdri;
3248
0
        for (int j= e_phnum; --j>=0; ++phdr)
3249
0
        if (Elf32_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
3250
0
            unsigned offset = check_pt_dynamic(phdr);
3251
0
            dynseg= (Elf32_Dyn *)(offset + file_image);
3252
0
            invert_pt_dynamic(dynseg,
3253
0
                umin(get_te32(&phdr->p_filesz), (unsigned)(file_size_u - offset)));
3254
0
        }
3255
0
        else if (is_LOAD(phdr)) {
3256
0
            if (!pload_x0
3257
0
            &&  Elf32_Phdr::PF_X & get_te32(&phdr->p_flags)
3258
0
            ) {
3259
0
                pload_x0 = phdr;
3260
0
            }
3261
0
            check_pt_load(phdr);
3262
0
        }
3263
0
        if (!pload_x0) {
3264
0
            throwCantPack("No PT_LOAD has (p_flags & PF_X)");
3265
0
        }
3266
        // elf_find_dynamic() returns 0 if 0==dynseg.
3267
0
        dynstr=          (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);
3268
0
        dynsym= (Elf32_Sym /*const*/ *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB);
3269
3270
0
        if (opt->o_unix.force_pie
3271
0
        ||      Elf32_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf32_Dyn::DT_FLAGS_1)
3272
0
        ||  calls_crt1((Elf32_Rel const *)elf_find_dynamic(Elf32_Dyn::DT_REL),
3273
0
                                 (int)elf_unsigned_dynamic(Elf32_Dyn::DT_RELSZ))
3274
0
        ||  calls_crt1((Elf32_Rel const *)elf_find_dynamic(Elf32_Dyn::DT_JMPREL),
3275
0
                                 (int)elf_unsigned_dynamic(Elf32_Dyn::DT_PLTRELSZ))) {
3276
0
            is_pie = true;  // UNUSED except to ignore is_shlib and xct_off
3277
0
            goto proceed;  // calls C library init for main program
3278
0
        }
3279
3280
0
        if (Elf32_Ehdr::EM_ARM==get_te16(&ehdri.e_machine)) {
3281
0
            sec_arm_attr = elf_find_section_type(Elf32_Shdr::SHT_ARM_ATTRIBUTES);
3282
0
            if (Elf32_Ehdr::ET_DYN == e_type) {
3283
                // See earlier comment in this function.  is_asl does not work.
3284
                //is_asl = (!!saved_opt_android_shlib) << 1;  // bit 1; see is_shlib
3285
0
                is_asl = 0;
3286
0
            }
3287
0
        }
3288
3289
        // Heuristic HACK for shared libraries (compare Darwin (MacOS) Dylib.)
3290
        // If there is an existing DT_INIT, and if everything that the dynamic
3291
        // linker ld-linux needs to perform relocations before calling DT_INIT
3292
        // resides below the first SHT_EXECINSTR Section in one PT_LOAD, then
3293
        // compress from the first executable Section to the end of that PT_LOAD.
3294
        // We must not alter anything that ld-linux might touch before it calls
3295
        // the DT_INIT function.
3296
        //
3297
        // Obviously this hack requires that the linker script put pieces
3298
        // into good positions when building the original shared library,
3299
        // and also requires ld-linux to behave.
3300
3301
0
        if (/*jni_onload_sym ||*/ elf_find_dynamic(upx_dt_init)) {
3302
0
            if (this->e_machine!=Elf32_Ehdr::EM_386
3303
0
            &&  this->e_machine!=Elf32_Ehdr::EM_MIPS
3304
0
            &&  this->e_machine!=Elf32_Ehdr::EM_ARM)
3305
0
                goto abandon;  // need stub: EM_PPC
3306
0
            if (elf_has_dynamic(Elf32_Dyn::DT_TEXTREL)) {
3307
0
                throwCantPack("DT_TEXTREL found; re-compile with -fPIC");
3308
0
                goto abandon;
3309
0
            }
3310
0
            if (!(Elf32_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf32_Dyn::DT_FLAGS_1))) {
3311
                // not explicitly PIE main program
3312
0
                if (Elf32_Ehdr::EM_ARM == e_machine  // Android is common
3313
0
                &&  0 && !is_asl  // but not explicit
3314
0
                ) {
3315
0
                    opt->info_mode++;
3316
0
                    info("note: use --android-shlib if appropriate");
3317
0
                    opt->info_mode--;
3318
0
                }
3319
0
            }
3320
0
            if (Elf32_Ehdr::EM_MIPS == get_te16(&ehdr->e_machine)
3321
0
            ||  Elf32_Ehdr::EM_PPC  == get_te16(&ehdr->e_machine)) {
3322
0
                throwCantPack("This test UPX cannot pack .so for MIPS or PowerPC; coming soon.");
3323
0
            }
3324
0
            xct_va = ~(upx_uint64_t)0;
3325
0
            if (e_shnum) {
3326
0
                xct_va = canPack_Shdr(pload_x0);
3327
0
            }
3328
0
            else { // no Sections; use heuristics
3329
0
                unsigned const strsz  = elf_unsigned_dynamic(Elf32_Dyn::DT_STRSZ);
3330
0
                unsigned const strtab = elf_unsigned_dynamic(Elf32_Dyn::DT_STRTAB);
3331
0
                unsigned const relsz  = elf_unsigned_dynamic(Elf32_Dyn::DT_RELSZ);
3332
0
                unsigned const rel    = elf_unsigned_dynamic(Elf32_Dyn::DT_REL);
3333
0
                unsigned const init   = elf_unsigned_dynamic(upx_dt_init);
3334
0
                if ((init == (relsz + rel   ) && rel    == (strsz + strtab))
3335
0
                ||  (init == (strsz + strtab) && strtab == (relsz + rel   ))
3336
0
                ) {
3337
0
                    xct_va = init;
3338
0
                    user_init_va = init;
3339
0
                    user_init_off = elf_get_offset_from_address(init);
3340
0
                }
3341
0
            }
3342
            // Rely on 0==elf_unsigned_dynamic(tag) if no such tag.
3343
0
            unsigned const va_gash = elf_unsigned_dynamic(Elf32_Dyn::DT_GNU_HASH);
3344
0
            unsigned const va_hash = elf_unsigned_dynamic(Elf32_Dyn::DT_HASH);
3345
0
            unsigned y = 0;
3346
0
            if ((y=1, xct_va < va_gash)  ||  (y=2, (0==va_gash && xct_va < va_hash))
3347
0
            ||  (y=3, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_STRTAB))
3348
0
            ||  (y=4, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_SYMTAB))
3349
0
            ||  (y=5, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_REL))
3350
0
            ||  (y=6, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_RELA))
3351
0
            ||  (y=7, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_JMPREL))
3352
0
            ||  (y=8, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERDEF))
3353
0
            ||  (y=9, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERSYM))
3354
0
            ||  (y=10, xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERNEED)) ) {
3355
0
                static char const *which[] = {
3356
0
                    "unknown",
3357
0
                    "DT_GNU_HASH",
3358
0
                    "DT_HASH",
3359
0
                    "DT_STRTAB",
3360
0
                    "DT_SYMTAB",
3361
0
                    "DT_REL",
3362
0
                    "DT_RELA",
3363
0
                    "DT_JMPREL",
3364
0
                    "DT_VERDEF",
3365
0
                    "DT_VERSYM",
3366
0
                    "DT_VERNEED",
3367
0
                };
3368
0
                char buf[30]; snprintf(buf, sizeof(buf), "%s above stub", which[y]);
3369
0
                throwCantPack(buf);
3370
0
                goto abandon;
3371
0
            }
3372
0
            xct_off = elf_get_offset_from_address(xct_va);
3373
0
            if (opt->debug.debug_level) {
3374
0
                fprintf(stderr, "shlib canPack: xct_va=%#lx  xct_off=%#lx\n",
3375
0
                    (long)xct_va, (long)xct_off);
3376
0
            }
3377
0
            goto proceed;  // But proper packing depends on checking xct_va.
3378
0
        }
3379
0
        else {
3380
0
            throwCantPack("need DT_INIT; try \"void _init(void){}\"");
3381
0
        }
3382
0
abandon:
3383
0
        return false;
3384
0
proceed: ;
3385
0
    }
3386
    // XXX Theoretically the following test should be first,
3387
    // but PackUnix::canPack() wants 0!=exetype ?
3388
0
    if (!super::canPack())
3389
0
        return false;
3390
0
    assert(exetype == 1);
3391
0
    exetype = 0;
3392
3393
    // set options
3394
    // this->blocksize: avoid over-allocating.
3395
    // (file_size - max_offset): debug info, non-globl symbols, etc.
3396
0
    opt->o_unix.blocksize = blocksize = UPX_MAX(max_LOADsz, (unsigned)(file_size - max_offset));
3397
0
    return true;
3398
0
}
3399
3400
tribool PackLinuxElf64::canUnpack() // bool, except -1: format known, but not packed
3401
65.2k
{
3402
65.2k
    if (checkEhdr(&ehdri)) {
3403
63.9k
        return false;
3404
63.9k
    }
3405
1.35k
    if (get_te16(&ehdri.e_phnum) < 2) {
3406
22
        throwCantUnpack("e_phnum must be >= 2");
3407
22
    }
3408
1.33k
    if (Elf64_Ehdr::ET_DYN==get_te16(&ehdri.e_type)) {
3409
296
        PackLinuxElf64help1(fi);
3410
296
    }
3411
1.33k
    if (super::canUnpack()) {
3412
801
        return true;
3413
801
    }
3414
530
    return false;
3415
1.33k
}
3416
3417
tribool PackLinuxElf64::canPack()
3418
0
{
3419
0
    union {
3420
0
        unsigned char buf[MAX_ELF_HDR_64];
3421
        //struct { Elf64_Ehdr ehdr; Elf64_Phdr phdr; } e;
3422
0
    } u;
3423
0
    COMPILE_TIME_ASSERT(sizeof(u) <= (2*1024))
3424
3425
0
    fi->readx(u.buf, sizeof(u.buf));
3426
0
    fi->seek(0, SEEK_SET);
3427
0
    Elf64_Ehdr const *const ehdr = (Elf64_Ehdr *) u.buf;
3428
3429
    // now check the ELF header
3430
0
    if (checkEhdr(ehdr) != 0)
3431
0
        return false;
3432
3433
    // additional requirements for linux/elf386
3434
0
    if (get_te16(&ehdr->e_ehsize) != sizeof(*ehdr)) {
3435
0
        throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
3436
0
        return false;
3437
0
    }
3438
0
    if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
3439
0
        throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
3440
0
        return false;
3441
0
    }
3442
3443
0
    upx_uint64_t max_LOADsz = 0, max_offset = 0;
3444
0
    Elf64_Phdr const *phdr = phdri;
3445
0
    for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
3446
0
        if (j > ((MAX_ELF_HDR_64 - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr))) {
3447
0
            throwCantPack("too many ElfXX_Phdr; try '--force-execve'");
3448
0
            return false;
3449
0
        }
3450
0
        if (is_LOAD(phdr)) {
3451
            // The first PT_LOAD must cover the beginning of the file (0==p_offset).
3452
0
            upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
3453
0
            if (1!= exetype) {
3454
0
                exetype = 1;
3455
0
                load_va = get_te64(&phdr->p_vaddr);  // class data member
3456
0
                upx_uint64_t const off = ~page_mask & load_va;
3457
0
                if (off && off == p_offset) { // specific hint
3458
0
                    throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
3459
                    // Fixing it inside upx fails because packExtent() reads original file.
3460
0
                    return false;
3461
0
                }
3462
0
                if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
3463
0
                    throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
3464
0
                    return false;
3465
0
                }
3466
                // FIXME: bad for shlib!
3467
0
                hatch_off = ~3ul & (3+ get_te64(&phdr->p_memsz));
3468
0
            }
3469
0
            upx_uint64_t align = get_te64(&phdr->p_align);
3470
0
            if (0x200000ul < align) align = 0x200000ul;  // UPX_MIN type problem
3471
0
            max_LOADsz = UPX_MAX(max_LOADsz, align);
3472
0
            upx_uint64_t filesz = get_te64(&phdr->p_filesz);
3473
0
            max_LOADsz = UPX_MAX(max_LOADsz, filesz);
3474
0
            max_offset = UPX_MAX(max_offset, filesz + p_offset);
3475
0
        }
3476
0
    }
3477
0
    if (canUnpack()) {
3478
0
        throwAlreadyPacked();
3479
0
    }
3480
    // Heuristic for lopped trailing PackHeader (packed and "hacked"!)
3481
0
    if (3 == e_phnum  // not shlib: PT_LOAD.C_BASE, PT_LOAD.C_TEXT, PT_GNU_STACK
3482
0
    && UPX_MAGIC_LE32 == get_le32(&((l_info *)&phdri[e_phnum])->l_magic)) {
3483
0
        throwAlreadyPacked();
3484
0
    }
3485
    // We want to compress position-independent executable (gcc -pie)
3486
    // main programs, but compressing a shared library must be avoided
3487
    // because the result is no longer usable.  In theory, there is no way
3488
    // to tell them apart: both are just ET_DYN.  Also in theory,
3489
    // neither the presence nor the absence of any particular symbol name
3490
    // can be used to tell them apart; there are counterexamples.
3491
    // However, we will use the following heuristic suggested by
3492
    // Peter S. Mazinger <ps.m@gmx.net> September 2005:
3493
    // If a ET_DYN has __libc_start_main as a global undefined symbol,
3494
    // then the file is a position-independent executable main program
3495
    // (that depends on libc.so.6) and is eligible to be compressed.
3496
    // Otherwise (no __libc_start_main as global undefined): skip it.
3497
    // Also allow  __uClibc_main  and  __uClibc_start_main .
3498
3499
0
    if (Elf64_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) {
3500
        // The DT_SYMTAB has no designated length.  Read the whole file.
3501
0
        alloc_file_image(file_image, file_size);
3502
0
        fi->seek(0, SEEK_SET);
3503
0
        fi->readx(file_image, file_size);
3504
0
        memcpy(&ehdri, ehdr, sizeof(Elf64_Ehdr));
3505
0
        phdri= (Elf64_Phdr *)((size_t)e_phoff + file_image);  // do not free() !!
3506
0
        shdri= (Elf64_Shdr *)((size_t)e_shoff + file_image);  // do not free() !!
3507
3508
0
        sec_strndx = nullptr;
3509
0
        shstrtab = nullptr;
3510
0
        if (e_shnum) {
3511
0
            e_shstrndx = get_te16(&ehdr->e_shstrndx);
3512
0
            if (e_shstrndx) {
3513
0
                if (e_shnum <= e_shstrndx) {
3514
0
                    char msg[40]; snprintf(msg, sizeof(msg),
3515
0
                        "bad e_shstrndx %#x >= e_shnum %d", e_shstrndx, e_shnum);
3516
0
                    throwCantPack(msg);
3517
0
                }
3518
0
                sec_strndx = &shdri[e_shstrndx];
3519
0
                upx_uint64_t sh_offset = get_te64(&sec_strndx->sh_offset);
3520
0
                if ((u64_t)file_size <= sh_offset) {
3521
0
                    char msg[50]; snprintf(msg, sizeof(msg),
3522
0
                        "bad .e_shstrndx->sh_offset %#lx", (long unsigned)sh_offset);
3523
0
                    throwCantPack(msg);
3524
0
                }
3525
0
                shstrtab = (char const *)(sh_offset + file_image);
3526
0
            }
3527
0
            sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
3528
0
            if (sec_dynsym) {
3529
0
                unsigned const sh_link = get_te32(&sec_dynsym->sh_link);
3530
0
                if (e_shnum <= sh_link) {
3531
0
                    char msg[50]; snprintf(msg, sizeof(msg),
3532
0
                        "bad SHT_DYNSYM.sh_link %#x", sh_link);
3533
0
                }
3534
0
                sec_dynstr = &shdri[sh_link];
3535
0
            }
3536
3537
0
            if (sec_strndx) {
3538
0
                unsigned const sh_name = get_te32(&sec_strndx->sh_name);
3539
0
                if (Elf64_Shdr::SHT_STRTAB != get_te32(&sec_strndx->sh_type)
3540
0
                || (u32_t)file_size <= (sizeof(".shstrtab")
3541
0
                    + sh_name + (shstrtab - (const char *)&file_image[0]))
3542
0
                || (sh_name
3543
0
                  && 0!=strcmp((char const *)".shstrtab", &shstrtab[sh_name]))
3544
0
                ) {
3545
0
                    throwCantPack("bad e_shstrtab");
3546
0
                }
3547
0
            }
3548
0
        }
3549
3550
0
        Elf64_Phdr const *pload_x0(nullptr);  // first eXecutable PT_LOAD
3551
0
        phdr= phdri;
3552
0
        for (int j= e_phnum; --j>=0; ++phdr)
3553
0
        if (Elf64_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
3554
0
            upx_uint64_t offset = check_pt_dynamic(phdr);
3555
0
            dynseg= (Elf64_Dyn *)(offset + file_image);
3556
0
            invert_pt_dynamic(dynseg,
3557
0
                umin(get_te64(&phdr->p_filesz), file_size - offset));
3558
0
        }
3559
0
        else if (is_LOAD(phdr)) {
3560
0
            if (!pload_x0
3561
0
            &&  Elf64_Phdr::PF_X & get_te32(&phdr->p_flags)
3562
0
            ) {
3563
0
                pload_x0 = phdr;
3564
0
            }
3565
0
            check_pt_load(phdr);
3566
0
        }
3567
0
        if (!pload_x0) {
3568
0
            throwCantPack("No PT_LOAD has (p_flags & PF_X)");
3569
0
        }
3570
        // elf_find_dynamic() returns 0 if 0==dynseg.
3571
0
        dynstr=          (char const *)elf_find_dynamic(Elf64_Dyn::DT_STRTAB);
3572
0
        dynsym= (Elf64_Sym /*const*/ *)elf_find_dynamic(Elf64_Dyn::DT_SYMTAB);
3573
3574
0
        if (opt->o_unix.force_pie
3575
0
        ||       Elf64_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf64_Dyn::DT_FLAGS_1)
3576
0
        ||  calls_crt1((Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_RELA),
3577
0
                                  (int)elf_unsigned_dynamic(Elf64_Dyn::DT_RELASZ))
3578
0
        ||  calls_crt1((Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_JMPREL),
3579
0
                                  (int)elf_unsigned_dynamic(Elf64_Dyn::DT_PLTRELSZ))) {
3580
0
            is_pie = true;  // UNUSED except to ignore is_shlib and xct_off
3581
0
            goto proceed;  // calls C library init for main program
3582
0
        }
3583
3584
0
        if (Elf64_Ehdr::EM_ARM==get_te16(&ehdri.e_machine)) {
3585
0
            sec_arm_attr = elf_find_section_type(Elf64_Shdr::SHT_ARM_ATTRIBUTES);
3586
0
            if (Elf64_Ehdr::ET_DYN == e_type) {
3587
                // See comment in Elf32_Linux::canPack().  is_asl does not work.
3588
                // 64-bit ARM (aarch64) also has no ARM_ATTRIBUTES.
3589
                //is_asl = (!!saved_opt_android_shlib) << 1;  // bit 1; see is_shlib
3590
0
                is_asl = 0;
3591
0
            }
3592
0
        }
3593
3594
        // Heuristic HACK for shared libraries (compare Darwin (MacOS) Dylib.)
3595
        // If there is an existing DT_INIT, and if everything that the dynamic
3596
        // linker ld-linux needs to perform relocations before calling DT_INIT
3597
        // resides below the first SHT_EXECINSTR Section in one PT_LOAD, then
3598
        // compress from the first executable Section to the end of that PT_LOAD.
3599
        // We must not alter anything that ld-linux might touch before it calls
3600
        // the DT_INIT function.
3601
        //
3602
        // Obviously this hack requires that the linker script put pieces
3603
        // into good positions when building the original shared library,
3604
        // and also requires ld-linux to behave.
3605
3606
0
        if (/*jni_onload_sym ||*/ elf_find_dynamic(upx_dt_init)) {
3607
0
            if (elf_has_dynamic(Elf64_Dyn::DT_TEXTREL)) {
3608
0
                throwCantPack("DT_TEXTREL found; re-compile with -fPIC");
3609
0
                goto abandon;
3610
0
            }
3611
0
            if (!(Elf64_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf64_Dyn::DT_FLAGS_1))) {
3612
                // not explicitly PIE main program
3613
0
                if (Elf64_Ehdr::EM_AARCH64 == e_machine  // Android is common
3614
0
                &&  !is_asl  // but not explicit
3615
0
                ) {
3616
0
                    opt->info_mode++;
3617
0
                    info("note: use --android-shlib if appropriate");
3618
0
                    opt->info_mode--;
3619
0
                }
3620
0
            }
3621
0
            if (Elf64_Ehdr::EM_PPC64 == get_te16(&ehdr->e_machine)) {
3622
0
                throwCantPack("This test UPX cannot pack .so for PowerPC64; coming soon.");
3623
0
            }
3624
0
            xct_va = ~(upx_uint64_t)0;
3625
0
            if (e_shnum) {
3626
0
                xct_va = canPack_Shdr(pload_x0);
3627
0
            }
3628
0
            else { // no Sections; use heuristics
3629
0
                upx_uint64_t const strsz  = elf_unsigned_dynamic(Elf64_Dyn::DT_STRSZ);
3630
0
                upx_uint64_t const strtab = elf_unsigned_dynamic(Elf64_Dyn::DT_STRTAB);
3631
0
                upx_uint64_t const relsz  = elf_unsigned_dynamic(Elf64_Dyn::DT_RELSZ);
3632
0
                upx_uint64_t const rel    = elf_unsigned_dynamic(Elf64_Dyn::DT_REL);
3633
0
                upx_uint64_t const init   = elf_unsigned_dynamic(upx_dt_init);
3634
0
                if ((init == (relsz + rel   ) && rel    == (strsz + strtab))
3635
0
                ||  (init == (strsz + strtab) && strtab == (relsz + rel   ))
3636
0
                ) {
3637
0
                    xct_va = init;
3638
0
                    user_init_va = init;
3639
0
                    user_init_off = elf_get_offset_from_address(init);
3640
0
                }
3641
0
            }
3642
            // Rely on 0==elf_unsigned_dynamic(tag) if no such tag.
3643
0
            upx_uint64_t const va_gash = elf_unsigned_dynamic(Elf64_Dyn::DT_GNU_HASH);
3644
0
            upx_uint64_t const va_hash = elf_unsigned_dynamic(Elf64_Dyn::DT_HASH);
3645
0
            unsigned y = 0;
3646
0
            if ((y=1, xct_va < va_gash)  ||  (y=2, (0==va_gash && xct_va < va_hash))
3647
0
            ||  (y=3, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_STRTAB))
3648
0
            ||  (y=4, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_SYMTAB))
3649
0
            ||  (y=5, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_REL))
3650
0
            ||  (y=6, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_RELA))
3651
0
            ||  (y=7, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_JMPREL))
3652
0
            ||  (y=8, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERDEF))
3653
0
            ||  (y=9, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERSYM))
3654
0
            ||  (y=10, xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERNEED)) ) {
3655
0
                static char const *which[] = {
3656
0
                    "unknown",
3657
0
                    "DT_GNU_HASH",
3658
0
                    "DT_HASH",
3659
0
                    "DT_STRTAB",
3660
0
                    "DT_SYMTAB",
3661
0
                    "DT_REL",
3662
0
                    "DT_RELA",
3663
0
                    "DT_JMPREL",
3664
0
                    "DT_VERDEF",
3665
0
                    "DT_VERSYM",
3666
0
                    "DT_VERNEED",
3667
0
                };
3668
0
                char buf[30]; snprintf(buf, sizeof(buf), "%s above stub", which[y]);
3669
0
                throwCantPack(buf);
3670
0
                goto abandon;
3671
0
            }
3672
0
            xct_off = elf_get_offset_from_address(xct_va);
3673
0
            if (opt->debug.debug_level) {
3674
0
                fprintf(stderr, "shlib canPack: xct_va=%#lx  xct_off=%#lx\n",
3675
0
                    (long)xct_va, (long)xct_off);
3676
0
            }
3677
0
            goto proceed;  // But proper packing depends on checking xct_va.
3678
0
        }
3679
0
        else {
3680
0
            throwCantPack("need DT_INIT; try \"void _init(void){}\"");
3681
0
        }
3682
0
abandon:
3683
0
        return false;
3684
0
proceed: ;
3685
0
    }
3686
    // XXX Theoretically the following test should be first,
3687
    // but PackUnix::canPack() wants 0!=exetype ?
3688
0
    if (!super::canPack())
3689
0
        return false;
3690
0
    assert(exetype == 1);
3691
0
    exetype = 0;
3692
3693
    // set options
3694
    // this->blocksize: avoid over-allocating.
3695
    // (file_size - max_offset): debug info, non-globl symbols, etc.
3696
0
    opt->o_unix.blocksize = blocksize = UPX_MAX(max_LOADsz, file_size - max_offset);
3697
0
    return true;
3698
0
}
3699
3700
off_t
3701
PackLinuxElf32::getbrk(Elf32_Phdr const *phdr, int nph) const
3702
0
{
3703
0
    off_t brka = 0;
3704
0
    for (int j = 0; j < nph; ++phdr, ++j) {
3705
0
        if (is_LOAD(phdr)) {
3706
0
            off_t b = get_te32(&phdr->p_vaddr) + get_te32(&phdr->p_memsz);
3707
0
            if (b > brka)
3708
0
                brka = b;
3709
0
        }
3710
0
    }
3711
0
    return brka;
3712
0
}
3713
3714
off_t
3715
PackLinuxElf32::getbase(const Elf32_Phdr *phdr, int nph) const
3716
0
{
3717
0
    off_t base = ~0u;
3718
0
    for (int j = 0; j < nph; ++phdr, ++j) {
3719
0
        if (is_LOAD(phdr)) {
3720
0
            unsigned const vaddr = get_te32(&phdr->p_vaddr);
3721
0
            if (vaddr < (unsigned) base)
3722
0
                base = vaddr;
3723
0
        }
3724
0
    }
3725
0
    if (0!=base) {
3726
0
        return base;
3727
0
    }
3728
0
    return 0x12000;
3729
0
}
3730
3731
off_t
3732
PackLinuxElf64::getbrk(const Elf64_Phdr *phdr, int nph) const
3733
0
{
3734
0
    off_t brka = 0;
3735
0
    for (int j = 0; j < nph; ++phdr, ++j) {
3736
0
        if (is_LOAD(phdr)) {
3737
0
            off_t b = get_te64(&phdr->p_vaddr) + get_te64(&phdr->p_memsz);
3738
0
            if (b > brka)
3739
0
                brka = b;
3740
0
        }
3741
0
    }
3742
0
    return brka;
3743
0
}
3744
3745
static unsigned
3746
is_pow2(unsigned x)
3747
0
{
3748
0
    return !((-1 + x) & x);
3749
0
}
3750
3751
void
3752
PackLinuxElf32::generateElfHdr(
3753
    OutputFile *fo,
3754
    void const *proto,
3755
    unsigned const brka
3756
)
3757
0
{
3758
0
    cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
3759
0
    cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
3760
0
    h3->ehdr =         ((cprElfHdr3 const *)proto)->ehdr;
3761
0
    e_type = get_te16(&h3->ehdr.e_type);
3762
0
    if (!memcmp("\x7f\x45\x4c\x46", proto, 4) && Elf32_Ehdr::ET_EXEC == e_type
3763
0
    &&  2 <= get_te16(&h3->ehdr.e_phnum)) {
3764
0
        h3->phdr[C_BASE] = ((cprElfHdr3 const *)proto)->phdr[1];  // .data; .p_align
3765
0
        h3->phdr[C_TEXT] = ((cprElfHdr3 const *)proto)->phdr[0];  // .text
3766
0
    }
3767
0
    else  {
3768
0
        memcpy(&h3->ehdr.e_ident[0], "\x7f\x45\x4c\x46", 4);
3769
0
        h3->ehdr.e_ident[EI_CLASS] = ei_class;
3770
0
        h3->ehdr.e_ident[EI_DATA] = ei_data;
3771
0
        h3->ehdr.e_ident[EI_VERSION] = EV_CURRENT;
3772
0
        h3->ehdr.e_ident[EI_OSABI] = ei_osabi;
3773
3774
0
        h3->ehdr.e_ident[EI_ABIVERSION] = ehdri.e_ident[EI_ABIVERSION];  // ei_abiversion ?
3775
        // Perhaps NT_GNU_ABI_TAG from Shdr .note.ABI-tag  or PT_NOTE ?
3776
        // But that is much too recent (and un-standardized) for other software.
3777
3778
0
        set_te32(&h3->ehdr.e_phoff, sizeof(Elf32_Ehdr));
3779
0
        set_te16(&h3->ehdr.e_ehsize,sizeof(Elf32_Ehdr));
3780
0
        set_te16(&h3->ehdr.e_phentsize, sizeof(Elf32_Phdr));
3781
0
        set_te16(&h3->ehdr.e_phnum, 2);
3782
0
        set_te16(&h3->ehdr.e_machine, e_machine);
3783
0
        set_te16(&h3->ehdr.e_shstrndx, 0);
3784
0
        memset(&h3->phdr[C_BASE], 0, sizeof(h3->phdr[C_BASE]));
3785
0
        memset(&h3->phdr[C_TEXT], 0, sizeof(h3->phdr[C_TEXT]));
3786
0
        memset(&h3->phdr[2     ], 0, sizeof(h3->phdr[2     ]));
3787
0
        set_te32(&h3->phdr[C_BASE].p_flags, 0);
3788
0
        set_te32(&h3->phdr[C_TEXT].p_flags, Elf32_Phdr::PF_X| Elf32_Phdr::PF_R);
3789
0
        if (!memcmp("\x7f\x45\x4c\x46", proto, 4) && Elf32_Ehdr::ET_REL == e_type) {
3790
0
        }
3791
0
        else {
3792
0
            throwCantPack("unknown e_type %#x", e_type);
3793
0
        }
3794
0
    }
3795
0
    h3->ehdr.e_type = ehdri.e_type;  // ET_EXEC vs ET_DYN (gcc -pie -fPIC)
3796
0
    memset(&h3->linfo, 0, sizeof(h3->linfo));
3797
3798
0
    h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;
3799
0
    if (Elf32_Ehdr::EM_MIPS==e_machine) { // MIPS R3000  FIXME
3800
0
        h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = Elf32_Ehdr::ELFOSABI_NONE;
3801
0
        h3->ehdr.e_flags = ehdri.e_flags;
3802
0
    }
3803
3804
0
    if (ph.format != getFormat()) {
3805
0
        assert(false);  // unknown ph.format, PackLinuxElf32
3806
0
    }
3807
0
    assert(get_te32(&h2->ehdr.e_phoff)     == sizeof(Elf32_Ehdr));
3808
0
    assert(get_te16(&h2->ehdr.e_ehsize)    == sizeof(Elf32_Ehdr));
3809
0
    assert(get_te16(&h2->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
3810
3811
0
    h2->ehdr.e_shoff = 0;
3812
0
    set_te16(&h2->ehdr.e_shentsize, sizeof(Elf32_Shdr));  // libbfd-2.41-38.fc40
3813
0
    if (o_elf_shnum) {
3814
0
        h2->ehdr.e_shnum = o_elf_shnum;
3815
0
        h2->ehdr.e_shstrndx = o_elf_shnum - 1;
3816
0
    }
3817
0
    else {
3818
        // https://bugzilla.redhat.com/show_bug.cgi?id=2131609
3819
        // 0==.e_shnum is a special case for libbfd
3820
        // that requires 0==.e_shentsize in order to force "no Shdrs"
3821
        // But qemu 8.2.9 with libbfd-2.41-38.fc40  says EXEC format error
3822
        // and uses 0==.e_shoff instead.
3823
        // h2->ehdr.e_shentsize = 0;
3824
0
        h2->ehdr.e_shnum = 0;
3825
0
        h2->ehdr.e_shstrndx = 0;
3826
0
    }
3827
3828
0
    unsigned phnum_o = 2 + n_phdrx;  // C_BASE, C_TEXT
3829
0
    set_te16(&h2->ehdr.e_phnum, phnum_o);
3830
3831
    // Info for OS kernel to set the brk()
3832
0
    if (brka) {
3833
        // linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
3834
0
        upx_uint32_t lo_va_user = ~0u;  // infinity
3835
0
        for (int j= e_phnum; --j>=0; ) {
3836
0
            if (is_LOAD(&phdri[j])) {
3837
0
                upx_uint32_t const vaddr = get_te32(&phdri[j].p_vaddr);
3838
0
                lo_va_user = umin(lo_va_user, vaddr);
3839
0
            }
3840
0
        }
3841
0
        set_te32(                 &h2->phdr[C_BASE].p_vaddr, lo_va_user);
3842
0
        h2->phdr[C_BASE].p_paddr = h2->phdr[C_BASE].p_vaddr;
3843
0
        h2->phdr[C_TEXT].p_vaddr = h2->phdr[C_BASE].p_vaddr;
3844
0
        h2->phdr[C_TEXT].p_paddr = h2->phdr[C_BASE].p_vaddr;
3845
0
        set_te32(&h2->phdr[C_BASE].p_type, PT_LOAD);  // be sure
3846
0
        set_te32(&h2->phdr[C_TEXT].p_type, PT_LOAD);  // be sure
3847
0
        h2->phdr[C_BASE].p_offset = 0;
3848
0
        h2->phdr[C_BASE].p_filesz = 0;
3849
        // .p_memsz = brka;  temporary until sz_pack2
3850
0
        set_te32(&h2->phdr[C_BASE].p_memsz, brka - lo_va_user);
3851
0
        set_te32(&h2->phdr[C_BASE].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);
3852
0
    }
3853
0
    set_te32(&h3->phdr[C_BASE].p_align, page_size);
3854
0
    set_te32(&h3->phdr[C_TEXT].p_align, page_size);
3855
0
    set_te32(&h2->phdr[C_TEXT].p_flags, ~Elf32_Phdr::PF_W & get_te32(&h2->phdr[C_TEXT].p_flags));
3856
0
    fo->write(h2, sizeof(Elf32_Ehdr) + 2* sizeof(Elf32_Phdr));  // C_BASE, C_TEXT
3857
3858
0
    u64_t const zero_pad = 0;
3859
0
    unsigned uva0 = get_te32(&h2->phdr[C_TEXT].p_vaddr);
3860
0
    unsigned off_o = 0;
3861
0
    for (unsigned phase = 0; phase < 2; ++phase) { // 0: Phdrs;  1: bodies
3862
0
        off_o = sizeof(Elf32_Ehdr) + phnum_o * sizeof(Elf32_Phdr);
3863
0
        for (unsigned j = 0; j < n_phdrx; ++j) {
3864
0
            Elf32_Phdr phtmp = *phdrx[j];
3865
0
            phtmp.p_vaddr = phtmp.p_paddr = 0;
3866
0
            unsigned const off_i = get_te32(&phtmp.p_offset);
3867
0
            unsigned const align = get_te32(&phtmp.p_align);
3868
0
            unsigned const filesz = get_te32(&phtmp.p_filesz);
3869
0
            unsigned pad = 0;
3870
0
            if (filesz && align && is_pow2(align)) {
3871
0
                unsigned alm1 = -1 + umin(8u, align);
3872
0
                pad = alm1 & (0u - off_o);
3873
0
                off_o += pad;
3874
0
                set_te32(&phtmp.p_vaddr, off_o + uva0); phtmp.p_paddr = phtmp.p_vaddr;
3875
0
            }
3876
0
            if (0==phase) {
3877
0
                set_te32(&phtmp.p_offset, (filesz ? off_o : 0));
3878
0
                fo->write(&phtmp, sizeof(phtmp));  // Phdr
3879
0
            }
3880
0
            if (1==phase) {
3881
0
                if (pad) fo->write(&zero_pad, pad);
3882
0
                if (filesz) fo->write(&file_image[off_i], filesz);  // body
3883
0
            }
3884
0
            off_o += filesz;
3885
0
        }
3886
0
    }
3887
0
    off_o = fpad4(fo, off_o);
3888
0
    sz_phdrx = off_o - (sizeof(Elf32_Ehdr) + phnum_o * sizeof(Elf32_Phdr));
3889
0
    set_te32(&h2->phdr[C_BASE].p_filesz, off_o);
3890
3891
0
    sz_elf_hdrs = sizeof(Elf32_Ehdr) + phnum_o * sizeof(Elf32_Phdr) + sz_phdrx;
3892
0
    overlay_offset = sz_elf_hdrs + sizeof(l_info);
3893
0
    o_binfo        = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
3894
3895
0
    l_info linfo2; memset(&linfo2, 0, sizeof(linfo2));
3896
0
    fo->write(&linfo2, sizeof(linfo2));
3897
0
}
3898
3899
void
3900
PackNetBSDElf32x86::generateElfHdr(
3901
    OutputFile *fo,
3902
    void const *proto,
3903
    unsigned const brka
3904
)
3905
0
{
3906
0
    cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
3907
0
    super::generateElfHdr(fo, proto, brka);
3908
3909
0
    sz_elf_hdrs = sizeof(*h2) - sizeof(linfo);
3910
0
    unsigned note_offset = sz_elf_hdrs;
3911
3912
    // Find the NetBSD PT_NOTE and the PaX PT_NOTE.
3913
0
    Elf32_Nhdr const *np_NetBSD = nullptr;  unsigned sz_NetBSD = 0;
3914
0
    Elf32_Nhdr const *np_PaX    = nullptr;  unsigned sz_PaX    = 0;
3915
0
    unsigned char *cp = (unsigned char *)note_body;
3916
0
    unsigned j;
3917
0
    for (j=0; j < note_size; ) {
3918
0
        Elf32_Nhdr const *const np = (Elf32_Nhdr const *)(void *)cp;
3919
0
        int k = sizeof(*np) + up4(get_te32(&np->namesz))
3920
0
            + up4(get_te32(&np->descsz));
3921
3922
0
        if (NHDR_NETBSD_TAG == np->type && 7== np->namesz
3923
0
        &&  NETBSD_DESCSZ == np->descsz
3924
0
        &&  0==strcmp(ELF_NOTE_NETBSD_NAME,
3925
0
                /* &np->body */ (char const *)(1+ np))) {
3926
0
            np_NetBSD = np;
3927
0
            sz_NetBSD = k;
3928
0
        }
3929
0
        if (NHDR_PAX_TAG == np->type && 4== np->namesz
3930
0
        &&  PAX_DESCSZ==np->descsz
3931
0
        &&  0==strcmp(ELF_NOTE_PAX_NAME,
3932
0
                /* &np->body */ (char const *)(1+ np))) {
3933
0
            np_PaX = np;
3934
0
            sz_PaX = k;
3935
0
        }
3936
0
        cp += k;
3937
0
        j += k;
3938
0
    }
3939
3940
    // Add PT_NOTE for the NetBSD note and PaX note, if any.
3941
0
    note_offset += (np_NetBSD ? sizeof(Elf32_Phdr) : 0);
3942
0
    note_offset += (np_PaX    ? sizeof(Elf32_Phdr) : 0);
3943
0
    Elf32_Phdr *phdr = &elfout.phdr[C_NOTE];
3944
0
    if (np_NetBSD) {
3945
0
        set_te32(&phdr->p_type, PT_NOTE32);
3946
0
        set_te32(&phdr->p_offset, note_offset);
3947
0
        set_te32(&phdr->p_vaddr, note_offset);
3948
0
        set_te32(&phdr->p_paddr, note_offset);
3949
0
        set_te32(&phdr->p_filesz, sz_NetBSD);
3950
0
        set_te32(&phdr->p_memsz,  sz_NetBSD);
3951
0
        set_te32(&phdr->p_flags, Elf32_Phdr::PF_R);
3952
0
        set_te32(&phdr->p_align, 4);
3953
3954
0
        sz_elf_hdrs += sz_NetBSD + sizeof(*phdr);
3955
0
        note_offset += sz_NetBSD;
3956
0
        ++phdr;
3957
0
    }
3958
0
    if (np_PaX) {
3959
0
        set_te32(&phdr->p_type, PT_NOTE32);
3960
0
        set_te32(&phdr->p_offset, note_offset);
3961
0
        set_te32(&phdr->p_vaddr, note_offset);
3962
0
        set_te32(&phdr->p_paddr, note_offset);
3963
0
        set_te32(&phdr->p_filesz, sz_PaX);
3964
0
        set_te32(&phdr->p_memsz,  sz_PaX);
3965
0
        set_te32(&phdr->p_flags, Elf32_Phdr::PF_R);
3966
0
        set_te32(&phdr->p_align, 4);
3967
3968
        /* &np_PaX->body[4] */
3969
0
        const unsigned char *p4 =  &(ACC_CCAST(const unsigned char *, (1+ np_PaX)))[4];
3970
0
        unsigned bits = get_te32(p4);
3971
0
        bits &= ~PAX_MPROTECT;
3972
0
        bits |=  PAX_NOMPROTECT;
3973
0
        set_te32(ACC_UNCONST_CAST(unsigned char *, p4), bits);
3974
3975
0
        sz_elf_hdrs += sz_PaX + sizeof(*phdr);
3976
0
        note_offset += sz_PaX;
3977
0
        ++phdr;
3978
0
    }
3979
0
    set_te32(&h2->phdr[C_TEXT].p_filesz, note_offset);
3980
0
              h2->phdr[C_TEXT].p_memsz = h2->phdr[C_TEXT].p_filesz;
3981
3982
0
    if (ph.format==getFormat()) {
3983
0
        set_te16(&h2->ehdr.e_phnum, !!sz_NetBSD + !!sz_PaX +
3984
0
        get_te16(&h2->ehdr.e_phnum));
3985
0
        fo->seek(0, SEEK_SET);
3986
0
        fo->rewrite(h2, sizeof(*h2) - sizeof(h2->linfo));
3987
3988
        // The 'if' guards on these two calls to memcpy are required
3989
        // because the C Standard Committee did not debug the Standard
3990
        // before publishing.  An empty region (0==size) must nevertheless
3991
        // have a valid (non-nullptr) pointer.
3992
0
        if (sz_NetBSD) memcpy(&((char *)phdr)[0],         np_NetBSD, sz_NetBSD);
3993
0
        if (sz_PaX)    memcpy(&((char *)phdr)[sz_NetBSD], np_PaX,    sz_PaX);
3994
3995
0
        fo->write(&elfout.phdr[C_NOTE],
3996
0
            &((char *)phdr)[sz_PaX + sz_NetBSD] - (char *)&elfout.phdr[C_NOTE]);
3997
3998
0
        l_info foo; memset(&foo, 0, sizeof(foo));
3999
0
        fo->rewrite(&foo, sizeof(foo));
4000
0
    }
4001
0
    else {
4002
0
        assert(false);  // unknown ph.format, PackLinuxElf32
4003
0
    }
4004
0
}
4005
4006
void
4007
PackOpenBSDElf32x86::generateElfHdr(
4008
    OutputFile *fo,
4009
    void const *proto,
4010
    unsigned const brka
4011
)
4012
0
{
4013
0
    cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
4014
0
    memcpy(h3, proto, sizeof(*h3));  // reads beyond, but OK
4015
0
    h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;
4016
0
    assert(2==get_te16(&h3->ehdr.e_phnum));
4017
0
    set_te16(&h3->ehdr.e_phnum, 3);
4018
4019
0
    assert(get_te32(&h3->ehdr.e_phoff)     == sizeof(Elf32_Ehdr));
4020
0
                         h3->ehdr.e_shoff = 0;
4021
0
    assert(get_te16(&h3->ehdr.e_ehsize)    == sizeof(Elf32_Ehdr));
4022
0
    assert(get_te16(&h3->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
4023
0
    set_te16(&h3->ehdr.e_shentsize, sizeof(Elf32_Shdr));  // libbfd-2.41-38.fc40
4024
0
    h3->ehdr.e_shnum = 0;
4025
0
    h3->ehdr.e_shstrndx = 0;
4026
4027
0
    struct {
4028
0
        Elf32_Nhdr nhdr;
4029
0
        char name[8];
4030
0
        unsigned body;
4031
0
    } elfnote;
4032
4033
0
    unsigned const note_offset = sizeof(*h3) - sizeof(linfo);
4034
0
    sz_elf_hdrs = sizeof(elfnote) + note_offset;
4035
4036
0
    set_te32(&h3->phdr[C_NOTE].p_type, PT_NOTE32);
4037
0
    set_te32(&h3->phdr[C_NOTE].p_offset, note_offset);
4038
0
    set_te32(&h3->phdr[C_NOTE].p_vaddr, note_offset);
4039
0
    set_te32(&h3->phdr[C_NOTE].p_paddr, note_offset);
4040
0
    set_te32(&h3->phdr[C_NOTE].p_filesz, sizeof(elfnote));
4041
0
    set_te32(&h3->phdr[C_NOTE].p_memsz,  sizeof(elfnote));
4042
0
    set_te32(&h3->phdr[C_NOTE].p_flags, Elf32_Phdr::PF_R);
4043
0
    set_te32(&h3->phdr[C_NOTE].p_align, 4);
4044
4045
    // Q: Same as this->note_body[0 .. this->note_size-1] ?
4046
0
    set_te32(&elfnote.nhdr.namesz, 8);
4047
0
    set_te32(&elfnote.nhdr.descsz, OPENBSD_DESCSZ);
4048
0
    set_te32(&elfnote.nhdr.type,   NHDR_OPENBSD_TAG);
4049
0
    memcpy(elfnote.name, "OpenBSD", sizeof(elfnote.name));
4050
0
    elfnote.body = 0;
4051
4052
0
    set_te32(&h3->phdr[C_TEXT].p_filesz, sz_elf_hdrs);
4053
0
              h3->phdr[C_TEXT].p_memsz = h3->phdr[C_TEXT].p_filesz;
4054
4055
0
    unsigned const brkb = brka | ((0==(~page_mask & brka)) ? 0x20 : 0);
4056
0
    set_te32(&h3->phdr[C_BASE].p_type, PT_LOAD);  // be sure
4057
0
    set_te32(&h3->phdr[C_BASE].p_offset, ~page_mask & brkb);
4058
0
    set_te32(&h3->phdr[C_BASE].p_vaddr, brkb);
4059
0
    set_te32(&h3->phdr[C_BASE].p_paddr, brkb);
4060
0
    h3->phdr[C_BASE].p_filesz = 0;
4061
    // Too many kernels have bugs when 0==.p_memsz
4062
0
    set_te32(&h3->phdr[C_BASE].p_memsz, 1);
4063
0
    set_te32(&h3->phdr[C_BASE].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);
4064
4065
0
    if (ph.format==getFormat()) {
4066
0
        memset(&h3->linfo, 0, sizeof(h3->linfo));
4067
0
        fo->write(h3, sizeof(*h3) - sizeof(h3->linfo));
4068
0
        fo->write(&elfnote, sizeof(elfnote));
4069
0
        fo->write(&h3->linfo, sizeof(h3->linfo));
4070
0
    }
4071
0
    else {
4072
0
        assert(false);  // unknown ph.format, PackLinuxElf32
4073
0
    }
4074
0
}
4075
4076
void
4077
PackLinuxElf64::generateElfHdr(
4078
    OutputFile *fo,
4079
    void const *proto,
4080
    unsigned const brka
4081
)
4082
0
{
4083
0
    cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
4084
0
    cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
4085
0
    h3->ehdr =         ((cprElfHdr3 const *)proto)->ehdr;
4086
0
    if (Elf64_Ehdr::ET_REL == get_te16(&h3->ehdr.e_type)) {
4087
0
        set_te64(&h3->ehdr.e_phoff, sizeof(Elf64_Ehdr));
4088
0
        set_te16(&h3->ehdr.e_ehsize,sizeof(Elf64_Ehdr));
4089
0
        set_te16(&h3->ehdr.e_phentsize, sizeof(Elf64_Phdr));
4090
0
        set_te16(&h3->ehdr.e_phnum, 2);
4091
0
        memset(&h3->phdr[C_BASE], 0, sizeof(h3->phdr[C_BASE]));
4092
0
        memset(&h3->phdr[C_TEXT], 0, sizeof(h3->phdr[C_TEXT]));
4093
0
        memset(&h3->phdr[2     ], 0, sizeof(h3->phdr[2     ]));
4094
0
        set_te32(&h3->phdr[C_BASE].p_flags, 0);
4095
0
        set_te32(&h3->phdr[C_TEXT].p_flags, Elf64_Phdr::PF_X| Elf64_Phdr::PF_R);
4096
0
    }
4097
0
    else {
4098
0
        h3->phdr[C_BASE] = ((cprElfHdr3 const *)proto)->phdr[1];  // .data; .p_align
4099
0
        h3->phdr[C_TEXT] = ((cprElfHdr3 const *)proto)->phdr[0];  // .text
4100
0
    }
4101
0
    memset(&h3->linfo, 0, sizeof(h3->linfo));
4102
4103
0
    h3->ehdr.e_type = ehdri.e_type;  // ET_EXEC vs ET_DYN (gcc -pie -fPIC)
4104
0
    h3->ehdr.e_ident[Elf64_Ehdr::EI_OSABI] = ei_osabi;
4105
0
    if (Elf64_Ehdr::ELFOSABI_LINUX == ei_osabi  // proper
4106
0
    &&  Elf64_Ehdr::ELFOSABI_NONE  == ehdri.e_ident[Elf64_Ehdr::EI_OSABI]  // sloppy
4107
0
    ) { // propagate sloppiness so that decompression does not complain
4108
0
        h3->ehdr.e_ident[Elf64_Ehdr::EI_OSABI] = ehdri.e_ident[Elf64_Ehdr::EI_OSABI];
4109
0
    }
4110
0
    if (Elf64_Ehdr::EM_PPC64 == get_te16(&ehdri.e_machine)) {
4111
0
        h3->ehdr.e_flags = ehdri.e_flags;  // "0x1, abiv1" vs "0x2, abiv2"
4112
0
    }
4113
4114
0
    assert(get_te64(&h2->ehdr.e_phoff)     == sizeof(Elf64_Ehdr));
4115
0
    assert(get_te16(&h2->ehdr.e_ehsize)    == sizeof(Elf64_Ehdr));
4116
0
    assert(get_te16(&h2->ehdr.e_phentsize) == sizeof(Elf64_Phdr));
4117
4118
0
    h2->ehdr.e_shoff = 0;
4119
0
    set_te16(&h2->ehdr.e_shentsize, sizeof(Elf64_Shdr));  // libbfd-2.41-38.fc40
4120
0
    if (o_elf_shnum) {
4121
0
        h2->ehdr.e_shnum = o_elf_shnum;
4122
0
        h2->ehdr.e_shstrndx = o_elf_shnum - 1;
4123
0
    }
4124
0
    else {
4125
        // https://bugzilla.redhat.com/show_bug.cgi?id=2131609
4126
        // 0==.e_shnum is a special case for libbfd
4127
        // that requires 0==.e_shentsize in order to force "no Shdrs"
4128
        // But qemu 8.2.9 with libbfd-2.41-38.fc40  says EXEC format error
4129
        // and uses 0==.e_shoff instead.
4130
        // h2->ehdr.e_shentsize = 0;
4131
0
        h2->ehdr.e_shnum = 0;
4132
0
        h2->ehdr.e_shstrndx = 0;
4133
0
    }
4134
4135
0
    unsigned const phnum_i = get_te16(&h2->ehdr.e_phnum);
4136
0
    unsigned       phnum_o = 2 + n_phdrx;  // C_BASE, C_TEXT
4137
0
    set_te16(&h2->ehdr.e_phnum, phnum_o);
4138
0
    o_binfo =  sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr)*phnum_o + sizeof(l_info) + sizeof(p_info);
4139
0
    set_te64(&h2->phdr[C_TEXT].p_filesz, sizeof(*h2));  // + identsize;
4140
0
              h2->phdr[C_TEXT].p_memsz = h2->phdr[C_TEXT].p_filesz;
4141
0
    set_te32(&h2->phdr[C_TEXT].p_type, PT_LOAD);  // be sure
4142
4143
0
    for (unsigned j=0; j < phnum_i; ++j) {
4144
0
        if (is_LOAD(&h3->phdr[j])) {
4145
0
            set_te64( &h3->phdr[j].p_align, page_size);
4146
0
        }
4147
0
    }
4148
4149
    // Info for OS kernel to set the brk()
4150
0
    if (brka) {
4151
        // linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
4152
0
        upx_uint64_t lo_va_user(~(upx_uint64_t)0);  // infinity
4153
0
        for (int j= e_phnum; --j>=0; ) {
4154
0
            if (is_LOAD(&phdri[j])) {
4155
0
                upx_uint64_t const vaddr = get_te64(&phdri[j].p_vaddr);
4156
0
                lo_va_user = umin(lo_va_user, vaddr);
4157
0
            }
4158
0
        }
4159
0
        set_te64(                 &h2->phdr[C_BASE].p_vaddr, lo_va_user);
4160
0
        h2->phdr[C_BASE].p_paddr = h2->phdr[C_BASE].p_vaddr;
4161
0
        h2->phdr[C_TEXT].p_vaddr = h2->phdr[C_BASE].p_vaddr;
4162
0
        h2->phdr[C_TEXT].p_paddr = h2->phdr[C_BASE].p_vaddr;
4163
0
        set_te32(&h2->phdr[C_BASE].p_type, PT_LOAD);  // be sure
4164
0
        h2->phdr[C_BASE].p_offset = 0;
4165
0
        h2->phdr[C_BASE].p_filesz = 0;
4166
        // .p_memsz = brka;  temporary until sz_pack2
4167
0
        set_te64(&h2->phdr[C_BASE].p_memsz, brka - lo_va_user);
4168
0
        set_te32(&h2->phdr[C_BASE].p_flags, Elf64_Phdr::PF_R | Elf64_Phdr::PF_W);
4169
0
    }
4170
0
    set_te64(&h3->phdr[C_BASE].p_align, page_size);
4171
0
    set_te64(&h3->phdr[C_TEXT].p_align, page_size);
4172
0
    set_te32(&h2->phdr[C_TEXT].p_flags, ~Elf64_Phdr::PF_W & get_te32(&h2->phdr[C_TEXT].p_flags));
4173
0
    fo->write(h2, sizeof(Elf64_Ehdr) + 2* sizeof(Elf64_Phdr));  // C_BASE, C_TEXT
4174
4175
0
    u64_t const zero_pad = 0;
4176
0
    unsigned uva0 = get_te64(&h2->phdr[C_TEXT].p_vaddr);
4177
0
    unsigned off_o = 0;
4178
0
    for (unsigned phase = 0; phase < 2; ++phase) { // 0: Phdrs;  1: bodies
4179
0
        off_o = sizeof(Elf64_Ehdr) + phnum_o * sizeof(Elf64_Phdr);
4180
0
        for (unsigned j = 0; j < n_phdrx; ++j) {
4181
0
            Elf64_Phdr phtmp = *phdrx[j];
4182
0
            phtmp.p_vaddr = phtmp.p_paddr = 0;
4183
0
            u64_t const off_i = get_te64(&phtmp.p_offset);
4184
0
            u64_t const align = get_te64(&phtmp.p_align);
4185
0
            u64_t const filesz = get_te64(&phtmp.p_filesz);
4186
0
            unsigned pad = 0;
4187
0
            if (filesz && align && is_pow2(align)) {
4188
0
                unsigned alm1 = -1 + umin(8u, (unsigned)align);
4189
0
                pad = alm1 & (0u - off_o);
4190
0
                off_o += pad;
4191
0
                set_te64(&phtmp.p_vaddr, off_o + uva0); phtmp.p_paddr = phtmp.p_vaddr;
4192
0
            }
4193
0
            if (0==phase) {
4194
0
                set_te64(&phtmp.p_offset, (filesz ? off_o : 0));
4195
0
                fo->write(&phtmp, sizeof(phtmp));  // Phdr
4196
0
            }
4197
0
            if (1==phase) {
4198
0
                if (pad) fo->write(&zero_pad, pad);
4199
0
                if (filesz) fo->write(&file_image[off_i], filesz);  // body
4200
0
            }
4201
0
            off_o += filesz;
4202
0
        }
4203
0
    }
4204
0
    off_o = fpad4(fo, off_o);
4205
0
    sz_phdrx = off_o - (sizeof(Elf64_Ehdr) + phnum_o * sizeof(Elf64_Phdr));
4206
0
    set_te64(&h2->phdr[C_BASE].p_filesz, off_o);
4207
4208
0
    sz_elf_hdrs = sizeof(Elf64_Ehdr) + phnum_o * sizeof(Elf64_Phdr) + sz_phdrx;
4209
0
    overlay_offset = sz_elf_hdrs + sizeof(l_info);
4210
0
    o_binfo        = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
4211
4212
0
    l_info linfo2; memset(&linfo2, 0, sizeof(linfo2));
4213
0
    fo->write(&linfo2, sizeof(linfo2));
4214
0
}
4215
4216
// Android shlib has ABS symbols that actually are relative.
4217
static char const abs_symbol_names[][14] = {
4218
      "__bss_end__"
4219
    ,  "_bss_end__"
4220
    , "__bss_start"
4221
    , "__bss_start__"
4222
    ,  "_edata"
4223
    ,  "_end"
4224
    , "__end__"
4225
    , ""
4226
};
4227
4228
int
4229
PackLinuxElf32::adjABS(Elf32_Sym *sym, unsigned delta)
4230
0
{
4231
0
    unsigned st_name = get_te32(&sym->st_name);
4232
0
    for (int j = 0; abs_symbol_names[j][0]; ++j) {
4233
0
        if (!strcmp(abs_symbol_names[j], get_str_name(st_name, (unsigned)-1))) {
4234
0
            sym->st_value += delta;
4235
0
            return 1;
4236
0
        }
4237
0
    }
4238
0
    return 0;
4239
0
}
4240
4241
int
4242
PackLinuxElf64::adjABS(Elf64_Sym *sym, unsigned long delta)
4243
0
{
4244
0
    unsigned st_name = get_te32(&sym->st_name);
4245
0
    for (int j = 0; abs_symbol_names[j][0]; ++j) {
4246
0
        if (!strcmp(abs_symbol_names[j], get_str_name(st_name, (unsigned)-1))) {
4247
0
            sym->st_value += delta;
4248
0
            return 1;
4249
0
        }
4250
0
    }
4251
0
    return 0;
4252
0
}
4253
4254
void PackLinuxElf32::pack1(OutputFile * /*fo*/, Filter &ft)
4255
0
{
4256
0
    fi->seek(0, SEEK_SET);
4257
0
    fi->readx(&ehdri, sizeof(ehdri));
4258
0
    assert(e_phoff == sizeof(Elf32_Ehdr));  // checked by canPack()
4259
0
    sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
4260
4261
// We compress separate pieces (usually each PT_LOAD, plus the gaps in the file
4262
// that are not covered by any PT_LOAD), but currently at run time there can be
4263
// only one decompressor method.
4264
// Therefore we must plan ahead because Packer::compressWithFilters tries
4265
// to find the smallest result among the available methods, for one piece only.
4266
// In the future we may allow more than one decompression method at run time.
4267
// For now we must choose only one, and force PackUnix::packExtent
4268
// (==> compressWithFilters) to use it.
4269
0
    int nfilters = 0;
4270
0
    {
4271
0
        int const *fp = getFilters();
4272
0
        while (FT_END != *fp++) {
4273
0
            ++nfilters;
4274
0
        }
4275
0
    }
4276
0
    {
4277
0
        int npieces = 1;  // tail after highest PT_LOAD
4278
0
        Elf32_Phdr *phdr = phdri;
4279
0
        for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
4280
0
            if (is_LOAD(phdr)) {
4281
0
                unsigned const  flags = get_te32(&phdr->p_flags);
4282
0
                unsigned       offset = get_te32(&phdr->p_offset);
4283
0
                if (!xct_off  // not shlib
4284
                  // new-style shlib: PT_LOAD[0] has symbol table
4285
                  // which must not be compressed, but also lacks PF_X
4286
0
                ||    (Elf32_Phdr::PF_X & flags)
4287
                  // Read-only, non-first PT_LOAD is _assumed_ to be compressible
4288
0
                ||  (!(Elf32_Phdr::PF_W & flags) && 0!=offset))
4289
0
                {
4290
0
                    ++npieces;  // will attempt compression of this PT_LOAD
4291
0
                }
4292
0
            }
4293
0
        }
4294
0
        uip->ui_total_passes += npieces;
4295
0
    }
4296
0
    int methods[256];
4297
0
    unsigned nmethods = prepareMethods(methods, ph.method, getCompressionMethods(M_ALL, ph.level));
4298
0
    if (1 < nmethods) { // Many are available, but we must choose only one
4299
0
        uip->ui_total_passes += 1;  // the batch for output
4300
0
        uip->ui_total_passes *= nmethods * (1+ nfilters);  // finding smallest total
4301
0
        PackHeader orig_ph = ph;
4302
0
        Filter orig_ft = ft;
4303
0
        unsigned max_offset = 0;
4304
0
        unsigned sz_best= ~0u;
4305
0
        int method_best = 0;
4306
0
        for (unsigned k = 0; k < nmethods; ++k) { // FIXME: parallelize; cost: working space
4307
0
            unsigned sz_this = 0;
4308
0
            Elf32_Phdr *phdr = phdri;
4309
0
            for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
4310
0
                if (is_LOAD(phdr)) {
4311
0
                    unsigned const  flags = get_te32(&phdr->p_flags);
4312
0
                    unsigned       offset = get_te32(&phdr->p_offset);
4313
0
                    unsigned       filesz = get_te32(&phdr->p_filesz);
4314
0
                    max_offset = UPX_MAX(max_offset, filesz + offset);
4315
0
                    if (!xct_off  // not shlib
4316
                      // new-style shlib: PT_LOAD[0] has symbol table
4317
                      // which must not be compressed, but also lacks PF_X
4318
0
                    ||    (Elf32_Phdr::PF_X & flags)
4319
                      // Read-only, non-first PT_LOAD is _assumed_ to be compressible
4320
0
                    ||  (!(Elf32_Phdr::PF_W & flags) && 0!=offset))
4321
0
                    {
4322
0
                        if (xct_off && 0==offset) { // old-style shlib
4323
0
                            offset  = xct_off;
4324
0
                            filesz -= xct_off;
4325
0
                        }
4326
0
                        fi->seek(offset, SEEK_SET);
4327
0
                        fi->readx(ibuf, filesz);
4328
0
                        ft = orig_ft;
4329
0
                        ph = orig_ph;
4330
0
                        ph.set_method(ph_force_method(methods[k]), offset);
4331
0
                        ph.u_len = filesz;
4332
0
                        compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true);
4333
0
                        sz_this += ph.c_len;
4334
0
                    }
4335
0
                }
4336
0
            }
4337
0
            unsigned const sz_tail = file_size - max_offset;  // debuginfo, etc.
4338
0
            if (sz_tail) {
4339
0
                fi->seek(max_offset, SEEK_SET);
4340
0
                fi->readx(ibuf, sz_tail);
4341
0
                ft = orig_ft;
4342
0
                ph = orig_ph;
4343
0
                ph.set_method(ph_force_method(methods[k]));
4344
0
                ph.u_len = sz_tail;
4345
0
                compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true);
4346
0
                sz_this += ph.c_len;
4347
0
            }
4348
            // FIXME: loader size also depends on method
4349
0
            if (sz_best > sz_this) {
4350
0
                sz_best = sz_this;
4351
0
                method_best = methods[k];
4352
0
            }
4353
0
        }
4354
0
        ft = orig_ft;
4355
0
        ph = orig_ph;
4356
0
        ph.set_method(ph_force_method(method_best));
4357
0
    }
4358
4359
0
    Elf32_Phdr *phdr = phdri;
4360
0
    for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
4361
0
        unsigned const type = get_te32(&phdr->p_type);
4362
0
        if (PT_GNU_STACK32 == type || PT_NOTE32 == type) {
4363
0
            add_phdrx(phdr);  // PT_GNU_STACK32, PT_NOTE32
4364
0
        }
4365
0
        if (PT_LOAD == type) {
4366
0
            unsigned x = get_te32(&phdr->p_align) >> lg2_page;
4367
0
            while (x>>=1) {
4368
0
                ++lg2_page;
4369
0
            }
4370
0
        }
4371
0
        if (PT_GNU_RELRO32 == type
4372
0
        &&  16 < lg2_page) {
4373
            // x86* allows 4K, 2M, 1G
4374
            // arm32 and arm64 both allow 4K, 16K, 64K; Apple Silicon uses 16K
4375
            // Oracle 5.4.17-2136.314.6.2.el8uek.aarch64 demands 64K
4376
            // PowerPC and PowerPC64 has 4K, 64K, 1M (?), 16M (?)
4377
            // MIPS  allows any power of 2 from 4K through 64K
4378
4379
            // If 64K < .p_align then we assume that 4K is also accepted.
4380
            // .p_align can be like 2M, which is a huge over-estimate.
4381
            // RELRO ends on a page boundary: usually close to actual page_size
4382
0
            unsigned offset = get_te32(&phdr->p_offset);
4383
0
            unsigned filesz = get_te32(&phdr->p_filesz);
4384
0
            if (!(0xfff & (filesz + offset))) { // a 4KiB boundary
4385
0
                unsigned b = 12;
4386
0
                while (!(~(~0u << b) & (filesz + offset))) {
4387
0
                    ++b;
4388
0
                }
4389
0
                lg2_page = umin(lg2_page, -1+ b);
4390
0
            }
4391
0
        }
4392
0
    }
4393
0
    page_size =  1u  <<lg2_page;
4394
0
    page_mask = ~0ull<<lg2_page;
4395
4396
0
    progid = 0;  // getRandomId();  not useful, so do not clutter
4397
0
    sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
4398
4399
    // only execute if option present
4400
0
    if (opt->o_unix.preserve_build_id) {
4401
        // set this so we can use elf_find_section_name
4402
0
        e_shnum = get_te16(&ehdri.e_shnum);
4403
0
        if (!shdri) {
4404
0
            mb_shdr.alloc(e_shnum * sizeof(Elf32_Shdr));
4405
0
            shdri = (Elf32_Shdr *)mb_shdr.getVoidPtr();
4406
0
            e_shoff = get_te32(&ehdri.e_shoff);
4407
0
            fi->seek(e_shoff, SEEK_SET);
4408
0
            fi->readx(shdri, e_shnum * sizeof(Elf32_Shdr));
4409
0
        }
4410
        //set the shstrtab
4411
0
        sec_strndx = &shdri[get_te16(&ehdri.e_shstrndx)];
4412
4413
0
        upx_uint32_t sh_size = get_te32(&sec_strndx->sh_size);
4414
0
        mb_shstrtab.alloc(sh_size); shstrtab = (char *)mb_shstrtab.getVoidPtr();
4415
0
        fi->seek(0,SEEK_SET);
4416
0
        fi->seek(sec_strndx->sh_offset,SEEK_SET);
4417
0
        fi->readx(mb_shstrtab, sh_size);
4418
4419
0
        Elf32_Shdr const *buildid = elf_find_section_name(".note.gnu.build-id");
4420
0
        if (buildid) {
4421
0
            unsigned bid_sh_size = get_te32(&buildid->sh_size);
4422
0
            buildid_data.alloc(bid_sh_size);
4423
0
            buildid_data.clear();
4424
0
            fi->seek(0,SEEK_SET);
4425
0
            fi->seek(buildid->sh_offset,SEEK_SET);
4426
0
            fi->readx((void *)buildid_data, bid_sh_size);
4427
4428
0
            o_elf_shnum = 3;
4429
0
            memset(&shdrout,0,sizeof(shdrout));
4430
4431
            //setup the build-id
4432
0
            memcpy(&shdrout.shdr[1], buildid, sizeof(shdrout.shdr[1]));
4433
0
            set_te32(&shdrout.shdr[1].sh_name, 1);
4434
4435
            //setup the shstrtab
4436
0
            memcpy(&shdrout.shdr[2], sec_strndx, sizeof(shdrout.shdr[2]));
4437
0
            set_te32(&shdrout.shdr[2].sh_name, 20);
4438
0
            set_te32(&shdrout.shdr[2].sh_size, 29); //size of our static shstrtab
4439
0
        }
4440
0
    }
4441
0
}
4442
4443
void PackLinuxElf32x86::pack1(OutputFile *fo, Filter &ft)
4444
0
{
4445
0
    super::pack1(fo, ft);
4446
0
    if (0!=xct_off)  // shared library
4447
0
        return;
4448
0
    generateElfHdr(fo, stub_i386_linux_elf_fold, getbrk(phdri, e_phnum) );
4449
0
}
4450
4451
void PackBSDElf32x86::pack1(OutputFile *fo, Filter &ft)
4452
0
{
4453
0
    super::pack1(fo, ft);
4454
0
    if (0!=xct_off) // shared library
4455
0
        return;
4456
0
    generateElfHdr(fo, stub_i386_bsd_elf_fold, getbrk(phdri, e_phnum) );
4457
0
}
4458
4459
void PackLinuxElf32armLe::pack1(OutputFile *fo, Filter &ft)
4460
0
{
4461
0
    super::pack1(fo, ft);
4462
0
    if (0!=xct_off)  // shared library
4463
0
        return;
4464
0
    unsigned const e_flags = get_te32(&ehdri.e_flags);
4465
0
    cprElfHdr3 h3;
4466
0
    if (Elf32_Ehdr::ELFOSABI_LINUX==ei_osabi) {
4467
0
        memcpy(&h3, stub_arm_v5a_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
4468
4469
0
        h3.ehdr.e_ident[Elf32_Ehdr::EI_ABIVERSION] = e_flags>>24;
4470
0
    }
4471
0
    else {
4472
0
        memcpy(&h3, stub_arm_v4a_linux_elf_fold,        sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
4473
0
    }
4474
    // Fighting over .e_ident[EI_ABIVERSION]: Debian armhf is latest culprit.
4475
    // So copy from input to output; but see PackLinuxElf32::generateElfHdr
4476
0
    memcpy(&h3.ehdr.e_ident[0], &ehdri.e_ident[0], sizeof(ehdri.e_ident));
4477
0
    set_te32(&h3.ehdr.e_flags, e_flags);
4478
0
    generateElfHdr(fo, &h3, getbrk(phdri, e_phnum) );
4479
0
}
4480
4481
void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft)
4482
0
{
4483
0
    super::pack1(fo, ft);
4484
0
    if (0!=xct_off)  // shared library
4485
0
        return;
4486
0
    unsigned const e_flags = get_te32(&ehdri.e_flags);
4487
0
    cprElfHdr3 h3;
4488
0
    memcpy(&h3, stub_armeb_v4a_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
4489
0
    set_te32(&h3.ehdr.e_flags, e_flags);
4490
0
    generateElfHdr(fo, &h3, getbrk(phdri, e_phnum) );
4491
0
}
4492
4493
void PackLinuxElf32mipsel::pack1(OutputFile *fo, Filter &ft)
4494
0
{
4495
0
    super::pack1(fo, ft);
4496
0
    if (0!=xct_off)  // shared library
4497
0
        return;
4498
0
    cprElfHdr3 h3;
4499
0
    memcpy(&h3, stub_mipsel_r3000_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
4500
0
    generateElfHdr(fo, &h3, getbrk(phdri, e_phnum) );
4501
0
}
4502
4503
void PackLinuxElf32mipseb::pack1(OutputFile *fo, Filter &ft)
4504
0
{
4505
0
    super::pack1(fo, ft);
4506
0
    if (0!=xct_off)  // shared library
4507
0
        return;
4508
0
    cprElfHdr3 h3;
4509
0
    memcpy(&h3, stub_mips_r3000_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
4510
0
    generateElfHdr(fo, &h3, getbrk(phdri, e_phnum) );
4511
0
}
4512
4513
void PackLinuxElf32ppc::pack1(OutputFile *fo, Filter &ft)
4514
0
{
4515
0
    super::pack1(fo, ft);
4516
0
    if (0!=xct_off)  // shared library
4517
0
        return;
4518
0
    generateElfHdr(fo, stub_powerpc_linux_elf_fold, getbrk(phdri, e_phnum) );
4519
0
}
4520
4521
void PackLinuxElf64ppcle::pack1(OutputFile *fo, Filter &ft)
4522
0
{
4523
0
    super::pack1(fo, ft);
4524
0
    if (0!=xct_off)  // shared library
4525
0
        return;
4526
0
    generateElfHdr(fo, stub_powerpc64le_linux_elf_fold, getbrk(phdri, e_phnum) );
4527
0
}
4528
4529
void PackLinuxElf64ppc::pack1(OutputFile *fo, Filter &ft)
4530
0
{
4531
0
    super::pack1(fo, ft);
4532
0
    if (0!=xct_off)  // shared library
4533
0
        return;
4534
0
    generateElfHdr(fo, stub_powerpc64_linux_elf_fold, getbrk(phdri, e_phnum) );
4535
0
}
4536
4537
void PackLinuxElf64::asl_pack2_Shdrs(OutputFile *fo, unsigned pre_xct_top)
4538
0
{
4539
0
    if (!fo) {
4540
0
        return;
4541
0
    }
4542
    // In order to pacify the runtime linker on Android "O" ("Oreo"),
4543
    // we will splice-in a 4KiB page that contains an "extra" copy
4544
    // of the Shdr, any PT_NOTE above xct_off, and shstrtab.
4545
    // File order: Ehdr, Phdr[], section contents below xct_off,
4546
    //    Shdr_copy[], PT_NOTEs.hi, shstrtab.
4547
0
    if (is_asl)
4548
0
        xct_va  += asl_delta;
4549
    //xct_off += asl_delta;  // not until ::pack3()
4550
4551
0
    total_in = pre_xct_top;
4552
4553
    // Relocate PT_DYNAMIC (in PT_LOAD with PF_W)
4554
0
    Elf64_Dyn *dyn = const_cast<Elf64_Dyn *>(dynseg);
4555
0
    for (; dyn->d_tag; ++dyn) {
4556
0
        upx_uint64_t d_tag = get_te64(&dyn->d_tag);
4557
0
        if (Elf64_Dyn::DT_FINI       == d_tag
4558
0
        ||  Elf64_Dyn::DT_FINI_ARRAY == d_tag
4559
0
        ||  Elf64_Dyn::DT_INIT_ARRAY == d_tag
4560
0
        ||  Elf64_Dyn::DT_PREINIT_ARRAY == d_tag
4561
0
        ||  Elf64_Dyn::DT_PLTGOT      == d_tag) {
4562
0
            upx_uint64_t d_val = get_te64(&dyn->d_val);
4563
0
            set_te64(&dyn->d_val, asl_delta + d_val);
4564
0
        }
4565
0
    }
4566
    // Updated dynseg (.dynamic, in PT_DYNAMIC (PT_LOAD{PF_W})) has not been written.
4567
    // dynseg is in file_image[] but not in low_mem[].
4568
4569
    // Relocate dynsym (DT_SYMTAB) which is below xct_va
4570
0
    upx_uint64_t const off_dynsym = get_te64(&sec_dynsym->sh_offset);
4571
0
    upx_uint64_t const sz_dynsym  = get_te64(&sec_dynsym->sh_size);
4572
0
    if ((upx_uint64_t)file_size < sz_dynsym
4573
0
    ||  (upx_uint64_t)file_size < off_dynsym
4574
0
    || ((upx_uint64_t)file_size - off_dynsym) < sz_dynsym) {
4575
0
        throwCantPack("bad DT_SYMTAB");
4576
0
    }
4577
0
    Elf64_Sym *dyntym = (Elf64_Sym *)lowmem.subref(
4578
0
        "bad dynsym", off_dynsym, sz_dynsym);
4579
0
    Elf64_Sym *sym = dyntym;
4580
0
    for (int j = sz_dynsym / sizeof(Elf64_Sym); --j>=0; ++sym) {
4581
0
        upx_uint64_t symval = get_te64(&sym->st_value);
4582
0
        unsigned symsec = get_te16(&sym->st_shndx);
4583
0
        if (Elf64_Sym::SHN_UNDEF != symsec
4584
0
        &&  Elf64_Sym::SHN_ABS   != symsec
4585
0
        &&  xct_off <= symval) {
4586
0
            set_te64(&sym->st_value, asl_delta + symval);
4587
0
        }
4588
0
        if (Elf64_Sym::SHN_ABS == symsec && xct_off <= symval) {
4589
0
            adjABS(sym, asl_delta);
4590
0
        }
4591
0
    }
4592
4593
    // Relocate Phdr virtual addresses, but not physical offsets and sizes
4594
0
    unsigned char buf_notes[512]; memset(buf_notes, 0, sizeof(buf_notes));
4595
0
    unsigned len_notes = 0;
4596
0
    Elf64_Phdr *phdr = (Elf64_Phdr *)lowmem.subref(
4597
0
        "bad e_phoff", e_phoff, e_phnum * sizeof(Elf64_Phdr));
4598
0
    for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
4599
0
        upx_uint64_t offset = get_te64(&phdr->p_offset);
4600
0
        if (xct_off <= offset) { // above the extra page
4601
0
            {
4602
                //set_te64(&phdr->p_offset, asl_delta + offset);  // physical
4603
0
                upx_uint64_t addr = get_te64(&phdr->p_paddr);
4604
0
                set_te64(&phdr->p_paddr, asl_delta + addr);
4605
0
                             addr = get_te64(&phdr->p_vaddr);
4606
0
                set_te64(&phdr->p_vaddr, asl_delta + addr);
4607
0
            }
4608
0
        }
4609
        // .p_filesz,.p_memsz are updated in ::pack3
4610
0
    }
4611
4612
0
    Elf64_Ehdr *const ehdr = (Elf64_Ehdr *)&lowmem[0];
4613
0
    upx_uint64_t e_entry = get_te64(&ehdr->e_entry);
4614
0
    if (xct_off < e_entry) {
4615
0
        set_te64(&ehdr->e_entry, asl_delta + e_entry);
4616
0
    }
4617
    // Relocate Shdr; and Rela, Rel (below xct_off)
4618
0
    unsigned const pal_xct_top = up8(pre_xct_top);
4619
0
    set_te64(&ehdr->e_shoff, up8(pal_xct_top));  // Shdr alignment
4620
0
    memcpy(&lowmem[pal_xct_top], shdri, e_shnum * sizeof(Elf64_Shdr));
4621
0
    shdro = (Elf64_Shdr *)&lowmem[pal_xct_top];
4622
0
    Elf64_Shdr *shdr = shdro;
4623
0
    upx_uint64_t sz_shstrtab  = get_te64(&sec_strndx->sh_size);
4624
0
    for (unsigned j = 0; j < e_shnum; ++j, ++shdr) {
4625
0
        unsigned sh_type = get_te32(&shdr->sh_type);
4626
0
        upx_uint64_t sh_size = get_te64(&shdr->sh_size);
4627
0
        upx_uint64_t sh_offset = get_te64(&shdr->sh_offset);
4628
0
        upx_uint64_t sh_entsize = get_te64(&shdr->sh_entsize);
4629
0
        if ((upx_uint64_t)file_size < sh_size
4630
0
        ||  (upx_uint64_t)file_size < sh_offset
4631
0
        || (Elf64_Shdr::SHT_NOBITS != sh_type
4632
0
           && ((upx_uint64_t)file_size - sh_offset) < sh_size) ) {
4633
0
            throwCantPack("bad SHT_STRNDX");
4634
0
        }
4635
4636
0
        if (xct_off <= sh_offset) {
4637
0
            upx_uint64_t addr = get_te64(&shdr->sh_addr);
4638
0
            set_te64(&shdr->sh_addr, asl_delta + addr);
4639
0
            set_te64(&shdr->sh_offset, asl_delta + sh_offset);
4640
0
        }
4641
0
        switch (sh_type) {
4642
0
        default: break;
4643
0
        case Elf64_Shdr::SHT_RELA: {
4644
0
            if (sizeof(Elf64_Rela) != sh_entsize) {
4645
0
                char msg[50];
4646
0
                snprintf(msg, sizeof(msg), "bad Rela.sh_entsize %lu", (long)sh_entsize);
4647
0
                throwCantPack(msg);
4648
0
            }
4649
0
            plt_va = ~0ull;
4650
0
            Elf64_Rela *const relb = (Elf64_Rela *)lowmem.subref(
4651
0
                 "bad Rela offset", sh_offset, sh_size);
4652
0
            Elf64_Rela *rela = relb;
4653
0
            for (int k = sh_size / sh_entsize; --k >= 0; ++rela) {
4654
0
                upx_uint64_t r_addend = get_te64(&rela->r_addend);
4655
0
                upx_uint64_t r_offset = get_te64(&rela->r_offset);
4656
0
                upx_uint64_t r_info   = get_te64(&rela->r_info);
4657
0
                unsigned r_type = ELF64_R_TYPE(r_info);
4658
0
                if (xct_off <= r_offset) {
4659
0
                    set_te64(&rela->r_offset, asl_delta + r_offset);
4660
0
                }
4661
0
                if (Elf64_Ehdr::EM_AARCH64 == e_machine) switch (r_type) {
4662
0
                    default: {
4663
0
                        char msg[90]; snprintf(msg, sizeof(msg),
4664
0
                            "unexpected relocation %#x [%#x]",
4665
0
                            r_type, -1 + (unsigned)(sh_size / sh_entsize) - k);
4666
0
                        throwCantPack(msg);
4667
0
                    } break;
4668
0
                    case R_AARCH64_ABS64: // FALL THROUGH
4669
0
                    case R_AARCH64_GLOB_DAT: // FALL THROUGH
4670
0
                    case R_AARCH64_RELATIVE: {
4671
0
                        if (xct_off <= r_addend) {
4672
0
                            set_te64(&rela->r_addend, asl_delta + r_addend);
4673
0
                        }
4674
0
                    } break;
4675
0
                    case R_AARCH64_JUMP_SLOT: {
4676
                        // .rela.plt contains offset of the "first time" target
4677
0
                        if (plt_va > r_offset) {
4678
0
                            plt_va = r_offset;
4679
0
                        }
4680
0
                        upx_uint64_t d = elf_get_offset_from_address(r_offset);
4681
0
                        upx_uint64_t w = get_te64(&file_image[d]);
4682
0
                        if (xct_off <= w) {
4683
0
                            set_te64(&file_image[d], asl_delta + w);
4684
0
                        }
4685
0
                        ++n_jmp_slot;
4686
0
                    } break;
4687
0
                }
4688
0
            }
4689
0
        }; break;
4690
0
        case Elf64_Shdr::SHT_REL: {
4691
0
            if (sizeof(Elf64_Rel) != sh_entsize) {
4692
0
                char msg[50];
4693
0
                snprintf(msg, sizeof(msg), "bad Rel.sh_entsize %lu", (long)sh_entsize);
4694
0
                throwCantPack(msg);
4695
0
            }
4696
0
            Elf64_Rel *rel = (Elf64_Rel *)lowmem.subref(
4697
0
                    "bad Rel sh_offset", sh_offset, sh_size);
4698
0
            for (int k = sh_size / sh_entsize; --k >= 0; ++rel) {
4699
0
                upx_uint64_t r_offset = get_te64(&rel->r_offset);
4700
0
                if (xct_off <= r_offset) {
4701
0
                    set_te64(&rel->r_offset, asl_delta + r_offset);
4702
0
                }
4703
                // r_offset must be in 2nd PT_LOAD; .p_vaddr was already relocated
4704
0
                upx_uint64_t d = elf_get_offset_from_address(asl_delta + r_offset);
4705
0
                upx_uint64_t w = get_te64(&file_image[d]);
4706
0
                upx_uint64_t r_info = get_te64(&rel->r_info);
4707
0
                unsigned r_type = ELF64_R_TYPE(r_info);
4708
0
                if (xct_off <= w
4709
0
                &&  Elf64_Ehdr::EM_AARCH64 == e_machine
4710
0
                &&  (  R_AARCH64_RELATIVE  == r_type
4711
0
                    || R_AARCH64_JUMP_SLOT == r_type)) {
4712
0
                    set_te64(&file_image[d], asl_delta + w);
4713
0
                }
4714
0
            }
4715
0
        }; break;
4716
0
        case Elf64_Shdr::SHT_NOTE: {
4717
0
            if (!(Elf64_Shdr::SHF_ALLOC & get_te64(&shdr->sh_flags))) {
4718
                // example: version number of 'gold' linker (static binder)
4719
0
                if (sizeof(buf_notes) < (sh_size + len_notes)) {
4720
0
                    throwCantPack("SHT_NOTEs too big");
4721
0
                }
4722
0
                set_te64(&shdro[j].sh_offset,
4723
0
                    len_notes + (e_shnum * sizeof(Elf64_Shdr)) + xct_off);
4724
0
                memcpy(&buf_notes[len_notes], &file_image[sh_offset], sh_size);
4725
0
                len_notes += sh_size;
4726
0
            }
4727
0
            else { // SHF_ALLOC: in PT_LOAD; but move sh_addr and sh_offset
4728
                // Not sure why we need this conditional.
4729
                // Anyway, some Android have multiple SHT_NOTE sections.
4730
0
                if (xct_off <= sh_offset) {
4731
0
                    upx_uint64_t pos = xct_off + e_shnum * sizeof(Elf64_Shdr);
4732
0
                    set_te64(&shdr->sh_addr,   pos);
4733
0
                    set_te64(&shdr->sh_offset, pos);
4734
0
                }
4735
0
            }
4736
0
        }; break;
4737
0
        } // end switch (sh_type)
4738
0
    }
4739
    // shstrndx will move
4740
0
    set_te64(&shdro[get_te16(&ehdri.e_shstrndx)].sh_offset,
4741
0
        len_notes + e_shnum * sizeof(Elf64_Shdr) + pal_xct_top);
4742
4743
    // ("Re-")write all changes below pal_xct_top
4744
0
    fo->seek(0, SEEK_SET);
4745
0
    fo->write(lowmem, pal_xct_top);
4746
0
    total_in = pal_xct_top;
4747
4748
    // New copy of Shdr
4749
0
    Elf64_Shdr blank; memset(&blank, 0, sizeof(blank));
4750
0
    set_te64(&blank.sh_offset, xct_off);  // hint for "upx -d"
4751
0
    fpad8(fo, total_out);  // Shdr alignment
4752
0
    fo->write(&blank, sizeof(blank));
4753
0
    fo->write(&shdro[1], (-1+ e_shnum) * sizeof(Elf64_Shdr));
4754
4755
0
    if (len_notes) {
4756
0
        fo->write(buf_notes, len_notes);
4757
0
    }
4758
4759
    // New copy of Shdr[.e_shstrndx].[ sh_offset, +.sh_size )
4760
0
    fo->write(shstrtab,  sz_shstrtab);
4761
4762
0
    sz_elf_hdrs = fpad8(fo, total_out);
4763
0
    total_out = sz_elf_hdrs;
4764
    //xct_off += asl_delta;  // wait until ::pack3
4765
0
    unsigned d = asl_delta + pal_xct_top - sz_elf_hdrs;
4766
0
    fo->seek(d, SEEK_CUR);
4767
0
    total_out += d;
4768
0
}
4769
4770
// asl (ANdroid Shared Library) creates a big mess!
4771
void PackLinuxElf32::asl_pack2_Shdrs(OutputFile *fo, unsigned pre_xct_top)
4772
0
{
4773
0
    if (!fo) {
4774
0
        return;
4775
0
    }
4776
    // In order to pacify the runtime linker on Android "O" ("Oreo"),
4777
    // we will splice-in a 4KiB page that contains an "extra" copy
4778
    // of the Shdr, any PT_NOTE above xct_off, and shstrtab.
4779
    // File order: Ehdr, Phdr[], section contents below xct_off,
4780
    //    Shdr_copy[], PT_NOTEs.hi, shstrtab.
4781
0
    if (is_asl)
4782
0
        xct_va  += asl_delta;
4783
    //xct_off += asl_delta;  // not until ::pack3()
4784
4785
0
    total_in = pre_xct_top;
4786
4787
    // Relocate PT_DYNAMIC (in PT_LOAD with PF_W)
4788
0
    Elf32_Dyn *dyn = const_cast<Elf32_Dyn *>(dynseg);
4789
0
    for (; dyn->d_tag; ++dyn) {
4790
0
        upx_uint32_t d_tag = get_te32(&dyn->d_tag);
4791
0
        if (Elf32_Dyn::DT_FINI       == d_tag
4792
0
        ||  Elf32_Dyn::DT_FINI_ARRAY == d_tag
4793
0
        ||  Elf32_Dyn::DT_INIT_ARRAY == d_tag
4794
0
        ||  Elf32_Dyn::DT_PREINIT_ARRAY == d_tag
4795
0
        ||  Elf32_Dyn::DT_PLTGOT      == d_tag) {
4796
0
            upx_uint32_t d_val = get_te32(&dyn->d_val);
4797
0
            set_te32(&dyn->d_val, asl_delta + d_val);
4798
0
        }
4799
0
    }
4800
    // Updated dynseg (.dynamic, in PT_DYNAMIC (PT_LOAD{PF_W})) has not been written.
4801
    // dynseg is in file_image[] but not in low_mem[].
4802
4803
    // Relocate dynsym (DT_SYMTAB) which is below xct_va
4804
0
    upx_uint32_t const off_dynsym = get_te32(&sec_dynsym->sh_offset);
4805
0
    upx_uint32_t const sz_dynsym  = get_te32(&sec_dynsym->sh_size);
4806
0
    if ((upx_uint32_t)file_size < sz_dynsym
4807
0
    ||  (upx_uint32_t)file_size < off_dynsym
4808
0
    || ((upx_uint32_t)file_size - off_dynsym) < sz_dynsym) {
4809
0
        throwCantPack("bad DT_SYMTAB");
4810
0
    }
4811
0
    Elf32_Sym *dyntym = (Elf32_Sym *)lowmem.subref(
4812
0
        "bad dynsym", off_dynsym, sz_dynsym);
4813
0
    Elf32_Sym *sym = dyntym;
4814
0
    for (int j = sz_dynsym / sizeof(Elf32_Sym); --j>=0; ++sym) {
4815
0
        upx_uint32_t symval = get_te32(&sym->st_value);
4816
0
        unsigned symsec = get_te16(&sym->st_shndx);
4817
0
        if (Elf32_Sym::SHN_UNDEF != symsec
4818
0
        &&  Elf32_Sym::SHN_ABS   != symsec
4819
0
        &&  xct_off <= symval) {
4820
0
            set_te32(&sym->st_value, asl_delta + symval);
4821
0
        }
4822
0
        if (Elf32_Sym::SHN_ABS == symsec && xct_off <= symval) {
4823
0
            adjABS(sym, asl_delta);
4824
0
        }
4825
0
    }
4826
4827
    // Relocate Phdr virtual addresses, but not physical offsets and sizes
4828
0
    unsigned char buf_notes[512]; memset(buf_notes, 0, sizeof(buf_notes));
4829
0
    unsigned len_notes = 0;
4830
0
    Elf32_Phdr *phdr = (Elf32_Phdr *)lowmem.subref(
4831
0
        "bad e_phoff", e_phoff, e_phnum * sizeof(Elf32_Phdr));
4832
0
    for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
4833
0
        upx_uint32_t offset = get_te32(&phdr->p_offset);
4834
0
        if (xct_off <= offset) { // above the extra page
4835
0
            {
4836
                //set_te32(&phdr->p_offset, asl_delta + offset);  // physical
4837
0
                upx_uint32_t v_addr = get_te32(&phdr->p_vaddr);
4838
0
                                      set_te32(&phdr->p_vaddr, asl_delta + v_addr);
4839
0
                upx_uint32_t p_addr = get_te32(&phdr->p_paddr);
4840
0
                                      set_te32(&phdr->p_paddr, asl_delta + p_addr);
4841
0
            }
4842
0
        }
4843
        // .p_filesz,.p_memsz are updated in ::pack3
4844
0
    }
4845
4846
0
    Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)&lowmem[0];
4847
0
    upx_uint32_t e_entry = get_te32(&ehdr->e_entry);
4848
0
    if (xct_off <= e_entry) { // FIXME: --android-shlib is different
4849
0
        set_te32(&ehdr->e_entry, asl_delta + e_entry);
4850
0
    }
4851
    // Relocate Shdr; and Rela, Rel (below xct_off)
4852
0
    unsigned const pal_xct_top = up4(pre_xct_top);
4853
0
    set_te32(&ehdr->e_shoff, pal_xct_top);  // Shdr alignment
4854
0
    memcpy(&lowmem[pal_xct_top], shdri, e_shnum * sizeof(Elf32_Shdr));
4855
0
    shdro = (Elf32_Shdr *)&lowmem[pal_xct_top];
4856
0
    Elf32_Shdr *shdr = shdro;
4857
0
    upx_uint32_t sz_shstrtab  = get_te32(&sec_strndx->sh_size);
4858
0
    for (unsigned j = 0; j < e_shnum; ++j, ++shdr) {
4859
0
        unsigned sh_type = get_te32(&shdr->sh_type);
4860
0
        unsigned sh_flags = get_te32(&shdr->sh_flags);
4861
0
        upx_uint32_t sh_size = get_te32(&shdr->sh_size);
4862
0
        upx_uint32_t sh_offset = get_te32(&shdr->sh_offset);
4863
0
        upx_uint32_t sh_entsize = get_te32(&shdr->sh_entsize);
4864
0
        if ((upx_uint32_t)file_size < sh_size
4865
0
        ||  (upx_uint32_t)file_size < sh_offset
4866
0
        || (Elf32_Shdr::SHT_NOBITS != sh_type
4867
0
           && ((upx_uint32_t)file_size - sh_offset) < sh_size) ) {
4868
0
            throwCantPack("bad SHT_STRNDX");
4869
0
        }
4870
4871
0
        if (xct_off <= sh_offset && Elf32_Shdr::SHF_ALLOC & sh_flags) {
4872
0
            upx_uint32_t addr = get_te32(&shdr->sh_addr);
4873
0
            set_te32(&shdr->sh_addr, asl_delta + addr);
4874
0
            set_te32(&shdr->sh_offset, asl_delta + sh_offset);
4875
0
        }
4876
0
        switch (sh_type) {
4877
0
        default: break;
4878
0
        case Elf32_Shdr::SHT_RELA: { // 32-bit Elf_Rela is unused (by convention)
4879
0
            if (sizeof(Elf32_Rela) != sh_entsize) {
4880
0
                char msg[50];
4881
0
                snprintf(msg, sizeof(msg), "bad Rela.sh_entsize %lu", (long)sh_entsize);
4882
0
                throwCantPack(msg);
4883
0
            }
4884
0
            plt_va = ~0ull;
4885
0
            Elf32_Rela *const relb = (Elf32_Rela *)lowmem.subref(
4886
0
                 "bad Rela offset", sh_offset, sh_size);
4887
0
            Elf32_Rela *rela = relb;
4888
0
            for (int k = sh_size / sh_entsize; --k >= 0; ++rela) {
4889
0
                upx_uint32_t r_addend = get_te32(&rela->r_addend);
4890
0
                upx_uint32_t r_offset = get_te32(&rela->r_offset);
4891
0
                upx_uint32_t r_info   = get_te32(&rela->r_info);
4892
0
                unsigned r_type = ELF32_R_TYPE(r_info);
4893
0
                if (xct_off <= r_offset) {
4894
0
                    set_te32(&rela->r_offset, asl_delta + r_offset);
4895
0
                }
4896
0
                if (Elf32_Ehdr::EM_386 == e_machine) switch (r_type) {
4897
0
                    default: {
4898
0
                        char msg[90]; snprintf(msg, sizeof(msg),
4899
0
                            "unexpected relocation %#x [%#x]",
4900
0
                            r_type, -1 + (unsigned)(sh_size / sh_entsize) - k);
4901
0
                        throwCantPack(msg);
4902
0
                    } break;
4903
0
                    case R_386_32: // FALL THROUGH
4904
0
                    case R_386_GLOB_DAT: // FALL THROUGH
4905
0
                    case R_386_RELATIVE: {
4906
0
                        if (xct_off <= r_addend) {
4907
0
                            set_te32(&rela->r_addend, asl_delta + r_addend);
4908
0
                        }
4909
0
                    } break;
4910
0
                    case R_386_JMP_SLOT: {
4911
                        // .rela.plt contains offset of the "first time" target
4912
0
                        if (plt_va > r_offset) {
4913
0
                            plt_va = r_offset;
4914
0
                        }
4915
0
                        upx_uint32_t d = elf_get_offset_from_address(r_offset);
4916
0
                        upx_uint32_t w = get_te32(&file_image[d]);
4917
0
                        if (xct_off <= w) {
4918
0
                            set_te32(&file_image[d], asl_delta + w);
4919
0
                        }
4920
0
                        ++n_jmp_slot;
4921
0
                    } break;
4922
0
                } // end EM_386 r_type
4923
0
                else if (Elf32_Ehdr::EM_ARM == e_machine) switch (r_type) {
4924
0
                    default: {
4925
0
                        char msg[90]; snprintf(msg, sizeof(msg),
4926
0
                            "unexpected relocation %#x [%#x]",
4927
0
                            r_type, -1 + (unsigned)(sh_size / sh_entsize) - k);
4928
0
                        throwCantPack(msg);
4929
0
                    } break;
4930
0
                    case R_ARM_ABS32: // FALL THROUGH
4931
0
                    case R_ARM_GLOB_DAT: // FALL THROUGH
4932
0
                    case R_ARM_RELATIVE: {
4933
0
                        if (xct_off <= r_addend) {
4934
0
                            set_te32(&rela->r_addend, asl_delta + r_addend);
4935
0
                        }
4936
0
                    } break;
4937
0
                    case R_ARM_JUMP_SLOT: {
4938
                        // .rela.plt contains offset of the "first time" target
4939
0
                        if (plt_va > r_offset) {
4940
0
                            plt_va = r_offset;
4941
0
                        }
4942
0
                        upx_uint32_t d = elf_get_offset_from_address(r_offset);
4943
0
                        upx_uint32_t w = get_te32(&file_image[d]);
4944
0
                        if (xct_off <= w) {
4945
0
                            set_te32(&file_image[d], asl_delta + w);
4946
0
                        }
4947
0
                        ++n_jmp_slot;
4948
0
                    } break;
4949
0
                }  // end EM_ARM r_type
4950
0
                else {
4951
0
                    char msg[40]; snprintf(msg, sizeof(msg),
4952
0
                        "Unknown architecture %d", this->e_machine);
4953
0
                    throwCantPack(msg);
4954
0
                }  // end e_machine
4955
0
            }
4956
0
        }; break;  // end Elf32_Shdr::SHT_RELA
4957
0
        case Elf32_Shdr::SHT_REL: {
4958
0
            if (sizeof(Elf32_Rel) != sh_entsize) {
4959
0
                char msg[50];
4960
0
                snprintf(msg, sizeof(msg), "bad Rel.sh_entsize %lu", (long)sh_entsize);
4961
0
                throwCantPack(msg);
4962
0
            }
4963
0
            Elf32_Rel *rel = (Elf32_Rel *)lowmem.subref(
4964
0
                    "bad Rel sh_offset", sh_offset, sh_size);
4965
0
            for (int k = sh_size / sh_entsize; --k >= 0; ++rel) {
4966
0
                upx_uint32_t r_offset = get_te32(&rel->r_offset);
4967
0
                if (xct_off <= r_offset) {
4968
0
                    set_te32(&rel->r_offset, asl_delta + r_offset);
4969
0
                }
4970
                // r_offset must be in 2nd PT_LOAD; .p_vaddr was already relocated
4971
0
                upx_uint32_t d = elf_get_offset_from_address(r_offset);
4972
0
                upx_uint32_t w = get_te32(&file_image[d]);
4973
0
                upx_uint32_t r_info = get_te32(&rel->r_info);
4974
0
                unsigned r_type = ELF32_R_TYPE(r_info);
4975
                //printf("d=%#x  w=%#x  r_info=%#x\n", d, w, r_info);
4976
                // FIXME: why change file_image[d] instead of lowmem[d] ?
4977
0
                if (Elf32_Ehdr::EM_386 == e_machine) switch (r_type) {
4978
0
                    default: {
4979
0
                        char msg[90]; snprintf(msg, sizeof(msg),
4980
0
                            "unexpected relocation %#x [%#x]",
4981
0
                            r_type, -1 + (unsigned)(sh_size / sh_entsize) - k);
4982
0
                        throwCantPack(msg);
4983
0
                    } break;
4984
0
                    case R_386_32: // FALL THROUGH
4985
0
                    case R_386_GLOB_DAT: // FALL THROUGH
4986
0
                    case R_386_RELATIVE: {
4987
0
                        if (xct_off <= w) {
4988
0
                            set_te32(&file_image[d], asl_delta + w);
4989
0
                        }
4990
0
                    } break;
4991
0
                    case R_386_JMP_SLOT: {
4992
                        // .rela.plt contains offset of the "first time" target
4993
0
                        if (plt_va > r_offset) {
4994
0
                            plt_va = r_offset;
4995
0
                        }
4996
0
                        if (xct_off <= w) {
4997
0
                            set_te32(&file_image[d], asl_delta + w);
4998
0
                        }
4999
0
                        ++n_jmp_slot;
5000
0
                    } break;
5001
0
                } // end EM_386 r_type
5002
0
                else if (Elf32_Ehdr::EM_ARM == e_machine) switch (r_type) {
5003
0
                    default: {
5004
0
                        char msg[90]; snprintf(msg, sizeof(msg),
5005
0
                            "unexpected relocation %#x [%#x]",
5006
0
                            r_type, -1 + (unsigned)(sh_size / sh_entsize) - k);
5007
0
                        throwCantPack(msg);
5008
0
                    } break;
5009
0
                    case R_ARM_ABS32: // FALL THROUGH
5010
0
                    case R_ARM_GLOB_DAT: // FALL THROUGH
5011
0
                    case R_ARM_RELATIVE: {
5012
0
                        if (xct_off <= w) {
5013
0
                            set_te32(&file_image[d], asl_delta + w);
5014
0
                        }
5015
0
                    } break;
5016
0
                    case R_ARM_JUMP_SLOT: {
5017
                        // .rela.plt contains offset of the "first time" target
5018
0
                        if (plt_va > r_offset) {
5019
0
                            plt_va = r_offset;
5020
0
                        }
5021
0
                        if (xct_off <= w) {
5022
0
                            set_te32(&file_image[d], asl_delta + w);
5023
0
                        }
5024
0
                        ++n_jmp_slot;
5025
0
                    } break;
5026
0
                }  // end EM_ARM r_type
5027
0
                else {
5028
0
                    char msg[40]; snprintf(msg, sizeof(msg),
5029
0
                        "Unknown architecture %d", this->e_machine);
5030
0
                    throwCantPack(msg);
5031
0
                }  // end e_machine
5032
0
            }  // end rel
5033
0
        }; break;  // end Elf32_Shdr::SHT_REL
5034
0
        case Elf32_Shdr::SHT_NOTE: {
5035
0
            if (!(Elf32_Shdr::SHF_ALLOC & sh_flags)) {
5036
                // example: version number of 'gold' linker (static binder)
5037
0
                if (sizeof(buf_notes) < (sh_size + len_notes)) {
5038
0
                    throwCantPack("SHT_NOTEs too big");
5039
0
                }
5040
0
                set_te32(&shdro[j].sh_offset,
5041
0
                    len_notes + (e_shnum * sizeof(Elf32_Shdr)) + xct_off);
5042
0
                memcpy(&buf_notes[len_notes], &file_image[sh_offset], sh_size);
5043
0
                len_notes += sh_size;
5044
0
            }
5045
0
            else { // SHF_ALLOC: in PT_LOAD; but move sh_addr and sh_offset
5046
                // Not sure why we need this conditional.
5047
                // Anyway, some Android have multiple SHT_NOTE sections.
5048
0
                if (xct_off <= sh_offset) {
5049
0
                    upx_uint32_t pos = xct_off + e_shnum * sizeof(Elf32_Shdr);
5050
                    //set_te32(&shdr->sh_addr,   pos);
5051
0
                    set_te32(&shdr->sh_offset, pos);
5052
0
                }
5053
0
            }
5054
0
        }; break;  // end Elf32_Shdr::SHT_NOTE
5055
0
        case Elf32_Shdr::SHT_ARM_ATTRIBUTES: {
5056
0
            sec_arm_attr = shdr;
5057
0
        }; break;
5058
0
        } // end switch (sh_type)
5059
0
    }
5060
    // shstrndx will move
5061
0
    set_te32(&shdro[get_te16(&ehdri.e_shstrndx)].sh_offset,
5062
0
        len_notes + e_shnum * sizeof(Elf32_Shdr) + up8(pal_xct_top));
5063
5064
    // Write all changes below pal_xct_top
5065
    // FIXME: why is this any more than Ehdr + Phdrs?
5066
0
    if (fo) {
5067
0
        fo->seek(0, SEEK_SET);
5068
0
        fo->write(lowmem, pal_xct_top);
5069
0
    }
5070
0
    total_out = pal_xct_top;
5071
0
    total_in  = pal_xct_top;
5072
5073
    // New copy of Shdr
5074
0
    Elf32_Shdr blank; memset(&blank, 0, sizeof(blank));
5075
0
    set_te32(&blank.sh_offset, xct_off);  // hint for "upx -d"
5076
0
    set_te32(&shdro->sh_offset, xct_off);  // hint for "upx -d"
5077
0
    total_out = fpad8(fo, total_out);  // Shdr alignment
5078
0
    unsigned arm_attr_off = 0;
5079
0
    if (sec_arm_attr) {
5080
0
        arm_attr_off = get_te32(&sec_arm_attr->sh_offset);
5081
0
        set_te32(&sec_arm_attr->sh_offset,
5082
0
            total_out + e_shnum*sizeof(Elf32_Shdr)
5083
0
            + len_notes + sz_shstrtab);
5084
0
    }
5085
0
    if (fo) {
5086
0
        fo->write(&blank, sizeof(blank));
5087
0
        fo->write(&shdro[1], (-1+ e_shnum) * sizeof(Elf32_Shdr));
5088
0
        if (len_notes) {
5089
0
            fo->write(buf_notes, len_notes);
5090
0
        }
5091
        // New copy of Shdr[.e_shstrndx].[ sh_offset, +.sh_size )
5092
0
        fo->write(shstrtab,  sz_shstrtab);
5093
5094
0
        if (sec_arm_attr) {
5095
0
            fo->write(&file_image[arm_attr_off],
5096
0
                get_te32(&sec_arm_attr->sh_size));
5097
0
        }
5098
0
    }
5099
5100
0
    sz_elf_hdrs = fpad8(fo, total_out);
5101
0
    total_out = sz_elf_hdrs;
5102
    //xct_off += asl_delta;  // wait until ::pack3
5103
0
    total_out = fpadN(fo, asl_delta - (sz_elf_hdrs - pal_xct_top));
5104
0
}
5105
5106
void PackLinuxElf64::pack1(OutputFile * /*fo*/, Filter &ft)
5107
0
{
5108
0
    fi->seek(0, SEEK_SET);
5109
0
    fi->readx(&ehdri, sizeof(ehdri));
5110
0
    assert(e_phoff == sizeof(Elf64_Ehdr));  // checked by canPack()
5111
0
    sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
5112
5113
// We compress separate pieces (usually each PT_LOAD, plus the gaps in the file
5114
// that are not covered by any PT_LOAD), but currently at run time there can be
5115
// only one decompressor method.
5116
// Therefore we must plan ahead because Packer::compressWithFilters tries
5117
// to find the smallest result among the available methods, for one piece only.
5118
// In the future we may allow more than one decompression method at run time.
5119
// For now we must choose only one, and force PackUnix::packExtent
5120
// (==> compressWithFilters) to use it.
5121
0
    int nfilters = 0;
5122
0
    {
5123
0
        int const *fp = getFilters();
5124
0
        while (FT_END != *fp++) {
5125
0
            ++nfilters;
5126
0
        }
5127
0
    }
5128
0
    {
5129
0
        int npieces = 1;  // tail after highest PT_LOAD
5130
0
        Elf64_Phdr *phdr = phdri;
5131
0
        for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
5132
0
            if (is_LOAD(phdr)) {
5133
0
                unsigned const  flags = get_te32(&phdr->p_flags);
5134
0
                unsigned       offset = get_te64(&phdr->p_offset);
5135
0
                if (!xct_off  // not shlib
5136
                  // new-style shlib: PT_LOAD[0] has symbol table
5137
                  // which must not be compressed, but also lacks PF_X
5138
0
                ||    (Elf64_Phdr::PF_X & flags)
5139
                  // Read-only, non-first PT_LOAD is _assumed_ to be compressible
5140
0
                ||  (!(Elf64_Phdr::PF_W & flags) && 0!=offset))
5141
0
                {
5142
0
                    ++npieces;  // will attempt compression of this PT_LOAD
5143
0
                }
5144
0
            }
5145
0
        }
5146
0
        uip->ui_total_passes += npieces;
5147
0
    }
5148
0
    int methods[256];
5149
0
    unsigned nmethods = prepareMethods(methods, ph.method, getCompressionMethods(M_ALL, ph.level));
5150
0
    if (1 < nmethods) { // Many are available, but we must choose only one
5151
0
        uip->ui_total_passes += 1;  // the batch for output
5152
0
        uip->ui_total_passes *= nmethods * (1+ nfilters);  // finding smallest total
5153
0
        PackHeader orig_ph = ph;
5154
0
        Filter orig_ft = ft;
5155
0
        unsigned max_offset = 0;
5156
0
        unsigned sz_best= ~0u;
5157
0
        int method_best = 0;
5158
0
        for (unsigned k = 0; k < nmethods; ++k) { // FIXME: parallelize; cost: working space
5159
0
            unsigned sz_this = 0;
5160
0
            Elf64_Phdr *phdr = phdri;
5161
0
            for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
5162
0
                if (is_LOAD(phdr)) {
5163
0
                    unsigned const  flags = get_te32(&phdr->p_flags);
5164
0
                    unsigned       offset = get_te64(&phdr->p_offset);
5165
0
                    unsigned       filesz = get_te64(&phdr->p_filesz);
5166
0
                    max_offset = UPX_MAX(max_offset, filesz + offset);
5167
0
                    if (!xct_off  // not shlib
5168
                      // new-style shlib: PT_LOAD[0] has symbol table
5169
                      // which must not be compressed, but also lacks PF_X
5170
0
                    ||    (Elf64_Phdr::PF_X & flags)
5171
                      // Read-only, non-first PT_LOAD is _assumed_ to be compressible
5172
0
                    ||  (!(Elf64_Phdr::PF_W & flags) && 0!=offset))
5173
0
                    {
5174
0
                        if (xct_off && 0==offset) { // old-style shlib
5175
0
                            offset  = xct_off;
5176
0
                            filesz -= xct_off;
5177
0
                        }
5178
0
                        fi->seek(offset, SEEK_SET);
5179
0
                        fi->readx(ibuf, filesz);
5180
0
                        ft = orig_ft;
5181
0
                        ph = orig_ph;
5182
0
                        ph.set_method(ph_force_method(methods[k]));
5183
0
                        ph.u_len = filesz;
5184
0
                        compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true);
5185
0
                        sz_this += ph.c_len;
5186
0
                    }
5187
0
                }
5188
0
            }
5189
0
            unsigned const sz_tail = file_size - max_offset;  // debuginfo, etc.
5190
0
            if (sz_tail) {
5191
0
                fi->seek(max_offset, SEEK_SET);
5192
0
                fi->readx(ibuf, sz_tail);
5193
0
                ft = orig_ft;
5194
0
                ph = orig_ph;
5195
0
                ph.set_method(ph_force_method(methods[k]));
5196
0
                ph.u_len = sz_tail;
5197
0
                compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true);
5198
0
                sz_this += ph.c_len;
5199
0
            }
5200
            // FIXME: loader size also depends on method
5201
0
            if (sz_best > sz_this) {
5202
0
                sz_best = sz_this;
5203
0
                method_best = methods[k];
5204
0
            }
5205
0
        }
5206
0
        ft = orig_ft;
5207
0
        ph = orig_ph;
5208
0
        ph.set_method(ph_force_method(method_best));
5209
0
    }
5210
5211
0
    Elf64_Phdr *phdr = phdri;
5212
0
    for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
5213
0
        unsigned const type = get_te32(&phdr->p_type);
5214
0
        if (PT_GNU_STACK64 == type || PT_NOTE64 == type) {
5215
0
            add_phdrx(phdr);  // PT_GNU_STACK64, PT_NOTE64
5216
0
        }
5217
0
        if (PT_LOAD == type) {
5218
0
            unsigned x = get_te64(&phdr->p_align) >> lg2_page;
5219
0
            while (x>>=1) {
5220
0
                ++lg2_page;
5221
0
            }
5222
0
        }
5223
0
        if (PT_GNU_RELRO64 == type
5224
0
        &&  16 < lg2_page) {
5225
            // x86* allows 4K, 2M, 1G
5226
            // arm32 and arm64 both allow 4K, 16K, 64K; Apple Silicon uses 16K
5227
            // Oracle 5.4.17-2136.314.6.2.el8uek.aarch64 demands 64K
5228
            // PowerPC and PowerPC64 has 4K, 64K, 1M (?), 16M (?)
5229
            // MIPS  allows any power of 2 from 4K through 64K
5230
5231
            // If 64K < .p_align then we assume that 4K is also accepted.
5232
            // .p_align can be like 2M, which is a huge over-estimate.
5233
            // RELRO ends on a page boundary: usually close to actual page_size
5234
0
            unsigned offset = get_te64(&phdr->p_offset);
5235
0
            unsigned filesz = get_te64(&phdr->p_filesz);
5236
0
            if (!(0xfff & (filesz + offset))) { // a 4KiB boundary
5237
0
                unsigned b = 12;
5238
0
                while (!(~(~0u << b) & (filesz + offset))) {
5239
0
                    ++b;
5240
0
                }
5241
0
                lg2_page = umin(lg2_page, -1+ b);
5242
0
            }
5243
0
        }
5244
0
    }
5245
0
    page_size =  1u  <<lg2_page;
5246
0
    page_mask = ~0ull<<lg2_page;
5247
5248
0
    progid = 0;  // getRandomId();  not useful, so do not clutter
5249
0
    sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
5250
5251
    // only execute if option present
5252
0
    if (opt->o_unix.preserve_build_id) {
5253
        // set this so we can use elf_find_section_name
5254
0
        e_shnum = get_te16(&ehdri.e_shnum);
5255
0
        if (!shdri) {
5256
0
            mb_shdr.alloc(e_shnum * sizeof(Elf64_Shdr));
5257
0
            shdri = (Elf64_Shdr *)mb_shdr.getVoidPtr();
5258
0
            e_shoff = get_te64(&ehdri.e_shoff);
5259
0
            fi->seek(e_shoff, SEEK_SET);
5260
0
            fi->readx(shdri, e_shnum * sizeof(Elf64_Shdr));
5261
0
        }
5262
        //set the shstrtab
5263
0
        sec_strndx = &shdri[get_te16(&ehdri.e_shstrndx)];
5264
5265
0
        upx_uint64_t sh_size = get_te64(&sec_strndx->sh_size);
5266
0
        mb_shstrtab.alloc(sh_size); shstrtab = (char *)mb_shstrtab.getVoidPtr();
5267
0
        fi->seek(0,SEEK_SET);
5268
0
        fi->seek(sec_strndx->sh_offset,SEEK_SET);
5269
0
        fi->readx(mb_shstrtab, sh_size);
5270
5271
0
        Elf64_Shdr const *buildid = elf_find_section_name(".note.gnu.build-id");
5272
0
        if (buildid) {
5273
0
            unsigned bid_sh_size = get_te64(&buildid->sh_size);  // UPX_RSIZE_MAX_MEM protects us
5274
0
            buildid_data.alloc(bid_sh_size);
5275
0
            buildid_data.clear();
5276
0
            fi->seek(0,SEEK_SET);
5277
0
            fi->seek(buildid->sh_offset,SEEK_SET);
5278
0
            fi->readx((void *)buildid_data, bid_sh_size);
5279
5280
0
            o_elf_shnum = 3;
5281
0
            memset(&shdrout,0,sizeof(shdrout));
5282
5283
            //setup the build-id
5284
0
            memcpy(&shdrout.shdr[1], buildid, sizeof(shdrout.shdr[1]));
5285
0
            set_te32(&shdrout.shdr[1].sh_name, 1);
5286
5287
            //setup the shstrtab
5288
0
            memcpy(&shdrout.shdr[2], sec_strndx, sizeof(shdrout.shdr[2]));
5289
0
            set_te32(&shdrout.shdr[2].sh_name, 20);
5290
0
            set_te64(&shdrout.shdr[2].sh_size, 29); //size of our static shstrtab; UPX_RSIZE_MAX_MEM
5291
0
        }
5292
0
    }
5293
0
}
5294
5295
void PackLinuxElf64amd::pack1(OutputFile *fo, Filter &ft)
5296
0
{
5297
0
    super::pack1(fo, ft);
5298
0
    if (0!=xct_off)  // shared library
5299
0
        return;
5300
0
    generateElfHdr(fo, stub_amd64_linux_elf_fold, getbrk(phdri, e_phnum) );
5301
0
}
5302
5303
void PackLinuxElf64arm::pack1(OutputFile *fo, Filter &ft)
5304
0
{
5305
0
    super::pack1(fo, ft);
5306
0
    if (0!=xct_off)  // shared library
5307
0
        return;
5308
0
    generateElfHdr(fo, stub_arm64_linux_elf_fold, getbrk(phdri, e_phnum) );
5309
0
}
5310
5311
// Determine length of gap between PT_LOAD phdr[k] and closest PT_LOAD
5312
// which follows in the file (or end-of-file).  Optimize for common case
5313
// where the PT_LOAD are adjacent ascending by .p_offset.  Assume no overlap.
5314
5315
unsigned PackLinuxElf32::find_LOAD_gap(
5316
    Elf32_Phdr const *const phdr,
5317
    unsigned const k,
5318
    unsigned const nph
5319
)
5320
487
{
5321
487
    if (!is_LOAD(&phdr[k])) {
5322
318
        return 0;
5323
318
    }
5324
169
    unsigned const hi = get_te32(&phdr[k].p_offset) +
5325
169
                        get_te32(&phdr[k].p_filesz);
5326
169
    unsigned lo = ph.u_file_size;
5327
169
    if (lo < hi)
5328
0
        throwCantPack("bad input: PT_LOAD beyond end-of-file");
5329
169
    unsigned j = k;
5330
1.04k
    for (;;) { // circular search, optimize for adjacent ascending
5331
1.04k
        ++j;
5332
1.04k
        if (nph==j) {
5333
153
            j = 0;
5334
153
        }
5335
1.04k
        if (k==j) {
5336
153
            break;
5337
153
        }
5338
888
        if (is_LOAD(&phdr[j])) {
5339
265
            unsigned const t = get_te32(&phdr[j].p_offset);
5340
265
            if ((t - hi) < (lo - hi)) {
5341
109
                lo = t;
5342
109
                if (hi==lo) {
5343
16
                    break;
5344
16
                }
5345
109
            }
5346
265
        }
5347
888
    }
5348
169
    return lo - hi;
5349
169
}
5350
5351
unsigned PackLinuxElf::pack2_shlib_overlay_init(OutputFile *fo)
5352
0
{
5353
0
    linfo.l_checksum = 0;  // preliminary
5354
0
    linfo.l_magic = UPX_MAGIC_LE32;
5355
5356
0
    set_le16(&linfo.l_lsize, lsize);  // preliminary (0)
5357
0
    linfo.l_version = (unsigned char)ph.version;
5358
0
    linfo.l_format =  (unsigned char)ph.format;
5359
0
    linfo_off = total_out;
5360
0
    fo->write(&linfo, sizeof(linfo));  total_out += sizeof(linfo);
5361
5362
0
    overlay_offset = total_out;
5363
5364
0
    p_info hbuf;
5365
0
    set_te32(&hbuf.p_progid, 0);
5366
0
    set_te32(&hbuf.p_filesize, file_size);
5367
0
    set_te32(&hbuf.p_blocksize, blocksize);
5368
0
    fo->write(&hbuf, sizeof(hbuf));  total_out += sizeof(hbuf);
5369
0
    return total_out;
5370
0
}
5371
5372
unsigned PackLinuxElf::pack2_shlib_overlay_write(OutputFile *fo, MemBuffer &mb,
5373
        unsigned u_len, unsigned c_len)
5374
0
{
5375
    // Write mb with b_info header.
5376
0
    b_info tmp;
5377
0
    memset(&tmp, 0, sizeof(tmp));
5378
0
    set_te32(&tmp.sz_unc, u_len);
5379
0
    set_te32(&tmp.sz_cpr, c_len);
5380
0
    tmp.b_method = (EM_ARM == e_machine) ? M_NRV2B_8 : M_NRV2B_LE32;
5381
0
    tmp.b_extra = 0;
5382
0
    fo->write(&tmp, sizeof(tmp));   total_out += sizeof(tmp);
5383
0
    b_len += sizeof(b_info);
5384
0
    fo->write(mb, c_len); total_out += c_len;
5385
0
    return total_out;
5386
0
}
5387
5388
// Returns compressed size
5389
unsigned PackLinuxElf::pack2_shlib_overlay_compress(
5390
    MemBuffer &bufo,
5391
    upx_byte const *inp,
5392
    unsigned u_len
5393
)
5394
0
{
5395
0
    ph.saved_u_adler = ph.u_adler;
5396
0
    ph.u_adler = upx_adler32(inp, u_len, ph.saved_u_adler);
5397
0
    ph.u_len += u_len;
5398
5399
0
    unsigned const method = (EM_ARM == e_machine) ? M_NRV2B_8 : M_NRV2B_LE32;
5400
0
    methods_used |= 1 << method;
5401
0
    unsigned c_len = 0;
5402
0
    int r = upx_compress(inp, u_len, bufo, &c_len,
5403
0
        /* &progress callback */ nullptr,
5404
0
        method, 10,
5405
0
        /* &config_t */ nullptr, /* &result_t */ nullptr);
5406
0
    if (r != UPX_E_OK)
5407
0
        throwInternalError("header compression failed");
5408
0
    if (c_len >= u_len)
5409
0
        throwInternalError("header compression size increase");
5410
5411
0
    ph.saved_c_adler = ph.c_adler;
5412
0
    ph.c_adler = upx_adler32(bufo,  c_len, ph.saved_c_adler);
5413
0
    ph.c_len += c_len;
5414
0
    return c_len;
5415
0
}
5416
5417
// Layout for compressed shared library:
5418
// 1. If first PT_LOAD is totally below xct_off
5419
//      (namely, (.p_memsz + .p_offset) <= xct_off )
5420
//    then it must be Ehdr+Phdrs followed only by PT_DYNAMIC (Dynamic
5421
//    section) and loader tables (DT_* data), and the order of output is:
5422
//      A. original first PT_LOAD (Ehdr+Phdrs will be overwritten later)
5423
//      B. compressed Ehdr+Phdrs (for de-compressor to restore); M_NRV2B_LE32, no filter
5424
//      C. compressed remaining PT_LOAD segments (except PT_WRITE),
5425
//         regardless of xct_off.
5426
//         Until xct_off is covered by some PT_LOAD, then there is a logical
5427
//         two-pass problem.  The best compression algorithm is not chosen
5428
//         until the PT_LOAD which contains xct_off, but before that
5429
//         compression is desired anyway for any preceding PT_LOAD.
5430
//         So use NRV2B for the "early" PT_LOADs, and do not use packExtent
5431
//         which calls compressWithFilters and also creates a loader.
5432
//         Instead, do the compression "by hand" explicitly using upx_compress
5433
//         and write().  This may require ELF2 multi-decompressor (NRV2B
5434
//         on the early PT_LOADs, then something better).
5435
//
5436
//         Example input Program Headers:
5437
//         Type   Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
5438
//         LOAD   0x000000 0x00000000 0x00000000 0x003a4 0x003a4 R   0x1000  Elf hdrs, loader tables
5439
//         LOAD   0x001000 0x00001000 0x00001000 0x001d4 0x001d4 R E 0x1000  small code
5440
//         LOAD   0x002000 0x00002000 0x00002000 0x09d40 0x09d40 R   0x1000  large app consts
5441
//         LOAD   0x00bef0 0x0000cef0 0x0000cef0 0x00118 0x0011c RW  0x1000  writeable
5442
//
5443
//         xct_off will have been increased artifically to point to
5444
//         the large compressable PT_LOAD (0x9d40==MemSiz), in order to avoid
5445
//         NotCompressable because the earlier PT_LOADs were too short (< 4KiB).
5446
// 2. If the first PT_LOAD covers xct_off, then the order of output is:
5447
//      A. original Ehdr+Phdrs (overwritten later)
5448
//      B. other original content below xct_off [loader tables]
5449
//      C. compressed Ehdr+Phdrs (for de-compressor to restore); M_NRV2B_LE32, no filter.
5450
//      D. compressed content above xct_off in first PT_LOAD;
5451
//         use filter for executable code.
5452
//      E. compressed remaining PT_LOAD (except PT_WRITE); no filter.
5453
//
5454
5455
int PackLinuxElf32::pack2_shlib(OutputFile *fo, Filter &ft, unsigned pre_xct_top)
5456
0
{
5457
    // prepare to alter Phdrs and Shdrs
5458
0
    lowmem.alloc(up8(xct_off + (!is_asl
5459
0
        ? 0
5460
0
        : e_shnum * sizeof(Elf32_Shdr))));
5461
0
    memcpy(lowmem, file_image, xct_off);  // android omits Shdr from copy now
5462
5463
0
    MemBuffer elf_buf;
5464
0
    elf_buf.allocForCompression(sz_elf_hdrs);
5465
0
    unsigned u_len = sz_elf_hdrs;
5466
0
    unsigned c_len = pack2_shlib_overlay_compress(elf_buf, lowmem, u_len);
5467
5468
0
    int n_ptload = 0;
5469
0
    Elf32_Phdr *phdr = &phdri[0];
5470
0
    for (unsigned k = 0; k < e_phnum; ++phdr, ++k)
5471
0
    if (is_LOAD(phdr)) {
5472
0
        unsigned p_offset = get_te32(&phdr->p_offset);
5473
0
        unsigned p_filesz = get_te32(&phdr->p_filesz);
5474
0
        if (!n_ptload) { // first PT_LOAD
5475
0
            if (is_asl) { // Copy up to xct_off, then add 2nd copy of Shdrs
5476
0
                asl_pack2_Shdrs(fo, pre_xct_top);
5477
0
            }
5478
0
            else {
5479
0
                fo->write(&lowmem[p_offset], sz_elf_hdrs);  total_out += sz_elf_hdrs;
5480
0
                total_in  += sz_elf_hdrs;
5481
0
                fo->seek(sz_phdrx, SEEK_CUR);  total_out += sz_phdrx;  // leave space
5482
5483
                // Compare PackUnix::packExtent, especially "if (u_len)" .
5484
                //
5485
5486
0
                unsigned const hi_offset = umin(xct_off, p_filesz + p_offset);
5487
0
                if (sz_elf_hdrs < hi_offset) {
5488
                    // Loader tables in first PT_LOAD, and below xct_off.
5489
                    //
5490
0
                    fo->write(&lowmem[sz_elf_hdrs], hi_offset - sz_elf_hdrs);  total_out += hi_offset - sz_elf_hdrs;
5491
0
                    total_in  += hi_offset - sz_elf_hdrs;
5492
0
                    Elf32_Phdr *lo_phdr = k + (Elf32_Phdr *)(1+ (Elf32_Ehdr *)&lowmem[0]);
5493
0
                    set_te32(&lo_phdr->p_flags, Elf32_Phdr::PF_X | get_te32(&lo_phdr->p_flags));
5494
0
                }
5495
0
            }
5496
0
            pack2_shlib_overlay_init(fo); // set overlay_offset
5497
            // Compressed ELF headers go first.
5498
0
            pack2_shlib_overlay_write(fo, elf_buf, u_len, c_len);
5499
5500
            // The (compressible) remainder above xct_off in first PT_LOAD
5501
0
            if (         p_filesz > (xct_off - p_offset)) {
5502
0
                Extent x;
5503
0
                x.size = p_filesz - (xct_off - p_offset);
5504
0
                x.offset = xct_off;
5505
0
                packExtent(x, &ft, fo, 0, 0, true);
5506
0
            }
5507
0
        }  // end first PT_LOAD
5508
0
        else if ((p_filesz + p_offset) <= xct_off) {
5509
            // Not first PT_LOAD, but below xct_offset.  Thus "interloper" PT_LOAD,
5510
            // below xct_off that was increased to a PT_LOAD large enough to compress.
5511
            // "Manually" compress it, do not use PackExtent.
5512
0
            MemBuffer buf2; buf2.allocForCompression(p_filesz);
5513
0
            c_len = pack2_shlib_overlay_compress(buf2, &lowmem[p_offset], p_filesz); total_in += p_filesz;
5514
0
            pack2_shlib_overlay_write(fo, buf2, p_filesz, c_len);
5515
0
            Elf32_Phdr *lo_phdr = k + (Elf32_Phdr *)(1+ (Elf32_Ehdr *)&lowmem[0]);
5516
0
            set_te32(&lo_phdr->p_type, Elf32_Phdr::PT_NULL);
5517
0
        }
5518
0
        else if ((xct_off - p_offset) < p_filesz) {
5519
0
            unsigned const len = xct_off - p_offset;
5520
            // Loader tables in non-first PT_LOAD.  (xct_off was increased.)
5521
            // Bytes below xct_off belong to rtld, so cannot be compressed.
5522
            // Note that asl_pack2_Shdrs() copies up to xct_off, then adds extra info.
5523
            // Copy up to xct_off
5524
0
            if (len) {
5525
0
                fo->write(&lowmem[p_offset], len);  total_out += len;
5526
0
                total_in += len;
5527
5528
                // Compressed ELF headers  FIXME: 1st PT_LOAD also did this!
5529
0
                pack2_shlib_overlay_write(fo, elf_buf, u_len, c_len);  // set overlay_offset
5530
0
            }
5531
            // The rest, above xct_off.
5532
0
            Extent x;
5533
0
            x.offset = xct_off;
5534
0
            x.size = p_filesz - len;
5535
0
            packExtent(x, &ft, fo, 0, 0, true);
5536
0
            Elf32_Phdr *lo_phdr = k + (Elf32_Phdr *)(1+ (Elf32_Ehdr *)&lowmem[0]);
5537
0
            set_te32(&lo_phdr->p_type, Elf32_Phdr::PT_NULL);
5538
0
        }
5539
0
        else { // definitely compressible unless writeable
5540
0
            if (!(Elf32_Phdr::PF_W & get_te32(&phdr->p_flags))) {
5541
                // Read-only PT_LOAD, assume not written by relocations.
5542
                // Also assume not the source for R_*_COPY relocation,
5543
                // therefore compress it.
5544
0
                Extent x;
5545
0
                x.offset = p_offset;
5546
0
                x.size = p_filesz;
5547
0
                packExtent(x, &ft, fo, 0, 0, true);  // choose filter and method, then do it
5548
                // De-compressing will re-create it, but otherwise ignore it.
5549
0
                Elf32_Phdr *phdro = (Elf32_Phdr *)(1+ (Elf32_Ehdr *)&lowmem[0]);
5550
0
                set_te32(&phdro[k].p_type, Elf32_Phdr::PT_NULL);
5551
0
            }
5552
0
            else {
5553
                // Read-write PT_LOAD.
5554
                // rtld might relocate, so we cannot compress.
5555
                // (Could compress if not relocated; complicates run-time.)
5556
                // Postpone writing until "slide", but account for its size.
5557
0
                total_in +=  p_filesz;
5558
0
            }
5559
0
        }
5560
0
        ++n_ptload;
5561
0
    }
5562
0
    return 0;  // FIXME
5563
0
}
5564
5565
int PackLinuxElf32::pack2(OutputFile *fo, Filter &ft)
5566
0
{
5567
0
    Extent x;
5568
0
    unsigned k;
5569
0
    unsigned const is_shlib = (0!=xct_off) | is_asl;
5570
0
    unsigned pre_xct_top = 0;  // offset of end of PT_LOAD _before_ xct_off
5571
5572
    // count passes, set ptload vars
5573
0
    uip->ui_total_passes = 0;
5574
0
    for (k = 0; k < e_phnum; ++k) {
5575
0
        if (is_LOAD(&phdri[k])) {
5576
0
            if (!is_shlib) {
5577
0
                uip->ui_total_passes++;
5578
0
            }
5579
0
            else {
5580
0
                unsigned p_flags = get_te32(&phdri[k].p_flags);
5581
0
                unsigned p_offset = get_te32(&phdri[k].p_offset);
5582
0
                unsigned p_filesz = get_te32(&phdri[k].p_filesz);
5583
0
                if ((xct_off - p_offset) < p_filesz) { // PT_LOAD covers xct_off
5584
0
                    if (!pre_xct_top && xct_off != p_offset) {
5585
0
                        pre_xct_top = xct_off;
5586
0
                    }
5587
0
                }
5588
0
                else if (p_offset < xct_off) { // candidate for pre_xct_top
5589
0
                    unsigned top = p_filesz + p_offset;
5590
0
                    if (pre_xct_top < top) {
5591
0
                        pre_xct_top = top;
5592
0
                    }
5593
0
                }
5594
0
                if (Elf32_Phdr::PF_W & p_flags) {
5595
                    // rtld might write, so cannot compress
5596
0
                }
5597
0
                else {
5598
                    // First PT_LOAD (partial) only if has instructions
5599
0
                    if (k || xct_off < p_filesz) {
5600
0
                        uip->ui_total_passes++;
5601
0
                    }
5602
0
                }
5603
0
            }
5604
0
            if (find_LOAD_gap(phdri, k, e_phnum)) {
5605
0
                uip->ui_total_passes++;
5606
0
            }
5607
0
        }
5608
0
    }
5609
5610
    // compress extents
5611
0
    unsigned hdr_u_len = sizeof(Elf32_Ehdr) + sz_phdrs;
5612
5613
0
    total_in =  0;
5614
0
    total_out = 0;
5615
0
    uip->ui_pass = 0;
5616
0
    ft.addvalue = 0;
5617
5618
0
    unsigned nk_f = 0; upx_uint32_t xsz_f = 0;
5619
0
    for (k = 0; k < e_phnum; ++k)
5620
0
    if (is_LOAD(&phdri[k])
5621
0
    &&  Elf32_Phdr::PF_X & get_te32(&phdri[k].p_flags)) {
5622
0
        upx_uint32_t xsz = get_te32(&phdri[k].p_filesz);
5623
0
        if (xsz_f < xsz) {
5624
0
            xsz_f = xsz;
5625
0
            nk_f = k;
5626
0
        }
5627
0
    }
5628
0
    if (is_shlib) {
5629
0
        pack2_shlib(fo, ft, pre_xct_top);
5630
0
    }
5631
0
    else { // main program
5632
0
        int n_ptload = 0;
5633
0
        for (k = 0; k < e_phnum; ++k)
5634
0
        if (is_LOAD(&phdri[k])) {
5635
0
            if (ft.id < 0x40) {
5636
                // FIXME: ??    ft.addvalue = phdri[k].p_vaddr;
5637
0
            }
5638
0
            unsigned p_offset = get_te32(&phdri[k].p_offset);
5639
0
            unsigned p_filesz = get_te32(&phdri[k].p_filesz);
5640
0
            x.offset = p_offset;
5641
0
            x.size   = p_filesz;
5642
0
            if ((u32_t)x.size < hdr_u_len) { // FIXME: main program, but how?
5643
0
                total_in += x.size;
5644
0
            }
5645
0
            else {  // main program, not shared library
5646
0
                if (0 == n_ptload) { // 1st PT_LOAD must cover Ehdr at 0==p_offset
5647
0
                    unsigned const delta = hdr_u_len;
5648
0
                    if (ft.id < 0x40) {
5649
                        // FIXME: ??     ft.addvalue += asl_delta;
5650
0
                    }
5651
0
                    if ((off_t)delta == x.size) { // PT_LOAD[0] with ElfXX.Ehdr only
5652
                        // QBE backend - http://c9x.me/compile/
5653
0
                        hdr_u_len = 0;  // no fiddling necessary!
5654
                        // &ft arg to packExtent will be zero because (k != nk_f)
5655
0
                    }
5656
0
                    else {
5657
0
                        total_in += delta - hdr_u_len;
5658
0
                        x.offset += delta;
5659
0
                        x.size   -= delta;
5660
0
                    }
5661
0
                }
5662
                // compressWithFilters() always assumes a "loader", so would
5663
                // throw NotCompressible for small .data Extents, which PowerPC
5664
                // sometimes marks as PF_X anyway.  So filter only first segment.
5665
0
                packExtent(x,
5666
0
                    (k==nk_f ? &ft : nullptr ), fo, hdr_u_len, 0, true);
5667
0
                hdr_u_len = 0;
5668
0
            }
5669
0
            ++n_ptload;
5670
0
        }
5671
0
    }
5672
0
    sz_pack2a = fpad4(fo, total_out);  // MATCH01
5673
0
    total_out = up4(total_out);
5674
5675
    // Accounting only; ::pack3 will do the compression and output
5676
0
    for (k = 0; k < e_phnum; ++k) {
5677
0
        total_in += find_LOAD_gap(phdri, k, e_phnum);
5678
0
    }
5679
5680
0
    if (total_in != (u32_t)file_size)
5681
0
        throwEOFException();
5682
5683
0
    return 0;  // omit end-of-compression bhdr for now
5684
0
}
5685
5686
// Determine length of gap between PT_LOAD phdr[k] and closest PT_LOAD
5687
// which follows in the file (or end-of-file).  Optimize for common case
5688
// where the PT_LOAD are adjacent ascending by .p_offset.  Assume no overlap.
5689
5690
unsigned PackLinuxElf64::find_LOAD_gap(
5691
    Elf64_Phdr const *const phdr,
5692
    unsigned const k,
5693
    unsigned const nph
5694
)
5695
749
{
5696
749
    if (!is_LOAD(&phdr[k])) {
5697
530
        return 0;
5698
530
    }
5699
219
    unsigned const hi = get_te64(&phdr[k].p_offset) +
5700
219
                        get_te64(&phdr[k].p_filesz);
5701
219
    unsigned lo = ph.u_file_size;
5702
219
    if (lo < hi)
5703
0
        throwCantPack("bad input: PT_LOAD beyond end-of-file");
5704
219
    unsigned j = k;
5705
1.46k
    for (;;) { // circular search, optimize for adjacent ascending
5706
1.46k
        ++j;
5707
1.46k
        if (nph==j) {
5708
213
            j = 0;
5709
213
        }
5710
1.46k
        if (k==j) {
5711
213
            break;
5712
213
        }
5713
1.25k
        if (is_LOAD(&phdr[j])) {
5714
411
            unsigned const t = get_te64(&phdr[j].p_offset);
5715
411
            if ((t - hi) < (lo - hi)) {
5716
154
                lo = t;
5717
154
                if (hi==lo) {
5718
6
                    break;
5719
6
                }
5720
154
            }
5721
411
        }
5722
1.25k
    }
5723
219
    return lo - hi;
5724
219
}
5725
5726
int PackLinuxElf64::pack2_shlib(OutputFile *fo, Filter &ft, unsigned pre_xct_top)
5727
0
{
5728
    // prepare to alter Phdrs and Shdrs
5729
0
    lowmem.alloc(up8(xct_off + (!is_asl
5730
0
        ? 0
5731
0
        : e_shnum * sizeof(Elf64_Shdr))));
5732
0
    memcpy(lowmem, file_image, xct_off);  // android omits Shdr from copy now
5733
5734
0
    MemBuffer elf_buf;
5735
0
    elf_buf.allocForCompression(sz_elf_hdrs);
5736
0
    unsigned u_len = sz_elf_hdrs;
5737
0
    unsigned c_len = pack2_shlib_overlay_compress(elf_buf, lowmem, u_len);
5738
5739
0
    int n_ptload = 0;
5740
0
    Elf64_Phdr *phdr = &phdri[0];
5741
0
    for (unsigned k = 0; k < e_phnum; ++phdr, ++k)
5742
0
    if (is_LOAD(phdr)) {
5743
0
        unsigned p_offset = get_te64_32(&phdr->p_offset);
5744
0
        unsigned p_filesz = get_te64_32(&phdr->p_filesz);
5745
0
        if (!n_ptload) { // first PT_LOAD
5746
0
            if (is_asl) { // Copy up to xct_off, then add 2nd copy of Shdrs
5747
0
                asl_pack2_Shdrs(fo, pre_xct_top);
5748
0
            }
5749
0
            else {
5750
0
                fo->write(&lowmem[p_offset], sz_elf_hdrs);  total_out += sz_elf_hdrs;
5751
0
                total_in  += sz_elf_hdrs;
5752
0
                fo->seek(sz_phdrx, SEEK_CUR);  total_out += sz_phdrx;  // leave space
5753
5754
                // Compare PackUnix::packExtent, especially "if (u_len)" .
5755
                //
5756
5757
0
                unsigned const hi_offset = umin(xct_off, (unsigned)(p_filesz + p_offset));
5758
0
                if (sz_elf_hdrs < hi_offset) {
5759
                    // Loader tables in first PT_LOAD, and below xct_off.
5760
                    //
5761
0
                    fo->write(&lowmem[sz_elf_hdrs], hi_offset - sz_elf_hdrs);  total_out += hi_offset - sz_elf_hdrs;
5762
0
                    total_in  += hi_offset - sz_elf_hdrs;
5763
0
                    Elf64_Phdr *lo_phdr = k + (Elf64_Phdr *)(1+ (Elf64_Ehdr *)&lowmem[0]);
5764
0
                    set_te32(&lo_phdr->p_flags, Elf64_Phdr::PF_X | get_te32(&lo_phdr->p_flags));
5765
0
                }
5766
0
            }
5767
0
            pack2_shlib_overlay_init(fo); // set overlay_offset
5768
            // Compressed ELF headers go first.
5769
0
            pack2_shlib_overlay_write(fo, elf_buf, u_len, c_len);
5770
5771
            // The (compressible) remainder above xct_off in first PT_LOAD
5772
0
            if (         p_filesz > (xct_off - p_offset)) {
5773
0
                Extent x;
5774
0
                x.size = p_filesz - (xct_off - p_offset);
5775
0
                x.offset = xct_off;
5776
0
                packExtent(x, &ft, fo, 0, 0, true);
5777
0
            }
5778
0
        }  // end first PT_LOAD
5779
0
        else if ((p_filesz + p_offset) <= xct_off) {
5780
            // Not first PT_LOAD, but below xct_offset.  Thus "interloper" PT_LOAD,
5781
            // below xct_off that was increased to a PT_LOAD large enough to compress.
5782
            // "Manually" compress it, do not use PackExtent.
5783
0
            MemBuffer buf2; buf2.allocForCompression(p_filesz);
5784
0
            c_len = pack2_shlib_overlay_compress(buf2, &lowmem[p_offset], p_filesz); total_in += p_filesz;
5785
0
            pack2_shlib_overlay_write(fo, buf2, p_filesz, c_len);
5786
0
            Elf64_Phdr *lo_phdr = k + (Elf64_Phdr *)(1+ (Elf64_Ehdr *)&lowmem[0]);
5787
0
            set_te32(&lo_phdr->p_type, Elf64_Phdr::PT_NULL);
5788
0
        }
5789
0
        else if ((xct_off - p_offset) < p_filesz) {
5790
0
            unsigned const len = xct_off - p_offset;
5791
            // Loader tables in non-first PT_LOAD.  (xct_off was increased.)
5792
            // Bytes below xct_off belong to rtld, so cannot be compressed.
5793
            // Note that asl_pack2_Shdrs() copies up to xct_off, then adds extra info.
5794
            // Copy up to xct_off
5795
0
            if (len) {
5796
0
                fo->write(&lowmem[p_offset], len);  total_out += len;
5797
0
                total_in += len;
5798
5799
                // Compressed ELF headers  FIXME: 1st PT_LOAD also did this!
5800
0
                pack2_shlib_overlay_write(fo, elf_buf, u_len, c_len);  // set overlay_offset
5801
0
            }
5802
            // The rest, above xct_off.
5803
0
            Extent x;
5804
0
            x.offset = xct_off;
5805
0
            x.size = p_filesz - len;
5806
0
            packExtent(x, &ft, fo, 0, 0, true);
5807
0
            Elf64_Phdr *lo_phdr = k + (Elf64_Phdr *)(1+ (Elf64_Ehdr *)&lowmem[0]);
5808
0
            set_te32(&lo_phdr->p_type, Elf64_Phdr::PT_NULL);
5809
0
        }
5810
0
        else { // definitely compressible unless writeable
5811
0
            if (!(Elf64_Phdr::PF_W & get_te32(&phdr->p_flags))) {
5812
                // Read-only PT_LOAD, assume not written by relocations.
5813
                // Also assume not the source for R_*_COPY relocation,
5814
                // therefore compress it.
5815
0
                Extent x;
5816
0
                x.offset = p_offset;
5817
0
                x.size = p_filesz;
5818
0
                packExtent(x, &ft, fo, 0, 0, true);  // choose filter and method, then do it
5819
                // De-compressing will re-create it, but otherwise ignore it.
5820
0
                Elf64_Phdr *phdro = (Elf64_Phdr *)(1+ (Elf64_Ehdr *)&lowmem[0]);
5821
0
                set_te32(&phdro[k].p_type, Elf32_Phdr::PT_NULL);
5822
0
            }
5823
0
            else {
5824
                // Read-write PT_LOAD.
5825
                // rtld might relocate, so we cannot compress.
5826
                // (Could compress if not relocated; complicates run-time.)
5827
                // Postpone writing until "slide", but account for its size.
5828
0
                total_in +=  p_filesz;
5829
0
            }
5830
0
        }
5831
0
        ++n_ptload;
5832
0
    }
5833
0
    return 0;  // FIXME
5834
0
}
5835
5836
int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
5837
0
{
5838
0
    Extent x;
5839
0
    unsigned k;
5840
    // See comment in Elf32_Linux::canPack().  is_asl does not work.
5841
    // 64-bit ARM (aarch64) also has no ARM_ATTRIBUTES.
5842
    //is_asl = (!!saved_opt_android_shlib) << 1;  // bit 1; see is_shlib
5843
0
    is_asl = 0;
5844
0
    unsigned const is_shlib = (0!=xct_off) | is_asl;
5845
0
    unsigned pre_xct_top = 0;  // offset of end of PT_LOAD _before_ xct_off
5846
5847
0
    if (Elf64_Ehdr::EM_ARM==get_te16(&ehdri.e_machine)) {
5848
0
        sec_arm_attr = elf_find_section_type(Elf64_Shdr::SHT_ARM_ATTRIBUTES);
5849
0
    }
5850
    // count passes, set ptload vars
5851
0
    uip->ui_total_passes = 0;
5852
0
    for (k = 0; k < e_phnum; ++k) {
5853
0
        if (is_LOAD(&phdri[k])) {
5854
0
            if (!is_shlib) {
5855
0
                uip->ui_total_passes++;
5856
0
            }
5857
0
            else {
5858
0
                unsigned p_flags = get_te32(&phdri[k].p_flags);
5859
0
                unsigned p_offset = get_te64_32(&phdri[k].p_offset);
5860
0
                unsigned p_filesz = get_te64_32(&phdri[k].p_filesz);
5861
0
                if ((xct_off - p_offset) < p_filesz) { // PT_LOAD covers xct_off
5862
0
                    if (!pre_xct_top && xct_off != p_offset) {
5863
0
                        pre_xct_top = xct_off;
5864
0
                    }
5865
0
                }
5866
0
                else if (p_offset < xct_off) { // candidate for pre_xct_top
5867
0
                    unsigned top = p_filesz + p_offset;
5868
0
                    if (pre_xct_top < top) {
5869
0
                        pre_xct_top = top;
5870
0
                    }
5871
0
                }
5872
0
                if (Elf64_Phdr::PF_W & p_flags) {
5873
                    // rtld might write, so cannot compress
5874
0
                }
5875
0
                else {
5876
                    // First PT_LOAD (partial) only if has instructions
5877
0
                    if (k || xct_off < p_filesz) {
5878
0
                        uip->ui_total_passes++;
5879
0
                    }
5880
0
                }
5881
0
            }
5882
0
            if (find_LOAD_gap(phdri, k, e_phnum)) {
5883
0
                uip->ui_total_passes++;
5884
0
            }
5885
0
        }
5886
0
    }
5887
5888
    // compress extents
5889
0
    unsigned hdr_u_len = sizeof(Elf64_Ehdr) + sz_phdrs;
5890
5891
0
    total_in =  0;
5892
0
    total_out = 0;
5893
0
    uip->ui_pass = 0;
5894
0
    ft.addvalue = 0;
5895
5896
0
    unsigned nk_f = 0; upx_uint32_t xsz_f = 0;
5897
0
    for (k = 0; k < e_phnum; ++k)
5898
0
    if (is_LOAD(&phdri[k])
5899
0
    &&  Elf32_Phdr::PF_X & get_te32(&phdri[k].p_flags)) {
5900
0
        unsigned xsz = get_te64_32(&phdri[k].p_filesz);
5901
0
        if (xsz_f < xsz) {
5902
0
            xsz_f = xsz;
5903
0
            nk_f = k;
5904
0
        }
5905
0
    }
5906
0
    if (is_shlib) {
5907
0
        pack2_shlib(fo, ft, pre_xct_top);
5908
0
    }
5909
0
    else { // main program
5910
0
        int n_ptload = 0;
5911
0
        for (k = 0; k < e_phnum; ++k)
5912
0
        if (is_LOAD(&phdri[k])) {
5913
0
            if (ft.id < 0x40) {
5914
                // FIXME: ??    ft.addvalue = phdri[k].p_vaddr;
5915
0
            }
5916
0
            unsigned p_offset = get_te64_32(&phdri[k].p_offset);
5917
0
            unsigned p_filesz = get_te64_32(&phdri[k].p_filesz);
5918
0
            x.offset = p_offset;
5919
0
            x.size   = p_filesz;
5920
0
            if ((u32_t)x.size < hdr_u_len) { // FIXME: main program, but how?
5921
0
                total_in += x.size;
5922
0
            }
5923
0
            else {  // main program, not shared library
5924
0
                if (0 == n_ptload) { // 1st PT_LOAD must cover Ehdr at 0==p_offset
5925
0
                    unsigned const delta = hdr_u_len;
5926
0
                    if (ft.id < 0x40) {
5927
                        // FIXME: ??     ft.addvalue += asl_delta;
5928
0
                    }
5929
0
                    if ((off_t)delta == x.size) { // PT_LOAD[0] with ElfXX.Ehdr only
5930
                        // QBE backend - http://c9x.me/compile/
5931
0
                        hdr_u_len = 0;  // no fiddling necessary!
5932
                        // &ft arg to packExtent will be zero because (k != nk_f)
5933
0
                    }
5934
0
                    else {
5935
0
                        total_in += delta - hdr_u_len;
5936
0
                        x.offset += delta;
5937
0
                        x.size   -= delta;
5938
0
                    }
5939
0
                }
5940
                // compressWithFilters() always assumes a "loader", so would
5941
                // throw NotCompressible for small .data Extents, which PowerPC
5942
                // sometimes marks as PF_X anyway.  So filter only first segment.
5943
0
                packExtent(x,
5944
0
                    (k==nk_f ? &ft : nullptr ), fo, hdr_u_len, 0, true);
5945
0
                hdr_u_len = 0;
5946
0
            }
5947
0
            ++n_ptload;
5948
0
        }
5949
0
    }
5950
0
    sz_pack2a = fpad4(fo, total_out);  // MATCH01
5951
0
    total_out = up4(total_out);
5952
5953
    // Accounting only; ::pack3 will do the compression and output
5954
0
    for (k = 0; k < e_phnum; ++k) {
5955
0
        total_in += find_LOAD_gap(phdri, k, e_phnum);
5956
0
    }
5957
5958
0
    if (total_in != (u32_t)file_size)
5959
0
        throwEOFException();
5960
5961
0
    return 0;  // omit end-of-compression bhdr for now
5962
0
}
5963
5964
// Filter 0x50, 0x51 assume HostPolicy::isLE
5965
static const int *
5966
ARM_getFilters(bool const isBE)
5967
0
{
5968
0
    static const int f50[] = { 0x50, FT_END };
5969
0
    static const int f51[] = { 0x51, FT_END };
5970
0
    if (isBE)
5971
0
        return f51;
5972
0
    return f50;
5973
0
}
5974
5975
const int *
5976
PackLinuxElf32armBe::getFilters() const
5977
0
{
5978
0
    return ARM_getFilters(true);
5979
0
}
5980
5981
const int *
5982
PackLinuxElf32armLe::getFilters() const
5983
0
{
5984
0
    return ARM_getFilters(false);
5985
0
}
5986
5987
const int *
5988
PackLinuxElf32mipseb::getFilters() const
5989
0
{
5990
0
    static const int f_none[] = { FT_END };
5991
0
    return f_none;
5992
0
}
5993
5994
const int *
5995
PackLinuxElf32mipsel::getFilters() const
5996
0
{
5997
0
    static const int f_none[] = { FT_END };
5998
0
    return f_none;
5999
0
}
6000
6001
// October 2011: QNX 6.3.0 has no unique signature?
6002
int PackLinuxElf32::ARM_is_QNX(void)
6003
0
{
6004
0
    if (Elf32_Ehdr::EM_ARM==get_te16(&ehdri.e_machine)
6005
0
    &&  Elf32_Ehdr::ELFDATA2MSB== ehdri.e_ident[Elf32_Ehdr::EI_DATA]
6006
0
    &&  Elf32_Ehdr::ELFOSABI_ARM==ehdri.e_ident[Elf32_Ehdr::EI_OSABI]
6007
0
    &&  0x100000==(page_mask & get_te32(&phdri[0].p_vaddr))) {
6008
0
        Elf32_Phdr const *phdr = phdri;
6009
0
        for (int j = get_te16(&ehdri.e_phnum); --j>=0; ++phdr) {
6010
0
            if (Elf32_Phdr::PT_INTERP==get_te32(&phdr->p_type)) {
6011
0
                char interp[64];
6012
0
                unsigned const sz_interp = get_te32(&phdr->p_filesz);
6013
0
                unsigned const pos_interp = get_te32(&phdr->p_offset);
6014
0
                if (sz_interp <= sizeof(interp)
6015
0
                &&  (sz_interp + pos_interp) <= (unsigned)file_size) {
6016
0
                    fi->seek(pos_interp, SEEK_SET);
6017
0
                    fi->readx(interp, sz_interp);
6018
0
                    for (int k = sz_interp - 5; k>=0; --k) {
6019
0
                        if (0==memcmp("ldqnx", &interp[k], 5))
6020
0
                            return 1;
6021
0
                    }
6022
0
                }
6023
0
            }
6024
0
        }
6025
0
    }
6026
0
    return 0;
6027
0
}
6028
6029
void PackLinuxElf32::ARM_defineSymbols(Filter const *ft)
6030
0
{
6031
0
    PackLinuxElf32::defineSymbols(ft);
6032
6033
0
#define MAP_PRIVATE      2     /* UNIX standard */
6034
0
#define MAP_FIXED     0x10     /* UNIX standard */
6035
0
#define MAP_ANONYMOUS 0x20     /* UNIX standard */
6036
0
#define MAP_PRIVANON     3     /* QNX anonymous private memory */
6037
0
    unsigned mflg = MAP_PRIVATE | MAP_ANONYMOUS;
6038
0
    if (ARM_is_QNX())
6039
0
        mflg = MAP_PRIVANON;
6040
0
    linker->defineSymbol("MFLG", mflg);
6041
0
}
6042
6043
void PackLinuxElf32armLe::defineSymbols(Filter const *ft)
6044
0
{
6045
0
    ARM_defineSymbols(ft);
6046
0
}
6047
6048
void PackLinuxElf32armBe::defineSymbols(Filter const *ft)
6049
0
{
6050
0
    ARM_defineSymbols(ft);
6051
0
}
6052
6053
void PackLinuxElf64arm::defineSymbols(Filter const *ft)
6054
0
{
6055
0
    PackLinuxElf64::defineSymbols(ft);
6056
6057
0
#define MAP_PRIVATE      2     /* UNIX standard */
6058
0
#define MAP_FIXED     0x10     /* UNIX standard */
6059
0
#define MAP_ANONYMOUS 0x20     /* UNIX standard */
6060
0
#define MAP_PRIVANON     3     /* QNX anonymous private memory */
6061
0
    unsigned mflg = MAP_PRIVATE | MAP_ANONYMOUS;
6062
    //if (ARM_is_QNX())
6063
    //    mflg = MAP_PRIVANON;
6064
0
    linker->defineSymbol("MFLG", mflg);
6065
0
}
6066
6067
void PackLinuxElf32mipseb::defineSymbols(Filter const *ft)
6068
0
{
6069
0
    PackLinuxElf32::defineSymbols(ft);
6070
0
}
6071
6072
void PackLinuxElf32mipsel::defineSymbols(Filter const *ft)
6073
0
{
6074
0
    PackLinuxElf32::defineSymbols(ft);
6075
0
}
6076
6077
// ::forward_Shdrs adds info for the benefit of gdb and Android dlopen().
6078
// De-compression (runtime and offline) ignores the added information
6079
// because it uses the de-compressed Ehdr etc.
6080
// All the added space is redundant; libbfd should take a hint:
6081
// if no Shdrs, then use PT_DYNAMIC instead.
6082
// (.ARM_attributes (ARM_ATTRIBUTES) is not redundant.)
6083
//
6084
// want_types_mask: SHT_PROGBITS is needed else gdb complains:
6085
//    /build/gdb-MVZsgD/gdb-10.1/gdb/symfile.c:878: internal-error: sect_index_text not initialized
6086
// and Continuing is not reasonable.
6087
// However, SHT_PROGBITS with compression gives:
6088
//    BFD: warning: ./libmain.so.upx has a section extending past end of file
6089
//    BFD: warning: ./libmain.so.upx has a section extending past end of file
6090
//    BFD: warning: ./libmain.so.upx has a section extending past end of file
6091
//    warning: Loadable section ".text" outside of ELF segments
6092
//    warning: Loadable section ".plt" outside of ELF segments
6093
// because compression gives smaller extents, with no reasonable _Shdr fields.
6094
// At least gdb can continue.
6095
6096
unsigned PackLinuxElf32::forward_Shdrs(OutputFile *fo, Elf32_Ehdr *const eho)
6097
0
{
6098
0
    if (!fo) {
6099
0
        return 0;
6100
0
    }
6101
0
    unsigned penalty = total_out;
6102
0
    if (sec_arm_attr) { // Forward select _Shdr.  EM_ARM (and Android ?) only.
6103
        // Keep _Shdr for rtld data (below xct_off).
6104
        // Discard _Shdr for compressed regions, except ".text" for gdb.
6105
        // Keep _Shdr for SHF_WRITE.
6106
        // Discard _Shdr with (0==sh_addr), except _Shdr[0]
6107
        // Keep ARM_ATTRIBUTES
6108
0
        unsigned const want_types_mask = 0
6109
0
            | 1u<<SHT_PROGBITS  // see comment above, and special code below
6110
0
            | 1u<<SHT_HASH
6111
0
            | 1u<<SHT_DYNAMIC
6112
0
            | 1u<<SHT_NOTE
6113
0
            | 1u<<SHT_REL
6114
0
            | 1u<<SHT_RELA
6115
0
            | 1u<<SHT_RELR
6116
0
            | 1u<<SHT_DYNSYM  // but not SHT_SYMTAB because compression confuses gdb
6117
0
            | 1u<<SHT_STRTAB  // .shstrtab and DYNSYM.sh_link; not SYMTAB.sh_link
6118
0
            | 1u<<SHT_INIT_ARRAY
6119
0
            | 1u<<SHT_FINI_ARRAY
6120
0
            | 1u<<SHT_PREINIT_ARRAY
6121
0
            | 1u<<(0x1f & SHT_GNU_versym)
6122
0
            | 1u<<(0x1f & SHT_GNU_verneed)
6123
0
            | 1u<<(0x1f & SHT_GNU_verdef)
6124
0
            | 1u<<(0x1f & SHT_GNU_HASH);
6125
6126
0
        u32_t xct_off_hi = 0;
6127
0
        Elf32_Phdr *ptr = phdri, *ptr_end = &phdri[e_phnum];
6128
0
        for (; ptr < ptr_end; ++ptr) {
6129
0
            if (is_LOAD(ptr)) {
6130
0
                u32_t hi = get_te32(&ptr->p_filesz)
6131
0
                    + get_te32(&ptr->p_offset);
6132
0
                if (xct_off < hi) {
6133
0
                    xct_off_hi = hi;
6134
0
                    break;
6135
0
                }
6136
0
            }
6137
0
        }
6138
6139
0
        MemBuffer mb_ask_for(e_shnum * sizeof(eho->e_shnum));
6140
0
        memset(mb_ask_for, 0, mb_ask_for.getSize());
6141
0
        unsigned short *const ask_for = (unsigned short *)mb_ask_for.getVoidPtr();
6142
6143
0
        MemBuffer mb_shdro(e_shnum * sizeof(*shdri));
6144
0
        Elf32_Shdr *sh_out0 = (Elf32_Shdr *)mb_shdro.getVoidPtr();
6145
0
        Elf32_Shdr *sh_out = sh_out0;
6146
0
        Elf32_Shdr *sh_in = shdri;
6147
0
        Elf32_Shdr *n_shstrsec = nullptr;
6148
6149
        // Some binutils does tail merging on section names; we don't.
6150
        // ".plt" == (4+ ".rel.plt"); ".hash" == (4+ ".gnu.hash")
6151
0
        MemBuffer mb_shstrings(100 + 2*get_te32(&sh_in[e_shstrndx].sh_size));
6152
0
        char *ptr_shstrings = (char *)&mb_shstrings[0];
6153
0
        *ptr_shstrings++ = '\0';
6154
6155
0
        memset(sh_out, 0, sizeof(*sh_out));  // blank sh_out[0]
6156
0
        ++sh_in; ++sh_out; unsigned n_sh_out = 1;
6157
6158
0
        for (unsigned j = 1; j < e_shnum; ++j, ++sh_in) {
6159
0
            unsigned sh_name   = get_te32(&sh_in->sh_name);
6160
0
            unsigned sh_type   = get_te32(&sh_in->sh_type);
6161
0
            unsigned sh_flags  = get_te32(&sh_in->sh_flags);
6162
            //unsigned sh_addr   = get_te32(&sh_in->sh_addr);
6163
0
            unsigned sh_offset = get_te32(&sh_in->sh_offset);
6164
0
            unsigned sh_size   = get_te32(&sh_in->sh_size);
6165
0
            unsigned sh_info   = get_te32(&sh_in->sh_info);
6166
0
            char const *name = &shstrtab[sh_name];
6167
0
            if (ask_for[j]) { // Some previous _Shdr requested  me
6168
                // Tell them my new index
6169
0
                set_te32(&sh_out0[ask_for[j]].sh_info, n_sh_out);  // sh_info vs st_shndx
6170
0
            }
6171
0
            if (sh_info < e_shnum) { // wild sh_info abounds!
6172
0
                ask_for[sh_info] = j;  // Enter my request, if any
6173
0
            }
6174
0
            if (   (sh_offset && sh_offset < xct_off)
6175
0
                || (j == e_shstrndx)
6176
0
                || (Elf32_Shdr::SHF_WRITE & sh_flags)
6177
0
                || (sh_type < Elf32_Shdr::SHT_LOPROC
6178
0
                    && want_types_mask & (1<<(0x1f & sh_type)))
6179
0
                || (Elf32_Shdr::SHT_ARM_ATTRIBUTES == sh_type)
6180
0
            ) {
6181
0
                *sh_out = *sh_in;  // *sh_in is a candidate for fowarding
6182
0
                if (sh_offset > xct_off) { // may slide down: earlier compression
6183
0
                    if (sh_offset >= xct_off_hi) { // easy: so_slide down
6184
0
                        if (Elf32_Shdr::SHT_ARM_ATTRIBUTES != sh_type) {
6185
0
                            slide_sh_offset(sh_out);
6186
0
                        }
6187
0
                    }
6188
0
                    else { // somewhere in compressed; try proportional (aligned)
6189
                        // But note that PROGBITS without SHF_ALLOC
6190
                        // will be dropped below.
6191
0
                        u32_t const slice = xct_off + (~0xFu & (unsigned)(
6192
0
                             (sh_offset - xct_off) *
6193
0
                            ((sh_offset - xct_off) / (float)(xct_off_hi - xct_off))));
6194
                        //set_te32(&sh_out->sh_addr,   slice);
6195
0
                        set_te32(&sh_out->sh_offset, slice);
6196
0
                    }
6197
0
                    u32_t const max_sz = total_out - get_te32(&sh_out->sh_offset);
6198
0
                    if (sh_size > max_sz) { // avoid complaint "extends beyond EOF"
6199
0
                        set_te32(&sh_out->sh_size, max_sz);
6200
0
                    }
6201
0
                }
6202
0
                if (j == e_shstrndx) { // changes Elf32_Ehdr itself
6203
0
                    set_te16(&eho->e_shstrndx, sh_out -
6204
0
                        (Elf32_Shdr *)mb_shdro.getVoidPtr());
6205
0
                }
6206
0
                if (Elf32_Shdr::SHT_ARM_ATTRIBUTES == sh_type
6207
0
                ||  (SHT_NOTE == sh_type && xct_off < sh_offset)
6208
0
                ) { // append a copy
6209
0
                    set_te32(&sh_out->sh_offset, total_out);
6210
0
                    fi->seek((upx_off_t)sh_offset, SEEK_SET);
6211
0
                    fi->read(ibuf,  sh_size);
6212
0
                    fo->write(ibuf, sh_size);
6213
0
                    total_out +=    sh_size;
6214
0
                } else
6215
0
                if (SHT_PROGBITS == sh_type) {
6216
0
                    if (!(Elf32_Shdr::SHF_ALLOC & sh_flags)) {
6217
                        // .debug_*, .gnu_debuglink etc.  Typically compressed
6218
                        // but not in RAM, and gdb (BFD) gets confused.
6219
0
                        continue;  // OMIT the commit: do not forward
6220
0
                    } else
6221
0
                    if (sh_offset <= xct_off
6222
0
                    &&  0 == strcmp(".text", name) ) {
6223
                        // .text was compressed (but perhaps omitting some leading
6224
                        // portion, if less than 4 PT_LOAD)
6225
0
                        set_te32(&sh_out->sh_size, so_slide + sh_size);
6226
                        // FIXME: so_slide is negative; avoid negative result
6227
0
                    }
6228
0
                } else
6229
0
                if (SHT_STRTAB == sh_type) {
6230
0
                    if (j == e_shstrndx) {
6231
0
                        n_shstrsec = sh_out;
6232
0
                    } else
6233
0
                    if (strcmp(".dynstr",    name)) {
6234
0
                        continue;  // OMIT the commit of non-global symbol names
6235
0
                    }
6236
0
                }
6237
0
                set_te32(&sh_out->sh_name, ptr_shstrings - (char *)mb_shstrings.getVoidPtr());
6238
0
                do { // stupid MSVC lacks stpcpy()
6239
0
                    *ptr_shstrings++ = *name;
6240
0
                } while (*name++);
6241
0
                ++sh_out; ++n_sh_out;  // actually commit the fowarding
6242
0
            }
6243
0
        }
6244
0
        unsigned len = ptr_shstrings - (char *)mb_shstrings.getVoidPtr();
6245
0
        set_te32(&n_shstrsec->sh_offset, total_out);
6246
0
        set_te32(&n_shstrsec->sh_size, len);
6247
0
        fo->write(mb_shstrings, len);
6248
0
        total_out += len;
6249
6250
0
        total_out = fpad4(fo, total_out);  // align _Shdr[]
6251
0
        set_te32(&eho->e_shoff, total_out);
6252
0
        len = (char *)sh_out - (char *)mb_shdro.getVoidPtr();
6253
0
        set_te16(&eho->e_shnum, len / sizeof(*sh_out));
6254
0
        set_te16(&eho->e_shentsize, sizeof(Elf32_Shdr));
6255
0
        fo->write(mb_shdro, len);
6256
0
        total_out += len;
6257
6258
        // Try to pacify gdb (before DT_INIT) by making it look like
6259
        // the compressed PT_LOAD extends all the way to the next PT_LOAD,
6260
        // with no gap in address space.  Thus gdb should not complain about
6261
        // "Loadable section "..." [Shdr] outside of ELF segments [PT_LOAD]".
6262
        // gdb still "warning: section ... not found in .gnu_debugdata"
6263
        // because .gdb_debugdata is not present (or gets removed),
6264
        // but that is separate and "just" a warning.
6265
0
        ptr = (Elf32_Phdr *)(1+ eho);
6266
0
        if (0)  // FIXME:  This is not required?
6267
0
        for (ptr_end = &ptr[e_phnum]; ptr < ptr_end; ++ptr) {
6268
0
            if (is_LOAD(ptr)) {
6269
0
                Elf32_Phdr *ptr2 = 1+ ptr;
6270
0
                for (; ptr2 < ptr_end; ++ptr2) {
6271
0
                    if (is_LOAD(ptr2)) {
6272
0
                        unsigned pmask = 0u - get_te32(&ptr2->p_align);
6273
0
                        set_te32(&ptr->p_memsz,
6274
0
                            (pmask & get_te32(&ptr2->p_vaddr)) -
6275
0
                            (pmask & get_te32(&ptr ->p_vaddr)) );
6276
0
                        ptr  = ptr_end;  // force end of outer loop
6277
0
                        ptr2 = ptr_end;  // force end of inner loop
6278
0
                    }
6279
0
                }
6280
0
            }
6281
0
        }
6282
6283
0
        fo->seek(0, SEEK_SET);
6284
0
        fo->rewrite(eho, sizeof(*eho));
6285
0
        fo->seek(0, SEEK_END);
6286
0
    }
6287
0
    penalty = total_out - penalty;
6288
0
    info("Android penalty = %d bytes", penalty);
6289
0
    return penalty;
6290
0
}
6291
6292
unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
6293
0
{
6294
0
    if (!fo) {
6295
0
        return 0;
6296
0
    }
6297
0
    unsigned penalty = total_out;
6298
0
    if (Elf64_Ehdr::EM_AARCH64 == e_machine
6299
0
    &&  saved_opt_android_shlib) { // Forward select _Shdr
6300
        // Keep _Shdr for rtld data (below xct_off).
6301
        // Discard _Shdr for compressed regions, except ".text" for gdb.
6302
        // Keep _Shdr with SHF_WRITE.
6303
        // Keep ARM_ATTRIBUTES
6304
        // Discard _Shdr with (0==sh_addr), except _Shdr[0]
6305
0
        unsigned const want_types_mask =
6306
0
              1u<<SHT_SYMTAB
6307
0
            | 1u<<SHT_RELA
6308
0
            | 1u<<SHT_PROGBITS  // see comment above
6309
0
            | 1u<<SHT_HASH
6310
0
            | 1u<<SHT_DYNAMIC
6311
0
            | 1u<<SHT_NOTE
6312
0
            | 1u<<SHT_REL
6313
0
            | 1u<<SHT_RELR
6314
0
            | 1u<<SHT_DYNSYM
6315
0
            | 1u<<SHT_STRTAB  // .shstrtab and .dynstr
6316
0
            | 1u<<SHT_INIT_ARRAY
6317
0
            | 1u<<SHT_FINI_ARRAY
6318
0
            | 1u<<SHT_PREINIT_ARRAY
6319
0
            | 1u<<(0x1f & SHT_GNU_versym)
6320
0
            | 1u<<(0x1f & SHT_GNU_verneed)
6321
0
            | 1u<<(0x1f & SHT_GNU_verdef)
6322
0
            | 1u<<(0x1f & SHT_GNU_HASH);
6323
6324
0
        upx_uint64_t xct_off_hi = 0;
6325
0
        Elf64_Phdr const *ptr = phdri, *ptr_end = &phdri[e_phnum];
6326
0
        for (; ptr < ptr_end; ++ptr) {
6327
0
            if (is_LOAD(ptr)) {
6328
0
                upx_uint64_t hi = get_te64(&ptr->p_filesz)
6329
0
                    + get_te64(&ptr->p_offset);
6330
0
                if (xct_off < hi) {
6331
0
                    xct_off_hi = hi;
6332
0
                    break;
6333
0
                }
6334
0
            }
6335
0
        }
6336
6337
0
        MemBuffer mb_ask_for(e_shnum * sizeof(eho->e_shnum));
6338
0
        memset(mb_ask_for, 0, mb_ask_for.getSize());
6339
0
        unsigned short *const ask_for = (unsigned short *)mb_ask_for.getVoidPtr();
6340
6341
0
        MemBuffer mb_shdro(e_shnum * sizeof(*shdri));
6342
0
        Elf64_Shdr *sh_out0 = (Elf64_Shdr *)mb_shdro.getVoidPtr();
6343
0
        Elf64_Shdr *sh_out = sh_out0;
6344
0
        Elf64_Shdr *sh_in = shdri;
6345
6346
0
        memset(sh_out, 0, sizeof(*sh_out));  // blank sh_out[0]
6347
0
        ++sh_in; ++sh_out; unsigned n_sh_out = 1;
6348
6349
0
        for (unsigned j = 1; j < e_shnum; ++j, ++sh_in) {
6350
0
            char const *sh_name = &shstrtab[get_te32(&sh_in->sh_name)];
6351
0
            (void)sh_name;  // debugging
6352
0
            unsigned sh_type = get_te32(&sh_in->sh_type);
6353
0
            u64_t sh_flags   = get_te64(&sh_in->sh_flags);
6354
0
            u64_t sh_addr    = get_te64(&sh_in->sh_addr);
6355
0
            u64_t sh_offset  = get_te64(&sh_in->sh_offset);
6356
0
            u64_t sh_size    = get_te64(&sh_in->sh_size);
6357
0
            unsigned sh_info = get_te32(&sh_in->sh_info);
6358
0
            if (ask_for[j]) { // Some previous _Shdr requested  me
6359
                // Tell them my new index
6360
0
                set_te32(&sh_out0[ask_for[j]].sh_info, n_sh_out);  // sh_info vs st_shndx
6361
0
            }
6362
0
            if (sh_info < e_shnum) { // wild sh_info abounds!
6363
0
                ask_for[sh_info] = j;  // Enter my request, if any
6364
0
            }
6365
0
            if (   (sh_offset && sh_offset < xct_off)
6366
0
                || (Elf64_Shdr::SHF_WRITE & sh_flags)
6367
0
                || (j == e_shstrndx)
6368
0
                || (sec_arm_attr == sh_in)
6369
0
                || (want_types_mask & (1<<(0x1f & sh_type)))
6370
0
                || (Elf32_Shdr::SHT_ARM_ATTRIBUTES == sh_type)
6371
0
            ) {
6372
0
                *sh_out = *sh_in;
6373
0
                if (sh_offset > xct_off) { // may slide down: earlier compression
6374
0
                    if (sh_offset >= xct_off_hi) { // easy: so_slide down
6375
0
                        if (sh_out->sh_addr) // change only if non-zero
6376
0
                        set_te64(&sh_out->sh_addr,   so_slide + sh_addr +
6377
0
                            (is_asl ? asl_delta : 0));
6378
0
                        set_te64(&sh_out->sh_offset, so_slide + sh_offset);
6379
0
                    }
6380
0
                    else { // somewhere in compressed; try proportional (aligned)
6381
0
                        u64_t const slice = xct_off + (~0xFu & (unsigned)(
6382
0
                             (sh_offset - xct_off) *
6383
0
                            ((sh_offset - xct_off) / (float)(xct_off_hi - xct_off))));
6384
0
                        set_te64(&sh_out->sh_addr,   slice);
6385
0
                        set_te64(&sh_out->sh_offset, slice);
6386
0
                    }
6387
0
                    u64_t const max_sz = total_out - get_te64(&sh_out->sh_offset);
6388
0
                    if (sh_size > max_sz) { // avoid complaint "extends beyond EOF"
6389
0
                        set_te64(&sh_out->sh_size, max_sz);
6390
0
                    }
6391
0
                }
6392
0
                if (j == e_shstrndx) { // changes Elf64_Ehdr itself
6393
0
                    set_te16(&eho->e_shstrndx, sh_out -
6394
0
                        (Elf64_Shdr *)mb_shdro.getVoidPtr());
6395
0
                }
6396
0
                if (j == e_shstrndx
6397
0
                ||  sec_arm_attr == sh_in
6398
0
                ||  (SHT_NOTE == sh_type && xct_off < sh_offset)
6399
0
                ) { // append a copy
6400
0
                    set_te64(&sh_out->sh_offset, total_out);
6401
0
                    fi->seek((upx_off_t)sh_offset, SEEK_SET);
6402
0
                    fi->read(ibuf,  sh_size);
6403
0
                    fo->write(ibuf, sh_size);
6404
0
                    total_out +=    sh_size;
6405
0
                } else
6406
0
                if (SHT_PROGBITS == sh_type) {
6407
0
                    if (sh_offset <= xct_off
6408
0
                    &&  0 == strcmp(".text", shstrtab + get_te32(&sh_in->sh_name)) ) {
6409
                        // .text was compressed (but perhaps omitting some leading
6410
                        // portion, if less than 4 PT_LOAD)
6411
0
                        set_te64(&sh_out->sh_size, so_slide + sh_size);
6412
0
                    } else
6413
0
                    if (0 == sh_in->sh_addr) { // .gnu_debuglink etc
6414
0
                        set_te64(&sh_out->sh_offset, so_slide + sh_offset);
6415
0
                    }
6416
0
                }
6417
                // Exploration for updating Shdrs from Dynamic, to pacify Android.
6418
                // Motivated by --force-pie with an input shared library;
6419
                // see https://github.com/upx/upx/issues/694
6420
                // But then realized that the pointed-to regions typically were
6421
                // just above Elfhdrs (overlay_offset), so the data would be
6422
                // incorrect because occupied by compressed PT_LOADS.
6423
                // But don't lose the code, so comment-out via "if (0)".
6424
0
                if (0) switch(sh_type) { // start {Shdr, Dynamic} pairs
6425
0
                case SHT_DYNSYM: {
6426
0
                    set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_SYMTAB));
6427
0
                    sh_out->sh_offset = sh_out->sh_addr;
6428
0
                } break;
6429
0
                case SHT_STRTAB: {
6430
0
                    if (e_shstrndx != j) {
6431
0
                        set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_STRTAB));
6432
0
                        sh_out->sh_offset = sh_out->sh_addr;
6433
0
                    }
6434
0
                } break;
6435
0
                case SHT_GNU_versym: {
6436
0
                    set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_VERSYM));
6437
0
                    sh_out->sh_offset = sh_out->sh_addr;
6438
0
                } break;
6439
0
                case SHT_GNU_verneed: {
6440
0
                    set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_VERNEED));
6441
0
                    sh_out->sh_offset = sh_out->sh_addr;
6442
0
                } break;
6443
0
                case SHT_GNU_HASH: {
6444
0
                    set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_GNU_HASH));
6445
0
                    sh_out->sh_offset = sh_out->sh_addr;
6446
0
                } break;
6447
0
                case SHT_HASH: {
6448
0
                    set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_HASH));
6449
0
                    sh_out->sh_offset = sh_out->sh_addr;
6450
0
                } break;
6451
0
                case SHT_RELA: {
6452
0
                    if (0==strcmp(".rela.dyn", sh_name)) {
6453
0
                        set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_RELA));
6454
0
                        sh_out->sh_offset = sh_out->sh_addr;
6455
0
                    }
6456
0
                    if (0==strcmp(".rela.plt", sh_name)) {
6457
0
                        set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_JMPREL));
6458
0
                        sh_out->sh_offset = sh_out->sh_addr;
6459
0
                    }
6460
0
                } break;
6461
0
                } // end {Shdr, Dynamic} pairs
6462
0
                ++sh_out; ++n_sh_out;
6463
0
            }
6464
0
        }
6465
0
        total_out = fpad8(fo, total_out);
6466
0
        set_te64(&eho->e_shoff, total_out);
6467
0
        unsigned len = (char *)sh_out - (char *)mb_shdro.getVoidPtr();
6468
0
        set_te16(&eho->e_shnum, len / sizeof(*sh_out));
6469
0
        set_te16(&eho->e_shentsize, sizeof(Elf64_Shdr));
6470
0
        fo->write(mb_shdro, len);
6471
0
        total_out += len;
6472
0
        fo->seek(0, SEEK_SET);
6473
0
        fo->rewrite(eho, sizeof(*eho));
6474
0
        fo->seek(0, SEEK_END);
6475
0
    }
6476
0
    penalty = total_out - penalty;
6477
0
    info("Android penalty = %d bytes", penalty);
6478
0
    return penalty;
6479
0
}
6480
6481
void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
6482
0
{
6483
0
    if (!xct_off) {
6484
0
        overlay_offset = sz_elf_hdrs + sizeof(linfo);
6485
0
    }
6486
6487
0
    cprElfHdr4 *eho = !xct_off
6488
0
            ? (cprElfHdr4 *)(void *)&elfout  // not shlib  FIXME: ugly casting
6489
0
            : (cprElfHdr4 *)lowmem.getVoidPtr();  // shlib
6490
0
    unsigned penalty = forward_Shdrs(fo, &eho->ehdr); (void)penalty;
6491
6492
0
    if (opt->o_unix.preserve_build_id) { // FIXME: co-ordinate with forward_Shdrs
6493
        // calc e_shoff here and write shdrout, then o_shstrtab
6494
        //NOTE: these are pushed last to ensure nothing is stepped on
6495
        //for the UPX structure.
6496
0
        total_out = fpad4(fo, total_out);
6497
0
        set_te32(&eho->ehdr.e_shoff, total_out);
6498
6499
0
        unsigned const ssize = sizeof(shdrout);
6500
0
        unsigned const ssize1 = get_te32(&shdrout.shdr[1].sh_size);
6501
0
        unsigned const ssize2 = get_te32(&shdrout.shdr[2].sh_size);
6502
6503
0
        set_te32(&shdrout.shdr[2].sh_offset,          ssize + total_out);
6504
0
        set_te32(&shdrout.shdr[1].sh_offset, ssize2 + ssize + total_out);
6505
6506
0
        fo->write(&shdrout, ssize); total_out += ssize;
6507
6508
0
        fo->write(o_shstrtab, ssize2); total_out += ssize2;
6509
0
        fo->write(buildid_data, ssize1); total_out += ssize1;
6510
0
    }
6511
6512
    // ph.u_len and ph.c_len are leftover from earliest days when there was
6513
    // only one compressed extent.  Use a good analogy for multiple extents.
6514
0
    ph.u_len = file_size;
6515
0
    ph.c_len = total_out;
6516
0
    super::pack4(fo, ft);  // write PackHeader and overlay_offset
6517
6518
0
    fo->seek(0, SEEK_SET);
6519
0
    if (0!=xct_off) {  // shared library
6520
0
        { // Shouldn't this special case be handled earlier?
6521
0
            if (overlay_offset < xct_off) {
6522
0
                Elf32_Phdr *phdro = (Elf32_Phdr *)&eho->phdr;
6523
0
                set_te32(&phdro->p_flags, Elf32_Phdr::PF_X | get_te32(&phdro->p_flags));
6524
0
            }
6525
0
        }
6526
0
        if (!sec_arm_attr && !saved_opt_android_shlib) {
6527
            // Make it abundantly clear that there are no Elf32_Shdr in this shlib
6528
0
            eho->ehdr.e_shoff = 0;
6529
0
            set_te16(&eho->ehdr.e_shentsize, sizeof(Elf32_Shdr));  // Android bug: cannot use 0
6530
0
            eho->ehdr.e_shnum = 0;
6531
0
            eho->ehdr.e_shstrndx = 0;
6532
0
        }
6533
0
        fo->rewrite(eho, sizeof(ehdri) + e_phnum * sizeof(*phdri));
6534
0
        fo->seek(linfo_off, SEEK_SET);
6535
0
        fo->rewrite(&linfo, sizeof(linfo));  // new info: l_checksum, l_size
6536
6537
0
        if (jni_onload_va) {
6538
0
            unsigned tmp = sz_pack2 + get_te32(&eho->phdr[C_TEXT].p_vaddr);
6539
0
            tmp |= (Elf32_Ehdr::EM_ARM==e_machine);  // THUMB mode
6540
0
            set_te32(&tmp, tmp);
6541
0
            fo->seek(ptr_udiff_bytes(&jni_onload_sym->st_value, file_image), SEEK_SET);
6542
0
            fo->rewrite(&tmp, sizeof(tmp));
6543
0
        }
6544
0
    }
6545
0
    else { // not shlib
6546
        // Cannot pre-round .p_memsz.  If .p_filesz < .p_memsz, then kernel
6547
        // tries to make .bss, which requires PF_W.
6548
        // But strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X.
6549
0
        set_te32(&eho->phdr[C_TEXT].p_filesz, sz_pack2 + lsize);
6550
0
                  eho->phdr[C_TEXT].p_memsz = eho->phdr[C_TEXT].p_filesz;
6551
6552
0
        fo->seek(0, SEEK_SET);
6553
0
        fo->rewrite(&eho->ehdr, sizeof(Elf32_Ehdr) + 2* sizeof(Elf32_Phdr));  // C_BASE, C_TEXT
6554
0
        fo->seek(overlay_offset - sizeof(l_info), SEEK_SET);
6555
0
        fo->rewrite(&linfo, sizeof(linfo));
6556
0
    }
6557
0
}
6558
6559
void PackLinuxElf64::pack4(OutputFile *fo, Filter &ft)
6560
0
{
6561
0
    if (!xct_off) {
6562
0
        overlay_offset = sz_elf_hdrs + sizeof(linfo);
6563
0
    }
6564
6565
0
    cprElfHdr4 *eho = !xct_off
6566
0
            ? &elfout  // not shlib
6567
0
            : (cprElfHdr4 *)lowmem.getVoidPtr();  // shlib
6568
0
    unsigned penalty = forward_Shdrs(fo, &eho->ehdr); (void)penalty;
6569
6570
0
    if (opt->o_unix.preserve_build_id) { // FIXME: co-ordinate with forward_Shdrs
6571
        // calc e_shoff here and write shdrout, then o_shstrtab
6572
        //NOTE: these are pushed last to ensure nothing is stepped on
6573
        //for the UPX structure.
6574
0
        total_out = fpad4(fo, total_out);
6575
0
        set_te64(&eho->ehdr.e_shoff, total_out);
6576
6577
0
        unsigned const ssize = sizeof(shdrout);
6578
0
        unsigned const ssize1 = get_te64(&shdrout.shdr[1].sh_size);
6579
0
        unsigned const ssize2 = get_te64(&shdrout.shdr[2].sh_size);
6580
6581
0
        set_te64(&shdrout.shdr[2].sh_offset,          ssize + total_out);
6582
0
        set_te64(&shdrout.shdr[1].sh_offset, ssize2 + ssize + total_out);
6583
6584
0
        fo->write(&shdrout, ssize); total_out += ssize;
6585
6586
0
        fo->write(o_shstrtab, ssize2); total_out += ssize2;
6587
0
        fo->write(buildid_data, ssize1); total_out += ssize1;
6588
0
    }
6589
6590
    // ph.u_len and ph.c_len are leftover from earliest days when there was
6591
    // only one compressed extent.  Use a good analogy for multiple extents.
6592
0
    ph.u_len = file_size;
6593
0
    ph.c_len = total_out;
6594
0
    super::pack4(fo, ft);  // write PackHeader and overlay_offset
6595
6596
0
    fo->seek(0, SEEK_SET);
6597
0
    if (0!=xct_off) {  // shared library
6598
0
        { // Shouldn't this special case be handled earlier?
6599
0
            if (overlay_offset < xct_off) {
6600
0
                Elf64_Phdr *phdro = (Elf64_Phdr *)(&eho->phdr);
6601
0
                set_te32(&phdro->p_flags, Elf64_Phdr::PF_X | get_te32(&phdro->p_flags));
6602
0
            }
6603
0
        }
6604
0
        if (!sec_arm_attr && !saved_opt_android_shlib) {
6605
            // Make it abundantly clear that there are no Elf64_Shdr in this shlib
6606
0
            eho->ehdr.e_shoff = 0;
6607
0
            set_te16(&eho->ehdr.e_shentsize, sizeof(Elf64_Shdr));  // Android bug: cannot use 0
6608
0
            eho->ehdr.e_shnum = 0;
6609
0
            eho->ehdr.e_shstrndx = 0;
6610
0
        }
6611
6612
0
        fo->rewrite(eho, sizeof(ehdri) + e_phnum * sizeof(*phdri));
6613
0
        fo->seek(linfo_off, SEEK_SET);
6614
0
        fo->rewrite(&linfo, sizeof(linfo));  // new info: l_checksum, l_size
6615
6616
0
        if (jni_onload_va) { // FIXME Does this apply to 64-bit, too?
6617
0
            upx_uint64_t tmp = sz_pack2 + get_te64(&eho->phdr[C_TEXT].p_vaddr);
6618
0
            tmp |= (Elf64_Ehdr::EM_ARM==e_machine);  // THUMB mode; no-op for 64-bit
6619
0
            set_te64(&tmp, tmp);
6620
0
            fo->seek(ptr_udiff_bytes(&jni_onload_sym->st_value, file_image), SEEK_SET);
6621
0
            fo->rewrite(&tmp, sizeof(tmp));
6622
0
        }
6623
0
    }
6624
0
    else { // not shlib
6625
        // Cannot pre-round .p_memsz.  If .p_filesz < .p_memsz, then kernel
6626
        // tries to make .bss, which requires PF_W.
6627
        // But strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X.
6628
0
        set_te64(&eho->phdr[C_TEXT].p_filesz, sz_pack2 + lsize);
6629
0
                  eho->phdr[C_TEXT].p_memsz = eho->phdr[C_TEXT].p_filesz;
6630
6631
0
        fo->seek(0, SEEK_SET);
6632
0
        fo->rewrite(&eho->ehdr, sizeof(Elf64_Ehdr) + 2* sizeof(Elf64_Phdr));  // C_BASE, C_TEXT
6633
0
        fo->seek(overlay_offset - sizeof(l_info), SEEK_SET);
6634
0
        fo->rewrite(&linfo, sizeof(linfo));
6635
0
    }
6636
0
}
6637
6638
void
6639
PackLinuxElf32::unRel32(
6640
    unsigned dt_rel,
6641
    Elf32_Rel *rel0,
6642
    unsigned relsz,
6643
    MemBuffer &ptload1,
6644
    unsigned const load_off,
6645
    OutputFile *fo
6646
)
6647
0
{
6648
0
    Elf32_Rel *rel = rel0;
6649
0
    for (int k = relsz / sizeof(Elf32_Rel); --k >= 0; ++rel) {
6650
0
        unsigned r_offset = get_te32(&rel->r_offset);
6651
0
        unsigned r_info   = get_te32(&rel->r_info);
6652
0
        unsigned r_type = ELF32_R_TYPE(r_info);
6653
0
        if (xct_off <= r_offset) {
6654
0
            set_te32(&rel->r_offset, r_offset - asl_delta);
6655
0
        }
6656
0
        if (Elf32_Ehdr::EM_ARM == e_machine) {
6657
0
            if (R_ARM_RELATIVE == r_type) {
6658
0
                unsigned d = r_offset - load_off - asl_delta;
6659
0
                unsigned w = get_te32(&ptload1[d]);
6660
0
                if (xct_off <= w) {
6661
0
                    set_te32(&ptload1[d], w - asl_delta);
6662
0
                }
6663
0
            }
6664
0
            if (R_ARM_JUMP_SLOT == r_type) {
6665
0
                ++n_jmp_slot;
6666
                // .rel.plt contains offset of the "first time" target
6667
0
                unsigned d = r_offset - load_off - asl_delta;
6668
0
                if (plt_va > d) {
6669
0
                    plt_va = d;
6670
0
                }
6671
0
                unsigned w = get_te32(&ptload1[d]);
6672
0
                if (xct_off <= w) {
6673
0
                    set_te32(&ptload1[d], w - asl_delta);
6674
0
                }
6675
0
            }
6676
0
        }
6677
0
        if (Elf32_Ehdr::EM_386 == e_machine) {
6678
0
            if (R_386_RELATIVE == r_type) {
6679
0
                unsigned d = r_offset - load_off - asl_delta;
6680
0
                unsigned w = get_te32(&ptload1[d]);
6681
0
                if (xct_off <= w) {
6682
0
                    set_te32(&ptload1[d], w - asl_delta);
6683
0
                }
6684
0
            }
6685
0
            if (R_386_JMP_SLOT == r_type) {
6686
0
                ++n_jmp_slot;
6687
                // .rel.plt contains offset of the "first time" target
6688
0
                unsigned d = r_offset - load_off - asl_delta;
6689
0
                if (plt_va > d) {
6690
0
                    plt_va = d;
6691
0
                }
6692
0
                unsigned w = get_te32(&ptload1[d]);
6693
0
                if (xct_off <= w) {
6694
0
                    set_te32(&ptload1[d], w - asl_delta);
6695
0
                }
6696
0
            }
6697
0
        }
6698
0
    }
6699
0
    fo->seek(dt_rel, SEEK_SET);
6700
0
    fo->rewrite(rel0, relsz);
6701
0
}
6702
6703
void
6704
PackLinuxElf64::unRela64(
6705
    upx_uint64_t const dt_rela,
6706
    Elf64_Rela *const rela0,
6707
    unsigned const relasz,
6708
    upx_uint64_t const old_dtinit,
6709
    OutputFile *const fo
6710
)
6711
0
{
6712
0
    Elf64_Rela *rela = rela0;
6713
0
    for (int k = relasz / sizeof(Elf64_Rela); --k >= 0; ++rela) {
6714
0
        upx_uint64_t r_addend = get_te64(&rela->r_addend);
6715
0
        if (xct_off <= r_addend) {
6716
0
            r_addend -= asl_delta;
6717
0
            set_te64(&rela->r_addend, r_addend);
6718
0
        }
6719
6720
0
        upx_uint64_t r_offset = get_te64(&rela->r_offset);
6721
0
        if (xct_off <= r_offset) {
6722
            //r_offset -= asl_delta;  // keep compressed value vs plt_va
6723
0
            set_te64(&rela->r_offset, r_offset - asl_delta);  // uncompressed value
6724
0
        }
6725
6726
        // ElfXX_Rela (used only on 64-bit) ignores the contents of memory
6727
        // at the target designated by r_offset.  The target is completely
6728
        // overwritten by (r_addend + f_reloc(r_info)).
6729
        //
6730
        // Nevertheless, the existing targets of .rela.plt in the .got
6731
        // seem to have values that matter to somebody. So restore original
6732
        // values when is_asl.
6733
0
        upx_uint64_t r_info   = get_te64(&rela->r_info);
6734
0
        unsigned r_type = ELF64_R_TYPE(r_info);
6735
0
        if (is_asl && Elf64_Ehdr::EM_AARCH64 == e_machine) {
6736
0
            if (R_AARCH64_RELATIVE == r_type) {
6737
#if 0  //{ FIXME
6738
                if (old_dtinit == r_addend) {
6739
                    set_te64(&ptload1[r_offset - plt_va], r_addend);
6740
                }
6741
#endif  //}
6742
0
            }
6743
0
            if (R_AARCH64_JUMP_SLOT == r_type) {
6744
0
                ++n_jmp_slot;
6745
                // .rela.plt contains offset of the "first time" target
6746
0
                if (jump_slots.getSize() < (r_offset - plt_va)) {
6747
0
                    throwInternalError("bad r_offset for jump_slots");
6748
0
                }
6749
                // really upx_uint64_t *, but clang makes it hard to say that
6750
0
                unsigned char *slot = r_offset - plt_va
6751
0
                    + (unsigned char *)jump_slots.getVoidPtr();
6752
0
                upx_uint64_t w = get_te64(slot);
6753
0
                if (xct_off <= w) {
6754
0
                    set_te64(slot, w - asl_delta);
6755
0
                }
6756
0
            }
6757
0
        }
6758
        // FIXME: but what about old_dtinit?
6759
0
        (void)old_dtinit;
6760
6761
0
    }  // end each RELA
6762
0
    if (fo) {
6763
0
        fo->seek(dt_rela, SEEK_SET);
6764
0
        fo->rewrite(rela0, relasz);
6765
0
    }
6766
0
}
6767
6768
void
6769
PackLinuxElf64::un_asl_dynsym( // ibuf has the input
6770
    unsigned orig_file_size,
6771
    OutputFile *fo  // else just leave in ibuf
6772
)
6773
0
{
6774
    // un-Relocate dynsym (DT_SYMTAB) which is below xct_off
6775
0
    dynstr = (char const *)elf_find_dynamic(Elf64_Dyn::DT_STRTAB);
6776
0
    sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
6777
0
    if (dynstr && sec_dynsym) {
6778
0
        upx_uint64_t const off_dynsym = get_te64(&sec_dynsym->sh_offset);
6779
0
        upx_uint64_t const sz_dynsym  = get_te64(&sec_dynsym->sh_size);
6780
0
        if (orig_file_size < sz_dynsym
6781
0
        ||  orig_file_size < off_dynsym
6782
0
        || (orig_file_size - off_dynsym) < sz_dynsym) {
6783
0
            throwCantUnpack("bad SHT_DYNSYM");
6784
0
        }
6785
0
        Elf64_Sym *const sym0 = (Elf64_Sym *)ibuf.subref(
6786
0
            "bad dynsym", off_dynsym, sz_dynsym);
6787
0
        Elf64_Sym *sym = sym0;
6788
0
        for (int j = sz_dynsym / sizeof(Elf64_Sym); --j>=0; ++sym) {
6789
0
            upx_uint64_t symval = get_te64(&sym->st_value);
6790
0
            unsigned symsec = get_te16(&sym->st_shndx);
6791
0
            if (Elf64_Sym::SHN_UNDEF != symsec
6792
0
            &&  Elf64_Sym::SHN_ABS   != symsec
6793
0
            &&  xct_off <= symval) {
6794
0
                set_te64(&sym->st_value, symval - asl_delta);
6795
0
            }
6796
0
            if (Elf64_Sym::SHN_ABS == symsec && xct_off <= symval) {
6797
0
                adjABS(sym, 0ul - (unsigned long)asl_delta);
6798
0
            }
6799
0
        }
6800
0
        if (fo) {
6801
0
            unsigned pos = fo->tell();
6802
0
            fo->seek(off_dynsym, SEEK_SET);
6803
0
            fo->rewrite(sym0, sz_dynsym);
6804
0
            fo->seek(pos, SEEK_SET);
6805
0
        }
6806
0
    }
6807
0
}
6808
6809
void
6810
PackLinuxElf32::un_asl_dynsym( // ibuf has the input
6811
    unsigned orig_file_size,
6812
    OutputFile *fo  // else just leave in ibuf
6813
)
6814
0
{
6815
    // un-Relocate dynsym (DT_SYMTAB) which is below xct_off
6816
0
    dynstr = (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);
6817
0
    sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);
6818
0
    if (dynstr && sec_dynsym) {
6819
0
        upx_uint32_t const off_dynsym = get_te32(&sec_dynsym->sh_offset);
6820
0
        upx_uint32_t const sz_dynsym  = get_te32(&sec_dynsym->sh_size);
6821
0
        if (orig_file_size < sz_dynsym
6822
0
        ||  orig_file_size < off_dynsym
6823
0
        || (orig_file_size - off_dynsym) < sz_dynsym) {
6824
0
            throwCantUnpack("bad SHT_DYNSYM");
6825
0
        }
6826
0
        Elf32_Sym *const sym0 = (Elf32_Sym *)ibuf.subref(
6827
0
            "bad dynsym", off_dynsym, sz_dynsym);
6828
0
        Elf32_Sym *sym = sym0;
6829
0
        for (int j = sz_dynsym / sizeof(Elf32_Sym); --j>=0; ++sym) {
6830
0
            upx_uint32_t symval = get_te32(&sym->st_value);
6831
0
            unsigned symsec = get_te16(&sym->st_shndx);
6832
0
            if (Elf32_Sym::SHN_UNDEF != symsec
6833
0
            &&  Elf32_Sym::SHN_ABS   != symsec
6834
0
            &&  xct_off <= symval) {
6835
0
                set_te32(&sym->st_value, symval - asl_delta);
6836
0
            }
6837
0
            if (Elf32_Sym::SHN_ABS == symsec && xct_off <= symval) {
6838
0
                adjABS(sym, 0u - (unsigned)asl_delta);
6839
0
            }
6840
0
        }
6841
0
        if (fo) {
6842
0
            unsigned pos = fo->tell();
6843
0
            fo->seek(off_dynsym, SEEK_SET);
6844
0
            fo->rewrite(sym0, sz_dynsym);
6845
0
            fo->seek(pos, SEEK_SET);
6846
0
        }
6847
0
    }
6848
0
}
6849
6850
// File layout of compressed .so (new-style: 3 or 4 PT_LOAD) shared library:
6851
// 1. new Elf headers: Ehdr, PT_LOAD (r-x), PT_LOAD (rw-, if any), non-PT_LOAD Phdrs
6852
// 2. Space for (original - 2) PT_LOAD Phdr
6853
// 3. Remaining original contents of file below xct_off
6854
// xct_off: (&lowest eXecutable Shdr section; in original PT_LOAD[0] or [1])
6855
// 3a. If --android-shlib, then 4KiB page of Shdr copy, etc.  (asl_pack2_Shdrs)
6856
//    And xct_off gets incremented by 4KiB at the right time.
6857
// 4. l_info (12 bytes)
6858
// overlay_offset:
6859
// 5. p_info (12 bytes)
6860
// 6. compressed original Elf headers (prefixed by b_info as usual)
6861
// 6a. un-compressed copy of input after Elf headers until xct_off.
6862
//    *user_init_rp has been modified if no DT_INIT
6863
// 7. compressed remainder of PT_LOAD above xct_off
6864
// 8. compressed read-only PT_LOAD above xct_off (if any)  // FIXME: check decompressor
6865
// 9. uncompressed Read-Write PT_LOAD (slide down N pages)
6866
// 10. int[6] tables for UPX runtime de-compressor
6867
// (new) DT_INIT:
6868
// 11. UPX runtime de-compressing loader
6869
// 12. compressed gaps between PT_LOADs (and EOF) above xct_off
6870
// 13. 32-byte pack header
6871
// 14. 4-byte overlay_offset
6872
6873
void PackLinuxElf64::un_shlib_1(
6874
    OutputFile *const fo,
6875
    MemBuffer &o_elfhdrs,
6876
    unsigned &c_adler,
6877
    unsigned &u_adler,
6878
    unsigned const orig_file_size
6879
)
6880
185
{
6881
    // xct_off [input side] was set by ::unpack when is_shlib
6882
    // yct_off [output side] set here unless is_asl in next 'if' block
6883
185
    unsigned yct_off = xct_off;
6884
6885
    // Below xct_off is not compressed (for benefit of rtld.)
6886
185
    fi->seek(0, SEEK_SET);
6887
185
    fi->readx(ibuf, umin(blocksize, file_size_u32));
6888
6889
    // Determine if the extra page with copy of _Shdrs was spliced in.
6890
    // This used to be the result of --android-shlib.
6891
    // But in 2023-02 the forwarding of ARM_ATTRIBUTES (by appending)
6892
    // takes care of this, so the 5th word before e_entry does not
6893
    // have the low bit 1, so is_asl should not be set.
6894
    // However, .so that were compressed before 2023-03
6895
    // may be marked.
6896
185
    e_shoff = get_te64(&ehdri.e_shoff);
6897
185
    if (e_shoff && e_shnum
6898
            // +36: (sizeof(PackHeader) + sizeof(overlay_offset))
6899
            //    after Shdrs for ARM_ATTRIBUTES
6900
104
    &&  (((e_shoff + sizeof(Elf64_Shdr) * e_shnum) + 36) < file_size_u)
6901
185
    ) { // possible --android-shlib
6902
10
        unsigned x = get_te32(&file_image[get_te64(&ehdri.e_entry) - (1+ 4)*sizeof(int)]);
6903
10
        if (1 & x) { // the clincher
6904
1
            is_asl = 1;
6905
1
            fi->seek(e_shoff, SEEK_SET);
6906
1
            mb_shdr.alloc(   sizeof(Elf64_Shdr) * e_shnum);
6907
1
            shdri = (Elf64_Shdr *)mb_shdr.getVoidPtr();
6908
1
            fi->readx(shdri, sizeof(Elf64_Shdr) * e_shnum);
6909
1
            yct_off = get_te64(&shdri->sh_offset);  // for the output file (de-compressed)
6910
1
            xct_off = asl_delta + yct_off;  // for the input file (compressed)
6911
1
        }
6912
10
    }
6913
6914
    // Decompress first Extent.  Old style covers [0, xct_off)
6915
    // which includes rtld constant data and eXecutable app code below DT_INIT.
6916
    // In old style, the first compressed Extent is redundant
6917
    // except for the compressed original Elf headers.
6918
    // New style covers just Elf headers: the rest below xct_off is
6919
    // rtld constant data: DT_*HASH, DT_SYMTAB, DT_STRTAB, etc.
6920
    // New style puts eXecutable app code in second PT_LOAD
6921
    // in order to mark Elf headers and rtld data as non-eXecutable.
6922
185
    fi->seek(overlay_offset - sizeof(l_info), SEEK_SET);
6923
185
    struct {
6924
185
        struct l_info l;
6925
185
        struct p_info p;
6926
185
        struct b_info b;
6927
185
    } hdr;
6928
185
    fi->readx(&hdr, sizeof(hdr));
6929
185
    if (hdr.l.l_magic != UPX_MAGIC_LE32
6930
176
    ||  get_te16(&hdr.l.l_lsize) != (unsigned)lsize
6931
176
    ||  get_te32(&hdr.p.p_filesize) != ph.u_file_size
6932
135
    ||  get_te32(&hdr.b.sz_unc) < sz_elf_hdrs  // peek: 1st b_info covers Elf headers
6933
185
    ) {
6934
49
        throwCantUnpack("corrupt l_info/p_info/b_info");
6935
49
    }
6936
136
    fi->seek(-(off_t)sizeof(struct b_info), SEEK_CUR); // hdr.b_info was a peek
6937
6938
// The default layout for a shared library created by binutils-2.29
6939
// (Fedora 28; 2018) has two PT_LOAD: permissions r-x and rw-.
6940
// xct_off (the lowest address of executable instructions;
6941
// the highest address of read-only data used by rtld (ld-linux))
6942
// will be somewhere in the first PT_LOAD.
6943
//
6944
// The default layout for a shared library created by binutils-2.31
6945
// (Fedora 29; 2018) has four PT_LOAD: permissions r--, r-x, r--, rw-.
6946
// xct_off will be the base of the second [r-x] PT_LOAD.
6947
//
6948
// Bytes below xct_off cannot be compressed because they are used
6949
// by rtld *before* the UPX run-time de-compression stub gets control
6950
// via DT_INIT. Bytes in a Writeable PT_LOAD cannot be compressed
6951
// because they may be relocated by rtld, again before stub execution.
6952
//
6953
// We need to know which layout of PT_LOAD. It seems risky to steal
6954
// bits in the input ElfXX_Ehdr or ElfXX_Phdr, so we decompress
6955
// the first compressed block.  For an old-style shared library
6956
// the first compressed block covers [0, xct_off) which is redundant
6957
// with the interval [sz_elf_hdrs, xct_off) because those bytes
6958
// must be present for use by rtl  (So that is a large inefficiency.)
6959
// Fortunately p_info.p_blocksize fits in ibuf, and unpackExtent
6960
// will just decompress it all.  For new style, the first compressed
6961
// block covers [0, sz_elf_hdrs).
6962
6963
    // Peek: unpack into ibuf, but do not write
6964
136
    unsigned const sz_block1 = unpackExtent(sz_elf_hdrs, nullptr,
6965
136
        c_adler, u_adler, false, -1);
6966
136
    if (sz_block1 < sz_elf_hdrs) {
6967
0
        throwCantUnpack("corrupt b_info");
6968
0
    }
6969
136
    memcpy(o_elfhdrs, ibuf, sz_elf_hdrs); // save de-compressed Elf headers
6970
136
    Elf64_Ehdr const *const ehdro = (Elf64_Ehdr const *)(void const *)o_elfhdrs;
6971
136
    if (ehdro->e_type   !=ehdri.e_type
6972
105
    ||  ehdro->e_machine!=ehdri.e_machine
6973
105
    ||  ehdro->e_version!=ehdri.e_version
6974
        // less strict for EM_PPC64 to workaround earlier bug
6975
105
    ||  !( ehdro->e_flags==ehdri.e_flags
6976
16
        || Elf64_Ehdr::EM_PPC64 == get_te16(&ehdri.e_machine))
6977
92
    ||  ehdro->e_ehsize !=ehdri.e_ehsize
6978
        // check EI_MAG[0-3], EI_CLASS, EI_DATA, EI_VERSION
6979
87
    ||  memcmp(ehdro->e_ident, ehdri.e_ident, Elf64_Ehdr::EI_OSABI)) {
6980
23
        throwCantUnpack("ElfXX_Ehdr corrupted");
6981
23
    }
6982
113
    if (fo) {
6983
53
        fo->write(ibuf, sz_block1);
6984
53
        total_out = sz_block1;
6985
53
    }
6986
113
    Elf64_Phdr const *o_phdr = (Elf64_Phdr const *)(1+ ehdro);
6987
    // Handle compressed PT_LOADs (must not have PF_W)
6988
113
    unsigned not_first_LOAD = 0;
6989
289
    for (unsigned j = 0; j < e_phnum; ++j, ++o_phdr) {
6990
176
        unsigned type = get_te32(&o_phdr->p_type);
6991
176
        unsigned flags = get_te32(&o_phdr->p_flags);
6992
176
        if (PT_LOAD != type || Elf64_Phdr::PF_W & flags) {
6993
150
            continue;
6994
150
        }
6995
26
        unsigned p_offset = get_te64(&o_phdr->p_offset);
6996
26
        unsigned p_filesz = get_te64(&o_phdr->p_filesz);
6997
26
        unsigned wanted = p_filesz;
6998
26
        if (!not_first_LOAD++) { // first PT_LOAD
6999
25
            wanted -= sz_block1;
7000
25
            if (sz_block1 >  sz_elf_hdrs) { // old style
7001
24
                if (is_asl) {
7002
0
                    un_asl_dynsym(orig_file_size, fo);
7003
0
                }
7004
24
                p_offset += sz_block1;
7005
24
            }
7006
25
            if (sz_block1 == sz_elf_hdrs) { // new style
7007
1
                unsigned const len = (yct_off ? yct_off : xct_off) - sz_elf_hdrs;
7008
1
                unsigned const ipos = fi->tell();
7009
1
                fi->seek(sz_elf_hdrs, SEEK_SET);
7010
1
                fi->readx(&ibuf[sz_elf_hdrs], len);
7011
1
                if (is_asl) {
7012
0
                    un_asl_dynsym(orig_file_size, nullptr);
7013
0
                }
7014
1
                if (fo) {
7015
0
                    fo->write(&ibuf[sz_elf_hdrs], len);
7016
0
                }
7017
1
                total_out += len;
7018
7019
// github-issue629: (overlay_offset = 0xa500), so initially (xct_off = 0xa494).
7020
// But "yct_off = get_te64(&shdri->sh_offset)" so if _Shdrs are aligned (??)
7021
// then (0x10500 == (xct_off = asl_delta + yct_off)), and we read+write
7022
// more than we need.
7023
// So assume the excess just lives there, or is overwritten later by seek+write.
7024
1
                if (wanted < len) { // FIXME: why does this happen?
7025
0
                    wanted = 0;
7026
0
                }
7027
1
                else {
7028
1
                    wanted -= len;
7029
1
                }
7030
1
                fi->seek(ipos, SEEK_SET);
7031
1
                if (total_out == p_filesz) {
7032
0
                    continue;   // already entirely re-generated
7033
0
                }
7034
1
                p_offset = total_out;
7035
1
            }
7036
25
        }
7037
26
        if (fo) {
7038
10
            fo->seek(p_offset, SEEK_SET);
7039
10
        }
7040
26
        unpackExtent(wanted, fo, c_adler, u_adler, false);
7041
26
    }
7042
113
    funpad4(fi);
7043
113
    loader_offset = fi->tell();
7044
7045
    // Handle PT_LOAD with PF_W: writeable, so not compressed.  "Slide"
7046
113
    o_phdr = (Elf64_Phdr const *)(1+ ehdro);
7047
113
    Elf64_Phdr const *i_phdr = phdri;
7048
272
    for (unsigned j = 0; j < e_phnum; ++j, ++o_phdr, ++i_phdr) {
7049
159
        unsigned type = get_te32(&o_phdr->p_type);
7050
159
        unsigned flags = get_te32(&o_phdr->p_flags);
7051
159
        if (PT_LOAD != type || !(Elf64_Phdr::PF_W & flags)) {
7052
156
            continue;
7053
156
        }
7054
3
        unsigned filesz = get_te64(&o_phdr->p_filesz);
7055
3
        unsigned o_offset = get_te64(&o_phdr->p_offset);
7056
3
        unsigned i_offset = get_te64(&i_phdr->p_offset);
7057
3
        fi->seek(i_offset, SEEK_SET);
7058
3
        fi->readx(ibuf, filesz);
7059
3
        total_in += filesz;
7060
3
        if (fo) {
7061
1
            fo->seek(o_offset, SEEK_SET);
7062
1
            fo->write(ibuf, filesz);
7063
1
        }
7064
3
        total_out = filesz + o_offset;  // high-water mark
7065
3
    }
7066
7067
    // Gaps between PT_LOAD will be handled by ::unpack()
7068
7069
    // position fi at loader offset
7070
113
    fi->seek(loader_offset, SEEK_SET);
7071
113
}
7072
7073
void PackLinuxElf32::un_shlib_1(
7074
    OutputFile *const fo,
7075
    MemBuffer &o_elfhdrs,
7076
    unsigned &c_adler,
7077
    unsigned &u_adler,
7078
    unsigned const orig_file_size
7079
)
7080
158
{
7081
    // xct_off [input side] was set by ::unpack when is_shlib
7082
    // yct_off [output side] set here unless is_asl in next 'if' block
7083
158
    unsigned yct_off = xct_off;
7084
7085
    // Below xct_off is not compressed (for benefit of rtld.)
7086
158
    fi->seek(0, SEEK_SET);
7087
158
    fi->readx(ibuf, umin(blocksize, file_size_u32));
7088
7089
    // Determine if the extra page with copy of _Shdrs was spliced in.
7090
    // This used to be the result of --android-shlib.
7091
    // But in 2023-02 the forwarding of ARM_ATTRIBUTES (by appending)
7092
    // takes care of this, so the 5th word before e_entry does not
7093
    // have the low bit 1, so is_asl should not be set.
7094
    // However, .so that were compressed before 2023-03
7095
    // may be marked.
7096
158
    e_shoff = get_te32(&ehdri.e_shoff);
7097
158
    if (e_shoff && e_shnum
7098
            // +36: (sizeof(PackHeader) + sizeof(overlay_offset))
7099
            //    after Shdrs for ARM_ATTRIBUTES
7100
35
    &&  (((e_shoff + sizeof(Elf32_Shdr) * e_shnum) + 36) < file_size_u32)
7101
158
    ) { // possible --android-shlib
7102
15
        unsigned x = get_te32(&file_image[get_te32(&ehdri.e_entry) - (1+ 4)*sizeof(int)]);
7103
15
        if (1 & x) { // the clincher
7104
2
            is_asl = 1;
7105
2
            fi->seek(e_shoff, SEEK_SET);
7106
2
            mb_shdr.alloc(   sizeof(Elf32_Shdr) * e_shnum);
7107
2
            shdri = (Elf32_Shdr *)mb_shdr.getVoidPtr();
7108
2
            fi->readx(shdri, sizeof(Elf32_Shdr) * e_shnum);
7109
2
            yct_off = get_te32(&shdri->sh_offset);  // for the output file (de-compressed)
7110
2
            xct_off = asl_delta + yct_off;  // for the input file (compressed)
7111
2
        }
7112
15
    }
7113
7114
    // Decompress first Extent.  Old style covers [0, xct_off)
7115
    // which includes rtld constant data and eXecutable app code below DT_INIT.
7116
    // In old style, the first compressed Extent is redundant
7117
    // except for the compressed original Elf headers.
7118
    // New style covers just Elf headers: the rest below xct_off is
7119
    // rtld constant data: DT_*HASH, DT_SYMTAB, DT_STRTAB, etc.
7120
    // New style puts eXecutable app code in second PT_LOAD
7121
    // in order to mark Elf headers and rtld data as non-eXecutable.
7122
158
    fi->seek(overlay_offset - sizeof(l_info), SEEK_SET);
7123
158
    struct {
7124
158
        struct l_info l;
7125
158
        struct p_info p;
7126
158
        struct b_info b;
7127
158
    } hdr;
7128
158
    fi->readx(&hdr, sizeof(hdr));
7129
158
    if (hdr.l.l_magic != UPX_MAGIC_LE32
7130
146
    ||  get_te16(&hdr.l.l_lsize) != (unsigned)lsize
7131
146
    ||  get_te32(&hdr.p.p_filesize) != ph.u_file_size
7132
130
    ||  get_te32(&hdr.b.sz_unc) < sz_elf_hdrs  // peek: 1st b_info covers Elf headers
7133
158
    ) {
7134
21
        throwCantUnpack("corrupt l_info/p_info/b_info");
7135
21
    }
7136
137
    fi->seek(-(off_t)sizeof(struct b_info), SEEK_CUR); // hdr.b_info was a peek
7137
7138
// The default layout for a shared library created by binutils-2.29
7139
// (Fedora 28; 2018) has two PT_LOAD: permissions r-x and rw-.
7140
// xct_off (the lowest address of executable instructions;
7141
// the highest address of read-only data used by rtld (ld-linux))
7142
// will be somewhere in the first PT_LOAD.
7143
//
7144
// The default layout for a shared library created by binutils-2.31
7145
// (Fedora 29; 2018) has four PT_LOAD: permissions r--, r-x, r--, rw-.
7146
// xct_off will be the base of the second [r-x] PT_LOAD.
7147
//
7148
// Bytes below xct_off cannot be compressed because they are used
7149
// by rtld *before* the UPX run-time de-compression stub gets control
7150
// via DT_INIT. Bytes in a Writeable PT_LOAD cannot be compressed
7151
// because they may be relocated by rtld, again before stub execution.
7152
//
7153
// We need to know which layout of PT_LOAD. It seems risky to steal
7154
// bits in the input ElfXX_Ehdr or ElfXX_Phdr, so we decompress
7155
// the first compressed block.  For an old-style shared library
7156
// the first compressed block covers [0, xct_off) which is redundant
7157
// with the interval [sz_elf_hdrs, xct_off) because those bytes
7158
// must be present for use by rtl  (So that is a large inefficiency.)
7159
// Fortunately p_info.p_blocksize fits in ibuf, and unpackExtent
7160
// will just decompress it all.  For new style, the first compressed
7161
// block covers [0, sz_elf_hdrs).
7162
7163
    // Peek: unpack into ibuf, but do not write
7164
137
    unsigned const sz_block1 = unpackExtent(sz_elf_hdrs, nullptr,
7165
137
        c_adler, u_adler, false, -1);
7166
137
    if (sz_block1 < sz_elf_hdrs) {
7167
0
        throwCantUnpack("corrupt b_info");
7168
0
    }
7169
137
    memcpy(o_elfhdrs, ibuf, sz_elf_hdrs); // save de-compressed Elf headers
7170
137
    Elf32_Ehdr const *const ehdro = (Elf32_Ehdr const *)(void const *)o_elfhdrs;
7171
137
    if (ehdro->e_type   !=ehdri.e_type
7172
103
    ||  ehdro->e_machine!=ehdri.e_machine
7173
103
    ||  ehdro->e_version!=ehdri.e_version
7174
        // less strict for EM_PPC to workaround earlier bug
7175
103
    ||  !( ehdro->e_flags==ehdri.e_flags
7176
9
        || Elf32_Ehdr::EM_PPC == get_te16(&ehdri.e_machine))
7177
96
    ||  ehdro->e_ehsize !=ehdri.e_ehsize
7178
        // check EI_MAG[0-3], EI_CLASS, EI_DATA, EI_VERSION
7179
92
    ||  memcmp(ehdro->e_ident, ehdri.e_ident, Elf32_Ehdr::EI_OSABI)) {
7180
22
        throwCantUnpack("ElfXX_Ehdr corrupted");
7181
22
    }
7182
115
    if (fo) {
7183
45
        fo->write(ibuf, sz_block1);
7184
45
        total_out = sz_block1;
7185
45
    }
7186
115
    Elf32_Phdr const *o_phdr = (Elf32_Phdr const *)(1+ ehdro);
7187
    // Handle compressed PT_LOADs (must not have PF_W)
7188
115
    unsigned not_first_LOAD = 0;
7189
281
    for (unsigned j = 0; j < e_phnum; ++j, ++o_phdr) {
7190
166
        unsigned type = get_te32(&o_phdr->p_type);
7191
166
        unsigned flags = get_te32(&o_phdr->p_flags);
7192
166
        if (PT_LOAD != type || Elf32_Phdr::PF_W & flags) {
7193
137
            continue;
7194
137
        }
7195
29
        unsigned p_offset = get_te32(&o_phdr->p_offset);
7196
29
        unsigned p_filesz = get_te32(&o_phdr->p_filesz);
7197
29
        unsigned wanted = p_filesz;
7198
29
        if (!not_first_LOAD++) { // first PT_LOAD
7199
29
            wanted -= sz_block1;
7200
29
            if (sz_block1 >  sz_elf_hdrs) { // old style
7201
17
                if (is_asl) {
7202
0
                    un_asl_dynsym(orig_file_size, fo);
7203
0
                }
7204
17
                p_offset += sz_block1;
7205
17
            }
7206
29
            if (sz_block1 == sz_elf_hdrs) { // new style
7207
12
                unsigned const len = (yct_off ? yct_off : xct_off) - sz_elf_hdrs;
7208
12
                unsigned const ipos = fi->tell();
7209
12
                fi->seek(sz_elf_hdrs, SEEK_SET);
7210
12
                fi->readx(&ibuf[sz_elf_hdrs], len);
7211
12
                if (is_asl) {
7212
0
                    un_asl_dynsym(orig_file_size, nullptr);
7213
0
                }
7214
12
                if (fo) {
7215
1
                    fo->write(&ibuf[sz_elf_hdrs], len);
7216
1
                }
7217
12
                total_out += len;
7218
7219
// github-issue629: (overlay_offset = 0xa500), so initially (xct_off = 0xa494).
7220
// But "yct_off = get_te32(&shdri->sh_offset)" so if _Shdrs are aligned (??)
7221
// then (0x10500 == (xct_off = asl_delta + yct_off)), and we read+write
7222
// more than we need.
7223
// So assume the excess just lives there, or is overwritten later by seek+write.
7224
12
                if (wanted < len) { // FIXME: why does this happen?
7225
0
                    wanted = 0;
7226
0
                }
7227
12
                else {
7228
12
                    wanted -= len;
7229
12
                }
7230
12
                fi->seek(ipos, SEEK_SET);
7231
12
                if (total_out == p_filesz) {
7232
0
                    continue;   // already entirely re-generated
7233
0
                }
7234
12
                p_offset = total_out;
7235
12
            }
7236
29
        }
7237
29
        if (fo) {
7238
7
            fo->seek(p_offset, SEEK_SET);
7239
7
        }
7240
29
        unpackExtent(wanted, fo, c_adler, u_adler, false);
7241
29
    }
7242
115
    funpad4(fi);
7243
115
    loader_offset = fi->tell();
7244
7245
    // Handle PT_LOAD with PF_W: writeable, so not compressed.  "Slide"
7246
115
    o_phdr = (Elf32_Phdr const *)(1+ ehdro);
7247
115
    Elf32_Phdr const *i_phdr = phdri;
7248
243
    for (unsigned j = 0; j < e_phnum; ++j, ++o_phdr, ++i_phdr) {
7249
128
        unsigned type = get_te32(&o_phdr->p_type);
7250
128
        unsigned flags = get_te32(&o_phdr->p_flags);
7251
128
        if (PT_LOAD != type || !(Elf32_Phdr::PF_W & flags)) {
7252
127
            continue;
7253
127
        }
7254
1
        unsigned filesz = get_te32(&o_phdr->p_filesz);
7255
1
        unsigned o_offset = get_te32(&o_phdr->p_offset);
7256
1
        unsigned i_offset = get_te32(&i_phdr->p_offset);
7257
1
        fi->seek(i_offset, SEEK_SET);
7258
1
        fi->readx(ibuf, filesz);
7259
1
        total_in += filesz;
7260
1
        if (fo) {
7261
1
            fo->seek(o_offset, SEEK_SET);
7262
1
            fo->write(ibuf, filesz);
7263
1
        }
7264
1
        total_out = filesz + o_offset;  // high-water mark
7265
1
    }
7266
7267
    // Gaps between PT_LOAD will be handled by ::unpack()
7268
7269
    // position fi at loader offset
7270
115
    fi->seek(loader_offset, SEEK_SET);
7271
115
}
7272
7273
void PackLinuxElf32::un_DT_INIT(
7274
    unsigned old_dtinit,
7275
    Elf32_Phdr const *const phdro,
7276
    Elf32_Phdr const *const dynhdr,  // in phdri
7277
    OutputFile *fo
7278
)
7279
2
{
7280
    // DT_INIT must be restored.
7281
    // If android_shlib, then the asl_delta relocations must be un-done.
7282
2
    unsigned n_plt = 0;
7283
2
    upx_uint32_t dt_pltrelsz(0), dt_jmprel(0), dt_pltgot(0);
7284
2
    upx_uint32_t dt_relsz(0), dt_rel(0);
7285
2
    upx_uint32_t const dyn_len = get_te32(&dynhdr->p_filesz);
7286
2
    upx_uint32_t const dyn_off = get_te32(&dynhdr->p_offset);
7287
2
    if (file_size_u32 < (dyn_len + dyn_off)) {
7288
0
        char msg[50]; snprintf(msg, sizeof(msg),
7289
0
                "bad PT_DYNAMIC .p_filesz %#lx", (long unsigned)dyn_len);
7290
0
        throwCantUnpack(msg);
7291
0
    }
7292
2
    fi->seek(dyn_off, SEEK_SET);
7293
2
    fi->readx(ibuf, dyn_len);
7294
2
    Elf32_Dyn *dyn = (Elf32_Dyn *)(void *)ibuf;
7295
2
    dynseg = dyn; invert_pt_dynamic(dynseg,
7296
2
        umin(dyn_len, file_size_u32 - dyn_off));
7297
2
    for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
7298
0
        upx_uint32_t const tag = get_te32(&dyn->d_tag);
7299
0
        upx_uint32_t       val = get_te32(&dyn->d_val);
7300
0
        if (is_asl) switch (tag) {
7301
0
        case Elf32_Dyn::DT_RELASZ:   { dt_relsz   = val; } break;
7302
0
        case Elf32_Dyn::DT_RELA:     { dt_rel     = val; } break;
7303
0
        case Elf32_Dyn::DT_JMPREL:   { dt_jmprel   = val; } break;
7304
0
        case Elf32_Dyn::DT_PLTRELSZ: { dt_pltrelsz = val;
7305
0
            n_plt = dt_pltrelsz / sizeof(Elf32_Rel);
7306
0
            if (is_asl) {
7307
0
                n_plt += 3;  // FIXME
7308
0
            }
7309
0
        };  break;
7310
7311
0
        case Elf32_Dyn::DT_PLTGOT:   { plt_va = dt_pltgot = val; (void)dt_pltgot; }
7312
        // FALL THROUGH
7313
0
        case Elf32_Dyn::DT_PREINIT_ARRAY:
7314
0
        case Elf32_Dyn::DT_INIT_ARRAY:
7315
0
        case Elf32_Dyn::DT_FINI_ARRAY:
7316
0
        case Elf32_Dyn::DT_FINI: if (is_asl) {
7317
0
            set_te32(&dyn->d_val, val - asl_delta);
7318
0
        }; break;
7319
0
        } // end switch() on tag when is_asl
7320
0
        if (upx_dt_init == tag) {
7321
0
            if (Elf32_Dyn::DT_INIT == tag) { // the easy case
7322
0
                set_te32(&dyn->d_val, old_dtinit);
7323
0
                if (!old_dtinit) { // compressor took the slot
7324
0
                    dyn->d_tag = Elf32_Dyn::DT_NULL;
7325
0
                    dyn->d_val = 0;
7326
0
                }
7327
0
            }
7328
            // Apparently the hard case is common for some Android IDEs.
7329
0
            else if (Elf32_Dyn::DT_INIT_ARRAY    == tag
7330
0
            ||       Elf32_Dyn::DT_PREINIT_ARRAY == tag) {
7331
                // 'val' is the RVA of the first slot, which is the slot that
7332
                // the compressor changed to be the entry to the run-time stub.
7333
0
                Elf32_Dyn *dyn_null = elf_find_dynptr(Elf32_Dyn::DT_NULL);
7334
0
                if (!dyn_null)
7335
0
                    throwCantUnpack("bad PT_DYNAMIC .end");
7336
0
                Elf32_Rel *rp = (Elf32_Rel *)elf_find_dynamic(dyn_null->d_val);
7337
0
                dyn_null->d_val = 0;
7338
0
                if (rp) {
7339
                    // Compressor saved the original *rp in dynsym[0]
7340
0
                    Elf32_Rel *rp_unc = (Elf32_Rel *)&dynsym[0];  // pointer
7341
0
                    rp->r_info = rp_unc->r_info;  // restore original r_info; r_offset not touched
7342
7343
0
                    unsigned e_entry = get_te32(&ehdri.e_entry);
7344
0
                    unsigned init_rva = get_te32(&file_image[e_entry - 3*sizeof(unsigned)]);
7345
0
                    unsigned arr_rva = get_te32(&rp_unc->r_offset);
7346
0
                    Elf32_Phdr const *phdr = elf_find_Phdr_for_va(arr_rva, phdro, e_phnum);
7347
0
                    unsigned arr_off = (arr_rva - get_te32(&phdr->p_vaddr)) + get_te32(&phdr->p_offset);
7348
7349
0
                    rp_unc->r_offset = 0;    rp_unc->r_info = 0;
7350
0
                    if (fo)  {
7351
0
                        fo->seek(elf_unsigned_dynamic(Elf32_Dyn::DT_SYMTAB), SEEK_SET);
7352
0
                        fo->rewrite(rp_unc, sizeof(Elf32_Rel));  // clear dynsym[0]
7353
7354
0
                        fo->seek((char *)rp - (char *)&file_image[0], SEEK_SET);
7355
0
                        fo->rewrite(rp, sizeof(*rp));  // restore original *rp
7356
0
                    }
7357
7358
                    // Set arr[0] to the first user init routine.
7359
0
                    unsigned r_info = get_te32(&rp->r_info);
7360
0
                    unsigned r_type = ELF32_R_TYPE(r_info);
7361
0
                    unsigned word;
7362
0
                    if (Elf32_Ehdr::EM_ARM == e_machine) {
7363
0
                        if (R_ARM_RELATIVE == r_type) {
7364
0
                            set_te32(&word, init_rva);
7365
0
                        }
7366
0
                        else if (R_ARM_ABS32 == r_type) {
7367
0
                            word = 0;
7368
0
                        }
7369
0
                        else {
7370
0
                            char msg[40]; snprintf(msg, sizeof(msg), "unknown relocation: %#x",
7371
0
                                r_type);
7372
0
                            throwCantUnpack(msg);
7373
0
                        }
7374
0
                    }
7375
0
                    else if (Elf32_Ehdr::EM_386 == e_machine) {
7376
0
                        if (R_386_RELATIVE == r_type) {
7377
0
                        }
7378
0
                        else if (R_386_32 == r_type) {
7379
0
                        }
7380
0
                        if (R_386_RELATIVE == r_type) {
7381
0
                            set_te32(&word, init_rva);
7382
0
                        }
7383
0
                        else if (R_386_32 == r_type) {
7384
0
                            word = 0;
7385
0
                        }
7386
0
                        else {
7387
0
                            char msg[40]; snprintf(msg, sizeof(msg), "unknown relocation: %#x",
7388
0
                                r_type);
7389
0
                            throwCantUnpack(msg);
7390
0
                        }
7391
0
                    }
7392
0
                    if (fo) {
7393
0
                        fo->seek(arr_off, SEEK_SET);
7394
0
                        fo->rewrite(&word, sizeof(unsigned));
7395
0
                        fo->seek(0, SEEK_END);
7396
0
                    }
7397
0
                }
7398
0
            }
7399
0
        }
7400
0
    }
7401
2
    if (fo) { // Write updated dt_*.val
7402
0
        upx_uint32_t dyn_offo = get_te32(&phdro[dynhdr - phdri].p_offset);
7403
0
        fo->seek(dyn_offo, SEEK_SET);
7404
0
        fo->rewrite(ibuf, dyn_len);
7405
0
    }
7406
2
    if (is_asl) {
7407
0
        MemBuffer ptload1;  // FIXME.  file_image has the whole file; ibuf is available
7408
0
        lowmem.alloc(xct_off);
7409
0
        fi->seek(0, SEEK_SET);
7410
0
        fi->read(lowmem, xct_off);  // contains relocation tables
7411
0
        if (dt_relsz && dt_rel) {
7412
0
            Elf32_Rel *const rel0 = (Elf32_Rel *)lowmem.subref(
7413
0
                "bad Rel offset", dt_rel, dt_relsz);
7414
0
            unRel32(dt_rel, rel0, dt_relsz, ptload1, old_dtinit, fo);
7415
0
        }
7416
0
        if (dt_pltrelsz && dt_jmprel) { // FIXME:  overlap w/ DT_REL ?
7417
0
            Elf32_Rel *const jmp0 = (Elf32_Rel *)lowmem.subref(
7418
0
                "bad Jmprel offset", dt_jmprel, dt_pltrelsz);
7419
0
            jump_slots.alloc(n_plt * sizeof(upx_uint32_t));
7420
0
            Elf32_Phdr const *phdr = phdri;
7421
0
            for (unsigned j = 0; j < e_phnum; ++j, ++phdr) if (is_LOAD(phdr)) {
7422
0
                upx_uint32_t vaddr = get_te32(&phdr->p_vaddr);
7423
0
                upx_uint32_t filesz = get_te32(&phdr->p_filesz);
7424
0
                upx_uint32_t d = plt_va - vaddr;
7425
0
                if (d < filesz) {
7426
0
                    upx_uint32_t offset = get_te32(&phdr->p_offset);
7427
0
                    fi->seek(d + offset, SEEK_SET);
7428
0
                    fi->readx(jump_slots, n_plt * sizeof(upx_uint32_t));
7429
0
                    break;
7430
0
                }
7431
0
            }
7432
0
            unRel32(dt_jmprel, jmp0, dt_pltrelsz, ptload1, old_dtinit, fo);
7433
7434
0
            Elf32_Ehdr const *const o_ehdr = (Elf32_Ehdr const *)(void *)lowmem;
7435
0
            unsigned const o_phnum = o_ehdr->e_phnum;
7436
0
            if (((1<<16) - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr) < o_phnum)
7437
0
                throwCantUnpack("bad Ehdr.e_phnum %#x", o_phnum);
7438
0
            phdr = phdro;
7439
0
            for (unsigned j = 0; j < o_phnum; ++j, ++phdr) if (is_LOAD(phdr)) {
7440
0
                upx_uint32_t vaddr = get_te32(&phdr->p_vaddr);
7441
0
                upx_uint32_t filesz = get_te32(&phdr->p_filesz);
7442
0
                upx_uint32_t d = plt_va - vaddr - asl_delta;
7443
0
                if (d < filesz) {
7444
0
                    upx_uint32_t offset = get_te32(&phdr->p_offset);
7445
0
                    if ((upx_uint32_t)file_size <= offset)
7446
0
                        throwCantUnpack("bad phdr[%d].p_offset %#zx", j, (size_t)offset);
7447
0
                    if (fo) {
7448
0
                        fo->seek(d + offset, SEEK_SET);
7449
0
                        fo->rewrite(jump_slots, n_plt * sizeof(upx_uint32_t));
7450
0
                    }
7451
0
                    break;
7452
0
                }
7453
0
            }
7454
0
        }
7455
        // Modified relocation tables are re-written by unRel32
7456
0
    }
7457
2
}
7458
7459
void PackLinuxElf64::un_DT_INIT(
7460
    unsigned old_dtinit,
7461
    Elf64_Phdr const *const phdro,
7462
    Elf64_Phdr const *const dynhdr,  // in phdri
7463
    OutputFile *fo
7464
)
7465
7
{
7466
    // DT_INIT must be restored.
7467
    // If android_shlib, then the asl_delta relocations must be un-done.
7468
7
    unsigned n_plt = 0;
7469
7
    upx_uint64_t dt_pltrelsz(0), dt_jmprel(0), dt_pltgot(0);
7470
7
    upx_uint64_t dt_relasz(0), dt_rela(0);
7471
7
    upx_uint64_t const dyn_len = get_te64(&dynhdr->p_filesz);
7472
7
    upx_uint64_t const dyn_off = get_te64(&dynhdr->p_offset);
7473
7
    if (file_size_u < (dyn_len + dyn_off)) {
7474
5
        char msg[50]; snprintf(msg, sizeof(msg),
7475
5
                "bad PT_DYNAMIC .p_filesz %#lx", (long unsigned)dyn_len);
7476
5
        throwCantUnpack(msg);
7477
5
    }
7478
2
    fi->seek(dyn_off, SEEK_SET);
7479
2
    fi->readx(ibuf, dyn_len);
7480
2
    Elf64_Dyn *dyn = (Elf64_Dyn *)(void *)ibuf;
7481
2
    dynseg = dyn; invert_pt_dynamic(dynseg,
7482
2
        umin(dyn_len, file_size_u - dyn_off));
7483
2
    for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
7484
0
        upx_uint64_t const tag = get_te64(&dyn->d_tag);
7485
0
        upx_uint64_t       val = get_te64(&dyn->d_val);
7486
0
        if (is_asl) switch (tag) {
7487
0
        case Elf64_Dyn::DT_RELASZ:   { dt_relasz   = val; } break;
7488
0
        case Elf64_Dyn::DT_RELA:     { dt_rela     = val; } break;
7489
0
        case Elf64_Dyn::DT_JMPREL:   { dt_jmprel   = val; } break;
7490
0
        case Elf64_Dyn::DT_PLTRELSZ: { dt_pltrelsz = val;
7491
0
            n_plt = dt_pltrelsz / sizeof(Elf32_Rel);
7492
0
            if (is_asl) {
7493
0
                n_plt += 3;  // FIXME
7494
0
            }
7495
0
        };  break;
7496
7497
0
        case Elf64_Dyn::DT_PLTGOT:   { plt_va = dt_pltgot = val; (void)dt_pltgot;}
7498
        // FALL THROUGH
7499
0
        case Elf64_Dyn::DT_PREINIT_ARRAY:
7500
0
        case Elf64_Dyn::DT_INIT_ARRAY:
7501
0
        case Elf64_Dyn::DT_FINI_ARRAY:
7502
0
        case Elf64_Dyn::DT_FINI: if (is_asl) {
7503
0
            set_te64(&dyn->d_val, val - asl_delta);
7504
0
        }; break;
7505
0
        } // end switch() on tag when is_asl
7506
0
        if (upx_dt_init == tag) { // the easy case
7507
0
            if (Elf64_Dyn::DT_INIT == tag) {
7508
0
                set_te64(&dyn->d_val, old_dtinit);
7509
0
                if (!old_dtinit) { // compressor took the slot
7510
0
                    dyn->d_tag = Elf64_Dyn::DT_NULL;
7511
0
                    dyn->d_val = 0;
7512
0
                }
7513
0
            }
7514
            // Apparently the hard case is common for some Android IDEs.
7515
            // No DT_INIT; only DT_INIT_ARRAY.
7516
0
            else if (Elf64_Dyn::DT_INIT_ARRAY    == tag
7517
0
            ||       Elf64_Dyn::DT_PREINIT_ARRAY == tag) {
7518
                // 'val' is the RVA of the first slot, which is the slot that
7519
                // the compressor changed to be the entry to the run-time stub.
7520
0
                Elf64_Dyn *dyn_null = elf_find_dynptr(Elf64_Dyn::DT_NULL);
7521
0
                if (!dyn_null)
7522
0
                    throwCantUnpack("bad PT_DYNAMIC .end");
7523
0
                Elf64_Rela *rp = (Elf64_Rela *)elf_find_dynamic(dyn_null->d_val);
7524
0
                dyn_null->d_val = 0;
7525
0
                if (rp) {
7526
                    // Compressor saved the original *rp in dynsym[0]
7527
0
                    Elf64_Rela *rp_unc = (Elf64_Rela *)&dynsym[0];  // pointer
7528
0
                    rp->r_info = rp_unc->r_info;  // restore original r_info; r_offset not touched
7529
0
                    rp->r_addend = rp_unc->r_addend;
7530
7531
0
                    unsigned arr_rva = get_te64(&rp_unc->r_offset);
7532
0
                    Elf64_Phdr const *phdr = elf_find_Phdr_for_va(arr_rva, phdro, e_phnum);
7533
0
                    unsigned arr_off = (arr_rva - get_te64(&phdr->p_vaddr)) + get_te64(&phdr->p_offset);
7534
7535
0
                    if (fo)  {
7536
0
                        memset(rp_unc, 0, sizeof(*rp_unc));
7537
0
                        fo->seek(elf_unsigned_dynamic(Elf64_Dyn::DT_SYMTAB), SEEK_SET);
7538
0
                        fo->rewrite(rp_unc, sizeof(Elf64_Rela));  // clear dynsym[0]
7539
7540
0
                        fo->seek((char *)rp - (char *)&file_image[0], SEEK_SET);
7541
0
                        fo->rewrite(rp, sizeof(*rp));  // restore original *rp
7542
7543
                        // Elf64_Rela overwrites; but put back original.
7544
0
                        fo->seek(arr_off, SEEK_SET);
7545
0
                        fo->rewrite(rp_unc, sizeof(u64_t));
7546
7547
0
                        fo->seek(0, SEEK_END);
7548
0
                    }
7549
0
                }
7550
0
            }
7551
0
        }
7552
0
    }
7553
2
    if (fo) { // Write updated dt_*.val
7554
0
        upx_uint64_t dyn_offo = get_te64(&phdro[dynhdr - phdri].p_offset);
7555
0
        fo->seek(dyn_offo, SEEK_SET);
7556
0
        fo->rewrite(ibuf, dyn_len);
7557
0
    }
7558
2
    if (is_asl) {
7559
0
        lowmem.alloc(xct_off);
7560
0
        fi->seek(0, SEEK_SET);
7561
0
        fi->read(lowmem, xct_off);  // contains relocation tables
7562
0
        if (dt_relasz && dt_rela) {
7563
0
            Elf64_Rela *const rela0 = (Elf64_Rela *)lowmem.subref(
7564
0
                "bad Rela offset", dt_rela, dt_relasz);
7565
0
            unRela64(dt_rela, rela0, dt_relasz, old_dtinit, fo);
7566
0
        }
7567
0
        if (dt_pltrelsz && dt_jmprel) { // FIXME:  overlap w/ DT_REL ?
7568
0
            Elf64_Rela *const jmp0 = (Elf64_Rela *)lowmem.subref(
7569
0
                "bad Jmprel offset", dt_jmprel, dt_pltrelsz);
7570
0
            jump_slots.alloc(n_plt * sizeof(upx_uint64_t));
7571
0
            Elf64_Phdr const *phdr = phdri;
7572
0
            for (unsigned j = 0; j < e_phnum; ++j, ++phdr) if (is_LOAD(phdr)) {
7573
0
                upx_uint64_t vaddr = get_te64(&phdr->p_vaddr);
7574
0
                upx_uint64_t filesz = get_te64(&phdr->p_filesz);
7575
0
                upx_uint64_t d = plt_va - vaddr;
7576
0
                if (d < filesz) {
7577
0
                    upx_uint64_t offset = get_te64(&phdr->p_offset);
7578
0
                    fi->seek(d + offset, SEEK_SET);
7579
0
                    fi->readx(jump_slots, n_plt * sizeof(upx_uint64_t));
7580
0
                    break;
7581
0
                }
7582
0
            }
7583
0
            unRela64(dt_jmprel, jmp0, dt_pltrelsz, old_dtinit, fo);
7584
7585
0
            Elf64_Ehdr const *const o_ehdr = (Elf64_Ehdr const *)(void *)lowmem;
7586
0
            unsigned const o_phnum = o_ehdr->e_phnum;
7587
0
            if (((1<<16) - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr) < o_phnum)
7588
0
                throwCantUnpack("bad Ehdr.e_phnum %#x", o_phnum);
7589
0
            phdr = phdro;
7590
0
            for (unsigned j = 0; j < o_phnum; ++j, ++phdr) if (is_LOAD(phdr)) {
7591
0
                upx_uint64_t vaddr = get_te64(&phdr->p_vaddr);
7592
0
                upx_uint64_t filesz = get_te64(&phdr->p_filesz);
7593
0
                upx_uint64_t d = plt_va - vaddr - asl_delta;
7594
0
                if (d < filesz) {
7595
0
                    upx_uint64_t offset = get_te64(&phdr->p_offset);
7596
0
                    if ((upx_uint64_t)file_size <= offset)
7597
0
                        throwCantUnpack("bad phdr[%d].p_offset %#zx", j, (size_t)offset);
7598
0
                    if (fo) {
7599
0
                        fo->seek(d + offset, SEEK_SET);
7600
0
                        fo->rewrite(jump_slots, n_plt * sizeof(upx_uint64_t));
7601
0
                    }
7602
0
                    break;
7603
0
                }
7604
0
            }
7605
0
        }
7606
        // Modified relocation tables are re-written by unRela64
7607
0
    }
7608
2
}
7609
7610
void PackLinuxElf64::unpack(OutputFile *fo)
7611
794
{
7612
794
    if (e_phoff != sizeof(Elf64_Ehdr)) {// Phdrs not contiguous with Ehdr
7613
0
        throwCantUnpack("bad e_phoff");
7614
0
    }
7615
794
    unsigned const c_phnum = get_te16(&ehdri.e_phnum);
7616
794
    unsigned u_phnum = 0;
7617
794
    upx_uint64_t old_dtinit = 0;
7618
7619
794
    if (Elf64_Ehdr::ET_EXEC == get_te16(&ehdri.e_type)) {
7620
// 40fddf17153ee3db73a04ff1bf288b91676138d6 2001-02-01 ph.version 11; b_info 12 bytes
7621
// df9db96bd1c013c07da1d7ec740021d588ab2815 2001-01-17 ph.version 11; no b_info (==> 8 bytes)
7622
768
        if (ph.version <= 11
7623
34
        &&  get_te64(&ehdri.e_entry) < 0x401180
7624
7
        &&  get_te16(&ehdri.e_machine)==Elf64_Ehdr::EM_X86_64) {
7625
            // old style, 8-byte b_info:
7626
            // sizeof(b_info.sz_unc) + sizeof(b_info.sz_cpr);
7627
7
            szb_info = 2*sizeof(unsigned);
7628
7
        }
7629
768
    }
7630
7631
794
    fi->seek(overlay_offset - sizeof(l_info), SEEK_SET);
7632
794
    fi->readx(&linfo, sizeof(linfo));
7633
794
    if (UPX_MAGIC_LE32 != get_le32(&linfo.l_magic)) {
7634
123
        NE32 const *const lp = (NE32 const *)(void const *)&linfo;
7635
        // Workaround for bug of extra linfo by some asl_pack2_Shdrs().
7636
123
        if (0==lp[0] && 0==lp[1] && 0==lp[2]) { // looks like blank extra
7637
8
            fi->readx(&linfo, sizeof(linfo));
7638
8
            if (UPX_MAGIC_LE32 == get_le32(&linfo.l_magic)) {
7639
2
                overlay_offset += sizeof(linfo);
7640
2
            }
7641
6
            else {
7642
6
                throwCantUnpack("l_info corrupted");
7643
6
            }
7644
8
        }
7645
115
        else {
7646
115
            throwCantUnpack("l_info corrupted");
7647
115
        }
7648
123
    }
7649
673
    lsize = get_te16(&linfo.l_lsize);
7650
673
    p_info hbuf;  fi->readx(&hbuf, sizeof(hbuf));
7651
673
    unsigned orig_file_size = get_te32(&hbuf.p_filesize);
7652
673
    blocksize = get_te32(&hbuf.p_blocksize);
7653
673
    if ((u32_t)file_size > orig_file_size || blocksize > orig_file_size
7654
631
        || (orig_file_size >> 8) > (u32_t)file_size  // heuristic anti-fuzz
7655
591
        ||      (blocksize >> 8) > (u32_t)file_size
7656
591
        || !mem_size_valid(1, blocksize, OVERHEAD))
7657
79
        throwCantUnpack("p_info corrupted");
7658
7659
594
    ibuf.alloc(blocksize + OVERHEAD);
7660
594
    b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
7661
594
    fi->readx(&bhdr, szb_info);
7662
594
    ph.u_len = get_te32(&bhdr.sz_unc);
7663
594
    ph.c_len = get_te32(&bhdr.sz_cpr);
7664
594
    ph.set_method(bhdr.b_method, overlay_offset + sizeof(p_info));
7665
594
    if (ph.c_len > file_size_u || ph.c_len == 0 || ph.u_len == 0
7666
584
    ||  ph.u_len > orig_file_size)
7667
20
        throwCantUnpack("b_info corrupted");
7668
574
    ph.filter_cto = bhdr.b_cto8;
7669
574
    prev_method = bhdr.b_method;  // FIXME if multiple de-compressors
7670
7671
574
    MemBuffer u(ph.u_len);
7672
574
    Elf64_Ehdr *const ehdr = (Elf64_Ehdr *)&u[0];
7673
574
    Elf64_Phdr const *phdr = nullptr;
7674
574
    total_in = 0;
7675
574
    total_out = 0;
7676
574
    unsigned c_adler = upx_adler32(nullptr, 0);
7677
574
    unsigned u_adler = upx_adler32(nullptr, 0);
7678
7679
574
    unsigned is_shlib = 0;
7680
574
    loader_offset = 0;
7681
574
    MemBuffer o_elfhdrs;
7682
574
    Elf64_Phdr const *const dynhdr = elf_find_ptype(Elf64_Phdr::PT_DYNAMIC, phdri, c_phnum);
7683
    // dynseg was set by PackLinuxElf64help1
7684
574
    if (dynhdr && !(Elf64_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf64_Dyn::DT_FLAGS_1))) {
7685
        // Packed shlib? (ET_DYN without -fPIE)
7686
185
        is_shlib = 1;
7687
185
        xct_off = overlay_offset - sizeof(l_info);
7688
185
        u_phnum = get_te16(&ehdri.e_phnum);
7689
185
        o_elfhdrs.alloc(sz_elf_hdrs);
7690
185
        un_shlib_1(fo, o_elfhdrs, c_adler, u_adler, orig_file_size);
7691
185
        *ehdr = ehdri;
7692
185
    }
7693
389
    else { // main executable
7694
        // Uncompress Ehdr and Phdrs: info for control of unpacking
7695
389
        if (ibuf.getSize() < ph.c_len)
7696
1
            throwCompressedDataViolation();
7697
7698
388
        fi->readx(ibuf, ph.c_len);
7699
        // "clickhouse" ET_EXEC for amd64 has 0x200000 <= .e_entry
7700
        // instead of 0x400000 that we checked earlier.
7701
388
        if (8 == szb_info
7702
0
        &&  Elf64_Ehdr::EM_X86_64 == e_machine
7703
0
        &&  Elf64_Ehdr::ET_EXEC   == e_type
7704
0
        &&  ph.u_len <= MAX_ELF_HDR_64
7705
388
        ) {
7706
0
            unsigned b_method = ibuf[0];
7707
0
            unsigned b_extra  = ibuf[3];
7708
0
            if (M_ZSTD >= b_method && 0 == b_extra) {
7709
0
                unsigned where = fi->seek( -(upx_off_t)(ph.c_len + szb_info), SEEK_CUR);
7710
0
                szb_info = 12;
7711
0
                fi->readx(&bhdr, szb_info);
7712
0
                ph.filter_cto = bhdr.b_cto8;
7713
0
                ph.set_method(bhdr.b_method, where);
7714
0
                prev_method = bhdr.b_method;  // FIXME if multiple de-compressors
7715
0
                fi->readx(ibuf, ph.c_len);
7716
0
            }
7717
0
        }
7718
388
        if (ph.u_len < sizeof(*ehdr))
7719
2
            throwCantUnpack("ElfXX_Ehdr corrupted");
7720
386
        decompress(ibuf, (upx_byte *)ehdr, false);
7721
386
        if (ehdr->e_type   !=ehdri.e_type
7722
352
        ||  ehdr->e_machine!=ehdri.e_machine
7723
352
        ||  ehdr->e_version!=ehdri.e_version
7724
            // less strict for EM_PPC64 to workaround earlier bug
7725
352
        ||  !( ehdr->e_flags==ehdri.e_flags
7726
6
            || Elf64_Ehdr::EM_PPC64 == get_te16(&ehdri.e_machine))
7727
348
        ||  ehdr->e_ehsize !=ehdri.e_ehsize
7728
            // check EI_MAG[0-3], EI_CLASS, EI_DATA, EI_VERSION
7729
345
        ||  memcmp(ehdr->e_ident, ehdri.e_ident, Elf64_Ehdr::EI_OSABI)) {
7730
12
            throwCantUnpack("ElfXX_Ehdr corrupted");
7731
12
        }
7732
        // Rewind: prepare for data phase
7733
374
        fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
7734
7735
374
        u_phnum = get_te16(&ehdr->e_phnum);
7736
374
        if ((umin(MAX_ELF_HDR_64, ph.u_len) - sizeof(Elf64_Ehdr))/sizeof(Elf64_Phdr) < u_phnum) {
7737
0
            throwCantUnpack("bad compressed e_phnum");
7738
0
        }
7739
374
        o_elfhdrs.alloc(sizeof(Elf64_Ehdr) + u_phnum * sizeof(Elf64_Phdr));
7740
374
        memcpy(o_elfhdrs, ehdr, o_elfhdrs.getSize());
7741
7742
        // Decompress each PT_LOAD.
7743
374
        bool first_PF_X = true;
7744
374
        phdr = (Elf64_Phdr *) (void *) (1+ ehdr);  // uncompressed
7745
1.67k
        for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
7746
1.30k
            if (is_LOAD(phdr)) {
7747
457
                unsigned const filesz = get_te64(&phdr->p_filesz);
7748
457
                unsigned const offset = get_te64(&phdr->p_offset);
7749
457
                if (fo) {
7750
251
                    fo->seek(offset, SEEK_SET);
7751
251
                    if (total_out < offset) {
7752
83
                        total_out = offset;  // FIXME: can it be re-write?
7753
83
                    }
7754
251
                }
7755
457
                if (Elf64_Phdr::PF_X & get_te32(&phdr->p_flags)) {
7756
262
                    unpackExtent(filesz, fo,
7757
262
                        c_adler, u_adler, first_PF_X);
7758
262
                    first_PF_X = false;
7759
262
                }
7760
195
                else {
7761
195
                    unpackExtent(filesz, fo,
7762
195
                        c_adler, u_adler, false);
7763
195
                }
7764
457
            }
7765
1.30k
        }
7766
374
    }
7767
7768
559
    upx_uint64_t const e_entry = get_te64(&ehdri.e_entry);
7769
559
    unsigned off_entry = 0;
7770
559
    phdr = phdri;
7771
559
    load_va = 0;
7772
18.9k
    for (unsigned j=0; j < c_phnum; ++j, ++phdr) {
7773
18.5k
        if (is_LOAD(phdr)) {
7774
555
            upx_uint64_t offset = get_te64(&phdr->p_offset);
7775
555
            upx_uint64_t vaddr  = get_te64(&phdr->p_vaddr);
7776
555
            upx_uint64_t filesz = get_te64(&phdr->p_filesz);
7777
555
            if (!load_va) {
7778
293
                load_va = vaddr;
7779
293
            }
7780
555
            if ((e_entry - vaddr) < filesz) {
7781
129
                off_entry = (e_entry - vaddr) + offset;
7782
129
                break;
7783
129
            }
7784
555
        }
7785
18.5k
    }
7786
559
    unsigned d_info[6];
7787
559
    unsigned sz_d_info = sizeof(d_info);
7788
559
    if (!is_shlib) {
7789
178
        if (get_te32(&phdri[0].p_flags) & Elf64_Phdr::PF_X) {
7790
            // Old style, such as upx-3.91 thru upx-3.95
7791
79
            switch (this->e_machine) {
7792
0
                default: {
7793
0
                    char msg[40]; snprintf(msg, sizeof(msg),
7794
0
                        "Unknown architecture %d", this->e_machine);
7795
0
                    throwCantUnpack(msg);
7796
0
                }; break;
7797
4
                case Elf64_Ehdr::EM_AARCH64: sz_d_info = 4 * sizeof(unsigned); break;
7798
9
                case Elf64_Ehdr::EM_PPC64:   sz_d_info = 3 * sizeof(unsigned); break;
7799
66
                case Elf64_Ehdr::EM_X86_64:  sz_d_info = 2 * sizeof(unsigned); break;
7800
79
            }
7801
79
        }
7802
178
        loader_offset = off_entry - sz_d_info;
7803
178
    }
7804
7805
559
    if (0x1000==get_te64(&phdri[0].p_filesz)  // detect C_BASE style
7806
89
    &&  0==get_te64(&phdri[1].p_offset)
7807
80
    &&  0==get_te64(&phdri[0].p_offset)
7808
62
    &&     get_te64(&phdri[1].p_filesz) == get_te64(&phdri[1].p_memsz)) {
7809
53
        fi->seek(up4(get_te64(&phdri[1].p_memsz)), SEEK_SET);  // past the loader
7810
53
    }
7811
506
    else if (is_shlib
7812
135
    ||  (off_entry + up4(lsize) + ph.getPackHeaderSize() + sizeof(overlay_offset))
7813
163
            < up4(file_size)) {
7814
        // Loader is not at end; skip past it.
7815
163
        if (loader_offset) {
7816
163
            fi->seek(loader_offset, SEEK_SET);
7817
163
        }
7818
0
        else {
7819
0
            funpad4(fi);  // MATCH01
7820
0
        }
7821
163
        fi->readx(d_info, sz_d_info);
7822
163
        if (is_shlib && 0==old_dtinit) {
7823
63
            old_dtinit = get_te32(&d_info[2 + (0==d_info[0])]);
7824
63
            is_asl = 1u& get_te32(&d_info[0 + (0==d_info[0])]);
7825
63
        }
7826
163
        fi->seek(lsize - sz_d_info, SEEK_CUR);
7827
163
    }
7828
7829
    // The gaps between PT_LOAD and after last PT_LOAD
7830
559
    phdr = (Elf64_Phdr const *)(1+ (Elf64_Ehdr const *)(void const *)o_elfhdrs);
7831
559
    upx_uint64_t hi_offset(0);
7832
1.50k
    for (unsigned j = 0; j < u_phnum; ++j) {
7833
943
        upx_uint64_t const offset = get_te64(&phdr[j].p_offset);
7834
943
        if (is_LOAD(&phdr[j])
7835
286
        &&  hi_offset < offset) {
7836
179
            hi_offset = offset;
7837
179
        }
7838
943
    }
7839
1.26k
    for (unsigned j = 0; j < u_phnum; ++j) {
7840
749
        unsigned const size = find_LOAD_gap(phdr, j, u_phnum);
7841
749
        if (size) {
7842
213
            unsigned const where = get_te64(&phdr[j].p_offset) +
7843
213
                                   get_te64(&phdr[j].p_filesz);
7844
213
            if (fo)
7845
96
                fo->seek(where, SEEK_SET);
7846
213
            { // Recover from some piracy [also serves as error tolerance :-) ]
7847
              // Getting past the loader is problematic, due to unintended
7848
              // variances between released versions:
7849
              //   l_info.l_lsize might be rounded up by 8 instead of by 4, and
7850
              //   sz_d_info might have changed.
7851
213
                b_info b_peek, *bp = &b_peek;
7852
213
                fi->readx(bp, sizeof(b_peek));
7853
213
                upx_off_t pos = fi->seek(-(off_t)sizeof(b_peek), SEEK_CUR);
7854
213
                unsigned sz_unc = get_te32(&bp->sz_unc);
7855
213
                unsigned sz_cpr = get_te32(&bp->sz_cpr);
7856
213
                unsigned word3  = get_te32(&bp->b_method);
7857
213
                unsigned method = bp->b_method;
7858
213
                unsigned ftid = bp->b_ftid;
7859
213
                unsigned cto8 = bp->b_cto8;
7860
213
                if (!( ((sz_cpr == sz_unc) && (0 == word3) && (size == sz_unc)) // incompressible literal
7861
213
                    || ((sz_cpr <  sz_unc)
7862
170
                        && (method == prev_method || M_NRV2B_LE32 == prev_method)
7863
132
                        && (0 == ftid) && (0 == cto8)) )
7864
213
                ) {
7865
84
                    opt->info_mode++;
7866
84
                    infoWarning("bad b_info at %#zx", (size_t)pos);
7867
84
                    unsigned const N_PEEK(16 * sizeof(int)), H_PEEK(N_PEEK >> 1);
7868
84
                    unsigned char peek_arr[N_PEEK];
7869
84
                    fi->seek(pos - H_PEEK, SEEK_SET);
7870
84
                    fi->readx(peek_arr, sizeof(peek_arr));
7871
84
                    fi->seek(pos, SEEK_SET);
7872
84
                    bool const is_be = ELFDATA2MSB == ehdri.e_ident[EI_DATA];
7873
84
                    if (is_be) {
7874
                        // Does the right thing for sz_unc and sz_cpr,
7875
                        // but swaps b_method and b_extra.  Need find_be32() :-)
7876
221
                        for (unsigned k = 0; k < N_PEEK; k += sizeof(int)) {
7877
208
                            set_le32(&peek_arr[k], get_be32(&peek_arr[k]));
7878
208
                        }
7879
13
                    }
7880
84
                    int boff = find_le32(peek_arr, sizeof(peek_arr), size);
7881
84
                    if (boff < 0
7882
48
                    || sizeof(peek_arr) < (boff + sizeof(b_info))) {
7883
41
                        throwCantUnpack("b_info corrupted");
7884
41
                    }
7885
43
                    bp = (b_info *)(void *)&peek_arr[boff];
7886
7887
43
                    sz_unc = get_le32(&bp->sz_unc);
7888
43
                    sz_cpr = get_le32(&bp->sz_cpr);
7889
43
                    word3  = get_le32(&bp->b_method);
7890
43
                    ftid = bp->b_ftid;
7891
43
                    cto8 = bp->b_cto8;
7892
43
                    if (0 <= boff  // found
7893
43
                    && ( ((sz_cpr == sz_unc) && (0 == word3) && (size == sz_unc)) // incompressible literal
7894
43
                      || ((sz_cpr <  sz_unc) && (0 == ftid) && (0 == cto8)
7895
35
                          && ((is_be ? bp->b_extra : bp->b_method) == prev_method)) )
7896
43
                    ) {
7897
30
                        pos -= H_PEEK;
7898
30
                        pos += boff;
7899
30
                        infoWarning("... recovery at %#zx", (size_t)pos);
7900
30
                        fi->seek(pos, SEEK_SET);
7901
30
                    }
7902
43
                    opt->info_mode--;
7903
43
                }
7904
213
            }
7905
172
            unpackExtent(size, fo,
7906
172
                c_adler, u_adler, false,
7907
172
                (hi_offset != get_te64(&phdr[j].p_offset)));
7908
172
        }
7909
749
    }
7910
7911
    // check for end-of-file
7912
518
    fi->readx(&bhdr, szb_info);
7913
518
    ph.set_method(bhdr.b_method, ~0u);
7914
518
    unsigned const sz_unc = ph.u_len = get_te32(&bhdr.sz_unc);
7915
7916
518
    if (sz_unc == 0) { // uncompressed size 0 -> EOF
7917
        // note: magic is always stored le32
7918
48
        unsigned const sz_cpr = get_le32(&bhdr.sz_cpr);
7919
48
        if (sz_cpr != UPX_MAGIC_LE32)  // sz_cpr must be h->magic
7920
11
            throwCompressedDataViolation();
7921
48
    }
7922
470
    else { // extra bytes after end?
7923
470
        throwCompressedDataViolation();
7924
470
    }
7925
7926
37
    if (is_shlib) {
7927
7
        un_DT_INIT(old_dtinit, (Elf64_Phdr *)(1+ (Elf64_Ehdr *)(void *)o_elfhdrs), dynhdr, fo);
7928
7
    }
7929
7930
    // update header with totals
7931
37
    ph.c_len = total_in;
7932
37
    ph.u_len = total_out;
7933
7934
    // all bytes must be written
7935
37
    if (fo && total_out != orig_file_size)
7936
1
        throwEOFException();
7937
7938
    // finally test the checksums
7939
36
    if (ph.c_adler != c_adler || ph.u_adler != u_adler)
7940
2
        throwChecksumError();
7941
36
}
7942
7943
7944
/*************************************************************************
7945
//
7946
**************************************************************************/
7947
7948
89.1k
PackLinuxElf32x86::PackLinuxElf32x86(InputFile *f) : super(f)
7949
89.1k
{
7950
89.1k
    e_machine = Elf32_Ehdr::EM_386;
7951
89.1k
    ei_class  = Elf32_Ehdr::ELFCLASS32;
7952
89.1k
    ei_data   = Elf32_Ehdr::ELFDATA2LSB;
7953
89.1k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
7954
89.1k
}
7955
7956
PackLinuxElf32x86::~PackLinuxElf32x86()
7957
88.1k
{
7958
88.1k
}
7959
7960
tribool PackLinuxElf32x86::canUnpack() // bool, except -1: format known, but not packed
7961
88.1k
{
7962
88.1k
    if (super::canUnpack()) {
7963
365
        return true;
7964
365
    }
7965
87.8k
    return false;
7966
88.1k
}
7967
7968
Linker* PackLinuxElf32x86::newLinker() const
7969
0
{
7970
0
    return new ElfLinkerX86;
7971
0
}
7972
7973
45.1k
PackBSDElf32x86::PackBSDElf32x86(InputFile *f) : super(f)
7974
45.1k
{
7975
45.1k
    e_machine = Elf32_Ehdr::EM_386;
7976
45.1k
    ei_class  = Elf32_Ehdr::ELFCLASS32;
7977
45.1k
    ei_data   = Elf32_Ehdr::ELFDATA2LSB;
7978
45.1k
}
7979
7980
PackBSDElf32x86::~PackBSDElf32x86()
7981
{
7982
}
7983
7984
23.0k
PackFreeBSDElf32x86::PackFreeBSDElf32x86(InputFile *f) : super(f)
7985
23.0k
{
7986
23.0k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_FREEBSD;
7987
23.0k
}
7988
7989
PackFreeBSDElf32x86::~PackFreeBSDElf32x86()
7990
{
7991
}
7992
7993
22.0k
PackNetBSDElf32x86::PackNetBSDElf32x86(InputFile *f) : super(f)
7994
22.0k
{
7995
22.0k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_NETBSD;
7996
22.0k
    osabi_note = "NetBSD";
7997
22.0k
}
7998
7999
PackNetBSDElf32x86::~PackNetBSDElf32x86()
8000
{
8001
}
8002
8003
22.0k
PackOpenBSDElf32x86::PackOpenBSDElf32x86(InputFile *f) : super(f)
8004
22.0k
{
8005
22.0k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_OPENBSD;
8006
22.0k
    osabi_note = "OpenBSD";
8007
22.0k
}
8008
8009
PackOpenBSDElf32x86::~PackOpenBSDElf32x86()
8010
{
8011
}
8012
8013
int const *
8014
PackLinuxElf32x86::getFilters() const
8015
0
{
8016
0
    static const int filters[] = {
8017
        // 0x49 is 5-byte CALL or JMP, and 6-byte Jxx
8018
        // 0x46 is 5-byte CALL or JMP
8019
0
        0x49, 0x46,
8020
// FIXME 2002-11-11: We use stub/fold_elf86.asm, which calls the
8021
// decompressor multiple times, and unfilter is independent of decompress.
8022
// Currently only filters 0x49, 0x46, 0x80..0x87 can handle this;
8023
// and 0x80..0x87 are regarded as "untested".
8024
#if 0
8025
        0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
8026
#endif
8027
#if 0
8028
        0x83, 0x36, 0x26,
8029
              0x86, 0x80,
8030
        0x84, 0x87, 0x81,
8031
        0x82, 0x85,
8032
        0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
8033
#endif
8034
0
    FT_END };
8035
0
    return filters;
8036
0
}
8037
8038
18.8k
PackLinuxElf32armLe::PackLinuxElf32armLe(InputFile *f) : super(f)
8039
18.8k
{
8040
18.8k
    e_machine = Elf32_Ehdr::EM_ARM;
8041
18.8k
    ei_class  = Elf32_Ehdr::ELFCLASS32;
8042
18.8k
    ei_data   = Elf32_Ehdr::ELFDATA2LSB;
8043
18.8k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_ARM;
8044
18.8k
}
8045
8046
PackLinuxElf32armLe::~PackLinuxElf32armLe()
8047
18.8k
{
8048
18.8k
}
8049
8050
14.3k
PackLinuxElf32mipseb::PackLinuxElf32mipseb(InputFile *f) : super(f)
8051
14.3k
{
8052
14.3k
    e_machine = Elf32_Ehdr::EM_MIPS;
8053
14.3k
    ei_class  = Elf32_Ehdr::ELFCLASS32;
8054
14.3k
    ei_data   = Elf32_Ehdr::ELFDATA2MSB;
8055
14.3k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
8056
14.3k
}
8057
8058
PackLinuxElf32mipseb::~PackLinuxElf32mipseb()
8059
14.3k
{
8060
14.3k
}
8061
8062
14.4k
PackLinuxElf32mipsel::PackLinuxElf32mipsel(InputFile *f) : super(f)
8063
14.4k
{
8064
14.4k
    e_machine = Elf32_Ehdr::EM_MIPS;
8065
14.4k
    ei_class  = Elf32_Ehdr::ELFCLASS32;
8066
14.4k
    ei_data   = Elf32_Ehdr::ELFDATA2LSB;
8067
14.4k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_LINUX;
8068
14.4k
}
8069
8070
PackLinuxElf32mipsel::~PackLinuxElf32mipsel()
8071
14.4k
{
8072
14.4k
}
8073
8074
Linker* PackLinuxElf32armLe::newLinker() const
8075
0
{
8076
0
    return new ElfLinkerArmLE();
8077
0
}
8078
8079
Linker* PackLinuxElf32mipseb::newLinker() const
8080
0
{
8081
0
    return new ElfLinkerMipsBE();
8082
0
}
8083
8084
Linker* PackLinuxElf32mipsel::newLinker() const
8085
0
{
8086
0
    return new ElfLinkerMipsLE();
8087
0
}
8088
8089
18.8k
PackLinuxElf32armBe::PackLinuxElf32armBe(InputFile *f) : super(f)
8090
18.8k
{
8091
18.8k
    e_machine = Elf32_Ehdr::EM_ARM;
8092
18.8k
    ei_class  = Elf32_Ehdr::ELFCLASS32;
8093
18.8k
    ei_data   = Elf32_Ehdr::ELFDATA2MSB;
8094
18.8k
    ei_osabi  = Elf32_Ehdr::ELFOSABI_ARM;
8095
18.8k
}
8096
8097
PackLinuxElf32armBe::~PackLinuxElf32armBe()
8098
16.8k
{
8099
16.8k
}
8100
8101
Linker* PackLinuxElf32armBe::newLinker() const
8102
0
{
8103
0
    return new ElfLinkerArmBE();
8104
0
}
8105
8106
unsigned
8107
PackLinuxElf32::elf_get_offset_from_address(unsigned addr) const
8108
19.4k
{
8109
19.4k
    return elf_get_offset_from_Phdrs(addr, phdri);
8110
19.4k
}
8111
8112
unsigned
8113
PackLinuxElf32::elf_get_offset_from_Phdrs(unsigned addr, Elf32_Phdr const *phdr0) const
8114
19.4k
{
8115
19.4k
    Elf32_Phdr const *phdr = phdr0;
8116
19.4k
    int j = e_phnum;
8117
52.5k
    for (; --j>=0; ++phdr) if (is_LOAD(phdr)) {
8118
22.4k
        unsigned const t = addr - get_te32(&phdr->p_vaddr);
8119
22.4k
        if (t < get_te32(&phdr->p_filesz)) {
8120
19.3k
            unsigned const p_offset = get_te32(&phdr->p_offset);
8121
19.3k
            if (file_size_u <= p_offset) { // FIXME: weak
8122
11
                char msg[40]; snprintf(msg, sizeof(msg),
8123
11
                    "bad Elf32_Phdr[%d].p_offset %x",
8124
11
                    -1+ e_phnum - j, p_offset);
8125
11
                throwCantPack(msg);
8126
11
            }
8127
19.2k
            return t + p_offset;
8128
19.3k
        }
8129
22.4k
    }
8130
147
    return 0;
8131
19.4k
}
8132
8133
u32_t  // returns .p_offset
8134
PackLinuxElf32::check_pt_load(Elf32_Phdr const *const phdr)
8135
6.59k
{
8136
6.59k
    u32_t filesz = get_te32(&phdr->p_filesz);
8137
6.59k
    u32_t offset = get_te32(&phdr->p_offset), offend = filesz + offset;
8138
6.59k
    u32_t vaddr  = get_te32(&phdr->p_vaddr);
8139
6.59k
    u32_t paddr  = get_te32(&phdr->p_paddr);
8140
6.59k
    u32_t align  = get_te32(&phdr->p_align);
8141
8142
6.59k
    if ((-1+ align) & (paddr ^ vaddr)
8143
6.51k
    ||  file_size_u32 <= (u32_t)offset
8144
6.46k
    ||  file_size_u32 <  (u32_t)offend
8145
6.38k
    ||  file_size_u32 <  (u32_t)filesz) {
8146
254
        char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
8147
254
            (unsigned)(phdr - phdri));
8148
254
        throwCantPack(msg);
8149
254
    }
8150
6.34k
    return offset;
8151
6.59k
}
8152
8153
Elf32_Dyn const *
8154
PackLinuxElf32::elf_has_dynamic(unsigned int key) const
8155
0
{
8156
0
    Elf32_Dyn const *dynp= dynseg;
8157
0
    if (dynp)
8158
0
    for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te32(&dynp->d_tag)==key) {
8159
0
        return dynp;
8160
0
    }
8161
0
    return nullptr;
8162
0
}
8163
8164
unsigned  // checked .p_offset; sz_dynseg set
8165
PackLinuxElf32::check_pt_dynamic(Elf32_Phdr const *const phdr)
8166
4.22k
{
8167
4.22k
    unsigned t = get_te32(&phdr->p_offset), s = sizeof(Elf32_Dyn) + t;
8168
4.22k
    unsigned vaddr = get_te32(&phdr->p_vaddr);
8169
4.22k
    unsigned filesz = get_te32(&phdr->p_filesz), memsz = get_te32(&phdr->p_memsz);
8170
4.22k
    unsigned align = get_te32(&phdr->p_align);
8171
4.22k
    if (file_size_u < t || s < t
8172
4.18k
    ||  file_size_u < filesz
8173
4.14k
    ||  file_size_u < (filesz + t)
8174
4.13k
    ||  t < (e_phnum*sizeof(Elf32_Phdr) + sizeof(Elf32_Ehdr))
8175
4.07k
    ||  (3 & t) || (7 & (filesz | memsz))  // .balign 4; 8==sizeof(Elf32_Dyn)
8176
4.06k
    ||  (-1+ align) & (t ^ vaddr)
8177
4.03k
    ||  file_size_u <= memsz
8178
3.99k
    ||  filesz < sizeof(Elf32_Dyn)
8179
3.98k
    ||  memsz  < sizeof(Elf32_Dyn)
8180
3.98k
    ||  filesz < memsz) {
8181
260
        char msg[50]; snprintf(msg, sizeof(msg), "bad PT_DYNAMIC phdr[%u]",
8182
260
            (unsigned)(phdr - phdri));
8183
260
        throwCantPack(msg);
8184
260
    }
8185
3.96k
    sz_dynseg = memsz;
8186
3.96k
    return t;
8187
4.22k
}
8188
8189
Elf32_Dyn *PackLinuxElf32::elf_find_dynptr(unsigned int key) const
8190
36.2k
{
8191
36.2k
    Elf32_Dyn *dynp= dynseg;
8192
36.2k
    if (dynp) {
8193
31.2k
        Elf32_Dyn *const last = (Elf32_Dyn *)(sz_dynseg + (char *)dynseg);
8194
581k
        for (; dynp < last; ++dynp) {
8195
578k
            if (get_te32(&dynp->d_tag)==key) {
8196
18.0k
                return dynp;
8197
18.0k
            }
8198
560k
            if (Elf32_Dyn::DT_NULL == dynp->d_tag) {
8199
10.9k
                return nullptr;
8200
10.9k
            }
8201
560k
        }
8202
31.2k
    }
8203
7.31k
    return nullptr;
8204
36.2k
}
8205
8206
Elf64_Dyn *PackLinuxElf64::elf_find_dynptr(unsigned int key) const
8207
24.7k
{
8208
24.7k
    Elf64_Dyn *dynp= dynseg;
8209
24.7k
    if (dynp) {
8210
21.9k
        Elf64_Dyn *const last = (Elf64_Dyn *)(sz_dynseg + (char *)dynseg);
8211
200k
        for (; dynp < last; ++dynp) {
8212
198k
            if (get_te64(&dynp->d_tag)==key) {
8213
10.8k
                return dynp;
8214
10.8k
            }
8215
187k
            if (Elf64_Dyn::DT_NULL == dynp->d_tag) {
8216
8.92k
                return nullptr;
8217
8.92k
            }
8218
187k
        }
8219
21.9k
    }
8220
4.96k
    return nullptr;
8221
24.7k
}
8222
8223
void *
8224
PackLinuxElf32::elf_find_dynamic(unsigned int key) const
8225
18.6k
{
8226
18.6k
    Elf32_Dyn const *dynp= elf_find_dynptr(key);
8227
18.6k
    if (dynp) {
8228
11.9k
        unsigned const t= elf_get_offset_from_address(get_te32(&dynp->d_val));
8229
11.9k
        if (t && t < file_size_u) {
8230
11.6k
            return t + file_image;
8231
11.6k
        }
8232
11.9k
    }
8233
7.07k
    return nullptr;
8234
18.6k
}
8235
8236
void *
8237
PackLinuxElf64::elf_find_dynamic(unsigned int key) const
8238
10.7k
{
8239
10.7k
    Elf64_Dyn const *dynp= elf_find_dynptr(key);
8240
10.7k
    if (dynp) {
8241
6.87k
        upx_uint64_t const t= elf_get_offset_from_address(get_te64(&dynp->d_val));
8242
6.87k
        if (t && t < file_size_u) {
8243
6.61k
            return t + file_image;
8244
6.61k
        }
8245
6.87k
    }
8246
4.16k
    return nullptr;
8247
10.7k
}
8248
8249
upx_uint64_t
8250
PackLinuxElf64::elf_unsigned_dynamic(unsigned int key) const
8251
13.9k
{
8252
13.9k
    Elf64_Dyn const *dynp= elf_find_dynptr(key);
8253
13.9k
    if (dynp) {
8254
3.93k
        return get_te64(&dynp->d_val);
8255
3.93k
    }
8256
9.98k
    return 0;
8257
13.9k
}
8258
8259
upx_uint64_t
8260
PackLinuxElf32::elf_unsigned_dynamic(unsigned int key) const
8261
17.5k
{
8262
17.5k
    Elf32_Dyn const *dynp= elf_find_dynptr(key);
8263
17.5k
    if (dynp) {
8264
6.10k
        return get_te32(&dynp->d_val);
8265
6.10k
    }
8266
11.4k
    return 0;
8267
17.5k
}
8268
8269
upx_uint64_t
8270
PackLinuxElf64::elf_get_offset_from_address(upx_uint64_t addr) const
8271
12.4k
{
8272
12.4k
    Elf64_Phdr const *phdr = phdri;
8273
12.4k
    int j = e_phnum;
8274
46.8k
    for (; --j>=0; ++phdr) if (is_LOAD(phdr)) {
8275
15.5k
        upx_uint64_t const t = addr - get_te64(&phdr->p_vaddr);
8276
15.5k
        if (t < get_te64(&phdr->p_filesz)) {
8277
12.3k
            upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
8278
12.3k
            if (file_size_u <= p_offset) { // FIXME: weak
8279
135
                char msg[40]; snprintf(msg, sizeof(msg),
8280
135
                    "bad Elf64_Phdr[%d].p_offset %#lx",
8281
135
                    -1+ e_phnum - j, (long unsigned)p_offset);
8282
135
                throwCantPack(msg);
8283
135
            }
8284
12.2k
            return t + p_offset;
8285
12.3k
        }
8286
15.5k
    }
8287
87
    return 0;
8288
12.4k
}
8289
8290
u64_t  // returns .p_offset
8291
PackLinuxElf64::check_pt_load(Elf64_Phdr const *const phdr)
8292
4.85k
{
8293
4.85k
    u64_t filesz = get_te64(&phdr->p_filesz);
8294
4.85k
    u64_t offset = get_te64(&phdr->p_offset), offend = filesz + offset;
8295
4.85k
    u64_t vaddr  = get_te64(&phdr->p_vaddr);
8296
4.85k
    u64_t paddr  = get_te64(&phdr->p_paddr);
8297
4.85k
    u64_t align  = get_te64(&phdr->p_align);
8298
8299
4.85k
    if ((-1+ align) & (paddr ^ vaddr)
8300
4.58k
    ||  file_size_u <= (u64_t)offset
8301
4.38k
    ||  file_size_u <  (u64_t)offend
8302
4.24k
    ||  file_size_u <  (u64_t)filesz) {
8303
663
        char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
8304
663
            (unsigned)(phdr - phdri));
8305
663
        throwCantPack(msg);
8306
663
    }
8307
4.18k
    return offset;
8308
4.85k
}
8309
8310
Elf64_Dyn const *
8311
PackLinuxElf64::elf_has_dynamic(unsigned int key) const
8312
0
{
8313
0
    Elf64_Dyn const *dynp= dynseg;
8314
0
    if (dynp)
8315
0
    for (; Elf64_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te64(&dynp->d_tag)==key) {
8316
0
        return dynp;
8317
0
    }
8318
0
    return nullptr;
8319
0
}
8320
8321
upx_uint64_t  // checked .p_offset; sz_dynseg set
8322
PackLinuxElf64::check_pt_dynamic(Elf64_Phdr const *const phdr)
8323
4.17k
{
8324
4.17k
    upx_uint64_t t = get_te64(&phdr->p_offset), s = sizeof(Elf64_Dyn) + t;
8325
4.17k
    upx_uint64_t vaddr = get_te64(&phdr->p_vaddr);
8326
4.17k
    upx_uint64_t filesz = get_te64(&phdr->p_filesz), memsz = get_te64(&phdr->p_memsz);
8327
4.17k
    upx_uint64_t align = get_te64(&phdr->p_align);
8328
4.17k
    if (file_size_u < t || s < t
8329
4.06k
    ||  file_size_u < filesz
8330
3.88k
    ||  file_size_u < (filesz + t)
8331
3.87k
    ||  t < (e_phnum*sizeof(Elf64_Phdr) + sizeof(Elf64_Ehdr))
8332
3.85k
    ||  (7 & t) || (0xf & (filesz | memsz))  // .balign 8; 16==sizeof(Elf64_Dyn)
8333
3.82k
    ||  (-1+ align) & (t ^ vaddr)
8334
3.71k
    ||  file_size_u <= memsz
8335
3.53k
    ||  filesz < sizeof(Elf64_Dyn)
8336
3.53k
    ||  memsz  < sizeof(Elf64_Dyn)
8337
3.53k
    ||  filesz < memsz) {
8338
659
        char msg[50]; snprintf(msg, sizeof(msg), "bad PT_DYNAMIC phdr[%u]",
8339
659
            (unsigned)(phdr - phdri));
8340
659
        throwCantPack(msg);
8341
659
    }
8342
3.52k
    sz_dynseg = memsz;
8343
3.52k
    return t;
8344
4.17k
}
8345
8346
void
8347
PackLinuxElf64::sort_DT64_offsets(Elf64_Dyn const *const dynp0)
8348
2.83k
{
8349
2.83k
    mb_dt_offsets.alloc(sizeof(unsigned) * sizeof(dt_keys)/sizeof(dt_keys[0]));
8350
2.83k
    mb_dt_offsets.clear();
8351
2.83k
    dt_offsets = (unsigned *)mb_dt_offsets.getVoidPtr();
8352
2.83k
    unsigned n_off = 0, k;
8353
34.0k
    for (unsigned j=0; ((k = dt_keys[j]),  k); ++j) {
8354
31.5k
        dt_offsets[n_off] = 0;  // default to "not found"
8355
31.5k
        u64_t rva = 0;
8356
31.5k
        if (k < DT_NUM) { // in range of easy table
8357
20.7k
            if (!dt_table[k]) {
8358
12.9k
                continue;
8359
12.9k
            }
8360
7.81k
            rva = get_te64(&dynp0[-1+ dt_table[k]].d_val);
8361
7.81k
        }
8362
10.7k
        else if (file_image) { // why is this guard necessary?
8363
10.7k
            rva = elf_unsigned_dynamic(k);  // zero if not found
8364
10.7k
        }
8365
18.5k
        if (!rva) { // not present in input
8366
9.28k
            continue;
8367
9.28k
        }
8368
9.31k
        Elf64_Phdr const *const phdr = elf_find_Phdr_for_va(rva, phdri, e_phnum);
8369
9.31k
        if (!phdr) {
8370
301
            char msg[60]; snprintf(msg, sizeof(msg), "bad DT_{%#x} = %#llx (no Phdr)",
8371
301
                k, rva);
8372
301
            throwCantPack(msg);
8373
301
        }
8374
9.01k
        dt_offsets[n_off] = (rva - get_te64(&phdr->p_vaddr)) + get_te64(&phdr->p_offset);
8375
8376
9.01k
        if (file_size <= dt_offsets[n_off]) {
8377
56
            char msg[60]; snprintf(msg, sizeof(msg), "bad DT_{%#x} = %#x (beyond EOF)",
8378
56
                k, dt_offsets[n_off]);
8379
56
                throwCantPack(msg);
8380
56
        }
8381
8.95k
        n_off += !!dt_offsets[n_off];
8382
8.95k
    }
8383
2.47k
    dt_offsets[n_off++] = file_size;  // sentinel
8384
2.47k
    upx_qsort(dt_offsets, n_off, sizeof(dt_offsets[0]), qcmp_unsigned);
8385
2.47k
}
8386
8387
unsigned PackLinuxElf64::find_dt_ndx(u64_t rva)
8388
4.11k
{
8389
4.11k
    unsigned *const dto = (unsigned *)mb_dt_offsets.getVoidPtr();
8390
4.11k
    unsigned const dto_size = mb_dt_offsets.getSize() / sizeof(*dto);
8391
9.84k
    for (unsigned j = 0; j < dto_size && dto[j]; ++j) { // linear search of short table
8392
9.65k
        if (rva == dto[j]) {
8393
3.93k
            return j;
8394
3.93k
        }
8395
9.65k
    }
8396
183
    return ~0u;
8397
4.11k
}
8398
8399
unsigned PackLinuxElf64::elf_find_table_size(unsigned dt_type, unsigned sh_type)
8400
4.45k
{
8401
4.45k
    Elf64_Shdr const *sec = elf_find_section_type(sh_type);
8402
4.45k
    if (sec) { // Cheat the easy way: use _Shdr.  (No _Shdr anyway for de-compression)
8403
0
        return get_te64(&sec->sh_size);
8404
0
    }
8405
    // Honest hard work: use _Phdr
8406
4.45k
    unsigned x_rva;
8407
4.45k
    if (dt_type < DT_NUM) {
8408
3.33k
        unsigned const x_ndx = dt_table[dt_type];
8409
3.33k
        if (!x_ndx) { // no such entry
8410
333
            return 0;
8411
333
        }
8412
3.00k
        x_rva = get_te64(&dynseg[-1+ x_ndx].d_val);
8413
3.00k
    }
8414
1.12k
    else {
8415
1.12k
        x_rva = elf_unsigned_dynamic(dt_type);
8416
1.12k
    }
8417
4.12k
    Elf64_Phdr const *const x_phdr = elf_find_Phdr_for_va(x_rva, phdri, e_phnum);
8418
4.12k
    if (!x_phdr)
8419
12
        return ~0u;  // corrupted Phdrs?
8420
4.11k
    unsigned const           d_off =             x_rva - get_te64(&x_phdr->p_vaddr);
8421
4.11k
    unsigned const           y_ndx = find_dt_ndx(d_off + get_te64(&x_phdr->p_offset));
8422
4.11k
    if (~0u != y_ndx) {
8423
3.93k
        return dt_offsets[1+ y_ndx] - dt_offsets[y_ndx];
8424
3.93k
    }
8425
183
    return ~0u;
8426
4.11k
}
8427
8428
void
8429
PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway)
8430
3.52k
{
8431
3.52k
    if (dt_table[Elf64_Dyn::DT_NULL]) {
8432
356
        return;  // not 1st time; do not change upx_dt_init
8433
356
    }
8434
3.16k
    Elf64_Dyn const *const dynp0 = dynp;
8435
3.16k
    unsigned ndx = 0;
8436
3.16k
    unsigned const limit = headway / sizeof(*dynp);
8437
3.16k
    if (dynp)
8438
36.4k
    for (; ; ++ndx, ++dynp) {
8439
36.4k
        if (limit <= ndx) {
8440
11
            throwCantPack("DT_NULL not found");
8441
11
        }
8442
36.4k
        upx_uint64_t const d_tag = get_te64(&dynp->d_tag);
8443
36.4k
        if (d_tag>>32) { // outrageous
8444
217
            throwCantPack("bad Elf64_Dyn[%d].d_tag %#lx",
8445
217
                ndx, (long unsigned)d_tag);
8446
217
        }
8447
36.2k
        if (d_tag < DT_NUM) {
8448
24.0k
            if (Elf64_Dyn::DT_NEEDED != d_tag
8449
22.3k
            &&  dt_table[d_tag]
8450
311
            &&    get_te64(&dynp->d_val)
8451
311
               != get_te64(&dynp0[-1+ dt_table[d_tag]].d_val)) {
8452
103
                throwCantPack("duplicate DT_%#x: [%#x] [%#x]",
8453
103
                    (unsigned)d_tag, -1+ dt_table[d_tag], ndx);
8454
103
            }
8455
23.9k
            dt_table[d_tag] = 1+ ndx;
8456
23.9k
        }
8457
36.1k
        if (Elf64_Dyn::DT_NULL == d_tag) {
8458
2.83k
            break;  // check here so that dt_table[DT_NULL] is set
8459
2.83k
        }
8460
36.1k
    }
8461
2.83k
    sort_DT64_offsets(dynp0);
8462
8463
2.83k
    upx_dt_init = 0;
8464
2.83k
         if (dt_table[Elf64_Dyn::DT_INIT])          upx_dt_init = Elf64_Dyn::DT_INIT;
8465
2.30k
    else if (dt_table[Elf64_Dyn::DT_PREINIT_ARRAY]) upx_dt_init = Elf64_Dyn::DT_PREINIT_ARRAY;
8466
2.05k
    else if (dt_table[Elf64_Dyn::DT_INIT_ARRAY])    upx_dt_init = Elf64_Dyn::DT_INIT_ARRAY;
8467
8468
2.83k
    unsigned const z_str = dt_table[Elf64_Dyn::DT_STRSZ];
8469
2.83k
    strtab_max = !z_str ? 0 : get_te64(&dynp0[-1+ z_str].d_val);
8470
2.83k
    unsigned const z_tab = dt_table[Elf64_Dyn::DT_STRTAB];
8471
2.83k
    unsigned const tmp1 = !z_tab ? 0 : get_te64(&dynp0[-1+ z_tab].d_val);
8472
2.83k
    if (tmp1 < sz_elf_hdrs) {
8473
85
        throwCantPack("bad DT_STRTAB %#x", tmp1);
8474
85
    }
8475
2.75k
    unsigned const strtab_beg = !z_tab ? 0 : elf_get_offset_from_address(tmp1);
8476
8477
2.75k
    if (!z_str || !z_tab || !(strtab_max + strtab_beg)
8478
2.22k
    || (this->file_size - strtab_beg) < strtab_max  // strtab overlaps EOF
8479
        // last string in table must have terminating NUL
8480
2.16k
    ||  '\0' != ((char *)file_image.getVoidPtr())[-1+ strtab_max + strtab_beg]
8481
2.75k
    ) {
8482
105
        throwCantPack("bad DT_STRSZ %#x", strtab_max);
8483
105
    }
8484
8485
2.64k
    { // Find end of DT_SYMTAB
8486
2.64k
        unsigned const tmp2 = elf_find_table_size(Elf64_Dyn::DT_SYMTAB,
8487
2.64k
            Elf64_Shdr::SHT_DYNSYM);
8488
2.64k
        symnum_max = (~0u == tmp2) ? 0 : tmp2 / sizeof(Elf64_Sym);
8489
2.64k
    }
8490
8491
2.64k
    unsigned v_sym = dt_table[Elf64_Dyn::DT_SYMTAB];
8492
2.64k
    if (v_sym) {
8493
1.82k
        v_sym = elf_get_offset_from_address(get_te64(&dynp0[-1+ v_sym].d_val));
8494
1.82k
    }
8495
8496
2.64k
    unsigned v_hsh = dt_table[Elf64_Dyn::DT_HASH];
8497
2.64k
    if (v_hsh) {
8498
1.34k
        v_hsh = elf_get_offset_from_address(get_te64(&dynp0[-1+ v_hsh].d_val));
8499
1.34k
    }
8500
2.64k
    if (v_hsh && file_image) {
8501
1.31k
        hashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_HASH);
8502
1.31k
        if (!hashtab) {
8503
133
            throwCantPack("bad DT_HASH %#x", v_hsh);
8504
133
        }
8505
        // Find end of DT_HASH
8506
1.18k
        hashend = (unsigned const *)(void const *)(elf_find_table_size(
8507
1.18k
            Elf64_Dyn::DT_HASH, Elf64_Shdr::SHT_HASH) + (char const *)hashtab);
8508
1.18k
        if (!hashtab || (char const *)hashend <= (char const *)&hashtab[2]
8509
1.17k
        ||  file_image.getSizeInBytes()
8510
1.17k
            < (unsigned)((char const *)&hashtab[2] - (char *)&file_image[0]) )
8511
8
        {
8512
8
            throwCantPack("bad DT_HASH %#x", v_hsh);
8513
8
        }
8514
8515
1.17k
        unsigned const nbucket = get_te32(&hashtab[0]);
8516
1.17k
        unsigned const *const buckets = &hashtab[2];
8517
1.17k
        unsigned const *const chains = &buckets[nbucket]; (void)chains;
8518
1.17k
        if ((unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image))
8519
1.17k
                <= sizeof(unsigned)*nbucket ) {
8520
57
            throwCantPack("bad nbucket %#x\n", nbucket);
8521
57
        }
8522
8523
1.11k
        if ((unsigned)(hashend - buckets) < nbucket
8524
1.10k
        || !v_sym || file_size_u <= v_sym
8525
1.09k
        || ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket))
8526
1.11k
        ) {
8527
47
            throwCantPack("bad DT_HASH nbucket=%#x  len=%#x",
8528
47
                nbucket, (v_sym - v_hsh));
8529
47
        }
8530
1.06k
        unsigned chmax = 0;
8531
221k
        for (unsigned j= 0; j < nbucket; ++j) {
8532
220k
            unsigned x = get_te32(&buckets[j]);
8533
220k
            if (chmax < x) {
8534
2.71k
                chmax = x;
8535
2.71k
            }
8536
220k
        }
8537
1.06k
        if ((v_hsh < v_sym) && (v_sym - v_hsh) <
8538
783
                (sizeof(*buckets)*(2+ nbucket) + sizeof(*chains)*(1+ chmax))) {
8539
80
            throwCantPack("bad DT_HASH nbucket=%#x  len=%#x",
8540
80
                nbucket, (v_sym - v_hsh));
8541
80
        }
8542
1.06k
    }
8543
2.32k
    unsigned const v_gsh = elf_unsigned_dynamic(Elf64_Dyn::DT_GNU_HASH);
8544
2.32k
    if (v_gsh && file_image) {
8545
        // Not similar to DT_HASH because DT_GNU_HASH is not small (0x6ffffef5).
8546
1.12k
        gashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_GNU_HASH);
8547
1.12k
        gashend = (unsigned const *)(void const *)(elf_find_table_size(
8548
1.12k
            Elf64_Dyn::DT_GNU_HASH, Elf64_Shdr::SHT_GNU_HASH) + (char const *)gashtab);
8549
1.12k
        if (!gashtab || (char const *)gashend <= (char const *)&gashtab[4]
8550
1.07k
        ||  file_image.getSizeInBytes()
8551
1.07k
            < (unsigned)((char const *)&gashtab[4] - (char *)&file_image[0]) )
8552
55
        {
8553
55
            throwCantPack("bad DT_GNU_HASH %#x", v_gsh);
8554
55
        }
8555
8556
1.07k
        unsigned const n_bucket = get_te32(&gashtab[0]);
8557
1.07k
        unsigned const symbias  = get_te32(&gashtab[1]);
8558
1.07k
        unsigned const n_bitmask = get_te32(&gashtab[2]);
8559
1.07k
        unsigned const gnu_shift = get_te32(&gashtab[3]);
8560
1.07k
        upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4];
8561
1.07k
        unsigned     const *const buckets = (unsigned const *)&bitmask[n_bitmask];
8562
1.07k
        unsigned     const *const hasharr = &buckets[n_bucket]; (void)hasharr;
8563
1.07k
        if (!n_bucket || (1u<<31) <= n_bucket  /* fie on fuzzers */
8564
986
        || (unsigned)(gashend - buckets) < n_bucket
8565
957
        || (file_size + file_image) <= (void const *)hasharr) {
8566
160
            throwCantPack("bad n_bucket %#x\n", n_bucket);
8567
160
        }
8568
        // It would be better to detect zeroes shifted into low 6 bits of:
8569
        //    (077 & (hash_32 >> gnu_shift))
8570
        // but compilers can be stupid.
8571
910
        if (31 < gnu_shift) {
8572
34
            throwCantPack("bad gnu_shift %#x", gnu_shift);
8573
34
        }
8574
        // unsigned const *const gashend = &hasharr[n_bucket];
8575
        // minimum, except:
8576
        // Rust and Android trim unused zeroes from high end of hasharr[]
8577
876
        unsigned bmax = 0;
8578
112k
        for (unsigned j= 0; j < n_bucket; ++j) {
8579
112k
            unsigned bj = get_te32(&buckets[j]);
8580
112k
            if (bj) {
8581
87.7k
                if (bj < symbias) {
8582
13
                    throwCantPack("bad DT_GNU_HASH bucket[%d] < symbias{%#x}\n",
8583
13
                            bj, symbias);
8584
13
                }
8585
87.7k
                if (bmax < bj) {
8586
3.05k
                    bmax = bj;
8587
3.05k
                }
8588
87.7k
            }
8589
112k
        }
8590
863
        if (1==n_bucket  && 0==buckets[0]
8591
179
        &&  1==n_bitmask && 0==bitmask[0]) {
8592
            // 2021-09-11 Rust on RaspberryPi apparently uses this to minimize space.
8593
            // But then the DT_GNU_HASH symbol lookup algorithm always fails?
8594
            // https://github.com/upx/upx/issues/525
8595
39
        } else
8596
824
        if (bmax) {
8597
675
            if ((1+ bmax) < symbias) {
8598
7
                throwCantPack("bad DT_GNU_HASH (1+ max_bucket)=%#x < symbias=%#x",
8599
7
                    1+ bmax, symbias);
8600
7
            }
8601
668
            bmax -= symbias;
8602
668
        }
8603
8604
856
        unsigned r = 0;
8605
856
        if (!n_bucket || !n_bitmask || !v_sym
8606
795
        || (r=1, ((-1+ n_bitmask) & n_bitmask))  // not a power of 2
8607
753
        || (r=2, (8*sizeof(upx_uint64_t) <= gnu_shift))  // shifted result always == 0
8608
753
        || (r=3, (n_bucket>>30))  // fie on fuzzers
8609
753
        || (r=4, (n_bitmask>>30))
8610
753
        || (r=5, ((file_size/sizeof(unsigned))
8611
753
                <= ((sizeof(*bitmask)/sizeof(unsigned))*n_bitmask + 2*n_bucket)))  // FIXME: weak
8612
750
        || (r=6, ((v_gsh < v_sym) && (v_sym - v_gsh) < (sizeof(unsigned)*4  // headers
8613
436
                + sizeof(*bitmask)*n_bitmask  // bitmask
8614
436
                + sizeof(*buckets)*n_bucket  // buckets
8615
436
                + sizeof(*hasharr)*(!bmax ? 0 : (1+ bmax))  // hasharr
8616
436
            )) )
8617
856
        ) {
8618
166
            throwCantPack("bad DT_GNU_HASH n_bucket=%#x  n_bitmask=%#x  len=%#lx  r=%d",
8619
166
                n_bucket, n_bitmask, (long unsigned)(v_sym - v_gsh), r);
8620
166
        }
8621
856
    }
8622
1.88k
    e_shstrndx = get_te16(&ehdri.e_shstrndx);  // who omitted this?
8623
1.88k
    if (e_shnum <= e_shstrndx
8624
278
    &&  !(0==e_shnum && 0==e_shstrndx) ) {
8625
87
        throwCantPack("bad .e_shstrndx %d >= .e_shnum %d", e_shstrndx, e_shnum);
8626
87
    }
8627
1.88k
}
8628
8629
unsigned PackLinuxElf::gnu_hash(char const *q)
8630
2.14k
{
8631
2.14k
    unsigned char const *p = (unsigned char const *)q;
8632
2.14k
    unsigned h;
8633
8634
23.6k
    for (h= 5381; 0!=*p; ++p) {
8635
21.4k
        h += *p + (h << 5);
8636
21.4k
    }
8637
2.14k
    return h;
8638
2.14k
}
8639
8640
unsigned PackLinuxElf::elf_hash(char const *p)
8641
2.02k
{
8642
2.02k
    unsigned h;
8643
22.2k
    for (h= 0; 0!=*p; ++p) {
8644
20.2k
        h = *p + (h<<4);
8645
20.2k
        {
8646
20.2k
            unsigned const t = 0xf0000000u & h;
8647
20.2k
            h &= ~t;
8648
20.2k
            h ^= t>>24;
8649
20.2k
        }
8650
20.2k
    }
8651
2.02k
    return h;
8652
2.02k
}
8653
8654
Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
8655
3.75k
{
8656
3.75k
    if (hashtab && dynsym && dynstr) {
8657
1.68k
        unsigned const n_bucket = get_te32(&hashtab[0]);
8658
1.68k
        unsigned const *const buckets = &hashtab[2];
8659
1.68k
        unsigned const *const chains = &buckets[n_bucket];
8660
        // Find the end of DT_HASH and DT_DYNSYM. Perhaps elf_find_table_size()
8661
        // depends on too many valid input values?
8662
1.68k
        void const *l_hash = nullptr, *l_sym = nullptr;
8663
5.08k
        for (unsigned j = 0; j < DT_NUM; ++j) {
8664
5.08k
            void const *const ptr = dt_offsets[j] + (char const *)file_image.getVoidPtr();
8665
5.08k
            if (!l_hash && hashtab == ptr) {
8666
1.64k
                l_hash = dt_offsets[1+ j] + (char const *)file_image.getVoidPtr();
8667
1.64k
            }
8668
5.08k
            if (!l_sym && dynsym == ptr) {
8669
1.64k
                l_sym = dt_offsets[1+ j] + (char const *)file_image.getVoidPtr();
8670
1.64k
            }
8671
5.08k
            if (l_sym && l_hash)
8672
1.63k
                break;  // found both
8673
3.44k
            if (this->file_size == (off_t)dt_offsets[j])
8674
51
                break;  // end sentinel
8675
3.44k
        }
8676
1.68k
        if (n_bucket) {
8677
1.35k
            void const *EOM = file_size + (char const *)file_image.getVoidPtr();
8678
1.35k
            unsigned const m = elf_hash(name) % n_bucket;
8679
1.35k
            unsigned n_visit = 0;
8680
1.35k
            unsigned si;
8681
1.35k
            if (l_hash <= &buckets[m])
8682
7
                throwCantPack("bad DT_HASH %u", m);
8683
4.60k
            for (si= get_te32(&buckets[m]); si; si = get_te32(&chains[si])) {
8684
3.34k
                if (l_sym <= &dynsym[si])
8685
42
                    throwCantPack("bad DT_HASH chain %d\n", si);
8686
3.30k
                char const *const p= get_dynsym_name(si, (unsigned)-1);
8687
3.30k
                if (p && 0==strcmp(name, p))
8688
32
                    return &dynsym[si];
8689
3.27k
                if (l_sym <= &dynsym[n_visit++])
8690
13
                    throwCantPack("circular DT_HASH chain %d\n", si);
8691
                // Detect next si out-of-bounds
8692
3.25k
                if ((unsigned)((unsigned int const *)EOM - chains) <= si)
8693
2
                    throwCantPack("bad DT_HASH chain %d\n", si);
8694
3.25k
            }
8695
1.34k
        }
8696
1.68k
    }
8697
3.66k
    if (gashtab && dynsym && dynstr) {
8698
1.50k
        unsigned const n_bucket = get_te32(&gashtab[0]);
8699
1.50k
        unsigned const symbias  = get_te32(&gashtab[1]);
8700
1.50k
        unsigned const n_bitmask = get_te32(&gashtab[2]);
8701
1.50k
        unsigned const gnu_shift = get_te32(&gashtab[3]);
8702
1.50k
        unsigned const *const bitmask = &gashtab[4];
8703
1.50k
        unsigned const *const buckets = &bitmask[n_bitmask];
8704
1.50k
        unsigned const *const hasharr = &buckets[n_bucket];
8705
1.50k
        if (31 < gnu_shift) {
8706
36
            throwCantPack("bad gnu_shift %#x", gnu_shift);
8707
36
        }
8708
1.46k
        if ((file_size + file_image) <= (void const *)hasharr) {
8709
1
            throwCantPack("bad n_bucket %#x\n", n_bucket);
8710
1
        }
8711
1.46k
        if (!n_bitmask
8712
1.46k
        || (unsigned)(file_size - ((char const *)bitmask - (char const *)(void const *)file_image))
8713
1.46k
                <= sizeof(unsigned)*n_bitmask ) {
8714
1
            throwCantPack("bad n_bitmask %#x\n", n_bitmask);
8715
1
        }
8716
1.46k
        if (n_bucket) { // -rust-musl can have "empty" hashtab
8717
1.45k
            unsigned const h = gnu_hash(name);
8718
1.45k
            unsigned const hbit1 = 037& h;
8719
1.45k
            unsigned const hbit2 = 037& (h>>gnu_shift);
8720
1.45k
            unsigned const w = get_te32(&bitmask[(n_bitmask -1) & (h>>5)]);
8721
8722
1.45k
            if (1& (w>>hbit1) & (w>>hbit2)) {
8723
394
                unsigned const hhead = get_te32(&buckets[h % n_bucket]);
8724
394
                if (symnum_max <= hhead || (hhead && hhead < symbias)) {
8725
85
                    throwCantPack("bad DT_GNU_HASH symnum_max{%#x} <= buckets[%d]{%#x} < symbias{%#x}\n",
8726
85
                            symnum_max, h % n_bucket, hhead, symbias);
8727
85
                }
8728
309
                if (hhead) {
8729
205
                    Elf32_Sym const *dsp = &dynsym[hhead];
8730
205
                    unsigned const *hp = &hasharr[hhead - symbias];
8731
205
                    unsigned k;
8732
735
                    do {
8733
735
                        if (gashend <= hp) {
8734
22
                            throwCantPack("bad DT_GNU_HASH[%#x]  head=%u",
8735
22
                                (unsigned)(hp - hasharr), hhead);
8736
22
                        }
8737
713
                        k = get_te32(hp);
8738
713
                        if (0==((h ^ k)>>1)) {
8739
0
                            unsigned const st_name = get_te32(&dsp->st_name);
8740
0
                            char const *const p = get_str_name(st_name, (unsigned)-1);
8741
0
                            if (0==strcmp(name, p)) {
8742
0
                                return dsp;
8743
0
                            }
8744
0
                        }
8745
713
                    } while (++dsp, ++hp, 0==(1u& k));
8746
205
                }
8747
309
            }
8748
1.45k
        }
8749
1.46k
    }
8750
    // 2021-12-25  FIXME: Some Rust programs use
8751
    //    (1==n_bucket && 0==buckets[0] && 1==n_bitmask && 0==bitmask[0])
8752
    // to minimize space in DT_GNU_HASH. This causes the fancy lookup to fail.
8753
    // Is a fallback to linear search assumed?
8754
    // 2022-03-12  Some Rust programs have 0==n_bucket.
8755
3.51k
    return nullptr;
8756
8757
3.66k
}
8758
8759
Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const
8760
2.07k
{
8761
2.07k
    if (hashtab && dynsym && dynstr) {
8762
939
        unsigned const n_bucket = get_te32(&hashtab[0]);
8763
939
        unsigned const *const buckets = &hashtab[2];
8764
939
        unsigned const *const chains = &buckets[n_bucket];
8765
        // Find the end of DT_HASH and DT_DYNSYM. Perhaps elf_find_table_size()
8766
        // depends on too many valid input values?
8767
939
        void const *l_hash = nullptr, *l_sym = nullptr;
8768
3.06k
        for (unsigned j = 0; j < DT_NUM; ++j) {
8769
3.06k
            void const *const ptr = dt_offsets[j] + (char const *)file_image.getVoidPtr();
8770
3.06k
            if (!l_hash && hashtab == ptr) {
8771
884
                l_hash = dt_offsets[1+ j] + (char const *)file_image.getVoidPtr();
8772
884
            }
8773
3.06k
            if (!l_sym && dynsym == ptr) {
8774
922
                l_sym = dt_offsets[1+ j] + (char const *)file_image.getVoidPtr();
8775
922
            }
8776
3.06k
            if (l_sym && l_hash)
8777
872
                break;  // found both
8778
2.19k
            if (this->file_size == (off_t)dt_offsets[j])
8779
67
                break;  //end
8780
2.19k
        }
8781
939
        if (n_bucket) { // -rust-musl can have "empty" hashtab
8782
671
            void const *const EOM = file_size + (char const *)file_image.getVoidPtr();
8783
671
            unsigned const m = elf_hash(name) % n_bucket;
8784
671
            unsigned n_visit = 0;
8785
671
            unsigned si;
8786
671
            if (l_hash <= &buckets[m])
8787
46
                throwCantPack("bad DT_HASH %u", m);
8788
8.58k
            for (si= get_te32(&buckets[m]); si; si = get_te32(&chains[si])) {
8789
8.09k
                if (l_sym <= &dynsym[si])
8790
96
                    throwCantPack("bad DT_HASH chain %d\n", si);
8791
8.00k
                char const *const p= get_dynsym_name(si, (unsigned)-1);
8792
8.00k
                if (p && 0==strcmp(name, p))
8793
10
                    return &dynsym[si];
8794
7.99k
                if (l_sym <= &dynsym[n_visit++])
8795
24
                    throwCantPack("circular DT_HASH chain %d\n", si);
8796
                // Detect next si out-of-bounds
8797
7.96k
                if ((unsigned)((unsigned int const *)EOM - chains) <= si)
8798
6
                    throwCantPack("bad DT_HASH chain %d\n", si);
8799
7.96k
            }
8800
625
        }
8801
939
    }
8802
1.88k
    if (gashtab && dynsym && dynstr) {
8803
708
        unsigned const n_bucket = get_te32(&gashtab[0]);
8804
708
        unsigned const symbias  = get_te32(&gashtab[1]);
8805
708
        unsigned const n_bitmask = get_te32(&gashtab[2]);
8806
708
        unsigned const gnu_shift = get_te32(&gashtab[3]);
8807
708
        upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4];
8808
708
        unsigned     const *const buckets = (unsigned const *)&bitmask[n_bitmask];
8809
708
        unsigned     const *const hasharr = &buckets[n_bucket];
8810
8811
708
        if (31 < gnu_shift) {
8812
2
            throwCantPack("bad gnu_shift %#x", gnu_shift);
8813
2
        }
8814
706
        if ((file_size + file_image) <= (void const *)hasharr) {
8815
1
            throwCantPack("bad n_bucket %#x\n", n_bucket);
8816
1
        }
8817
705
        if (!n_bitmask
8818
704
        || (unsigned)(file_size - ((char const *)bitmask - (char const *)(void const *)file_image))
8819
704
                <= sizeof(unsigned)*n_bitmask ) {
8820
1
            throwCantPack("bad n_bitmask %#x\n", n_bitmask);
8821
1
        }
8822
704
        if (n_bucket) { // -rust-musl can have "empty" gashtab
8823
694
            unsigned const h = gnu_hash(name);
8824
694
            unsigned const hbit1 = 077& h;
8825
694
            unsigned const hbit2 = 077& (h>>gnu_shift);
8826
694
            upx_uint64_t const w = get_te64(&bitmask[(n_bitmask -1) & (h>>6)]);
8827
694
            if (1& (w>>hbit1) & (w>>hbit2)) {
8828
290
                unsigned hhead = get_te32(&buckets[h % n_bucket]);
8829
290
                if (symnum_max <= hhead || (hhead && hhead < symbias)) {
8830
83
                    throwCantPack("bad DT_GNU_HASH symnum_max{%#x} <= buckets[%d]{%#x} < symbias{%#x}\n",
8831
83
                            symnum_max, h % n_bucket, hhead, symbias);
8832
83
                }
8833
207
                if (hhead) {
8834
129
                    Elf64_Sym const *dsp = &dynsym[hhead];
8835
129
                    unsigned const *hp = &hasharr[hhead - symbias];
8836
129
                    unsigned k;
8837
1.44k
                    do {
8838
1.44k
                        if (gashend <= hp) {
8839
13
                            throwCantPack("bad gnu_hash[%#tx]  head=%u",
8840
13
                                hp - hasharr, hhead);
8841
13
                        }
8842
1.43k
                        k = get_te32(hp);
8843
1.43k
                        if (0==((h ^ k)>>1)) {
8844
0
                            unsigned const st_name = get_te32(&dsp->st_name);
8845
0
                            char const *const p = get_str_name(st_name, (unsigned)-1);
8846
0
                            if (0==strcmp(name, p)) {
8847
0
                                return dsp;
8848
0
                            }
8849
0
                        }
8850
1.43k
                    } while (++dsp, ++hp, 0==(1u& k));
8851
129
                }
8852
207
            }
8853
694
        }
8854
704
    }
8855
    // 2021-12-25  FIXME: Some Rust programs use
8856
    //    (1==n_bucket && 0==buckets[0] && 1==n_bitmask && 0==bitmask[0])
8857
    // to minimize space in DT_GNU_HASH. This causes the fancy lookup to fail.
8858
    // Is a fallback to linear search assumed?
8859
    // 2022-03-12  Some Rust programs have 0==n_bucket.
8860
1.78k
    return nullptr;
8861
8862
1.88k
}
8863
8864
void PackLinuxElf32::unpack(OutputFile *fo)
8865
789
{
8866
789
    if (e_phoff != sizeof(Elf32_Ehdr)) {// Phdrs not contiguous with Ehdr
8867
0
        throwCantUnpack("bad e_phoff");
8868
0
    }
8869
789
    unsigned const c_phnum = get_te16(&ehdri.e_phnum);
8870
789
    unsigned u_phnum = 0;
8871
789
    upx_uint32_t old_dtinit = 0;
8872
8873
789
    if (Elf32_Ehdr::ET_EXEC == get_te16(&ehdri.e_type)) {
8874
// 40fddf17153ee3db73a04ff1bf288b91676138d6 2001-02-01 ph.version 11; b_info 12 bytes
8875
// df9db96bd1c013c07da1d7ec740021d588ab2815 2001-01-17 ph.version 11; no b_info (==> 8 bytes)
8876
754
        if (ph.version <= 11
8877
2
        &&  get_te32(&ehdri.e_entry) < 0x401180
8878
1
        &&  get_te16(&ehdri.e_machine)==Elf32_Ehdr::EM_386) {
8879
            // old style, 8-byte b_info:
8880
            // sizeof(b_info.sz_unc) + sizeof(b_info.sz_cpr);
8881
1
            szb_info = 2*sizeof(unsigned);
8882
1
        }
8883
754
    }
8884
8885
789
    fi->seek(overlay_offset - sizeof(l_info), SEEK_SET);
8886
789
    fi->readx(&linfo, sizeof(linfo));
8887
789
    if (UPX_MAGIC_LE32 != get_le32(&linfo.l_magic)) {
8888
103
        NE32 const *const lp = (NE32 const *)(void const *)&linfo;
8889
        // Workaround for bug of extra linfo by some asl_pack2_Shdrs().
8890
103
        if (0==lp[0] && 0==lp[1] && 0==lp[2]) { // looks like blank extra
8891
10
            fi->readx(&linfo, sizeof(linfo));
8892
10
            if (UPX_MAGIC_LE32 == get_le32(&linfo.l_magic)) {
8893
2
                overlay_offset += sizeof(linfo);
8894
2
            }
8895
8
            else {
8896
8
                throwCantUnpack("l_info corrupted");
8897
8
            }
8898
10
        }
8899
93
        else {
8900
93
            throwCantUnpack("l_info corrupted");
8901
93
        }
8902
103
    }
8903
688
    lsize = get_te16(&linfo.l_lsize);
8904
688
    p_info hbuf;  fi->readx(&hbuf, sizeof(hbuf));
8905
688
    unsigned orig_file_size = get_te32(&hbuf.p_filesize);
8906
688
    blocksize = get_te32(&hbuf.p_blocksize);
8907
688
    if ((u32_t)file_size > orig_file_size || blocksize > orig_file_size
8908
658
        || (orig_file_size >> 8) > (u32_t)file_size  // heuristic anti-fuzz
8909
592
        ||      (blocksize >> 8) > (u32_t)file_size
8910
592
        || !mem_size_valid(1, blocksize, OVERHEAD))
8911
92
        throwCantUnpack("p_info corrupted");
8912
8913
596
    ibuf.alloc(blocksize + OVERHEAD);
8914
596
    b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
8915
596
    fi->readx(&bhdr, szb_info);
8916
596
    ph.u_len = get_te32(&bhdr.sz_unc);
8917
596
    ph.c_len = get_te32(&bhdr.sz_cpr);
8918
596
    ph.set_method(bhdr.b_method, overlay_offset + sizeof(p_info));
8919
596
    if (ph.c_len > (unsigned)file_size || ph.c_len == 0 || ph.u_len == 0
8920
559
    ||  ph.u_len > orig_file_size)
8921
39
        throwCantUnpack("b_info corrupted");
8922
557
    ph.filter_cto = bhdr.b_cto8;
8923
557
    prev_method = bhdr.b_method;  // FIXME if multiple de-compressors
8924
8925
557
    MemBuffer u(ph.u_len);
8926
557
    Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)&u[0];
8927
557
    Elf32_Phdr const *phdr = nullptr;
8928
557
    total_in = 0;
8929
557
    total_out = 0;
8930
557
    unsigned c_adler = upx_adler32(nullptr, 0);
8931
557
    unsigned u_adler = upx_adler32(nullptr, 0);
8932
8933
557
    unsigned is_shlib = 0;
8934
557
    loader_offset = 0;
8935
557
    MemBuffer o_elfhdrs;
8936
557
    Elf32_Phdr const *const dynhdr = elf_find_ptype(Elf32_Phdr::PT_DYNAMIC, phdri, c_phnum);
8937
    // dynseg was set by PackLinuxElf32help1
8938
557
    if (dynhdr && !(Elf32_Dyn::DF_1_PIE & elf_unsigned_dynamic(Elf32_Dyn::DT_FLAGS_1))) {
8939
        // Packed shlib? (ET_DYN without -fPIE)
8940
158
        is_shlib = 1;
8941
158
        xct_off = overlay_offset - sizeof(l_info);
8942
158
        u_phnum = get_te16(&ehdri.e_phnum);
8943
158
        o_elfhdrs.alloc(sz_elf_hdrs);
8944
158
        un_shlib_1(fo, o_elfhdrs, c_adler, u_adler, orig_file_size);
8945
158
        *ehdr = ehdri;
8946
158
    }
8947
399
    else { // main executable
8948
        // Uncompress Ehdr and Phdrs: info for control of unpacking
8949
399
        if (ibuf.getSize() < ph.c_len)
8950
2
            throwCompressedDataViolation();
8951
397
        fi->readx(ibuf, ph.c_len);
8952
397
        if (ph.u_len < sizeof(*ehdr))
8953
5
            throwCantUnpack("ElfXX_Ehdr corrupted");
8954
392
        decompress(ibuf, (upx_byte *)ehdr, false);
8955
392
        if (ehdr->e_type   !=ehdri.e_type
8956
304
        ||  ehdr->e_machine!=ehdri.e_machine
8957
304
        ||  ehdr->e_version!=ehdri.e_version
8958
            // less strict for EM_PPC to workaround earlier bug
8959
304
        ||  !( ehdr->e_flags==ehdri.e_flags
8960
22
            || Elf32_Ehdr::EM_PPC == get_te16(&ehdri.e_machine))
8961
300
        ||  ehdr->e_ehsize !=ehdri.e_ehsize
8962
            // check EI_MAG[0-3], EI_CLASS, EI_DATA, EI_VERSION
8963
297
        ||  memcmp(ehdr->e_ident, ehdri.e_ident, Elf32_Ehdr::EI_OSABI)) {
8964
13
            throwCantUnpack("ElfXX_Ehdr corrupted");
8965
13
        }
8966
        // Rewind: prepare for data phase
8967
379
        fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
8968
8969
379
        u_phnum = get_te16(&ehdr->e_phnum);
8970
379
        if ((umin(MAX_ELF_HDR_32, ph.u_len) - sizeof(Elf32_Ehdr))/sizeof(Elf32_Phdr) < u_phnum) {
8971
2
            throwCantUnpack("bad compressed e_phnum");
8972
2
        }
8973
377
        o_elfhdrs.alloc(sizeof(Elf32_Ehdr) + u_phnum * sizeof(Elf32_Phdr));
8974
377
        memcpy(o_elfhdrs, ehdr, o_elfhdrs.getSize());
8975
8976
        // Decompress each PT_LOAD.
8977
377
        bool first_PF_X = true;
8978
377
        phdr = (Elf32_Phdr *) (void *) (1+ ehdr);  // uncompressed
8979
1.37k
        for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
8980
1.00k
            if (is_LOAD(phdr)) {
8981
432
                unsigned const filesz = get_te32(&phdr->p_filesz);
8982
432
                unsigned const offset = get_te32(&phdr->p_offset);
8983
432
                if (fo) {
8984
223
                    fo->seek(offset, SEEK_SET);
8985
223
                    if (total_out < offset) {
8986
57
                        total_out = offset;  // FIXME: can it be re-write?
8987
57
                    }
8988
223
                }
8989
432
                if (Elf32_Phdr::PF_X & get_te32(&phdr->p_flags)) {
8990
295
                    unpackExtent(filesz, fo,
8991
295
                        c_adler, u_adler, first_PF_X);
8992
295
                    first_PF_X = false;
8993
295
                }
8994
137
                else {
8995
137
                    unpackExtent(filesz, fo,
8996
137
                        c_adler, u_adler, false);
8997
137
                }
8998
432
            }
8999
1.00k
        }
9000
377
    }
9001
9002
535
    upx_uint32_t const e_entry = get_te32(&ehdri.e_entry);
9003
535
    unsigned off_entry = 0;
9004
535
    phdr = phdri;
9005
535
    load_va = 0;
9006
1.24k
    for (unsigned j=0; j < c_phnum; ++j, ++phdr) {
9007
812
        if (is_LOAD(phdr)) {
9008
169
            upx_uint32_t offset = get_te32(&phdr->p_offset);
9009
169
            upx_uint32_t vaddr  = get_te32(&phdr->p_vaddr);
9010
169
            upx_uint32_t filesz = get_te32(&phdr->p_filesz);
9011
169
            if (!load_va) {
9012
146
                load_va = vaddr;
9013
146
            }
9014
169
            if ((e_entry - vaddr) < filesz) {
9015
100
                off_entry = (e_entry - vaddr) + offset;
9016
100
                break;
9017
100
            }
9018
169
        }
9019
812
    }
9020
535
    unsigned d_info[6];
9021
535
    unsigned sz_d_info = sizeof(d_info);
9022
535
    if (!is_shlib) {
9023
95
        if (get_te32(&phdri[0].p_flags) & Elf32_Phdr::PF_X) {
9024
            // Old style, such as upx-3.91 thru upx-3.95
9025
56
            switch (this->e_machine) {
9026
0
                default: {
9027
0
                    char msg[40]; snprintf(msg, sizeof(msg),
9028
0
                        "Unknown architecture %d", this->e_machine);
9029
0
                    throwCantUnpack(msg);
9030
0
                }; break;
9031
9
                case Elf32_Ehdr::EM_MIPS:sz_d_info = 1 * sizeof(unsigned); break;
9032
19
                case Elf32_Ehdr::EM_ARM: sz_d_info = 4 * sizeof(unsigned); break;
9033
8
                case Elf32_Ehdr::EM_PPC: sz_d_info = 3 * sizeof(unsigned); break;
9034
20
                case Elf32_Ehdr::EM_386: sz_d_info = 2 * sizeof(unsigned); break;
9035
56
            }
9036
56
        }
9037
95
        loader_offset = off_entry - sz_d_info;
9038
95
    }
9039
9040
535
    if (0x1000==get_te32(&phdri[0].p_filesz)  // detect C_BASE style
9041
41
    &&  0==get_te32(&phdri[1].p_offset)
9042
36
    &&  0==get_te32(&phdri[0].p_offset)
9043
29
    &&     get_te32(&phdri[1].p_filesz) == get_te32(&phdri[1].p_memsz)) {
9044
23
        fi->seek(up4(get_te32(&phdri[1].p_memsz)), SEEK_SET);  // past the loader
9045
23
    }
9046
512
    else if (is_shlib
9047
77
    ||  (off_entry + up4(lsize) + ph.getPackHeaderSize() + sizeof(overlay_offset))
9048
128
            < up4(file_size)) {
9049
        // Loader is not at end; skip past it.
9050
128
        if (loader_offset) {
9051
128
            fi->seek(loader_offset, SEEK_SET);
9052
128
        }
9053
0
        else {
9054
0
            funpad4(fi);  // MATCH01
9055
0
        }
9056
128
        fi->readx(d_info, sz_d_info);
9057
128
        if (is_shlib && 0==old_dtinit) {
9058
56
            old_dtinit = get_te32(&d_info[2 + (0==d_info[0])]);
9059
56
            is_asl = 1u& get_te32(&d_info[0 + (0==d_info[0])]);
9060
56
        }
9061
128
        fi->seek(lsize - sz_d_info, SEEK_CUR);
9062
128
    }
9063
9064
    // The gaps between PT_LOAD and after last PT_LOAD
9065
535
    phdr = (Elf32_Phdr const *)(1+ (Elf32_Ehdr const *)(void const *)o_elfhdrs);
9066
535
    upx_uint32_t hi_offset(0);
9067
1.15k
    for (unsigned j = 0; j < u_phnum; ++j) {
9068
620
        if (is_LOAD(&phdr[j])
9069
199
        &&  hi_offset < get_te32(&phdr[j].p_offset))
9070
114
            hi_offset = get_te32(&phdr[j].p_offset);
9071
620
    }
9072
995
    for (unsigned j = 0; j < u_phnum; ++j) {
9073
487
        unsigned const size = find_LOAD_gap(phdr, j, u_phnum);
9074
487
        if (size) {
9075
153
            unsigned const where = get_te32(&phdr[j].p_offset) +
9076
153
                                   get_te32(&phdr[j].p_filesz);
9077
153
            if (fo)
9078
71
                fo->seek(where, SEEK_SET);
9079
153
            { // Recover from some piracy [also serves as error tolerance :-) ]
9080
              // Getting past the loader is problematic, due to unintended
9081
              // variances between released versions:
9082
              //   l_info.l_lsize might be rounded up by 8 instead of by 4, and
9083
              //   sz_d_info might have changed.
9084
153
                b_info b_peek, *bp = &b_peek;
9085
153
                fi->readx(bp, sizeof(b_peek));
9086
153
                upx_off_t pos = fi->seek(-(off_t)sizeof(b_peek), SEEK_CUR);
9087
153
                unsigned sz_unc = get_te32(&bp->sz_unc);
9088
153
                unsigned sz_cpr = get_te32(&bp->sz_cpr);
9089
153
                unsigned word3  = get_te32(&bp->b_method);
9090
153
                unsigned method = bp->b_method;
9091
153
                unsigned ftid = bp->b_ftid;
9092
153
                unsigned cto8 = bp->b_cto8;
9093
153
                if (!( ((sz_cpr == sz_unc) && (0 == word3) && (size == sz_unc)) // incompressible literal
9094
149
                    || ((sz_cpr <  sz_unc)
9095
113
                        && (method == prev_method || M_NRV2B_LE32 == prev_method)
9096
81
                        && (0 == ftid) && (0 == cto8)) )
9097
153
                ) {
9098
69
                    opt->info_mode++;
9099
69
                    infoWarning("bad b_info at %#zx", (size_t)pos);
9100
69
                    unsigned const N_PEEK(16 * sizeof(int)), H_PEEK(N_PEEK >> 1);
9101
69
                    unsigned char peek_arr[N_PEEK];
9102
69
                    fi->seek(pos - H_PEEK, SEEK_SET);
9103
69
                    fi->readx(peek_arr, sizeof(peek_arr));
9104
69
                    fi->seek(pos, SEEK_SET);
9105
69
                    bool const is_be = ELFDATA2MSB == ehdri.e_ident[EI_DATA];
9106
69
                    if (is_be) {
9107
                        // Does the right thing for sz_unc and sz_cpr,
9108
                        // but swaps b_method and b_extra.  Need find_be32() :-)
9109
459
                        for (unsigned k = 0; k < N_PEEK; k += sizeof(int)) {
9110
432
                            set_le32(&peek_arr[k], get_be32(&peek_arr[k]));
9111
432
                        }
9112
27
                    }
9113
69
                    int boff = find_le32(peek_arr, sizeof(peek_arr), size);
9114
69
                    if (boff < 0 || sizeof(peek_arr) < (sizeof(*bp) + boff)) {
9115
27
                        throwCantUnpack("b_info corrupted");
9116
27
                    }
9117
42
                    bp = (b_info *)(void *)&peek_arr[boff];
9118
9119
42
                    sz_unc = get_le32(&bp->sz_unc);
9120
42
                    sz_cpr = get_le32(&bp->sz_cpr);
9121
42
                    word3  = get_le32(&bp->b_method);
9122
42
                    ftid = bp->b_ftid;
9123
42
                    cto8 = bp->b_cto8;
9124
42
                    if (0 <= boff  // found
9125
41
                    && ( ((sz_cpr == sz_unc) && (0 == word3) && (size == sz_unc)) // incompressible literal
9126
37
                      || ((sz_cpr <  sz_unc) && (0 == ftid) && (0 == cto8)
9127
29
                          && ((is_be ? bp->b_extra : bp->b_method) == prev_method)) )
9128
42
                    ) {
9129
27
                        pos -= H_PEEK;
9130
27
                        pos += boff;
9131
27
                        infoWarning("... recovery at %#zx", (size_t)pos);
9132
27
                        fi->seek(pos, SEEK_SET);
9133
27
                    }
9134
42
                    opt->info_mode--;
9135
42
                }
9136
153
            }
9137
126
            unpackExtent(size, fo,
9138
126
                c_adler, u_adler, false,
9139
126
                (hi_offset != get_te32(&phdr[j].p_offset)));
9140
126
        }
9141
487
    }
9142
9143
    // check for end-of-file
9144
508
    fi->readx(&bhdr, szb_info);
9145
508
    ph.set_method(bhdr.b_method, ~0u);
9146
508
    unsigned const sz_unc = ph.u_len = get_te32(&bhdr.sz_unc);
9147
9148
508
    if (sz_unc == 0) { // uncompressed size 0 -> EOF
9149
        // note: magic is always stored le32
9150
51
        unsigned const sz_cpr = get_le32(&bhdr.sz_cpr);
9151
51
        if (sz_cpr != UPX_MAGIC_LE32)  // sz_cpr must be h->magic
9152
14
            throwCompressedDataViolation();
9153
51
    }
9154
457
    else { // extra bytes after end?
9155
457
        throwCompressedDataViolation();
9156
457
    }
9157
9158
37
    if (is_shlib) {
9159
2
        un_DT_INIT(old_dtinit, (Elf32_Phdr *)(1+ (Elf32_Ehdr *)(void *)o_elfhdrs), dynhdr, fo);
9160
2
    }
9161
9162
    // update header with totals
9163
37
    ph.c_len = total_in;
9164
37
    ph.u_len = total_out;
9165
9166
    // all bytes must be written
9167
37
    if (fo && total_out != orig_file_size)
9168
0
        throwEOFException();
9169
9170
    // finally test the checksums
9171
37
    if (ph.c_adler != c_adler || ph.u_adler != u_adler)
9172
2
        throwChecksumError();
9173
37
}
9174
9175
void PackLinuxElf::unpack(OutputFile * /*fo*/)
9176
0
{
9177
0
    throwCantUnpack("internal error");
9178
0
}
9179
9180
// NOLINTEND(clang-analyzer-deadcode.DeadStores)
9181
// NOLINTEND(clang-analyzer-core.CallAndMessage)
9182
9183
/* vim:set ts=4 sw=4 et: */