Upx_Doxygen
https://github.com/upx/upx
packer.h
1 /* packer.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_PACKER_H
30 #define __UPX_PACKER_H 1
31 
32 #include "mem.h"
33 
34 class InputFile;
35 class OutputFile;
36 class Packer;
37 class PackMaster;
38 class UiPacker;
39 class Filter;
40 
41 
42 /*************************************************************************
43 //
44 **************************************************************************/
45 
46 // see stub/src/include/header.S
48 {
49  friend class Packer;
50 
51 private:
52  // these are strictly private to Packer and not accessible in subclasses:
53  PackHeader();
54 
55  void putPackHeader(upx_bytep p);
56  bool fillPackHeader(const upx_bytep b, int blen);
57  bool PACKHEADER_TRYFILLPACK(const upx_bytep buf,int blen,unsigned int type);
58 
59 public:
60  int getPackHeaderSize() const;
61 
62 public:
63  // fields stored in compressed file
64  //enum { magic = UPX_MAGIC_LE32 };
65  int version;
66  int format; // executable format
67  int method; // compresison method
68  int level; // compresison level 1..10
69  unsigned u_len;
70  unsigned c_len;
71  unsigned u_adler;
72  unsigned c_adler;
73  off_t u_file_size;
74  int filter;
75  int filter_cto;
76  int n_mru; // FIXME: rename to filter_misc
77  int header_checksum;
78 
79  // support fields for verifying decompression
80  unsigned saved_u_adler;
81  unsigned saved_c_adler;
82 
83  // info fields set by fillPackHeader()
84  unsigned buf_offset;
85 
86  // info fields set by Packer::compress()
87  upx_compress_result_t compress_result;
88  //unsigned min_offset_found;
89  unsigned max_offset_found;
90  //unsigned min_match_found;
91  unsigned max_match_found;
92  //unsigned min_run_found;
93  unsigned max_run_found;
94  unsigned first_offset_found;
95  //unsigned same_match_offsets_found;
96 
97  // info fields set by Packer::compressWithFilters()
98  unsigned overlap_overhead;
99 };
100 
101 
102 bool ph_skipVerify(const PackHeader &ph);
103 void ph_decompress(PackHeader &ph, const upx_bytep in, upx_bytep out,
104  bool verify_checksum, Filter *ft);
105 bool ph_testOverlappingDecompression(const PackHeader &ph, const upx_bytep buf,
106  unsigned overlap_overhead);
107 
108 
109 /*************************************************************************
110 // abstract base class for packers
111 //
112 // FIXME: this class is way too fat and badly needs a decomposition
113 **************************************************************************/
114 
115 class Packer
116 {
117  //friend class PackMaster;
118  friend class UiPacker;
119 protected:
120  Packer(InputFile *f);
121 public:
122  virtual ~Packer();
123  virtual void assertPacker() const;
124 
125  virtual int getVersion() const = 0;
126  // A unique integer ID for this executable format. See conf.h.
127  virtual int getFormat() const = 0;
128  virtual const char *getName() const = 0;
129  virtual const char *getFullName(const options_t *) const = 0;
130  virtual const int *getCompressionMethods(int method, int level) const = 0;
131  virtual const int *getFilters() const = 0;
132 
133  // PackMaster entries
134  void initPackHeader();
135  void updatePackHeader();
136  void doPack(OutputFile *fo);
137  void doUnpack(OutputFile *fo);
138  void doTest();
139  void doList();
140  void doFileInfo();
141 
142  // unpacker capabilities
143  virtual bool canUnpackVersion(int version) const
144  { return (version >= 8); }
145  virtual bool canUnpackFormat(int format) const
146  { return (format == getFormat()); }
147 
148 protected:
149  // unpacker tests - these may throw exceptions
150  virtual bool testUnpackVersion(int version) const;
151  virtual bool testUnpackFormat(int format) const;
152 
153 protected:
154  // implementation
155  virtual void pack(OutputFile *fo) = 0;
156  virtual void unpack(OutputFile *fo) = 0;
157  virtual void test();
158  virtual void list();
159  virtual void fileInfo();
160 
161 public:
162  // canPack() should throw a cantPackException eplaining why it
163  // cannot pack a recognized format.
164  // canUnpack() can return -1 meaning "format recognized, but file
165  // is definitely not packed" (see packmast.cpp).
166  virtual bool canPack() = 0;
167  virtual int canUnpack() = 0;
168  virtual int canTest() { return canUnpack(); }
169  virtual int canList() { return canUnpack(); }
170 
171 protected:
172  // main compression drivers
173  virtual bool compress(upx_bytep i_ptr, unsigned i_len, upx_bytep o_ptr,
174  const upx_compress_config_t *cconf = NULL);
175  virtual void decompress(const upx_bytep in, upx_bytep out,
176  bool verify_checksum = true, Filter *ft = NULL);
177  virtual bool checkDefaultCompressionRatio(unsigned u_len, unsigned c_len) const;
178  virtual bool checkCompressionRatio(unsigned u_len, unsigned c_len) const;
179  virtual bool checkFinalCompressionRatio(const OutputFile *fo) const;
180 
181  // high-level compression drivers
182  void compressWithFilters(Filter *ft,
183  const unsigned overlap_range,
184  const upx_compress_config_t *cconf,
185  int filter_strategy = 0,
186  int inhibit_compression_check = 0);
187  void compressWithFilters(Filter *ft,
188  const unsigned overlap_range,
189  const upx_compress_config_t *cconf,
190  int filter_strategy,
191  unsigned filter_buf_off,
192  unsigned compress_ibuf_off,
193  unsigned compress_obuf_off,
194  const upx_bytep hdr_ptr, unsigned hdr_len,
195  int inhibit_compression_check = 0);
196  // real compression driver
197  void compressWithFilters(upx_bytep i_ptr, unsigned i_len,
198  upx_bytep o_ptr,
199  upx_bytep f_ptr, unsigned f_len,
200  const upx_bytep hdr_ptr, unsigned hdr_len,
201  Filter *ft,
202  const unsigned overlap_range,
203  const upx_compress_config_t *cconf,
204  int filter_strategy,
205  int inhibit_compression_check = 0);
206 
207  // util for verifying overlapping decompresion
208  // non-destructive test
209  virtual bool testOverlappingDecompression(const upx_bytep buf,
210  const upx_bytep tbuf,
211  unsigned overlap_overhead) const;
212  // non-destructive find
213  virtual unsigned findOverlapOverhead(const upx_bytep buf,
214  const upx_bytep tbuf,
215  unsigned range = 0,
216  unsigned upper_limit = ~0u) const;
217  // destructive decompress + verify
218  void verifyOverlappingDecompression(Filter *ft = NULL);
219  void verifyOverlappingDecompression(upx_bytep o_ptr, unsigned o_size, Filter *ft = NULL);
220 
221  // packheader handling
222  virtual int patchPackHeader(void *b, int blen);
223  virtual bool getPackHeader(void *b, int blen, bool allow_incompressible=false);
224  virtual bool readPackHeader(int len, bool allow_incompressible=false);
225  virtual void checkAlreadyPacked(const void *b, int blen);
226 
227  // loader core
228  virtual void buildLoader(const Filter *ft) = 0;
229  virtual Linker* newLinker() const = 0;
230  virtual void relocateLoader();
231  // loader util for linker
232  virtual upx_byte *getLoader() const;
233  virtual int getLoaderSize() const;
234  virtual void initLoader(const void *pdata, int plen, int small=-1);
235 #define C const char *
236  void addLoader(C); void addLoader(C,C); void addLoader(C,C,C);
237  void addLoader(C,C,C,C); void addLoader(C,C,C,C,C);
238  void addLoader(C,C,C,C,C,C); void addLoader(C,C,C,C,C,C,C);
239  void addLoader(C,C,C,C,C,C,C,C); void addLoader(C,C,C,C,C,C,C,C,C);
240  void addLoader(C,C,C,C,C,C,C,C,C,C);
241 #undef C
242 #if 1 && (ACC_CC_CLANG || (ACC_CC_GNUC >= 0x040100))
243  void __acc_cdecl_va addLoaderVA(const char *s, ...) __attribute__((__sentinel__));
244 #else
245  void __acc_cdecl_va addLoaderVA(const char *s, ...);
246 #endif
247  virtual bool hasLoaderSection(const char *name) const;
248  virtual int getLoaderSection(const char *name, int *slen=NULL) const;
249  virtual int getLoaderSectionStart(const char *name, int *slen=NULL) const;
250 
251  // compression handling [see packer_c.cpp]
252 public:
253  static bool isValidCompressionMethod(int method);
254 protected:
255  const int *getDefaultCompressionMethods_8(int method, int level, int small=-1) const;
256  const int *getDefaultCompressionMethods_le32(int method, int level, int small=-1) const;
257  virtual const char *getDecompressorSections() const;
258  virtual unsigned getDecompressorWrkmemSize() const;
259  virtual void defineDecompressorSymbols();
260 
261  // filter handling [see packer_f.cpp]
262  virtual bool isValidFilter(int filter_id) const;
263  virtual void optimizeFilter(Filter *, const upx_byte *, unsigned) const { }
264  virtual void addFilter32(int filter_id);
265  virtual void defineFilterSymbols(const Filter *ft);
266 
267  // stub and overlay util
268  static void handleStub(InputFile *fi, OutputFile *fo, unsigned size);
269  virtual void checkOverlay(unsigned overlay);
270  virtual void copyOverlay(OutputFile *fo, unsigned overlay,
271  MemBuffer *buf, bool do_seek=true);
272 
273  // misc util
274  virtual unsigned getRandomId() const;
275 
276  // patch util
277  int patch_be16(void *b, int blen, unsigned old, unsigned new_);
278  int patch_be16(void *b, int blen, const void * old, unsigned new_);
279  int patch_be32(void *b, int blen, unsigned old, unsigned new_);
280  int patch_be32(void *b, int blen, const void * old, unsigned new_);
281  int patch_le16(void *b, int blen, unsigned old, unsigned new_);
282  int patch_le16(void *b, int blen, const void * old, unsigned new_);
283  int patch_le32(void *b, int blen, unsigned old, unsigned new_);
284  int patch_le32(void *b, int blen, const void * old, unsigned new_);
285  void checkPatch(void *b, int blen, int boff, int size);
286 
287  // relocation util
288  static upx_byte *optimizeReloc(upx_byte *in,unsigned relocnum,upx_byte *out,upx_byte *image,int bs,int *big, int bits);
289  static unsigned unoptimizeReloc(upx_byte **in,upx_byte *image,MemBuffer *out,int bs, int bits);
290  static upx_byte *optimizeReloc32(upx_byte *in,unsigned relocnum,upx_byte *out,upx_byte *image,int bs,int *big);
291  static unsigned unoptimizeReloc32(upx_byte **in,upx_byte *image,MemBuffer *out,int bs);
292  static upx_byte *optimizeReloc64(upx_byte *in,unsigned relocnum,upx_byte *out,upx_byte *image,int bs,int *big);
293  static unsigned unoptimizeReloc64(upx_byte **in,upx_byte *image,MemBuffer *out,int bs);
294 
295  // target endianness abstraction
296  unsigned get_te16(const void *p) const { return bele->get16(p); }
297  unsigned get_te32(const void *p) const { return bele->get32(p); }
298  upx_uint64_t get_te64(const void *p) const { return bele->get64(p); }
299  void set_te16(void *p, unsigned v) const { bele->set16(p, v); }
300  void set_te32(void *p, unsigned v) const { bele->set32(p, v); }
301  void set_te64(void *p, upx_uint64_t v) const { bele->set64(p, v); }
302 
303 protected:
304  const N_BELE_RTP::AbstractPolicy *bele; // target endianness
305  InputFile *fi;
306  off_t file_size; // will get set by constructor
307  PackHeader ph; // must be filled by canUnpack()
308  int ph_format;
309  int ph_version;
310 
311  // compression buffers
312  MemBuffer ibuf; // input
313  MemBuffer obuf; // output
314 
315  // UI handler
316  UiPacker *uip;
317 
318  // linker
319  Linker *linker;
320 
321 private:
322  // private to checkPatch()
323  void *last_patch;
324  int last_patch_len;
325  int last_patch_off;
326 
327 private:
328  // disable copy and assignment
329  Packer(const Packer &); // {}
330  Packer& operator= (const Packer &); // { return *this; }
331 };
332 
333 
334 #endif /* already included */
335 
336 /* vim:set ts=4 sw=4 et: */
Definition: mem.h:37
Definition: linker.h:35
Definition: options.h:45
Definition: conf.h:620
Definition: file.h:89
Definition: packer.h:115
Definition: packmast.h:41
Definition: conf.h:574
Definition: file.h:121
Definition: ui.h:40
Definition: filter.h:53
Definition: bele.h:55
Definition: packer.h:47