Upx_Doxygen
https://github.com/upx/upx
pefile.h
1 /* pefile.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  All Rights Reserved.
8 
9  UPX and the UCL library are free software; you can redistribute them
10  and/or modify them under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of
12  the License, or (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; see the file COPYING.
21  If not, write to the Free Software Foundation, Inc.,
22  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24  Markus F.X.J. Oberhumer Laszlo Molnar
25  <markus@oberhumer.com> <ezerotven+github@gmail.com>
26  */
27 
28 
29 #ifndef __UPX_PEFILE_H
30 #define __UPX_PEFILE_H 1
31 
32 
33 /*************************************************************************
34 // general/pe handling
35 **************************************************************************/
36 
37 class PeFile : public Packer
38 {
39  typedef Packer super;
40 protected:
41  class Interval;
42  class Reloc;
43  class Resource;
44  class Export;
45  class ImportLinker;
46  struct pe_section_t;
47 
48  PeFile(InputFile *f);
49  virtual ~PeFile();
50  virtual int getVersion() const { return 13; }
51 
52  void readSectionHeaders(unsigned objs, unsigned sizeof_ih);
53  unsigned readSections(unsigned objs, unsigned usize,
54  unsigned ih_filealign, unsigned ih_datasize);
55  void checkHeaderValues(unsigned subsystem, unsigned mask,
56  unsigned ih_entry, unsigned ih_filealign);
57  unsigned handleStripRelocs(upx_uint64_t ih_imagebase,
58  upx_uint64_t default_imagebase,
59  unsigned dllflags);
60 
61  virtual bool handleForceOption() = 0;
62  virtual void callCompressWithFilters(Filter &, int filter_strategy,
63  unsigned ih_codebase);
64  virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
65  unsigned sizeof_oh, unsigned isize_isplit,
66  Reloc &rel, unsigned s1addr) = 0;
67  virtual void addNewRelocations(Reloc &, unsigned) {}
68  void callProcessRelocs(Reloc &rel, unsigned &ic);
69  void callProcessResources(Resource &res, unsigned &ic);
70  virtual unsigned getProcessImportParam(unsigned) { return 0; }
71  virtual void setOhDataBase(const pe_section_t *osection) = 0;
72  virtual void setOhHeaderSize(const pe_section_t *osection) = 0;
73 
74  template <typename LEXX, typename ht>
75  void pack0(OutputFile *fo, ht &ih, ht &oh,
76  unsigned subsystem_mask, upx_uint64_t default_imagebase,
77  bool last_section_rsrc_only);
78 
79  template <typename ht, typename LEXX, typename ord_mask_t>
80  void unpack0(OutputFile *fo, const ht &ih, ht &oh,
81  ord_mask_t ord_mask, bool set_oft);
82 
83  // unpacker capabilities
84  virtual bool canUnpackVersion(int version) const
85  { return (version >= 12 && version <= 13); }
86 
87  int canUnpack0(unsigned max_sections, LE16 &ih_objects,
88  LE32 &ih_entry, unsigned ihsize);
89 
90 protected:
91  virtual int readFileHeader();
92  virtual bool testUnpackVersion(int version) const;
93  virtual void readPeHeader() = 0;
94 
95  unsigned pe_offset;
96 
97  template <typename LEXX, typename ord_mask_t>
98  unsigned processImports0(ord_mask_t ord_mask);
99 
100  template <typename LEXX, typename ord_mask_t>
101  void rebuildImports(upx_byte *& extrainfo,
102  ord_mask_t ord_mask, bool set_oft);
103  virtual unsigned processImports() = 0;
104  virtual void processImports2(unsigned, unsigned);
105  upx_byte *oimport;
106  unsigned soimport;
107  upx_byte *oimpdlls;
108  unsigned soimpdlls;
109  ImportLinker *ilinker;
110  virtual const char *kernelDll() const { return "KERNEL32.DLL"; }
111  void addKernelImport(const char *);
112  virtual void addStubImports();
113  upx_uint64_t ilinkerGetAddress(const char *, const char *) const;
114 
115  virtual void processRelocs() = 0;
116  void processRelocs(Reloc *);
117  void rebuildRelocs(upx_byte *&, unsigned bits,
118  unsigned flags, upx_uint64_t imagebase);
119  upx_byte *orelocs;
120  unsigned sorelocs;
121  upx_byte *oxrelocs;
122  unsigned soxrelocs;
123 
124  void processExports(Export *);
125  void processExports(Export *,unsigned);
126  void rebuildExports();
127  upx_byte *oexport;
128  unsigned soexport;
129 
130  void processResources(Resource *);
131  void processResources(Resource *, unsigned);
132  void rebuildResources(upx_byte *&, unsigned);
133  upx_byte *oresources;
134  unsigned soresources;
135 
136  template <typename>
137  struct tls_traits;
138  template <typename LEXX>
139  void processTls1(Interval *iv,
140  typename tls_traits<LEXX>::cb_value_t imagebase,
141  unsigned imagesize); // pass 1
142  template <typename LEXX>
143  void processTls2(Reloc *rel,const Interval *iv,unsigned newaddr,
144  typename tls_traits<LEXX>::cb_value_t imagebase); // pass 2
145  virtual void processTls(Interval *iv) = 0;
146  virtual void processTls(Reloc *r, const Interval *iv, unsigned a) = 0;
147 
148  void rebuildTls();
149  upx_byte *otls;
150  unsigned sotls;
151  unsigned tlsindex;
152  unsigned tlscb_ptr;
153  unsigned tls_handler_offset;
154  bool use_tls_callbacks;
155 
156  void processLoadConf(Reloc *, const Interval *, unsigned);
157  void processLoadConf(Interval *);
158  upx_byte *oloadconf;
159  unsigned soloadconf;
160 
161  unsigned stripDebug(unsigned);
162 
163  unsigned icondir_offset;
164  int icondir_count;
165 
166  bool importbyordinal;
167  bool kernel32ordinal;
168  unsigned rvamin;
169  unsigned cimports; // rva of preprocessed imports
170  unsigned crelocs; // rva of preprocessed fixups
171  int big_relocs;
172 
173  __packed_struct(ddirs_t)
174  LE32 vaddr;
175  LE32 size;
176  __packed_struct_end()
177  ddirs_t *iddirs;
178  ddirs_t *oddirs;
179 
180  LE32 &IDSIZE(unsigned x) { return iddirs[x].size; }
181  LE32 &IDADDR(unsigned x) { return iddirs[x].vaddr; }
182  LE32 &ODSIZE(unsigned x) { return oddirs[x].size; }
183  LE32 &ODADDR(unsigned x) { return oddirs[x].vaddr; }
184 
185  __packed_struct(pe_section_t)
186  char name[8];
187  LE32 vsize;
188  LE32 vaddr;
189  LE32 size;
190  LE32 rawdataptr;
191  char _[12];
192  LE32 flags;
193  __packed_struct_end()
194 
195  pe_section_t *isection;
196  bool isdll;
197  bool isrtm;
198  bool use_dep_hack;
199  bool use_clear_dirty_stack;
200 
201 
202  static unsigned virta2objnum (unsigned, pe_section_t *, unsigned);
203  unsigned tryremove (unsigned, unsigned);
204 
205  enum {
206  PEDIR_EXPORT = 0,
207  PEDIR_IMPORT = 1,
208  PEDIR_RESOURCE = 2,
209  PEDIR_EXCEPTION = 3, // Exception table
210  PEDIR_SEC = 4, // Certificate table (file pointer)
211  PEDIR_RELOC = 5,
212  PEDIR_DEBUG = 6,
213  PEDIR_COPYRIGHT = 7, // Architecture-specific data
214  PEDIR_GLOBALPTR = 8, // Global pointer
215  PEDIR_TLS = 9,
216  PEDIR_LOADCONF = 10, // Load Config Table
217  PEDIR_BOUNDIM = 11,
218  PEDIR_IAT = 12,
219  PEDIR_DELAYIMP = 13, // Delay Import Descriptor
220  PEDIR_COMRT = 14 // Com+ Runtime Header
221  };
222 
223  enum {
224  PEFL_CODE = 0x20,
225  PEFL_DATA = 0x40,
226  PEFL_BSS = 0x80,
227  PEFL_INFO = 0x200,
228  PEFL_EXTRELS = 0x01000000, // extended relocations
229  PEFL_DISCARD = 0x02000000,
230  PEFL_NOCACHE = 0x04000000,
231  PEFL_NOPAGE = 0x08000000,
232  PEFL_SHARED = 0x10000000,
233  PEFL_EXEC = 0x20000000,
234  PEFL_READ = 0x40000000,
235  PEFL_WRITE = 0x80000000
236  };
237 
238  enum {
239  RELOCS_STRIPPED = 0x0001,
240  EXECUTABLE = 0x0002,
241  LNUM_STRIPPED = 0x0004,
242  LSYMS_STRIPPED = 0x0008,
243  AGGRESSIVE_TRIM = 0x0010,
244  TWO_GIGS_AWARE = 0x0020,
245  FLITTLE_ENDIAN = 0x0080,
246  BITS_32_MACHINE = 0x0100,
247  DEBUG_STRIPPED = 0x0200,
248  REMOVABLE_SWAP = 0x0400,
249  SYSTEM_PROGRAM = 0x1000,
250  DLL_FLAG = 0x2000,
251  FBIG_ENDIAN = 0x8000
252  };
253 
254  //NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann
255  enum {
256  IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
257  IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
258  IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
259  IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
260  IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
261  IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
262  IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
263  IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
264  };
265 
266  // predefined resource types
267  enum {
268  RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, RT_DIALOG, RT_STRING,
269  RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGETABLE,
270  RT_GROUP_CURSOR, RT_GROUP_ICON = 14, RT_VERSION = 16, RT_DLGINCLUDE,
271  RT_PLUGPLAY = 19, RT_VXD, RT_ANICURSOR, RT_ANIICON, RT_HTML,
272  RT_MANIFEST, RT_LAST
273  };
274 
275  class Interval : private noncopyable
276  {
277  unsigned capacity;
278  void *base;
279  public:
280  struct interval
281  {
282  unsigned start, len;
283  } *ivarr;
284 
285  unsigned ivnum;
286 
287  Interval(void *b);
288  ~Interval();
289 
290  void add(unsigned start,unsigned len);
291  void add(const void *start,unsigned len);
292  void add(const void *start,const void *end);
293  void add(const Interval *iv);
294  void flatten();
295 
296  void clear();
297  void dump() const;
298 
299  private:
300  static int __acc_cdecl_qsort compare(const void *p1,const void *p2);
301  };
302 
303  class Reloc : private noncopyable
304  {
305  upx_byte *start;
306  unsigned size;
307 
308  void newRelocPos(void *p);
309 
310  struct reloc;
311  reloc *rel;
312  LE16 *rel1;
313  unsigned counts[16];
314 
315  public:
316  Reloc(upx_byte *,unsigned);
317  Reloc(unsigned rnum);
318  //
319  bool next(unsigned &pos,unsigned &type);
320  const unsigned *getcounts() const { return counts; }
321  //
322  void add(unsigned pos,unsigned type);
323  void finish(upx_byte *&p,unsigned &size);
324  };
325 
326  class Resource : private noncopyable
327  {
328  struct res_dir_entry;
329  struct res_dir;
330  struct res_data;
331  struct upx_rnode;
332  struct upx_rbranch;
333  struct upx_rleaf;
334 
335  const upx_byte *start;
336  upx_byte *newstart;
337  upx_rnode *root;
338  upx_rleaf *head;
339  upx_rleaf *current;
340  unsigned dsize;
341  unsigned ssize;
342 
343  const upx_byte *ibufstart;
344  const upx_byte *ibufend;
345 
346  void check(const res_dir*,unsigned);
347  upx_rnode *convert(const void *,upx_rnode *,unsigned);
348  void build(const upx_rnode *,unsigned &,unsigned &,unsigned);
349  void clear(upx_byte *,unsigned,Interval *);
350  void dump(const upx_rnode *,unsigned) const;
351  void destroy(upx_rnode *urd,unsigned level);
352 
353  void ibufcheck(const void *m, unsigned size);
354 
355  public:
356  Resource(const upx_byte *ibufstart, const upx_byte *ibufen);
357  Resource(const upx_byte *p, const upx_byte *ibufstart,
358  const upx_byte *ibufend);
359  ~Resource();
360  void init(const upx_byte *);
361 
362  unsigned dirsize() const;
363  bool next();
364 
365  unsigned itype() const;
366  const upx_byte *ntype() const;
367  unsigned size() const;
368  unsigned offs() const;
369  unsigned &newoffs();
370 
371  upx_byte *build();
372  bool clear();
373 
374  void dump() const;
375  unsigned iname() const;
376  const upx_byte *nname() const;
377  /*
378  unsigned ilang() const {return current->id;}
379  const upx_byte *nlang() const {return current->name;}
380  */
381  };
382 
383  class Export : private noncopyable
384  {
385  __packed_struct(export_dir_t)
386  char _[12]; // flags, timedate, version
387  LE32 name;
388  char __[4]; // ordinal base
389  LE32 functions;
390  LE32 names;
391  LE32 addrtable;
392  LE32 nameptrtable;
393  LE32 ordinaltable;
394  __packed_struct_end()
395 
396  export_dir_t edir;
397  char *ename;
398  char *functionptrs;
399  char *ordinals;
400  char **names;
401 
402  char *base;
403  unsigned size;
404  Interval iv;
405 
406  public:
407  Export(char *_base);
408  ~Export();
409 
410  void convert(unsigned eoffs,unsigned esize);
411  void build(char *base,unsigned newoffs);
412  unsigned getsize() const { return size; }
413  };
414 
415 };
416 
417 class PeFile32 : public PeFile
418 {
419  typedef PeFile super;
420 protected:
421  PeFile32(InputFile *f);
422  virtual ~PeFile32();
423  void pack0(OutputFile *fo, unsigned subsystem_mask,
424  upx_uint64_t default_imagebase, bool last_section_rsrc_only);
425  virtual void unpack(OutputFile *fo);
426  virtual int canUnpack();
427 
428  virtual void readPeHeader();
429 
430  virtual unsigned processImports();
431  virtual void processRelocs();
432  virtual void processTls(Interval *);
433  void processTls(Reloc *, const Interval *, unsigned);
434 
435  __packed_struct(pe_header_t)
436  // 0x0
437  char _[4]; // pemagic
438  LE16 cpu;
439  LE16 objects;
440  char __[12]; // timestamp + reserved
441  LE16 opthdrsize;
442  LE16 flags;
443  // optional header
444  LE16 coffmagic; // NEW: Stefan Widmann
445  char ___[2]; // linkerversion
446  LE32 codesize;
447  // 0x20
448  LE32 datasize;
449  LE32 bsssize;
450  LE32 entry;
451  LE32 codebase;
452  // 0x30
453  LE32 database;
454  // nt specific fields
455  LE32 imagebase;
456  LE32 objectalign;
457  LE32 filealign; // should set to 0x200 ?
458  // 0x40
459  char ____[16]; // versions
460  // 0x50
461  LE32 imagesize;
462  LE32 headersize;
463  LE32 chksum; // should set to 0
464  LE16 subsystem;
465  LE16 dllflags;
466  // 0x60
467  char _____[20]; // stack + heap sizes
468  // 0x74
469  LE32 ddirsentries; // usually 16
470 
471  ddirs_t ddirs[16];
472  __packed_struct_end()
473 
474  pe_header_t ih, oh;
475 };
476 
477 class PeFile64 : public PeFile
478 {
479  typedef PeFile super;
480 protected:
481  PeFile64(InputFile *f);
482  virtual ~PeFile64();
483 
484  void pack0(OutputFile *fo, unsigned subsystem_mask,
485  upx_uint64_t default_imagebase);
486 
487  virtual void unpack(OutputFile *fo);
488  virtual int canUnpack();
489 
490  virtual void readPeHeader();
491 
492  virtual unsigned processImports();
493  virtual void processRelocs();
494  virtual void processTls(Interval *);
495  void processTls(Reloc *, const Interval *, unsigned);
496 
497  __packed_struct(pe_header_t)
498  // 0x0
499  char _[4]; // pemagic
500  LE16 cpu;
501  LE16 objects; // number of sections
502  char __[12]; // timestamp + reserved
503  LE16 opthdrsize;
504  LE16 flags; // characteristics
505  // optional header
506  LE16 coffmagic; // NEW: Stefan Widmann
507  char ___[2]; // linkerversion
508  LE32 codesize;
509  // 0x20
510  LE32 datasize;
511  LE32 bsssize;
512  LE32 entry; // still a 32 bit RVA
513  LE32 codebase;
514  // 0x30
515  //LE32 database; // field does not exist in PE+!
516  // nt specific fields
517  LE64 imagebase; // LE32 -> LE64 - Stefan Widmann standard is 0x0000000140000000
518  LE32 objectalign;
519  LE32 filealign; // should set to 0x200 ?
520  // 0x40
521  char ____[16]; // versions
522  // 0x50
523  LE32 imagesize;
524  LE32 headersize;
525  LE32 chksum; // should set to 0
526  LE16 subsystem;
527  LE16 dllflags;
528  // 0x60
529  char _____[36]; // stack + heap sizes + loader flag
530  // 0x84
531  LE32 ddirsentries; // usually 16
532 
533  ddirs_t ddirs[16];
534  __packed_struct_end()
535 
536  pe_header_t ih, oh;
537 };
538 
539 #endif /* already included */
540 
541 /* vim:set ts=4 sw=4 et: */
Definition: pefile.h:417
Definition: pefile.h:383
Definition: pefile.h:303
Definition: pefile.cpp:1462
Definition: pefile.h:477
Definition: file.h:89
Definition: pefile.h:137
Definition: packer.h:115
Definition: pefile.h:37
Definition: pefile.cpp:1455
Definition: pefile.h:326
Definition: pefile.h:280
Definition: pefile.h:275
Definition: file.h:121
Definition: filter.h:53
Definition: conf.h:320