Upx_Doxygen
https://github.com/upx/upx
All Classes
p_lx_elf.h
1 /* p_lx_elf.h --
2 
3  This file is part of the UPX executable compressor.
4 
5  Copyright (C) 1996-2016 Markus Franz Xaver Johannes Oberhumer
6  Copyright (C) 1996-2016 Laszlo Molnar
7  Copyright (C) 2000-2016 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 #ifndef __UPX_P_LX_ELF_H //{
34 #define __UPX_P_LX_ELF_H 1
35 
36 
37 class PackLinuxElf : public PackUnix
38 {
39  typedef PackU
40  nix super;
41 public:
43  virtual ~PackLinuxElf();
44  /*virtual void buildLoader(const Filter *);*/
45  virtual bool canUnpackVersion(int version) const { return (version >= 11); }
46 
47 protected:
48  virtual const int *getCompressionMethods(int method, int level) const;
49 
50  // All other virtual functions in this class must be pure virtual
51  // because they depend on Elf32 or Elf64 data structures, which differ.
52 
53  virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
54  virtual int pack2(OutputFile *, Filter &) = 0; // append compressed data
55  virtual void pack3(OutputFile *, Filter &) = 0; // append loader
56  //virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
57 
58  virtual void generateElfHdr(
59  OutputFile *,
60  void const *proto,
61  unsigned const brka
62  ) = 0;
63  virtual void defineSymbols(Filter const *);
64  virtual void addStubEntrySections(Filter const *);
65  virtual void unpack(OutputFile *fo);
66 
67  //virtual void const *elf_find_dynamic(unsigned) const = 0;
68  virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const = 0;
69  static unsigned elf_hash(char const *) /*const*/;
70  static unsigned gnu_hash(char const *) /*const*/;
71 
72 protected:
73  unsigned e_type;
74  unsigned e_phnum; /* Program header table entry count */
75  unsigned e_shnum;
76  MemBuffer file_image; // if ET_DYN investigation
77  char const *dynstr; // from DT_STRTAB
78 
79  unsigned sz_phdrs; // sizeof Phdr[]
80  unsigned sz_elf_hdrs; // all Elf headers
81  unsigned sz_pack2; // after pack2(), before loader
82  unsigned sz_pack2a; // after pack2() of all PT_LOAD
83  unsigned lg2_page; // log2(PAGE_SIZE)
84  unsigned page_size; // 1u<<lg2_page
85  unsigned is_big; // stub style: must use area above the brk
86  unsigned xct_off; // shared library: file offset of SHT_EXECINSTR
87  unsigned hatch_off; // file offset of escape hatch
88  upx_uint64_t load_va; // PT_LOAD[0].p_vaddr
89  upx_uint64_t xct_va; // minimum SHT_EXECINSTR virtual address
90  upx_uint64_t jni_onload_va; // runtime &JNI_OnLoad
91 
92  upx_uint16_t e_machine;
93  unsigned char ei_class;
94  unsigned char ei_data;
95  unsigned char ei_osabi;
96  char const *osabi_note;
97 
98  unsigned char const *buildid_data;
99  int o_elf_shnum; // num output Shdrs
100  static unsigned char o_shstrtab[];
101 };
102 
104 {
105  typedef PackLinuxElf super;
106 public:
108  virtual ~PackLinuxElf32();
109 protected:
110  virtual void PackLinuxElf32help1(InputFile *f);
111  virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
112  virtual bool canPack();
113 
114  // These ARM routines are essentially common to big/little endian,
115  // but the class hierarchy splits after this class.
116  virtual void ARM_defineSymbols(Filter const *ft);
117  virtual void ARM_updateLoader(OutputFile *);
118  virtual int ARM_is_QNX(void);
119 
120  virtual void pack1(OutputFile *, Filter &); // generate executable header
121  virtual int pack2(OutputFile *, Filter &); // append compressed data
122  virtual void pack3(OutputFile *, Filter &); // append loader
123  virtual void pack4(OutputFile *, Filter &); // append pack header
124  virtual void unpack(OutputFile *fo);
125 
126  virtual void generateElfHdr(
127  OutputFile *,
128  void const *proto,
129  unsigned const brka
130  );
131  virtual void buildLinuxLoader(
132  upx_byte const *const proto, // assembly-only sections
133  unsigned const szproto,
134  upx_byte const *const fold, // linked assembly + C section
135  unsigned const szfold,
136  Filter const *ft
137  );
138  virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
139  virtual void patchLoader();
140  virtual void updateLoader(OutputFile *fo);
141  virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
142  unsigned const e_phnum);
143  virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
144 
145  virtual Elf32_Sym const *elf_lookup(char const *) const;
146  virtual unsigned elf_get_offset_from_address(unsigned) const;
147  Elf32_Shdr const *elf_find_section_name(char const *) const;
148  Elf32_Shdr const *elf_find_section_type(unsigned) const;
149  void const *elf_find_dynamic(unsigned) const;
150  Elf32_Dyn const *elf_has_dynamic(unsigned) const;
151  upx_uint64_t elf_unsigned_dynamic(unsigned) const;
152 
153 protected:
154  Elf32_Ehdr ehdri; // from input file
155  Elf32_Phdr *phdri; // for input file
156  unsigned e_phoff;
157  unsigned e_shoff;
158  unsigned char *note_body; // concatenated contents of PT_NOTEs, if any
159  unsigned note_size; // total size of PT_NOTEs
160  Elf32_Shdr const *shdri; // from input file
161  unsigned page_mask; // AND clears the offset-within-page
162 
163  Elf32_Dyn const *dynseg; // from PT_DYNAMIC
164  unsigned int const *hashtab; // from DT_HASH
165  unsigned int const *gashtab; // from DT_GNU_HASH
166  Elf32_Sym const *dynsym; // from DT_SYMTAB
167  Elf32_Sym const *jni_onload_sym;
168  char const *shstrtab; // via Elf32_Shdr
169 
170  Elf32_Shdr const *sec_strndx;
171  Elf32_Shdr const *sec_dynsym;
172  Elf32_Shdr const *sec_dynstr;
173 
174  __packed_struct(cprElfHdr1)
175  Elf32_Ehdr ehdr;
176  Elf32_Phdr phdr[1];
177  l_info linfo;
178  __packed_struct_end()
179 
180  __packed_struct(cprElfHdr2)
181  Elf32_Ehdr ehdr;
182  Elf32_Phdr phdr[2];
183  l_info linfo;
184  __packed_struct_end()
185 
186  __packed_struct(cprElfHdr3)
187  Elf32_Ehdr ehdr;
188  Elf32_Phdr phdr[3];
189  l_info linfo;
190  __packed_struct_end()
191 
192  __packed_struct(cprElfHdrNetBSD)
193  Elf32_Ehdr ehdr;
194  Elf32_Phdr phdr[4];
195  unsigned char notes[512];
196  __packed_struct_end()
197 
198  cprElfHdrNetBSD elfout;
199 
200  __packed_struct(cprElfShdr3)
201  Elf32_Shdr shdr[3];
202  __packed_struct_end()
203 
204  cprElfShdr3 shdrout;
205 
206  struct Elf32_Nhdr {
207  unsigned namesz;
208  unsigned descsz;
209  unsigned type;
210  //unsigned char body[0];
211  };
212 
213  static void compileTimeAssertions() {
214  COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 52 + 1*32 + 12)
215  COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 52 + 2*32 + 12)
216  COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 52 + 3*32 + 12)
217  COMPILE_TIME_ASSERT(sizeof(cprElfHdrNetBSD) == 52 + 4*32 + 512)
218  COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
219  COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
220  COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
221  COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdrNetBSD)
222  }
223 };
224 
225 
227 {
228  typedef PackLinuxElf super;
229 public:
231  virtual ~PackLinuxElf64();
232  /*virtual void buildLoader(const Filter *);*/
233 
234 protected:
235  virtual void PackLinuxElf64help1(InputFile *f);
236  virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
237 
238  virtual void pack1(OutputFile *, Filter &); // generate executable header
239  virtual int pack2(OutputFile *, Filter &); // append compressed data
240  virtual void pack3(OutputFile *, Filter &); // append loader
241  virtual void pack4(OutputFile *, Filter &); // append pack header
242  virtual void unpack(OutputFile *fo);
243 
244  virtual void generateElfHdr(
245  OutputFile *,
246  void const *proto,
247  unsigned const brka
248  );
249  virtual void buildLinuxLoader(
250  upx_byte const *const proto, // assembly-only sections
251  unsigned const szproto,
252  upx_byte const *const fold, // linked assembly + C section
253  unsigned const szfold,
254  Filter const *ft
255  );
256  virtual off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
257  virtual void patchLoader();
258  virtual void updateLoader(OutputFile *fo);
259  virtual unsigned find_LOAD_gap(Elf64_Phdr const *const phdri, unsigned const k,
260  unsigned const e_phnum);
261 
262  virtual Elf64_Sym const *elf_lookup(char const *) const;
263  virtual upx_uint64_t elf_get_offset_from_address(upx_uint64_t) const;
264  Elf64_Shdr const *elf_find_section_name(char const *) const;
265  Elf64_Shdr const *elf_find_section_type(unsigned) const;
266  void const *elf_find_dynamic(unsigned) const;
267  Elf64_Dyn const *elf_has_dynamic(unsigned) const;
268  upx_uint64_t elf_unsigned_dynamic(unsigned) const;
269 
270 protected:
271  Elf64_Ehdr ehdri; // from input file
272  Elf64_Phdr *phdri; // for input file
273  upx_uint64_t e_phoff;
274  upx_uint64_t e_shoff;
275  unsigned char *note_body; // concatenated contents of PT_NOTEs, if any
276  unsigned note_size; // total size of PT_NOTEs
277  Elf64_Shdr const *shdri; // from input file
278  upx_uint64_t page_mask; // AND clears the offset-within-page
279 
280  Elf64_Dyn const *dynseg; // from PT_DYNAMIC
281  unsigned int const *hashtab; // from DT_HASH
282  unsigned int const *gashtab; // from DT_GNU_HASH
283  Elf64_Sym const *dynsym; // from DT_SYMTAB
284  Elf64_Sym const *jni_onload_sym;
285  char const *shstrtab; // via Elf64_Shdr
286 
287  Elf64_Shdr const *sec_strndx;
288  Elf64_Shdr const *sec_dynsym;
289  Elf64_Shdr const *sec_dynstr;
290 
291  __packed_struct(cprElfHdr1)
292  Elf64_Ehdr ehdr;
293  Elf64_Phdr phdr[1];
294  l_info linfo;
295  __packed_struct_end()
296 
297  __packed_struct(cprElfHdr2)
298  Elf64_Ehdr ehdr;
299  Elf64_Phdr phdr[2];
300  l_info linfo;
301  __packed_struct_end()
302 
303  __packed_struct(cprElfHdr3)
304  Elf64_Ehdr ehdr;
305  Elf64_Phdr phdr[3];
306  l_info linfo;
307  __packed_struct_end()
308 
309  __packed_struct(cprElfHdr4)
310  Elf64_Ehdr ehdr;
311  Elf64_Phdr phdr[4];
312  l_info linfo;
313  __packed_struct_end()
314 
315  cprElfHdr4 elfout;
316 
317  __packed_struct(cprElfShdr3)
318  Elf64_Shdr shdr[3];
319  __packed_struct_end()
320 
321  cprElfShdr3 shdrout;
322 
323  static void compileTimeAssertions() {
324  COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 64 + 1*56 + 12)
325  COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 64 + 2*56 + 12)
326  COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 64 + 3*56 + 12)
327  COMPILE_TIME_ASSERT(sizeof(cprElfHdr4) == 64 + 4*56 + 12)
328  COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
329  COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
330  COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
331  COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr4)
332  }
333 };
334 
336 {
337  typedef PackLinuxElf32 super;
338 protected:
339  PackLinuxElf32Be(InputFile *f) : super(f) {
340  bele = &N_BELE_RTP::be_policy;
341  PackLinuxElf32help1(f);
342  }
343 };
344 
346 {
347  typedef PackLinuxElf32 super;
348 protected:
349  PackLinuxElf32Le(InputFile *f) : super(f) {
350  bele = &N_BELE_RTP::le_policy;
351  PackLinuxElf32help1(f);
352  }
353 };
354 
356 {
357  typedef PackLinuxElf64 super;
358 protected:
359  PackLinuxElf64Le(InputFile *f) : super(f) {
360  lg2_page=16;
361  page_size=1u<<lg2_page;
362  bele = &N_BELE_RTP::le_policy;
363  PackLinuxElf64help1(f);
364  }
365 };
366 
367 
368 /*************************************************************************
369 // linux/elf64amd
370 **************************************************************************/
371 
373 {
374  typedef PackLinuxElf64Le super;
375 public:
377  virtual ~PackLinuxElf64amd();
378  virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; }
379  virtual const char *getName() const { return "linux/amd64"; }
380  virtual const char *getFullName(const options_t *) const { return "amd64-linux.elf"; }
381  virtual const int *getFilters() const;
382  virtual bool canPack();
383 protected:
384  virtual void pack1(OutputFile *, Filter &); // generate executable header
385  //virtual void pack3(OutputFile *, Filter &); // append loader
386  virtual void buildLoader(const Filter *);
387  virtual Linker* newLinker() const;
388  virtual void defineSymbols(Filter const *);
389 };
390 
391 
392 /*************************************************************************
393 // linux/elf32ppc
394 **************************************************************************/
395 
397 {
398  typedef PackLinuxElf32Be super;
399 public:
401  virtual ~PackLinuxElf32ppc();
402  virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
403  virtual const char *getName() const { return "linux/ppc32"; }
404  virtual const char *getFullName(const options_t *) const { return "powerpc-linux.elf"; }
405  virtual const int *getFilters() const;
406 protected:
407  virtual void pack1(OutputFile *, Filter &); // generate executable header
408  virtual void buildLoader(const Filter *);
409  virtual Linker* newLinker() const;
410 };
411 
412 /*************************************************************************
413 // linux/elf64ppcle
414 **************************************************************************/
415 
417 {
418  typedef PackLinuxElf64Le super;
419 public:
421  virtual ~PackLinuxElf64ppcle();
422  virtual int getFormat() const { return UPX_F_LINUX_ELFPPC64LE; }
423  virtual const char *getName() const { return "linux/ppc64le"; }
424  virtual const char *getFullName(const options_t *) const { return "powerpc64le-linux.elf"; }
425  virtual const int *getFilters() const;
426 protected:
427  unsigned lg2_page; // log2(PAGE_SIZE)
428  unsigned page_size; // 1u<<lg2_page
429  virtual bool canPack();
430  virtual void pack1(OutputFile *, Filter &); // generate executable header
431  virtual void buildLoader(const Filter *);
432  virtual Linker* newLinker() const;
433 };
434 
435 
436 /*************************************************************************
437 // linux/elf386
438 **************************************************************************/
439 
441 {
442  typedef PackLinuxElf32Le super;
443 public:
445  virtual ~PackLinuxElf32x86();
446  virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
447  virtual const char *getName() const { return "linux/i386"; }
448  virtual const char *getFullName(const options_t *) const { return "i386-linux.elf"; }
449  virtual const int *getFilters() const;
450 
451 protected:
452  virtual void pack1(OutputFile *, Filter &); // generate executable header
453 
454  virtual void buildLoader(const Filter *);
455  virtual void addStubEntrySections(Filter const *);
456  virtual Linker* newLinker() const;
457  virtual void defineSymbols(Filter const *);
458 };
459 
461 {
462  typedef PackLinuxElf32x86 super;
463 public:
465  virtual ~PackBSDElf32x86();
466  virtual int getFormat() const = 0;
467  virtual const char *getName() const = 0;
468  virtual const char *getFullName(const options_t *) const = 0;
469 
470 protected:
471  virtual void pack1(OutputFile *, Filter &); // generate executable header
472 
473  virtual void buildLoader(const Filter *);
474 };
475 
477 {
478  typedef PackBSDElf32x86 super;
479 public:
481  virtual ~PackFreeBSDElf32x86();
482  virtual int getFormat() const { return UPX_F_BSD_ELF_i386; }
483  virtual const char *getName() const { return "freebsd/i386"; }
484  virtual const char *getFullName(const options_t *) const { return "i386-freebsd.elf"; }
485 };
486 
488 {
489  typedef PackLinuxElf32x86 super;
490 public:
492  virtual ~PackNetBSDElf32x86();
493  virtual int getFormat() const { return UPX_F_BSD_ELF_i386; }
494  virtual const char *getName() const { return "netbsd/i386"; }
495  virtual const char *getFullName(const options_t *) const { return "i386-netbsd.elf"; }
496 protected:
497  virtual void buildLoader(const Filter *ft);
498  virtual void generateElfHdr(
499  OutputFile *,
500  void const *proto,
501  unsigned const brka
502  );
503 };
504 
506 {
507  typedef PackBSDElf32x86 super;
508 public:
510  virtual ~PackOpenBSDElf32x86();
511  virtual int getFormat() const { return UPX_F_BSD_ELF_i386; }
512  virtual const char *getName() const { return "openbsd/i386"; }
513  virtual const char *getFullName(const options_t *) const { return "i386-openbsd.elf"; }
514 
515 protected:
516  virtual void buildLoader(const Filter *ft);
517  virtual void generateElfHdr(
518  OutputFile *,
519  void const *proto,
520  unsigned const brka
521  );
522 };
523 
524 
525 /*************************************************************************
526 // linux/elfarm
527 **************************************************************************/
528 
530 {
531  typedef PackLinuxElf32Le super;
532 public:
534  virtual ~PackLinuxElf32armLe();
535  virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEL; }
536  virtual const char *getName() const { return "linux/arm"; }
537  virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; }
538  virtual const int *getFilters() const;
539 
540 protected:
541  virtual const int *getCompressionMethods(int method, int level) const;
542  virtual Linker* newLinker() const;
543  virtual void pack1(OutputFile *, Filter &); // generate executable header
544  virtual void buildLoader(const Filter *);
545  virtual void updateLoader(OutputFile *);
546  virtual void defineSymbols(Filter const *);
547 };
548 
550 {
551  typedef PackLinuxElf32Be super;
552 public:
554  virtual ~PackLinuxElf32armBe();
555  virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEB; }
556  virtual const char *getName() const { return "linux/armeb"; }
557  virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; }
558  virtual const int *getFilters() const;
559 
560 protected:
561  virtual const int *getCompressionMethods(int method, int level) const;
562  virtual Linker* newLinker() const;
563  virtual void pack1(OutputFile *, Filter &); // generate executable header
564  virtual void buildLoader(const Filter *);
565  virtual void updateLoader(OutputFile *);
566  virtual void defineSymbols(Filter const *);
567 };
568 
570 {
571  typedef PackLinuxElf32Be super;
572 public:
574  virtual ~PackLinuxElf32mipseb();
575  virtual int getFormat() const { return UPX_F_LINUX_ELF32_MIPSEB; }
576  virtual const char *getName() const { return "linux/mips"; }
577  virtual const char *getFullName(const options_t *) const { return "mips-linux.elf"; }
578  virtual const int *getFilters() const;
579 
580 protected:
581  virtual Linker* newLinker() const;
582  virtual void pack1(OutputFile *, Filter &); // generate executable header
583  virtual void buildLoader(const Filter *);
584  virtual void updateLoader(OutputFile *);
585  virtual void defineSymbols(Filter const *);
586 };
587 
589 {
590  typedef PackLinuxElf32Le super;
591 public:
593  virtual ~PackLinuxElf32mipsel();
594  virtual int getFormat() const { return UPX_F_LINUX_ELF32_MIPSEL; }
595  virtual const char *getName() const { return "linux/mipsel"; }
596  virtual const char *getFullName(const options_t *) const { return "mipsel-linux.elf"; }
597  virtual const int *getFilters() const;
598 
599 protected:
600  virtual Linker* newLinker() const;
601  virtual void pack1(OutputFile *, Filter &); // generate executable header
602  virtual void buildLoader(const Filter *);
603  virtual void updateLoader(OutputFile *);
604  virtual void defineSymbols(Filter const *);
605 };
606 
607 
608 #endif /*} already included */
609 
610 /* vim:set ts=4 sw=4 et: */
Definition: mem.h:37
Definition: linker.h:35
Definition: p_lx_elf.h:335
Definition: options.h:45
Definition: p_lx_elf.h:37
Definition: p_lx_elf.h:440
Definition: p_lx_elf.h:226
Definition: p_lx_elf.h:416
Definition: p_unix.h:38
Definition: p_lx_elf.h:505
Definition: p_lx_elf.h:460
Definition: file.h:89
Definition: p_lx_elf.h:529
Definition: p_lx_elf.h:345
Definition: p_lx_elf.h:476
Definition: p_lx_elf.h:372
Definition: p_lx_elf.h:588
Definition: p_lx_elf.h:206
Definition: p_lx_elf.h:487
Definition: p_lx_elf.h:355
Definition: p_lx_elf.h:569
Definition: p_lx_elf.h:103
Definition: file.h:121
Definition: filter.h:53
Definition: p_lx_elf.h:549
Definition: p_lx_elf.h:396