Compare commits

...

209 Commits

Author SHA1 Message Date
Markus F.X.J. Oberhumer 70632e5541 Bump release date. 2007-01-23 22:11:23 +01:00
John Reiser 0bba700105 merge 2007-01-23 10:35:20 -08:00
John Reiser b71aaccff3 fix amd64-linux.elf-entry.S invoking large programs (>3MB compressed) 2007-01-23 10:34:33 -08:00
Markus F.X.J. Oberhumer 7271ae9611 Small updates. 2007-01-23 13:50:39 +01:00
László Molnár 6e32dff2ad armpe_tester.c updated to work with files containing 4 sections 2007-01-17 21:53:18 +01:00
László Molnár 8f7c898c08 use an exception instead of assert() for overlay checking (bug #1624840) 2007-01-16 12:58:35 +01:00
Markus F.X.J. Oberhumer f4a9815f48 Keep entries sorted in stub/Makefile. 2007-01-15 07:46:22 +01:00
John Reiser 0f8d5c7e98 arm-linux.kernel.vmlinux.S remove unused sections 2007-01-14 13:40:50 -08:00
Markus F.X.J. Oberhumer 5e83596a1b Enter 2007. 2007-01-14 13:08:58 +01:00
Markus F.X.J. Oberhumer 6361213e07 More portability fixes. 2007-01-14 12:47:38 +01:00
John Reiser 9c59a5d9b6 p_vmlinx test jig for ARM 2007-01-13 17:30:03 -08:00
John Reiser bb04844bd5 Decompressor for UPX_F_VMLINUX_ARM follows ELF convention 2007-01-13 15:26:05 -08:00
Markus F.X.J. Oberhumer 0b988176fa Portability fixes. 2007-01-10 17:16:59 +01:00
Markus F.X.J. Oberhumer a354f18a2d Consistently use .arch nojumps on i086 and i386. 2007-01-09 22:40:01 +01:00
Markus F.X.J. Oberhumer a7ca0fec88 Merge. 2007-01-09 18:31:13 +01:00
Markus F.X.J. Oberhumer 06eec508df Cosmetic macros.S cleanups. 2007-01-09 18:27:53 +01:00
John Reiser 10dc580a3a tweak i386-linux.kernel.vmlinux-head.S 2007-01-08 13:56:47 -08:00
John Reiser 2f6ae3ef01 merge 2007-01-07 16:33:04 -08:00
John Reiser 392e803905 vmlinux/AMD64 works 2007-01-07 16:31:46 -08:00
John Reiser 83a5fb585b ELF External_Note 2007-01-03 06:54:48 -08:00
László Molnár c6205ffbe0 tls index should be zero after decompression 2007-01-02 18:16:16 +01:00
Markus F.X.J. Oberhumer c04737ce20 Cosmetic cleanup. 2006-12-31 15:51:17 +01:00
John Reiser 11b92172fe PackVmlinuxBase my_boot_label; kernel Makefiles 2006-12-25 13:55:28 -08:00
László Molnár 3a6c574376 pe: correctly handle import table with 0 entries during decompression (#1620733) 2006-12-24 16:25:36 +01:00
Markus F.X.J. Oberhumer b21ce925fb Factor out a common Packer::defineFilterSymbols(). Enable filters
0x49 and 0x49 for all i386-dos32.* formats. Needs testing.
2006-12-22 16:39:42 +01:00
Markus F.X.J. Oberhumer de9dcc4ed6 Enable filters 0x49 and 0x46 for win32/pe. This needs some more testing. 2006-12-22 15:28:14 +01:00
Markus F.X.J. Oberhumer 9e77dbfe20 Added an assertion to make sure I've really understood the semantics
of the ctok32 filter length.
2006-12-22 15:19:51 +01:00
Markus F.X.J. Oberhumer 4cee0676a4 Consistently rename section names of ctok32 filter. 2006-12-22 14:22:45 +01:00
Markus F.X.J. Oberhumer 8ad9d21db3 Also add ICHECK() calls to p_armpe.cpp. 2006-12-22 13:37:19 +01:00
Markus F.X.J. Oberhumer 8ba8317eea sf.net bug #1620733: As a very first step, added two calls to
ICHECK(dname,1). Of course we still need a proper fix for this.
2006-12-22 13:35:39 +01:00
Markus F.X.J. Oberhumer d221187f24 Misc cosmetical cleanups. 2006-12-22 12:36:55 +01:00
Markus F.X.J. Oberhumer db54ec294f Added some missing stub/tmp/*.bin.dump files. 2006-12-20 10:50:49 +01:00
John Reiser 1d39796e3f PackVmlinuxBase::canPack bug for AMD64 with holes between PT_LOAD 2006-12-19 18:18:47 -08:00
John Reiser cd6a318903 cleanup merge 2006-12-19 16:19:19 -08:00
John Reiser 73090b98ab merge 2006-12-19 16:16:20 -08:00
John Reiser 745de1abab refactor PackVmlinuxBase::pack() 2006-12-19 16:12:59 -08:00
John Reiser 961031efc1 make_st_info() 2006-12-19 16:12:15 -08:00
Markus F.X.J. Oberhumer 2487595778 vmlinux: U32 already has target-endian representation, so there is no need
to call BeLePolicy::get32() here.
2006-12-19 22:39:37 +01:00
John Reiser 5c4863d504 refactor PackVmlinuxBase ::canUnpack(), ::unpack() 2006-12-19 10:58:20 -08:00
Markus F.X.J. Oberhumer 5e3a658932 Made a method pure virtual. 2006-12-19 16:21:57 +01:00
Markus F.X.J. Oberhumer cb4704c821 Cosmetic cleanups. 2006-12-19 15:22:50 +01:00
Markus F.X.J. Oberhumer cc0b7d1492 Use the preprocessor to make sure that the ELF types are PODs. 2006-12-19 14:43:14 +01:00
Markus F.X.J. Oberhumer f8ebbf8b08 Rework p_elf.h. 2006-12-19 14:24:35 +01:00
Markus F.X.J. Oberhumer 8795f60bf1 vmlinux: use template types throughout. 2006-12-19 11:06:58 +01:00
Markus F.X.J. Oberhumer f00c0a9436 Fix typo. 2006-12-19 11:04:47 +01:00
Markus F.X.J. Oberhumer 767bc71870 Expose integral types in p_elf.h. 2006-12-19 10:49:13 +01:00
John Reiser 4c068e3e00 PackVmlinuxBase::canPack(); templates are fun! 2006-12-18 22:55:38 -08:00
John Reiser 277d862172 PackVmlinuxBase try template definitions in .cpp file 2006-12-18 20:17:10 -08:00
John Reiser dbed6a47bb PackVmlinuxBase use simple templates 2006-12-18 20:08:24 -08:00
Markus F.X.J. Oberhumer 94f3749784 vmlinux refactoring: move destructor into PackVmlinuxBase. 2006-12-19 00:48:38 +01:00
Markus F.X.J. Oberhumer 728e6d851e Introduce ElfClass and PackVmlinuxBase for refactoring elf based packers. 2006-12-19 00:37:35 +01:00
Markus F.X.J. Oberhumer 11e863545f Strip trailing whitespace. 2006-12-18 16:56:14 +01:00
Markus F.X.J. Oberhumer dde49f0bb4 Try to avoid fatal filter failures by better scanning during the setup phase. 2006-12-18 16:54:14 +01:00
Markus F.X.J. Oberhumer a37a75aecc First step for preprocessing dumps with xstrip.py. Not working yet. 2006-12-18 16:39:57 +01:00
John Reiser e43e3aeb1c arm-linux.kernel documentation update for Debian on nslu2 2006-12-17 18:49:38 -08:00
John Reiser a8fe529814 arm-linux.kernel preserve .e_flags 2006-12-17 17:39:47 -08:00
John Reiser d9f5e2bb08 arm-linux.kernel alignment fix 2006-12-17 16:34:21 -08:00
John Reiser dfa83b0ac8 arm-linux.kernel methods 2006-12-17 15:34:13 -08:00
John Reiser bd5cef1411 unfilter for arm-linux.kernel 2006-12-17 14:53:10 -08:00
John Reiser cd70b48831 src/stub/src/arch/arm/v5a directory 2006-12-17 13:24:14 -08:00
John Reiser 50ebf8088a R_ARM_ABS8 2006-12-17 13:19:37 -08:00
John Reiser c5cfb7eb40 more arm-linux.kernel work 2006-12-16 22:02:51 -08:00
John Reiser bccaafda6d arm-linux stub interfacing for lzma 2006-12-16 17:16:32 -08:00
John Reiser bf0086d7b5 arm-linux.kernel decompressor 2006-12-16 14:52:22 -08:00
John Reiser 7e65938ca6 fix filename in initial comment 2006-12-16 08:40:41 -08:00
John Reiser 112eff2509 add UPX_F_VMLINUX_AMD64, UPX_F_VMLINUX_ARM 2006-12-16 08:13:34 -08:00
Markus F.X.J. Oberhumer d7837d9179 Use FT_ULTRA_BRUTE. 2006-12-12 10:06:24 +01:00
Markus F.X.J. Oberhumer 6cdd057f80 Coding style cleanups. 2006-12-12 10:05:57 +01:00
Markus F.X.J. Oberhumer 5a03b213fb More stricter check in xstrip.py. 2006-12-12 07:50:05 +01:00
Markus F.X.J. Oberhumer f270213246 Make sure ph.first_offset_found is set. 2006-12-12 07:49:50 +01:00
László Molnár 2e1795c5ba win32/pe: loadconf data should not be put into section 2 2006-12-10 23:42:27 +01:00
Markus F.X.J. Oberhumer 732d6710d3 Remove misleading "const" from Linker::preprocessXX(). 2006-12-10 00:38:28 +01:00
Markus F.X.J. Oberhumer edf384d2ee Micro-optimization: save 1 byte in tmt/adam stub. 2006-12-09 13:56:47 +01:00
László Molnár c307640826 use memcmp instead of strncmp when searching for ljmp 2006-12-08 19:20:35 +01:00
Markus F.X.J. Oberhumer a77b598f82 Implement a micro-optimization which has been on our TODO list for ages:
remove "or ebp,-1" when not needed
2006-12-08 09:20:14 +01:00
Markus F.X.J. Oberhumer 217420cfa5 Also verifyOverlappingDecompression() for watcom/le. 2006-12-06 12:20:22 +01:00
Markus F.X.J. Oberhumer f2b9dff596 More work so that watom/le now uses compressWithFilters(). 2006-12-06 11:08:32 +01:00
Markus F.X.J. Oberhumer ae945ed315 Clean up help and avoid using backticks as quoting chars. 2006-12-06 08:11:55 +01:00
Markus F.X.J. Oberhumer 770c153c76 Start using FT_ULTRA_BRUTE. 2006-12-06 07:42:43 +01:00
Markus F.X.J. Oberhumer 29c4a7e606 Remove debugging leftover. 2006-12-06 07:34:57 +01:00
Markus F.X.J. Oberhumer 8875470b37 Refactored compressWithFilters(). 2006-12-06 07:27:23 +01:00
Markus F.X.J. Oberhumer 6e52364bcb Minor cleanup of callback code. 2006-12-05 17:09:18 +01:00
Markus F.X.J. Oberhumer 7015d616b4 Whitespace changes. 2006-12-05 17:06:37 +01:00
László Molnár 92e6da3260 use the current version of http://www.gnu.org/licenses/gpl.txt 2006-12-05 12:16:42 +01:00
László Molnár 9220b6f1d5 win32/pe should only handle ix86 files 2006-12-03 10:46:14 +01:00
Markus F.X.J. Oberhumer 1d0d538d0c Added new option '--ultra-brute'. 2006-12-01 02:47:46 +01:00
Markus F.X.J. Oberhumer 83052eafae Minor cleanups. 2006-12-01 00:57:03 +01:00
Markus F.X.J. Oberhumer fa95c3c4a2 Display full format name with --fileinfo. 2006-11-30 23:34:19 +01:00
Markus F.X.J. Oberhumer 665dcf221b Cosmetic cleanup. 2006-11-30 23:21:47 +01:00
Markus F.X.J. Oberhumer 8f73dbd253 Mention --compress-icons=3. 2006-11-30 23:18:21 +01:00
Markus F.X.J. Oberhumer 826312cbad Show all supported formats in show_help(). 2006-11-30 23:17:22 +01:00
Markus F.X.J. Oberhumer 72a18f2b3f Added Packer::getFullName() method. 2006-11-29 06:44:48 +01:00
Markus F.X.J. Oberhumer a6b5e3d0ae Bump version for next release. 2006-11-29 05:41:39 +01:00
Markus F.X.J. Oberhumer 1b321f4fa3 Added tag for RELEASE_291. 2006-11-29 05:14:25 +01:00
Markus F.X.J. Oberhumer fbde0b9f35 Bump release date. 2006-11-29 03:43:29 +01:00
Markus F.X.J. Oberhumer 0e5f5e54cc Initalize isrtm member. 2006-11-27 17:35:16 +01:00
Markus F.X.J. Oberhumer cbb5902066 Improve xstrip.py. 2006-11-25 15:36:56 +01:00
Markus F.X.J. Oberhumer 92ec1b0598 Add and use stub/scripts/xstrip.py. 2006-11-23 05:27:40 +01:00
Markus F.X.J. Oberhumer a62fc3abff Try to remove .shstrtab, .strtab and .symtab sections. This does not seem to
work with objcopy.
2006-11-23 03:31:43 +01:00
Markus F.X.J. Oberhumer 08f8e55446 More updates on bin2h.py. 2006-11-23 03:11:53 +01:00
Markus F.X.J. Oberhumer 68f54a3247 Updated bin2h.py. 2006-11-23 02:23:39 +01:00
Markus F.X.J. Oberhumer 29c099fe56 Disallow --exact with --overlay=strip. 2006-11-22 19:29:07 +01:00
Markus F.X.J. Oberhumer 76b81c7b35 More stricter check for arm-wince Debian. 2006-11-22 18:52:57 +01:00
László Molnár d6b33ffd6b pe: --compress-icons=3 option added to compress all icons 2006-11-22 15:28:35 +01:00
Markus F.X.J. Oberhumer 16b9873fa8 Quick workaround for arm-wince build with Debian cross-compiler packages. 2006-11-22 01:56:59 +01:00
Markus F.X.J. Oberhumer ba4a686d1c Fix endian issue in execve formats. 2006-11-21 18:42:38 +01:00
László Molnár 4be3d79e12 arm/pe: fix "missing" icon & version info resource problem for wince 5 2006-11-21 18:25:23 +01:00
Markus F.X.J. Oberhumer 2569b09dbe Added debugging option --disable-random-id. 2006-11-21 18:17:51 +01:00
Markus F.X.J. Oberhumer 5d71e69941 Added two checks for throwCantPackExact. 2006-11-21 18:01:16 +01:00
Markus F.X.J. Oberhumer 16163bf20b Initial support for option '--exact'. 2006-11-21 17:53:11 +01:00
Markus F.X.J. Oberhumer f1a97fecbd Minor cleanups. 2006-11-21 17:35:22 +01:00
Markus F.X.J. Oberhumer a050f82f0e Implemented the remaining missing pieces of compress_zlib. 2006-11-21 17:19:24 +01:00
Markus F.X.J. Oberhumer ef7beea334 Cosmetic cleanups. 2006-11-21 16:17:47 +01:00
Markus F.X.J. Oberhumer 3f4acb33f9 First step for possibly using ElfLinker with linux execve/interp/shell stubs
as well.
2006-11-21 16:00:25 +01:00
Markus F.X.J. Oberhumer 14822e6395 Now that it seems to work, disable usage of pre-compressed stubs again. 2006-11-21 07:14:07 +01:00
Markus F.X.J. Oberhumer e82db4ed38 Use proper const_cast. 2006-11-21 06:32:13 +01:00
Markus F.X.J. Oberhumer 87b7ea9cf3 Add LZMA support for pre-compressed stubs. 2006-11-21 06:09:04 +01:00
Markus F.X.J. Oberhumer 787b1fceff Actually generate and use pre-compressed stubs. Currently this is mainly
for testing as the self-packed upx binary does get _larger_ this way.
2006-11-21 05:29:29 +01:00
Markus F.X.J. Oberhumer 140d6ad839 Avoid compiler warning. 2006-11-21 05:09:01 +01:00
Markus F.X.J. Oberhumer 46e8e22236 Prepare generating pre-compressed stubs. 2006-11-21 05:03:25 +01:00
Markus F.X.J. Oberhumer c386db2b33 Small cosmetic changes. 2006-11-21 05:01:54 +01:00
Markus F.X.J. Oberhumer 8dad091c6b Decompress pre-compressed stubs in Linker::init(). 2006-11-21 05:01:00 +01:00
Markus F.X.J. Oberhumer 3365ccbb9c Implemented upx_zlib_decompress(). 2006-11-21 04:42:47 +01:00
Markus F.X.J. Oberhumer 2ced230965 Updated packers to use new stub names. 2006-11-21 03:40:11 +01:00
Markus F.X.J. Oberhumer 989d10a3e1 Rebuilt all stubs with new bin2h.py and --ident=auto-stub. 2006-11-21 03:36:48 +01:00
Markus F.X.J. Oberhumer 62d8c69774 Enhanced bin2h.py: added --ident=auto, added --compress=XXX. 2006-11-21 03:34:08 +01:00
Markus F.X.J. Oberhumer cf704257b0 Remove some traces of patch_le32. 2006-11-20 18:19:37 +01:00
Markus F.X.J. Oberhumer a6cb6f57d3 Introduce Packer::relocateLoader(). This is the first step of finally getting
rid of all Packer::patchXXX() methods.
2006-11-20 18:10:23 +01:00
Markus F.X.J. Oberhumer 141c703ed5 Use ld option --no-warn-mismatch when generating binary output. 2006-11-20 17:36:04 +01:00
John Reiser 796d58867b use separate stub/armeb-linux.elf-entry and fold 2006-11-20 08:02:28 -08:00
Markus F.X.J. Oberhumer 2f483ec8e8 Fix compression ratio check. 2006-11-20 13:48:34 +01:00
Markus F.X.J. Oberhumer e338918773 Disable new/delete for bele policies. 2006-11-20 12:57:49 +01:00
Markus F.X.J. Oberhumer d9effc58cf Added initial version of armeb-linux.elf stubs. Completely untested. 2006-11-20 12:40:57 +01:00
Markus F.X.J. Oberhumer 05d03f97fc Introduce Packer::bele. 2006-11-20 12:01:59 +01:00
Markus F.X.J. Oberhumer 03e891c0e8 Remove implicit magic from OptVar copy operator and introduce oassign()
function instead.
2006-11-20 11:04:31 +01:00
Markus F.X.J. Oberhumer 4dfe9d52e9 Don't be too strict when checking the compression ratio (sf.net
feature request #1596111).
2006-11-20 09:40:46 +01:00
John Reiser 9e65692b69 Merge 2006-11-19 14:32:28 -08:00
John Reiser 0687c9a57a PackLinuxElf32::ARM_buildLoader endianness bugs 2006-11-19 14:28:15 -08:00
Markus F.X.J. Oberhumer ffe1287016 Added option '--cpr-lzma-ds=XX'. 2006-11-19 18:50:35 +01:00
Markus F.X.J. Oberhumer 75b7e7260f Merge. 2006-11-19 05:16:12 +01:00
Markus F.X.J. Oberhumer d631e081bc arm-linux.elf: make two symbols global. 2006-11-19 05:09:01 +01:00
John Reiser db5843d904 branch merge 2006-11-18 19:57:56 -08:00
John Reiser 5ec16153f7 PackLinuxElf64amd::defineSymbols forgot a get_native64() 2006-11-18 19:52:55 -08:00
Markus F.X.J. Oberhumer 8c873ccdc8 watcom/le: initialize memory when aligning. 2006-11-18 21:59:59 +01:00
Markus F.X.J. Oberhumer c95088f8d5 Merge. 2006-11-18 20:55:07 +01:00
Markus F.X.J. Oberhumer 519fa55df7 ps1/exe: fill pad.code section with zeros. 2006-11-18 20:54:10 +01:00
John Reiser b8dda033ed branch merge 2006-11-18 11:51:23 -08:00
John Reiser 0359e9c5c7 members of struct l_info loader header must be little endian 2006-11-18 11:42:08 -08:00
Markus F.X.J. Oberhumer d822b4a62a Store shentsize in target byte-order. 2006-11-18 18:25:11 +01:00
Markus F.X.J. Oberhumer d9e8c953b1 Fixed some ElfLinker endian issues. 2006-11-18 17:43:29 +01:00
Markus F.X.J. Oberhumer 9eca502026 Make upx build with gcc-2.95 again. 2006-11-18 14:37:22 +01:00
Markus F.X.J. Oberhumer cd0efe3edb Some atari/tos cleanups. 2006-11-18 02:39:11 +01:00
Markus F.X.J. Oberhumer 8146e9cbcd Implemented some small atari/tos optimizations. 2006-11-17 18:47:33 +01:00
Markus F.X.J. Oberhumer 5d95275024 Add some more calls to f-objstrip. 2006-11-17 14:50:59 +01:00
Markus F.X.J. Oberhumer 49a97eea4b More brandelf.py updates. 2006-11-17 14:50:42 +01:00
Markus F.X.J. Oberhumer 36e9c27e9c Updated brandelf.py. 2006-11-16 22:23:01 +01:00
Markus F.X.J. Oberhumer 6e5153cd07 Minor Makefile updates. 2006-11-16 21:14:58 +01:00
Markus F.X.J. Oberhumer c73da864c8 Avoid -Wshadow warnings. 2006-11-16 20:14:14 +01:00
Markus F.X.J. Oberhumer 071bb75700 Use new addLoader() method. 2006-11-16 20:12:53 +01:00
Markus F.X.J. Oberhumer 99374de340 Clean up stub sources. 2006-11-16 19:36:13 +01:00
Markus F.X.J. Oberhumer db7ae4ed5d Improve Packer:addLoader(). We're still somewhat limited because of gcc-bug
#29823 (see http://gcc.gnu.org/PR29823).
2006-11-16 18:52:20 +01:00
Markus F.X.J. Oberhumer e61f481881 Added .DELETE_ON_ERROR rules. 2006-11-16 18:49:34 +01:00
Markus F.X.J. Oberhumer 396a3ad2fc Small atari cleanups. 2006-11-13 10:51:45 +01:00
Markus F.X.J. Oberhumer be235ddc38 Removed unused Packer::freezeLoader(). Changed return type of
buildLoader() from "int" to "void".
2006-11-12 20:57:08 +01:00
Markus F.X.J. Oberhumer 9e72ecd93d Fix version date. 2006-11-12 18:49:48 +01:00
Markus F.X.J. Oberhumer 8e0bd936eb atari/tos now seems to work again. 2006-11-12 18:25:46 +01:00
Markus F.X.J. Oberhumer 9d0270dcd6 We have to bswap32 lzma_properties on big-endian machines. 2006-11-12 18:10:42 +01:00
Markus F.X.J. Oberhumer 713415c354 Fix broken "glibc sscanf bug workaround". 2006-11-12 14:47:50 +01:00
Markus F.X.J. Oberhumer 786550572e More work on atari/tos. 2006-11-12 13:46:38 +01:00
Markus F.X.J. Oberhumer 46caeddc81 Added some more debugging support to Linker. 2006-11-12 13:45:27 +01:00
Markus F.X.J. Oberhumer 71bfde2bfe Bump tentative release date. 2006-11-12 10:59:27 +01:00
Markus F.X.J. Oberhumer 76771b845a Started work on atari/tos. 2006-11-12 10:58:04 +01:00
Markus F.X.J. Oberhumer a74e239e28 Major cleanup of ElfLinker. 2006-11-12 10:57:18 +01:00
Markus F.X.J. Oberhumer 6e763b0b42 Updated options. 2006-11-12 10:56:17 +01:00
Markus F.X.J. Oberhumer 2f41ece017 Minor cleanups. 2006-11-10 13:49:22 +01:00
Markus F.X.J. Oberhumer 01cd5fe0d5 Added tag BRANCHPOINT_FOR_upx2.hg . 2006-11-08 21:09:50 +01:00
Markus F.X.J. Oberhumer ed12ff7bb3 Updated NEWS from 2.03 release. 2006-11-07 19:56:15 +01:00
Markus F.X.J. Oberhumer f1386bb60d Update NEWS. 2006-11-07 14:07:43 +01:00
Markus F.X.J. Oberhumer 417bd06e76 Fixed --brute and --lzma for dos/exe. 2006-11-07 13:58:32 +01:00
Markus F.X.J. Oberhumer 91e46e3cf8 Small cleanups. 2006-11-07 13:43:43 +01:00
Markus F.X.J. Oberhumer deb5139c4d Re-enable --crp-ms= option. 2006-11-07 13:37:46 +01:00
Markus F.X.J. Oberhumer 862ac5d014 Update options_t::crp_t to directly use the XXX_compress_config_t types. 2006-11-07 13:11:36 +01:00
Markus F.X.J. Oberhumer 028235d421 Keep variable names sorted. 2006-11-07 10:24:54 +01:00
Markus F.X.J. Oberhumer 143d399849 Updated two "xchg" commands to produce byte-identical results with UPX 2.02. 2006-11-07 09:35:00 +01:00
László Molnár 375f171e47 dos/com&sys: correctly set carry bit by using "sub si,-xx" instead of "add si,xx" 2006-11-06 17:54:37 +01:00
László Molnár 387edcf4b2 dos/com: fix fatal bug #1589758 2006-11-03 15:52:20 +01:00
Markus F.X.J. Oberhumer 011cd37cfb Small cleanup of arm sources. 2006-10-30 14:10:51 +01:00
Markus F.X.J. Oberhumer 0d4254f319 Added tc_objdump_disasm_options. 2006-10-30 13:21:48 +01:00
Markus F.X.J. Oberhumer 4c407c2850 Rebuild all stubs. Minor Makefile cleanup. 2006-10-25 04:08:59 +02:00
John Reiser 829e2d6c5d set e_shentsize to work around bug in binutils [mostly cosmetic] 2006-10-24 09:43:50 -07:00
John Reiser a31c4bd474 more renaming for i386-linux.kernel.vmlinux-head.h 2006-10-24 09:29:01 -07:00
John Reiser 17f24dc377 PackBvmlinuzI386 allow x86_64 2006-10-18 08:35:25 -07:00
John Reiser de3e9f2809 vmlinuz/386 fix for physical_start not at bzimage_offset 2006-10-16 17:18:19 -07:00
John Reiser 4442a282e1 fix filename in #includ 2006-10-16 10:52:57 -07:00
John Reiser 261010f23d fix comment 2006-10-16 06:12:58 -07:00
John Reiser ede44ca6ee vmlinux/386 naming convention for source files 2006-10-16 06:11:49 -07:00
John Reiser 452a953234 vmlinux/386 check for __ksymtab; fix unpack 2006-10-15 14:51:02 -07:00
John Reiser 2b122562ad new file i386-linux.kernel.head-vmlinux.S 2006-10-14 14:55:10 -07:00
John Reiser 6891bc3da3 vmlinux/i386: fix filters, 0x400000 start, integration with kernel build 2006-10-14 14:52:30 -07:00
Markus F.X.J. Oberhumer b31b8cd7f0 Added option '--crp-lzma-fb='. Started tuning lzma compression
levels '-1' and '-2'.
2006-10-12 14:23:22 +02:00
Markus F.X.J. Oberhumer e1379ac5ce Removed debugging leftover. 2006-10-12 13:48:07 +02:00
Markus F.X.J. Oberhumer 0ef3f75d7a Introduced class OptVar for tracking optionally set options. Also
added three new options for finetuning lzma compression.
2006-10-12 13:47:15 +02:00
Markus F.X.J. Oberhumer 407a9e5be0 Clean up NEWS. 2006-10-11 13:47:12 +02:00
Markus F.X.J. Oberhumer 892bb9bf30 Re-add "beta" string to versions. 2006-10-11 13:06:17 +02:00
Markus F.X.J. Oberhumer 47ac871a12 Added version_string() functions for the compression algorithms. Also
reserved M_DEFLATE and added a mostly empty compress_zlib.cpp.
2006-10-11 12:56:28 +02:00
László Molnár a38c3e7f6d ps1: initialize an uninitialized variable 2006-10-10 15:44:02 +02:00
Markus F.X.J. Oberhumer 08818355d1 Updated README.SRC. 2006-10-10 11:23:32 +02:00
Markus F.X.J. Oberhumer 0a68afef00 Bump version for next release. 2006-10-08 22:38:57 +02:00
Markus F.X.J. Oberhumer 2c0783e327 Added tag for RELEASE_290. 2006-10-08 22:35:47 +02:00
328 changed files with 44035 additions and 42081 deletions
+3
View File
@@ -2,10 +2,13 @@
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
b82ef51896199484afe5b0553af7d1e59b7ce428 BRANCHPOINT_FOR_upx2.hg
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net
+14 -15
View File
@@ -1,8 +1,8 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
+21 -5
View File
@@ -2,22 +2,38 @@
User visible changes for UPX
==================================================================
Changes in 2.90 (08 Oct 2006):
Changes in 2.92 beta (23 Jan 2007):
* new option '--ultra-brute' which tries even more variants
* slightly improved compression ratio for some files when
using '--brute' or '--ultra-brute'
* bug fixes
Changes in 2.91 beta (29 Nov 2006):
* assorted bug fixes
* arm/pe: fix "missing" icon & version info resource problem for wince 5
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
Changes in 2.90 beta (08 Oct 2006):
* LZMA algorithm support for most of the 32-bit and 64-bit file formats;
use new option '--lzma' to enable
* new format: BSD/elf386 supporting FreeBSD, NetBSD and OpenBSD
via auto-detection of PT_NOTE or EI_OSABI
* arm/pe: all the NRV compression methods are now supported
(only NRV2D is missing in thumb mode)
* linux/elf386, linux/ElfAMD remember /proc/self/exe in environment
* vmlinuz/386: fixed zlib uncompression problem on dos
* major source code change: the runtime decompression stubs are now
* linux/elf386, linux/ElfAMD: remember /proc/self/exe in environment
* major source code changes: the runtime decompression stubs are now
built from internal ELF objects
==================================================================
Changes in 2.03 (07 Nov 2006):
* bvmlinuz/386: fix for kernels not at 0x100000; also allow x86_64
* linux/elf386: work around Linux kernel bug (0-length .bss needs PF_W)
Changes in 2.02 (13 Aug 2006):
* linux/386: work around Linux kernel bug (".bss" requires PF_W)
* linux/ppc32, mach/ppc32: compressed programs now work on a 405 CPU
* vmlinuz/386: fixed zlib uncompression problem on dos
* vmlinuz/386: fixed zlib uncompression problem on DOS
Changes in 2.01 (06 Jun 2006):
* arm/pe: better DLL support
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net
+4 -4
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net
@@ -108,9 +108,9 @@ THE FUTURE
COPYRIGHT
=========
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
This program may be used freely, and you are welcome to
redistribute it under certain conditions.
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net
+8 -3
View File
@@ -75,13 +75,18 @@ Tools needed to build/modify the UPX sources
To compile the packer sources
-----------------------------
set the environment variable UPX_UCLDIR to point to your
UCL installation, e.g.
Set the environment variable UPX_UCLDIR to point to your
UCL build directory, e.g.
set UPX_UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
export UPX_UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
then type
Set the environment variable UPX_LZMADIR to point to your
to your unpacked lzma443.tar.bz2 source directory, e.g.
export UPX_LZMADIR=$HOME/local/src/lzma-4.43 (Unix)
Finally type
make
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net
+1 -7
View File
@@ -1,4 +1,4 @@
UPX TODO list. Last updated 2006-03-11.
UPX TODO list. Last updated 2006-12-08.
IMPORTANT PROBLEMS THAT SHOULD BE FIXED SOON:
@@ -41,8 +41,6 @@ ALL FORMATS
- implement `--cpu=486' option to use bswap on the 32-bit formats
(if cpu >= 486)
- consider removing "or ebp,-1" when not needed
FORMAT DJGPP2/COFF
==================
@@ -86,10 +84,6 @@ FORMAT WATCOM/LE
- handle holes in the file
- implement compressWithFilters()
- add a call to verifyOverlappingDecompression()
FORMAT WIN16/NE
===============
+2 -1
View File
@@ -25,7 +25,7 @@ endif
# //
# ************************************************************************/
top_srcdir = ..
top_srcdir ?= ..
PACKAGE = upx
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
@@ -81,4 +81,5 @@ mostlyclean clean distclean maintainer-clean:
###
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
.DELETE_ON_ERROR: $(BUILT_SOURCES)
+1 -1
View File
@@ -1,5 +1,5 @@
Decompressing ELF Directly to Memory on Linux/x86
Copyright (C) 2000-2006 John F. Reiser jreiser@BitWagon.com
Copyright (C) 2000-2007 John F. Reiser jreiser@BitWagon.com
References:
<elf.h> definitions for the ELF file format
+12 -33
View File
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
=head1 ABSTRACT
The Ultimate Packer for eXecutables
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net
@@ -138,6 +138,9 @@ B<--help>: prints the help
B<--version>: print the version of B<UPX>
B<--exact>: when compressing, require to be able to get a byte-identical file
after decompression with option B<-d>
[ ...to be written... - type `B<upx --help>' for now ]
@@ -172,38 +175,13 @@ Note that compression level B<--best> can be somewhat slow for large
files, but you definitely should use it when releasing a final version
of your program.
Quick start for achieving the best compression ratio:
=over 4
Try B<upx --brute myfile.exe>.
=back
Details for achieving the best compression ratio:
Quick info for achieving the best compression ratio:
=over 4
=item *
Use the compression level B<--best>.
=item *
Try one or both of the options B<--all-methods> and B<--all-filters>.
=item *
Try the option B<--crp-ms=NUMBER>. This uses more memory during compression
to achieve a (slightly) better compression ratio.
NUMBER must be a decimal value from 10000 to 999999, inclusive.
The default value is 10000 (ten thousand).
=item *
Info: the option B<--brute> is an abbrevation for the options
B<S<--best> S<--all-methods> S<--all-filters> S<--crp-ms=999999>>.
Try B<upx --brute myfile.exe> or even B<upx --ultra-brute myfile.exe>.
=item *
@@ -852,7 +830,7 @@ Screensavers are supported, with the restriction that the filename
must end with ".scr" (as screensavers are handled slightly different
than normal exe files).
UPX compressed PE files has some minor memory overhead (usually in the
UPX compressed PE files have some minor memory overhead (usually in the
10 - 30 kbytes range) which can be seen by specifying the "-i" command
line switch during compression.
@@ -872,6 +850,7 @@ Extra options available for this executable format:
--compress-icons=1 Compress all but the first icon.
--compress-icons=2 Compress all icons which are not in the
first icon directory. [DEFAULT]
--compress-icons=3 Compress all icons.
--compress-resources=0 Don't compress any resources at all.
@@ -947,13 +926,13 @@ Please report all bugs immediately to the authors.
=head1 COPYRIGHT
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 2000-2007 John F. Reiser
Copyright (C) 2002-2006 Jens Medoch
Copyright (C) 2002-2007 Jens Medoch
This program may be used freely, and you are welcome to
redistribute it under certain conditions.
+1 -23
View File
@@ -51,22 +51,10 @@ ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
DEFS += -DWITH_LZMA
INCLUDES += -I$(UPX_LZMADIR)
endif
# you should set envvar UPX_LUADIR to point to your unpacked lua-5.1.1.tar.gz
# [disabled for now]
ifneq ($(wildcard $(UPX_LUADIR)/src/lua.h),)
##DEFS += -DWITH_LUA
##upx_SOURCES_LUA := $(wildcard $(UPX_LUADIR)/src/*.c)
##upx_SOURCES_LUA := $(filter-out %lua.c, $(upx_SOURCES_LUA))
##upx_SOURCES_LUA := $(filter-out %luac.c, $(upx_SOURCES_LUA))
##upx_OBJECTS_LUA := $(notdir $(upx_SOURCES_LUA:.c=$(objext)))
##upx_OBJECTS_LUA := $(addprefix lua_,$(upx_OBJECTS_LUA))
##upx_OBJECTS += $(upx_OBJECTS_LUA)
else
##$(error please set UPX_LUADIR)
endif
all: upx$(exeext)
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS)
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
$($(notdir $@).PRE_LINK_STEP)
@@ -86,16 +74,6 @@ compress_lzma$(objext) : CXXFLAGS += -Wno-unused
##compress_lzma$(objext) : CXXFLAGS += -Wno-error
endif
ifneq ($(strip $(upx_OBJECTS_LUA)),)
$(upx_OBJECTS_LUA) : lua_%.o : $(UPX_LUADIR)/src/%.c
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
ifeq ($(USE_GNUC),1)
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-cast-align
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-cast-qual
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-error
endif
endif
mostlyclean clean distclean maintainer-clean:
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
+147 -16
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -183,81 +183,143 @@ inline void set_le64(void *p, acc_uint64l_t v)
// get signed values, i.e. sign-extend
**************************************************************************/
inline int sign_extend(int v, int bits)
inline int sign_extend(unsigned v, unsigned bits)
{
const unsigned sign_bit = 1u << (bits - 1);
v |= 0u - (v & sign_bit);
return v;
v &= sign_bit | (sign_bit - 1);
//v = (v ^ sign_bit) - sign_bit;
v |= 0 - (v & sign_bit);
return (int) v;
}
inline acc_int64l_t sign_extend(acc_int64l_t v, int bits)
inline acc_int64l_t sign_extend(acc_uint64l_t v, unsigned bits)
{
const acc_uint64l_t sign_bit = ACC_UINT64_C(1) << (bits - 1);
v |= ACC_UINT64_C(0) - (v & sign_bit);
return v;
v &= sign_bit | (sign_bit - 1);
//v = (v ^ sign_bit) - sign_bit;
v |= 0 - (v & sign_bit);
return (acc_int64l_t) v;
}
inline int get_be16_signed(const void *p)
{
int v = get_be16(p);
unsigned v = get_be16(p);
return sign_extend(v, 16);
}
inline int get_be24_signed(const void *p)
{
int v = get_be24(p);
unsigned v = get_be24(p);
return sign_extend(v, 24);
}
inline int get_be32_signed(const void *p)
{
int v = get_be32(p);
unsigned v = get_be32(p);
return sign_extend(v, 32);
}
inline acc_int64l_t get_be64_signed(const void *p)
{
acc_int64l_t v = get_be64(p);
acc_uint64l_t v = get_be64(p);
return sign_extend(v, 64);
}
inline int get_le16_signed(const void *p)
{
int v = get_le16(p);
unsigned v = get_le16(p);
return sign_extend(v, 16);
}
inline int get_le24_signed(const void *p)
{
int v = get_le24(p);
unsigned v = get_le24(p);
return sign_extend(v, 24);
}
inline int get_le32_signed(const void *p)
{
int v = get_le32(p);
unsigned v = get_le32(p);
return sign_extend(v, 32);
}
inline acc_int64l_t get_le64_signed(const void *p)
{
acc_int64l_t v = get_le64(p);
acc_uint64l_t v = get_le64(p);
return sign_extend(v, 64);
}
/*************************************************************************
// swab (bswap)
**************************************************************************/
inline unsigned acc_swab16(unsigned v)
{
return ((v & 0x00ff) << 8) |
((v & 0xff00) >> 8);
}
inline unsigned acc_swab32(unsigned v)
{
return ((v & 0x000000ff) << 24) |
((v & 0x0000ff00) << 8) |
((v & 0x00ff0000) >> 8) |
((v & 0xff000000) >> 24);
}
inline unsigned acc_swab16p(const acc_uint16e_t *p)
{
return acc_swab16(*p);
}
inline unsigned acc_swap32p(const acc_uint32e_t *p)
{
return acc_swab32(*p);
}
inline void acc_swab16s(acc_uint16e_t *p)
{
*p = acc_swab16(*p);
}
inline void acc_swab32s(acc_uint32e_t *p)
{
*p = acc_swab32(*p);
}
inline void acc_ua_swab16s(void *p)
{
set_be16(p, get_le16(p));
}
inline void acc_ua_swab32s(void *p)
{
set_be32(p, get_le32(p));
}
/*************************************************************************
// classes for portable unaligned access
//
// Important: these classes must be PODs (Plain Old Data), i.e. no
// constructor, no destructor, no virtual functions and no default
// assignment operator, and all fields must be public(!).
//
// [Actually we _can_ use a safe non-POD subset, but for this we need
// to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
**************************************************************************/
struct BE16
{
unsigned char d[2];
//inline BE16() { }
//BE16(unsigned v) { set_be16(d, v); }
BE16& operator = (unsigned v) { set_be16(d, v); return *this; }
BE16& operator += (unsigned v) { set_be16(d, get_be16(d) + v); return *this; }
BE16& operator -= (unsigned v) { set_be16(d, get_be16(d) - v); return *this; }
@@ -278,6 +340,9 @@ struct BE32
{
unsigned char d[4];
//inline BE32() { }
//BE32(unsigned v) { set_be32(d, v); }
BE32& operator = (unsigned v) { set_be32(d, v); return *this; }
BE32& operator += (unsigned v) { set_be32(d, get_be32(d) + v); return *this; }
BE32& operator -= (unsigned v) { set_be32(d, get_be32(d) - v); return *this; }
@@ -298,6 +363,9 @@ struct BE64
{
unsigned char d[8];
//inline BE64() { }
//BE64(acc_uint64l_t v) { set_be64(d, v); }
BE64& operator = (acc_uint64l_t v) { set_be64(d, v); return *this; }
BE64& operator += (acc_uint64l_t v) { set_be64(d, get_be64(d) + v); return *this; }
BE64& operator -= (acc_uint64l_t v) { set_be64(d, get_be64(d) - v); return *this; }
@@ -318,6 +386,9 @@ struct LE16
{
unsigned char d[2];
//inline LE16() { }
//LE16(unsigned v) { set_le16(d, v); }
LE16& operator = (unsigned v) { set_le16(d, v); return *this; }
LE16& operator += (unsigned v) { set_le16(d, get_le16(d) + v); return *this; }
LE16& operator -= (unsigned v) { set_le16(d, get_le16(d) - v); return *this; }
@@ -338,6 +409,9 @@ struct LE32
{
unsigned char d[4];
//inline LE32() { }
//LE32(unsigned v) { set_le32(d, v); }
LE32& operator = (unsigned v) { set_le32(d, v); return *this; }
LE32& operator += (unsigned v) { set_le32(d, get_le32(d) + v); return *this; }
LE32& operator -= (unsigned v) { set_le32(d, get_le32(d) - v); return *this; }
@@ -358,6 +432,9 @@ struct LE64
{
unsigned char d[8];
//inline LE64() { }
//LE64(acc_uint64l_t v) { set_le64(d, v); }
LE64& operator = (acc_uint64l_t v) { set_le64(d, v); return *this; }
LE64& operator += (acc_uint64l_t v) { set_le64(d, get_le64(d) + v); return *this; }
LE64& operator -= (acc_uint64l_t v) { set_le64(d, get_le64(d) - v); return *this; }
@@ -417,11 +494,47 @@ template <class T> T* operator + (const LE64& v, T* ptr);
template <class T> T* operator - (T* ptr, const LE64& v);
/*************************************************************************
// global overloads
**************************************************************************/
#if 1 && !defined(ALIGN_DOWN)
inline unsigned ALIGN_DOWN(unsigned a, const LE32& b) { return ALIGN_DOWN(a, (unsigned) b); }
inline unsigned ALIGN_DOWN(const LE32& a, unsigned b) { return ALIGN_DOWN((unsigned) a, b); }
inline unsigned ALIGN_UP (unsigned a, const LE32& b) { return ALIGN_UP (a, (unsigned) b); }
inline unsigned ALIGN_UP (const LE32& a, unsigned b) { return ALIGN_UP ((unsigned) a, b); }
#endif
#if !defined(UPX_MAX)
inline unsigned UPX_MAX(unsigned a, const BE16& b) { return UPX_MAX(a, (unsigned) b); }
inline unsigned UPX_MAX(const BE16& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
inline unsigned UPX_MIN(unsigned a, const BE16& b) { return UPX_MIN(a, (unsigned) b); }
inline unsigned UPX_MIN(const BE16& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
inline unsigned UPX_MAX(unsigned a, const BE32& b) { return UPX_MAX(a, (unsigned) b); }
inline unsigned UPX_MAX(const BE32& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
inline unsigned UPX_MIN(unsigned a, const BE32& b) { return UPX_MIN(a, (unsigned) b); }
inline unsigned UPX_MIN(const BE32& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
inline unsigned UPX_MAX(unsigned a, const LE16& b) { return UPX_MAX(a, (unsigned) b); }
inline unsigned UPX_MAX(const LE16& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
inline unsigned UPX_MIN(unsigned a, const LE16& b) { return UPX_MIN(a, (unsigned) b); }
inline unsigned UPX_MIN(const LE16& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
inline unsigned UPX_MAX(unsigned a, const LE32& b) { return UPX_MAX(a, (unsigned) b); }
inline unsigned UPX_MAX(const LE32& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
inline unsigned UPX_MIN(unsigned a, const LE32& b) { return UPX_MIN(a, (unsigned) b); }
inline unsigned UPX_MIN(const LE32& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
#endif
/*************************************************************************
// misc
**************************************************************************/
// for use with qsort()
extern "C" {
int __acc_cdecl_qsort be16_compare(const void *, const void *);
int __acc_cdecl_qsort be24_compare(const void *, const void *);
int __acc_cdecl_qsort be32_compare(const void *, const void *);
@@ -438,6 +551,7 @@ int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
} // extern "C"
// just for testing...
@@ -486,10 +600,14 @@ int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
// forward declarations
namespace N_BELE_CTP {
class BEPolicy; class LEPolicy;
extern const BEPolicy be_policy;
extern const LEPolicy le_policy;
}
namespace N_BELE_RTP {
class AbstractPolicy;
class BEPolicy; class LEPolicy;
extern const BEPolicy be_policy;
extern const LEPolicy le_policy;
}
namespace N_BELE_CTP {
@@ -504,6 +622,19 @@ namespace N_BELE_RTP {
#undef BELE_RTP
}
namespace N_BELE_CTP {
template <class T>
inline const N_BELE_RTP::AbstractPolicy* getRTP();
template <>
inline const N_BELE_RTP::AbstractPolicy* getRTP<BEPolicy>()
{ return &N_BELE_RTP::be_policy; }
template <>
inline const N_BELE_RTP::AbstractPolicy* getRTP<LEPolicy>()
{ return &N_BELE_RTP::le_policy; }
}
#endif /* already included */
+25 -15
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -53,7 +53,8 @@
#if defined(BELE_RTP)
struct AbstractPolicy
{
virtual inline ~AbstractPolicy() {}
inline AbstractPolicy() { }
virtual inline ~AbstractPolicy() { }
V bool isBE() C = 0;
V bool isLE() C = 0;
@@ -81,6 +82,9 @@ struct AbstractPolicy
S u24_compare_signed(const void *a, const void *b) C = 0;
S u32_compare_signed(const void *a, const void *b) C = 0;
S u64_compare_signed(const void *a, const void *b) C = 0;
// disable dynamic allocation
DISABLE_NEW_DELETE
};
#endif
@@ -90,14 +94,14 @@ struct BEPolicy
: public AbstractPolicy
#endif
{
inline BEPolicy() { }
#if defined(BELE_CTP)
typedef N_BELE_RTP::BEPolicy RTP_Policy;
enum { isBE = 1, isLE = 0 };
#elif defined(BELE_RTP)
typedef N_BELE_CTP::BEPolicy CTP_Policy;
V bool isBE() C { return CTP_Policy::isBE; }
V bool isLE() C { return CTP_Policy::isLE; }
#endif
V bool isBE() C { return true; }
V bool isLE() C { return false; }
typedef BE16 U16;
typedef BE32 U32;
@@ -152,10 +156,13 @@ struct BEPolicy
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
COMPILE_TIME_ASSERT_ALIGNED1(U16)
COMPILE_TIME_ASSERT_ALIGNED1(U32)
COMPILE_TIME_ASSERT_ALIGNED1(U64)
}
// disable dynamic allocation
DISABLE_NEW_DELETE
};
@@ -164,14 +171,14 @@ struct LEPolicy
: public AbstractPolicy
#endif
{
inline LEPolicy() { }
#if defined(BELE_CTP)
typedef N_BELE_RTP::LEPolicy RTP_Policy;
enum { isBE = 0, isLE = 1 };
#elif defined(BELE_RTP)
typedef N_BELE_CTP::LEPolicy CTP_Policy;
V bool isBE() C { return CTP_Policy::isBE; }
V bool isLE() C { return CTP_Policy::isLE; }
#endif
V bool isBE() C { return false; }
V bool isLE() C { return true; }
typedef LE16 U16;
typedef LE32 U32;
@@ -226,10 +233,13 @@ struct LEPolicy
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
COMPILE_TIME_ASSERT_ALIGNED1(U16)
COMPILE_TIME_ASSERT_ALIGNED1(U32)
COMPILE_TIME_ASSERT_ALIGNED1(U64)
}
// disable dynamic allocation
DISABLE_NEW_DELETE
};
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+9 -5
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -106,7 +106,7 @@ int upx_compress ( const upx_bytep src, unsigned src_len,
cresult->c_len = 0;
#endif
if (method < 0) {
if (0) {
}
#if defined(WITH_LZMA)
else if (M_IS_LZMA(method))
@@ -152,7 +152,7 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
if (cresult && cresult->method == 0)
cresult = NULL;
if (method < 0) {
if (0) {
}
#if defined(WITH_LZMA)
else if (M_IS_LZMA(method))
@@ -165,6 +165,10 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
#if defined(WITH_UCL)
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult);
#endif
#if defined(WITH_ZLIB)
else if (M_IS_DEFLATE(method))
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
#endif
else {
throwInternalError("unknown decompression method");
@@ -193,7 +197,7 @@ int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
unsigned overlap_overhead = src_off + src_len - *dst_len;
assert((int)overlap_overhead > 0);
if (method < 0) {
if (0) {
}
#if defined(WITH_LZMA)
else if (M_IS_LZMA(method))
+23 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -35,6 +35,7 @@
**************************************************************************/
#if defined(WITH_LZMA)
const char *upx_lzma_version_string(void);
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
@@ -53,6 +54,7 @@ int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
#if defined(WITH_NRV)
const char *upx_nrv_version_string(void);
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
@@ -71,6 +73,7 @@ int upx_nrv_test_overlap ( const upx_bytep buf, unsigned src_off,
#if defined(WITH_UCL)
const char *upx_ucl_version_string(void);
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
@@ -87,6 +90,24 @@ int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
const upx_compress_result_t *cresult );
#endif
#if defined(WITH_ZLIB)
const char *upx_zlib_version_string(void);
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
int method, int level,
const upx_compress_config_t *cconf,
upx_compress_result_t *cresult );
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult );
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
unsigned src_len, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult );
#endif
#endif /* already included */
+146 -69
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -28,6 +28,24 @@
#include "conf.h"
#include "compress.h"
void lzma_compress_config_t::reset()
{
memset(this, 0, sizeof(*this));
pos_bits.reset();
lit_pos_bits.reset();
lit_context_bits.reset();
dict_size.reset();
fast_mode = 2;
num_fast_bytes.reset();
match_finder_cycles = 0;
max_num_probs = 0;
}
#if !defined(WITH_LZMA)
extern int compress_lzma_dummy;
int compress_lzma_dummy = 0;
@@ -89,49 +107,49 @@ int compress_lzma_dummy = 0;
namespace MyLzma {
struct InStreamRam: public ISequentialInStream, public CMyUnknownImp
struct InStream: public ISequentialInStream, public CMyUnknownImp
{
MY_UNKNOWN_IMP
const Byte *Data; size_t Size; size_t Pos;
const Byte *b_buf; size_t b_size; size_t b_pos;
void Init(const Byte *data, size_t size) {
Data = data; Size = size; Pos = 0;
b_buf = data; b_size = size; b_pos = 0;
}
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP InStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 remain = Size - Pos;
if (size > remain) size = remain;
memmove(data, Data + Pos, size);
Pos += size;
size_t remain = b_size - b_pos;
if (size > remain) size = (UInt32) remain;
memcpy(data, b_buf + b_pos, size);
b_pos += size;
if (processedSize != NULL) *processedSize = size;
return S_OK;
}
struct OutStreamRam : public ISequentialOutStream, public CMyUnknownImp
struct OutStream : public ISequentialOutStream, public CMyUnknownImp
{
MY_UNKNOWN_IMP
Byte *Data; size_t Size; size_t Pos; bool Overflow;
Byte *b_buf; size_t b_size; size_t b_pos; bool overflow;
void Init(Byte *data, size_t size) {
Data = data; Size = size; Pos = 0; Overflow = false;
b_buf = data; b_size = size; b_pos = 0; overflow = false;
}
HRESULT WriteByte(Byte b) {
if (Pos >= Size) { Overflow = true; return E_FAIL; }
Data[Pos++] = b;
HRESULT WriteByte(Byte c) {
if (b_pos >= b_size) { overflow = true; return E_FAIL; }
b_buf[b_pos++] = c;
return S_OK;
}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP OutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 i;
for (i = 0; i < size && Pos < Size; i++)
Data[Pos++] = ((const Byte *)data)[i];
if (processedSize != NULL) *processedSize = i;
if (i != size) { Overflow = true; return E_FAIL; }
return S_OK;
size_t remain = b_size - b_pos;
if (size > remain) size = (UInt32) remain, overflow = true;
memcpy(b_buf + b_pos, data, size);
b_pos += size;
if (processedSize != NULL) *processedSize = size;
return overflow ? E_FAIL : S_OK;
}
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
@@ -151,6 +169,23 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
} // namespace
#if (ACC_CC_INTELC) && defined(__linux__)
# pragma warning(disable: 424) // #424: extra ";" ignored
#endif
#include "C/Common/Alloc.cpp"
#include "C/Common/CRC.cpp"
//#include "C/7zip/Common/InBuffer.cpp"
#include "C/7zip/Common/OutBuffer.cpp"
#include "C/7zip/Common/StreamUtils.cpp"
#include "C/7zip/Compress/LZ/LZInWindow.cpp"
//#include "C/7zip/Compress/LZ/LZOutWindow.cpp"
//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
#undef RC_NORMALIZE
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
@@ -158,15 +193,16 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
const upx_compress_config_t *cconf_parm,
upx_compress_result_t *cresult )
{
assert(method == M_LZMA);
assert(M_IS_LZMA(method));
assert(level > 0); assert(cresult != NULL);
int r = UPX_E_ERROR;
HRESULT rh;
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL;
lzma_compress_result_t *res = &cresult->result_lzma;
MyLzma::InStreamRam is; is.AddRef();
MyLzma::OutStreamRam os; os.AddRef();
MyLzma::InStream is; is.AddRef();
MyLzma::OutStream os; os.AddRef();
is.Init(src, src_len);
os.Init(dst, *dst_len);
@@ -174,27 +210,47 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
progress.cb = cb;
NCompress::NLZMA::CEncoder enc;
const PROPID propIDs[7] = {
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
NCoderPropID::kDictionarySize, // 3
NCoderPropID::kAlgorithm, // 4 _fastmode
NCoderPropID::kNumFastBytes, // 5
NCoderPropID::kMatchFinderCycles // 6
const PROPID propIDs[8] = {
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
NCoderPropID::kDictionarySize, // 3 ds
NCoderPropID::kAlgorithm, // 4 fm _fastmode
NCoderPropID::kNumFastBytes, // 5 fb
NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue
NCoderPropID::kMatchFinder // 7 mf
};
PROPVARIANT pr[7];
PROPVARIANT pr[8];
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
pr[7].vt = VT_BSTR;
// setup defaults
pr[0].uintVal = 2; // 0..4
pr[1].uintVal = 0; // 0..4
pr[2].uintVal = 3; // 0..8
pr[3].uintVal = 1024 * 1024;
pr[0].uintVal = 2; // 0 .. 4
pr[1].uintVal = 0; // 0 .. 4
pr[2].uintVal = 3; // 0 .. 8
pr[3].uintVal = 4 * 1024 * 1024; // 1 .. 2**30
pr[4].uintVal = 2;
pr[5].uintVal = 64; // 5..
pr[5].uintVal = 64; // 5 .. 273
pr[6].uintVal = 0;
#ifdef COMPRESS_MF_BT4
static wchar_t matchfinder[] = L"BT4";
#endif
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
pr[7].bstrVal = matchfinder;
#if 1
pr[0].uintVal = lzma_compress_config_t::pos_bits_t::default_value_c;
pr[1].uintVal = lzma_compress_config_t::lit_pos_bits_t::default_value_c;
pr[2].uintVal = lzma_compress_config_t::lit_context_bits_t::default_value_c;
pr[3].uintVal = lzma_compress_config_t::dict_size_t::default_value_c;
pr[5].uintVal = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
#endif
// method overrides
if (method >= 0x100) {
pr[0].uintVal = (method >> 16) & 15;
pr[1].uintVal = (method >> 12) & 15;
pr[2].uintVal = (method >> 8) & 15;
}
#if 0
// DEBUG - set sizes so that we use a maxmimum amount of stack.
// These settings cause res->num_probs == 3147574, i.e. we will
@@ -209,8 +265,11 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
case 1:
pr[3].uintVal = 256 * 1024;
pr[4].uintVal = 0;
pr[5].uintVal = 8;
break;
case 2:
pr[3].uintVal = 256 * 1024;
pr[4].uintVal = 0;
break;
case 3:
break;
@@ -234,17 +293,27 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
goto error;
}
// cconf overrides
if (lcconf)
{
oassign(pr[0].uintVal, lcconf->pos_bits);
oassign(pr[1].uintVal, lcconf->lit_pos_bits);
oassign(pr[2].uintVal, lcconf->lit_context_bits);
oassign(pr[3].uintVal, lcconf->dict_size);
oassign(pr[5].uintVal, lcconf->num_fast_bytes);
}
// limit dictionary size
if (pr[3].uintVal > src_len)
pr[3].uintVal = src_len;
// limit num_probs
if (cconf_parm && cconf_parm->conf_lzma.max_num_probs)
if (lcconf && lcconf->max_num_probs)
{
for (;;)
{
unsigned n = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
if (n <= cconf_parm->conf_lzma.max_num_probs)
if (n <= lcconf->max_num_probs)
break;
if (pr[1].uintVal > pr[2].uintVal)
{
@@ -265,9 +334,13 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
res->lit_pos_bits = pr[1].uintVal;
res->lit_context_bits = pr[2].uintVal;
res->dict_size = pr[3].uintVal;
res->fast_mode = pr[4].uintVal;
res->num_fast_bytes = pr[5].uintVal;
res->match_finder_cycles = pr[6].uintVal;
//res->num_probs = LzmaGetNumProbs(&s.Properties));
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
#ifndef _NO_EXCEPTIONS
try {
@@ -275,20 +348,20 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
# error
#endif
if (enc.SetCoderProperties(propIDs, pr, 7) != S_OK)
if (enc.SetCoderProperties(propIDs, pr, 8) != S_OK)
goto error;
if (enc.WriteCoderProperties(&os) != S_OK)
goto error;
if (os.Overflow) {
if (os.overflow) {
//r = UPX_E_OUTPUT_OVERRUN;
r = UPX_E_NOT_COMPRESSIBLE;
goto error;
}
assert(os.Pos == 5);
assert(os.b_pos == 5);
#if defined(USE_LZMA_PROPERTIES)
os.Pos = 1;
os.b_pos = 1;
#else
os.Pos = 0;
os.b_pos = 0;
// extra stuff in first byte: 5 high bits convenience for stub decompressor
unsigned t = res->lit_context_bits + res->lit_pos_bits;
os.WriteByte((t << 3) | res->pos_bits);
@@ -298,44 +371,33 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
rh = enc.Code(&is, &os, NULL, NULL, &progress);
#ifndef _NO_EXCEPTIONS
} catch(...) { return UPX_E_OUT_OF_MEMORY; }
} catch (...) { rh = E_OUTOFMEMORY; }
#endif
assert(is.Pos <= src_len);
assert(os.Pos <= *dst_len);
assert(is.b_pos <= src_len);
assert(os.b_pos <= *dst_len);
if (rh == E_OUTOFMEMORY)
r = UPX_E_OUT_OF_MEMORY;
else if (os.Overflow)
else if (os.overflow)
{
assert(os.Pos == *dst_len);
assert(os.b_pos == *dst_len);
//r = UPX_E_OUTPUT_OVERRUN;
r = UPX_E_NOT_COMPRESSIBLE;
}
else if (rh == S_OK)
{
assert(is.Pos == src_len);
assert(is.b_pos == src_len);
r = UPX_E_OK;
}
error:
*dst_len = os.Pos;
*dst_len = os.b_pos;
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
//printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
return r;
}
#include "C/Common/Alloc.cpp"
#include "C/Common/CRC.cpp"
//#include "C/7zip/Common/InBuffer.cpp"
#include "C/7zip/Common/OutBuffer.cpp"
#include "C/7zip/Common/StreamUtils.cpp"
#include "C/7zip/Compress/LZ/LZInWindow.cpp"
//#include "C/7zip/Compress/LZ/LZOutWindow.cpp"
//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
#undef RC_NORMALIZE
/*************************************************************************
// decompress
**************************************************************************/
@@ -352,7 +414,7 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
int method,
const upx_compress_result_t *cresult )
{
assert(method == M_LZMA);
assert(M_IS_LZMA(method));
// see res->num_probs above
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
@@ -391,6 +453,9 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
const lzma_compress_result_t *res = &cresult->result_lzma;
UNUSED(res);
//printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
}
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
if (!s.Probs)
@@ -426,7 +491,7 @@ int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
int method,
const upx_compress_result_t *cresult )
{
assert(method == M_LZMA);
assert(M_IS_LZMA(method));
// FIXME - implement this
// Note that Packer::verifyOverlappingDecompression() will
@@ -443,6 +508,18 @@ int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
}
/*************************************************************************
// misc
**************************************************************************/
const char *upx_lzma_version_string(void)
{
// FIXME
// return NULL;
return "4.43";
}
#endif /* WITH_LZMA */
/*
vi:ts=4:et:nowrap
+22 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -84,13 +84,14 @@ static int convert_errno_from_ucl(int r)
}
extern "C" {
static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
{
if (state != -1 && state != 3) return;
upx_callback_p cb = (upx_callback_p) user;
if (cb && cb->nprogress)
cb->nprogress(cb, a, b);
}
}}
/*************************************************************************
@@ -107,6 +108,8 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
int r;
assert(level > 0); assert(cresult != NULL);
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
ucl_progress_callback_t cb;
cb.callback = 0;
cb.user = NULL;
@@ -115,8 +118,7 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
cb.user = cb_parm;
}
ucl_compress_config_t cconf;
memset(&cconf, 0xff, sizeof(cconf));
ucl_compress_config_t cconf; cconf.reset();
if (cconf_parm)
cconf = cconf_parm->conf_ucl; // struct copy
@@ -134,7 +136,7 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
// prepare bit-buffer settings
cconf.bb_endian = 0;
cconf.bb_size = 0;
if (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16)
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
{
static const unsigned char sizes[3] = {32, 8, 16};
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
@@ -164,6 +166,10 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
return UPX_E_ERROR;
}
// make sure first_offset_found is set
if (res[6] == 0)
res[6] = 1;
return convert_errno_from_ucl(r);
}
@@ -268,6 +274,16 @@ int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
}
/*************************************************************************
// misc
**************************************************************************/
const char *upx_ucl_version_string(void)
{
return ucl_version_string();
}
#endif /* WITH_UCL */
/*
vi:ts=4:et:nowrap
+230
View File
@@ -0,0 +1,230 @@
/* compress_zlib.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
*/
#include "conf.h"
#include "compress.h"
void zlib_compress_config_t::reset()
{
memset(this, 0, sizeof(*this));
mem_level.reset();
window_bits.reset();
strategy.reset();
}
#if !defined(WITH_ZLIB)
extern int compress_zlib_dummy;
int compress_zlib_dummy = 0;
#else
#include <zlib.h>
static int convert_errno_from_zlib(int zr)
{
switch (zr)
{
case Z_OK: return UPX_E_OK;
case Z_DATA_ERROR: return UPX_E_ERROR;
case Z_NEED_DICT: return UPX_E_ERROR;
}
return UPX_E_ERROR;
}
/*************************************************************************
//
**************************************************************************/
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb_parm,
int method, int level,
const upx_compress_config_t *cconf_parm,
upx_compress_result_t *cresult )
{
assert(method == M_DEFLATE);
assert(level > 0); assert(cresult != NULL);
UNUSED(cb_parm);
int r = UPX_E_ERROR;
int zr;
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : NULL;
zlib_compress_result_t *res = &cresult->result_zlib;
if (level == 10)
level = 9;
zlib_compress_config_t::mem_level_t mem_level;
zlib_compress_config_t::window_bits_t window_bits;
zlib_compress_config_t::strategy_t strategy;
// cconf overrides
if (lcconf)
{
oassign(mem_level, lcconf->mem_level);
oassign(window_bits, lcconf->window_bits);
oassign(strategy, lcconf->strategy);
}
res->dummy = 0;
z_stream s;
s.zalloc = (alloc_func) 0;
s.zfree = (free_func) 0;
s.next_in = const_cast<upx_bytep>(src); // UNCONST
s.avail_in = src_len;
s.next_out = dst;
s.avail_out = *dst_len;
s.total_in = s.total_out = 0;
zr = deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
mem_level, strategy);
if (zr != Z_OK)
goto error;
zr = deflate(&s, Z_FINISH);
if (zr != Z_STREAM_END)
goto error;
zr = deflateEnd(&s);
if (zr != Z_OK)
goto error;
r = UPX_E_OK;
goto done;
error:
(void) deflateEnd(&s);
r = convert_errno_from_zlib(zr);
if (r == UPX_E_OK)
r = UPX_E_ERROR;
done:
if (r == UPX_E_OK)
{
if (s.avail_in != 0 || s.total_in != src_len)
r = UPX_E_ERROR;
}
assert(s.total_in <= src_len);
assert(s.total_out <= *dst_len);
*dst_len = s.total_out;
return r;
}
/*************************************************************************
//
**************************************************************************/
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult )
{
assert(method == M_DEFLATE);
UNUSED(method);
UNUSED(cresult);
int r = UPX_E_ERROR;
int zr;
z_stream s;
s.zalloc = (alloc_func) 0;
s.zfree = (free_func) 0;
s.next_in = const_cast<upx_bytep>(src); // UNCONST
s.avail_in = src_len;
s.next_out = dst;
s.avail_out = *dst_len;
s.total_in = s.total_out = 0;
zr = inflateInit2(&s, -15);
if (zr != Z_OK)
goto error;
zr = inflate(&s, Z_FINISH);
if (zr != Z_STREAM_END)
goto error;
zr = inflateEnd(&s);
if (zr != Z_OK)
goto error;
r = UPX_E_OK;
goto done;
error:
(void) inflateEnd(&s);
r = convert_errno_from_zlib(zr);
if (r == UPX_E_OK)
r = UPX_E_ERROR;
done:
if (r == UPX_E_OK)
{
if (s.avail_in != 0 || s.total_in != src_len)
r = UPX_E_INPUT_NOT_CONSUMED;
}
assert(s.total_in <= src_len);
assert(s.total_out <= *dst_len);
*dst_len = s.total_out;
return r;
}
/*************************************************************************
// test_overlap
**************************************************************************/
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
unsigned src_len, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult )
{
assert(method == M_DEFLATE);
// FIXME - implement this
// Note that Packer::verifyOverlappingDecompression() will
// verify the final result in any case.
UNUSED(buf);
unsigned overlap_overhead = src_off + src_len - *dst_len;
//printf("upx_zlib_test_overlap: %d\n", overlap_overhead);
if ((int)overlap_overhead >= 256)
return UPX_E_OK;
UNUSED(cresult);
return UPX_E_ERROR;
}
/*************************************************************************
// misc
**************************************************************************/
const char *upx_zlib_version_string(void)
{
return zlibVersion();
}
#endif /* WITH_ZLIB */
/*
vi:ts=4:et:nowrap
*/
+306 -182
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -40,8 +40,16 @@
#if ((ACC_OS_WIN32 || ACC_OS_WIN64) && ACC_CC_MWERKS) && defined(__MSL__)
# undef HAVE_UTIME_H /* this pulls in <windows.h> */
#endif
// FIXME - quick hack for arm-wince-gcc-3.4 (Debian pocketpc-*.deb packages)
#if 1 && (ACC_ARCH_ARM) && defined(__pe__) && !defined(_WIN32)
# undef HAVE_CHMOD
# undef HAVE_CHOWN
# undef HAVE_LSTAT
# undef HAVE_UTIME
#endif
// pragmas
#if (ACC_CC_BORLANDC)
# if (__BORLANDC__ < 0x0500)
# error "need Borland C++ 5.0 or newer"
@@ -96,6 +104,8 @@
# if (_MSC_VER >= 1400)
# pragma warning(disable: 4996) // W1: 'function': was declared deprecated
# endif
#elif (ACC_CC_SUNPROC)
//# pragma error_messages(off,"badargtype2w") // FIXME
#elif (ACC_CC_WATCOMC)
# if (__WATCOMC__ < 1100)
# error "need Watcom C++ 11.0c or newer"
@@ -159,11 +169,14 @@
# include <nrv/nrvconf.h>
#endif
#if defined(WITH_UCL)
# define ucl_compress_config_t REAL_ucl_compress_config_t
# include <ucl/uclconf.h>
# include <ucl/ucl.h>
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010300L)
# error "please upgrade your UCL installation"
# endif
# undef ucl_compress_config_t
# undef ucl_compress_config_p
#endif
#if !defined(__UPX_CHECKER)
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
@@ -176,91 +189,6 @@
#define upx_byte unsigned char
#define upx_bytep upx_byte *
#define UPX_E_OK (0)
#define UPX_E_ERROR (-1)
#define UPX_E_OUT_OF_MEMORY (-2)
#define UPX_E_NOT_COMPRESSIBLE (-3)
#define UPX_E_INPUT_OVERRUN (-4)
#define UPX_E_OUTPUT_OVERRUN (-5)
#define UPX_E_LOOKBEHIND_OVERRUN (-6)
#define UPX_E_EOF_NOT_FOUND (-7)
#define UPX_E_INPUT_NOT_CONSUMED (-8)
#define UPX_E_NOT_YET_IMPLEMENTED (-9)
#define UPX_E_INVALID_ARGUMENT (-10)
struct upx_callback_t;
#define upx_callback_p upx_callback_t *
typedef void* (__acc_cdecl *upx_alloc_func_t)
(upx_callback_p self, unsigned items, unsigned size);
typedef void (__acc_cdecl *upx_free_func_t)
(upx_callback_p self, void* ptr);
typedef void (__acc_cdecl *upx_progress_func_t)
(upx_callback_p, unsigned, unsigned);
struct upx_callback_t
{
#if 0
upx_alloc_func_t nalloc;
upx_free_func_t nfree;
#endif
upx_progress_func_t nprogress;
void * user1;
#if 0
unsigned user2;
unsigned user3;
#endif
};
struct lzma_compress_config_t
{
unsigned max_num_probs;
#if 0
unsigned pos_bits; // pb
unsigned lit_pos_bits; // lp
unsigned lit_context_bits; // lc
unsigned dict_size;
unsigned mf_passes;
#endif
void reset() { memset(this, 0, sizeof(*this)); }
};
#define upx_compress_config_p upx_compress_config_t *
struct upx_compress_config_t
{
lzma_compress_config_t conf_lzma;
ucl_compress_config_t conf_ucl;
void reset() {
conf_lzma.reset();
memset(&conf_ucl, 0xff, sizeof(conf_ucl));
}
};
struct lzma_compress_result_t
{
unsigned pos_bits; // pb
unsigned lit_pos_bits; // lp
unsigned lit_context_bits; // lc
unsigned dict_size;
unsigned num_probs;
};
struct ucl_compress_result_t
{
ucl_uint result[16];
};
struct upx_compress_result_t
{
#if 1
// debug
int method, level;
unsigned u_len, c_len;
#endif
lzma_compress_result_t result_lzma;
ucl_compress_result_t result_ucl;
};
/*************************************************************************
@@ -270,18 +198,6 @@ struct upx_compress_result_t
// malloc debuggers
#if defined(WITH_VALGRIND)
# include <valgrind/memcheck.h>
#elif defined(WITH_DMALLOC)
# define DMALLOC_FUNC_CHECK
# include <dmalloc.h>
#elif defined(WITH_GC)
# define GC_DEBUG
# include <gc/gc.h>
# undef malloc
# undef realloc
# undef free
# define malloc GC_MALLOC
# define realloc GC_REALLOC
# define free GC_FREE
#endif
#if !defined(VALGRIND_MAKE_WRITABLE)
@@ -299,6 +215,7 @@ struct upx_compress_result_t
#endif
// unconditionally turn on assertions
#undef NDEBUG
#include <assert.h>
@@ -375,18 +292,6 @@ struct upx_compress_result_t
#undef PAGE_MASK
#undef PAGE_SIZE
#undef __attribute_packed
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
# if (1 && (ACC_ARCH_I386))
# define __attribute_packed
# else
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
# endif
#else
# define __attribute_packed
#endif
#if !defined(O_BINARY)
# define O_BINARY 0
#endif
@@ -396,6 +301,19 @@ struct upx_compress_result_t
#endif
#undef __attribute_packed
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
# if (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386))
# define __attribute_packed
# else
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
# endif
#endif
#if !defined(__attribute_packed)
# define __attribute_packed
#endif
/*************************************************************************
//
**************************************************************************/
@@ -403,68 +321,52 @@ struct upx_compress_result_t
#define UNUSED(var) ACC_UNUSED(var)
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
#if 1
# define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
#define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
struct acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z[7]; } __attribute_packed; \
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 8*sizeof(b)+sizeof(a)) \
struct acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; } __attribute_packed; \
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \
}
#else
# define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
struct acc_tmp_t { b x; a y; b z[7]; } __attribute_packed; \
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 8*sizeof(b)+sizeof(a)) \
}
#endif
#if defined(__acc_alignof)
# define COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) \
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b))
#else
# define COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b)
#endif
#define COMPILE_TIME_ASSERT_ALIGNED1(a) __COMPILE_TIME_ASSERT_ALIGNOF(a,char)
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0])))
#if 0
#define ALIGN_DOWN(a,b) (((a) / (b)) * (b))
#define ALIGN_UP(a,b) ALIGN_DOWN((a) + ((b) - 1), b)
#define ALIGN_GAP(a,b) (ALIGN_UP(a,b) - (a))
#elif 1
template <class T>
inline T ALIGN_DOWN(const T& a, const T& b) { T r; r = (a / b) * b; return r; }
template <class T>
inline T ALIGN_UP (const T& a, const T& b) { T r; r = ((a + b - 1) / b) * b; return r; }
template <class T>
inline T ALIGN_GAP (const T& a, const T& b) { T r; r = ALIGN_UP(a, b) - a; return r; }
#else
inline unsigned ALIGN_DOWN(unsigned a, unsigned b) { return (a / b) * b; }
inline unsigned ALIGN_UP (unsigned a, unsigned b) { return ((a + b - 1) / b) * b; }
inline unsigned ALIGN_GAP (unsigned a, unsigned b) { return ALIGN_UP(a, b) - a; }
#endif
#if 0
#define UPX_MAX(a,b) ((a) >= (b) ? (a) : (b))
#define UPX_MIN(a,b) ((a) <= (b) ? (a) : (b))
#define UPX_MAX3(a,b,c) ((a) >= (b) ? UPX_MAX(a,c) : UPX_MAX(b,c))
#define UPX_MIN3(a,b,c) ((a) <= (b) ? UPX_MIN(a,c) : UPX_MIN(b,c))
#if 0 && defined(__cplusplus) && !defined(new) && !defined(delete)
// global operators - debug
inline void *operator new(size_t l)
{
void *p = malloc(l);
printf("new %6ld %p\n",(long)l,p);
fflush(stdout);
return p;
}
inline void *operator new[](size_t l)
{
void *p = malloc(l);
printf("new[] %6ld %p\n",(long)l,p);
fflush(stdout);
return p;
}
inline void operator delete(void *p)
{
printf("delete %p\n",p);
fflush(stdout);
if (p) free(p);
}
inline void operator delete[](void *p)
{
printf("delete[] %p\n",p);
fflush(stdout);
if (p) free(p);
}
#elif 1
template <class T>
inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a; }
template <class T>
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
#else
inline unsigned UPX_MAX(unsigned a, unsigned b) { return a < b ? b : a; }
inline unsigned UPX_MIN(unsigned a, unsigned b) { return a < b ? a : b; }
#endif
@@ -477,6 +379,14 @@ inline void operator delete[](void *p)
#define ByteArray(var, size) Array(unsigned char, var, size)
struct nocopy
{
inline nocopy() {}
private:
nocopy(const nocopy &); // undefined
nocopy& operator=(const nocopy &); // undefined
};
/*************************************************************************
// constants
@@ -496,28 +406,23 @@ inline void operator delete[](void *p)
#define EXIT_INTERNAL 1
// compression methods - DO NOT CHANGE
#define M_SKIP (-2)
#define M_END (-1)
#define M_NRV2B_LE32 2
#define M_NRV2B_8 3
#define M_NRV2B_LE16 4
#define M_NRV2D_LE32 5
#define M_NRV2D_8 6
#define M_NRV2D_LE16 7
#define M_NRV2E_LE32 8
#define M_NRV2E_8 9
#define M_NRV2E_LE16 10
#define M_CL1B_LE32 11
#define M_CL1B_8 12
#define M_CL1B_LE16 13
#define M_LZMA 14
// magic constants for patching
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
#define UPX_MAGIC2_LE32 0xD5D0D8A1
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
#define M_IS_LZMA(x) ((x) == M_LZMA)
// upx_compress() error codes
#define UPX_E_OK (0)
#define UPX_E_ERROR (-1)
#define UPX_E_OUT_OF_MEMORY (-2)
#define UPX_E_NOT_COMPRESSIBLE (-3)
#define UPX_E_INPUT_OVERRUN (-4)
#define UPX_E_OUTPUT_OVERRUN (-5)
#define UPX_E_LOOKBEHIND_OVERRUN (-6)
#define UPX_E_EOF_NOT_FOUND (-7)
#define UPX_E_INPUT_NOT_CONSUMED (-8)
#define UPX_E_NOT_YET_IMPLEMENTED (-9)
#define UPX_E_INVALID_ARGUMENT (-10)
// Executable formats. Note: big endian types are >= 128.
@@ -544,11 +449,13 @@ inline void operator delete[](void *p)
#define UPX_F_WINCE_ARM_PE 21
#define UPX_F_LINUX_ELF64_AMD 22
#define UPX_F_LINUX_ELF32_ARMLE 23
#define UPX_F_BSD_i386 24
#define UPX_F_BSD_ELF_i386 25
#define UPX_F_BSD_SH_i386 26
#define UPX_F_VMLINUX_AMD64 27
#define UPX_F_VMLINUX_ARM 28
#define UPX_F_PLAIN_TEXT 127
#define UPX_F_ATARI_TOS 129
@@ -558,8 +465,226 @@ inline void operator delete[](void *p)
#define UPX_F_LINUX_ELF32_ARMBE 133
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
#define UPX_MAGIC2_LE32 0xD5D0D8A1
// compression methods
#define M_ALL (-1)
#define M_END (-2)
#define M_NONE (-3)
#define M_SKIP (-4)
#define M_ULTRA_BRUTE (-5)
// compression methods - DO NOT CHANGE
#define M_NRV2B_LE32 2
#define M_NRV2B_8 3
#define M_NRV2B_LE16 4
#define M_NRV2D_LE32 5
#define M_NRV2D_8 6
#define M_NRV2D_LE16 7
#define M_NRV2E_LE32 8
#define M_NRV2E_8 9
#define M_NRV2E_LE16 10
//#define M_CL1B_LE32 11
//#define M_CL1B_8 12
//#define M_CL1B_LE16 13
#define M_LZMA 14
#define M_DEFLATE 15 /* zlib */
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
// filters
#define FT_END (-1)
#define FT_NONE (-2)
#define FT_SKIP (-3)
#define FT_ULTRA_BRUTE (-4)
/*************************************************************************
// compression - callback_t
**************************************************************************/
struct upx_callback_t;
#define upx_callback_p upx_callback_t *
#if 0
typedef void* (__acc_cdecl *upx_alloc_func_t)
(upx_callback_p self, unsigned items, unsigned size);
typedef void (__acc_cdecl *upx_free_func_t)
(upx_callback_p self, void* ptr);
#endif
typedef void (__acc_cdecl *upx_progress_func_t)
(upx_callback_p, unsigned, unsigned);
struct upx_callback_t
{
upx_progress_func_t nprogress;
void *user;
void reset() { memset(this, 0, sizeof(*this)); }
};
/*************************************************************************
// compression - config_t
**************************************************************************/
template <class T, T default_value, T min_value, T max_value>
struct OptVar
{
typedef T Type;
static const T default_value_c = default_value;
static const T min_value_c = min_value;
static const T max_value_c = max_value;
void assertValue() {
// FIXME: this generates annoying warnings "unsigned >= 0 is always true"
//assert((v >= min_value) && (v <= max_value));
}
OptVar() : v(default_value), is_set(0) { }
OptVar& operator= (const T other) {
v = other; is_set += 1;
assertValue();
return *this;
}
#if 0
#error
// there is too much implicit magic in this copy operator;
// better introduce an explicit "oassign" function.
OptVar& operator= (const OptVar& other) {
if (other.is_set) { v = other.v; is_set += 1; }
assertValue(); return *this;
}
#endif
void reset() { v = default_value; is_set = 0; }
operator T () const { return v; }
T v;
unsigned is_set;
};
// optional assignments
template <class T> inline void oassign(T& self, const T& other) {
if (other.is_set) { self.v = other.v; self.is_set += 1; }
}
#if 0
template <class V, class T> inline void oassign(V& v, const T& other) {
if (other.is_set) { v = other.v; }
}
#else
template <class T> inline void oassign(unsigned& v, const T& other) {
if (other.is_set) { v = other.v; }
}
#endif
struct lzma_compress_config_t
{
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lb
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
typedef OptVar<unsigned, (1u<<22), 1u, (1u<<30) > dict_size_t;
typedef OptVar<unsigned, 64u, 5u, 273u> num_fast_bytes_t;
pos_bits_t pos_bits; // pb
lit_pos_bits_t lit_pos_bits; // lp
lit_context_bits_t lit_context_bits; // lc
dict_size_t dict_size;
unsigned fast_mode;
num_fast_bytes_t num_fast_bytes;
unsigned match_finder_cycles;
unsigned max_num_probs;
void reset();
};
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
{
void reset() { memset(this, 0xff, sizeof(*this)); }
};
struct zlib_compress_config_t
{
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
mem_level_t mem_level; // ml
window_bits_t window_bits; // wb
strategy_t strategy; // st
void reset();
};
struct upx_compress_config_t
{
lzma_compress_config_t conf_lzma;
ucl_compress_config_t conf_ucl;
zlib_compress_config_t conf_zlib;
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); }
};
#define NULL_cconf ((upx_compress_config_t *) NULL)
/*************************************************************************
// compression - result_t
**************************************************************************/
struct lzma_compress_result_t
{
unsigned pos_bits; // pb
unsigned lit_pos_bits; // lp
unsigned lit_context_bits; // lc
unsigned dict_size;
unsigned fast_mode;
unsigned num_fast_bytes;
unsigned match_finder_cycles;
unsigned num_probs; // (computed result)
void reset() { memset(this, 0, sizeof(*this)); }
};
struct ucl_compress_result_t
{
ucl_uint result[16];
void reset() { memset(this, 0, sizeof(*this)); }
};
struct zlib_compress_result_t
{
unsigned dummy;
void reset() { memset(this, 0, sizeof(*this)); }
};
struct upx_compress_result_t
{
// debug
int method, level;
unsigned u_len, c_len;
lzma_compress_result_t result_lzma;
ucl_compress_result_t result_ucl;
zlib_compress_result_t result_zlib;
void reset() {
memset(this, 0, sizeof(*this));
result_lzma.reset(); result_ucl.reset(); result_zlib.reset();
}
};
/*************************************************************************
@@ -585,7 +710,6 @@ typedef ElfLinker Linker;
// main.cpp
extern const char *progname;
void init_options(struct options_t *o);
bool set_ec(int ec);
#if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
void e_exit(int ec) __attribute__((__noreturn__));
@@ -632,7 +756,7 @@ void do_files(int i, int argc, char *argv[]);
// help.cpp
void show_head(void);
void show_help(int x = 0);
void show_help(int verbose=0);
void show_license(void);
void show_usage(void);
void show_version(int);
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+7 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -85,6 +85,11 @@ void throwCantPack(const char *msg)
throw CantUnpackException(msg);
}
void throwCantPackExact()
{
throwCantPack("option '--exact' does not work with this file");
}
void throwFilterException()
{
throwCantPack("filter problem");
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -208,6 +208,7 @@ public:
#endif
void throwCantPack(const char *msg) NORET;
void throwCantPackExact() NORET;
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
void throwNotCompressible(const char *msg = NULL) NORET;
void throwAlreadyPacked(const char *msg = NULL) NORET;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -131,7 +131,7 @@ public:
off_t getBytesWritten() const { return bytes_written; }
// FIXME - these won't work when using the `--stdout' option
// FIXME - these won't work when using the '--stdout' option
virtual void seek(off_t off, int whence)
{
assert(!opt->to_stdout);
+20 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -61,10 +61,10 @@ const FilterImp::FilterEntry *FilterImp::getFilter(int id)
memset(filter_map, 0xff, sizeof(filter_map));
for (int i = 0; i < n_filters; i++)
{
int fid = filters[i].id;
assert(fid >= 0 && fid <= 255);
assert(filter_map[fid] == 0xff);
filter_map[fid] = (unsigned char) i;
int filter_id = filters[i].id;
assert(filter_id >= 0 && filter_id <= 255);
assert(filter_map[filter_id] == 0xff);
filter_map[filter_id] = (unsigned char) i;
}
done = true;
}
@@ -85,6 +85,20 @@ bool Filter::isValidFilter(int filter_id)
return fe != NULL;
}
bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
{
if (!isValidFilter(filter_id))
return false;
if (filter_id == 0)
return true;
if (allowed_filters == NULL)
return false;
while (*allowed_filters != FT_END)
if (*allowed_filters++ == filter_id)
return true;
return false;
}
/*************************************************************************
// high level API
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -62,6 +62,7 @@ public:
bool scan(const upx_byte *buf, unsigned buf_len);
static bool isValidFilter(int filter_id);
static bool isValidFilter(int filter_id, const int *allowed_filters);
public:
// Will be set by each call to filter()/unfilter().
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+13 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -58,10 +58,18 @@ static int F(Filter *f)
// must not conflict with the mark.
// Note that unsigned comparison checks both edges of buffer.
for (ic = 0; ic < size - 5; ic++)
if (COND(b,ic) && get_le32(b+ic+1)+ic+1 >= size)
{
if (!COND(b,ic))
continue;
jc = get_le32(b+ic+1)+ic+1;
if (jc < size)
{
buf[b[ic+1]] |= 1;
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1;
}
else
buf[b[ic+1]] |= 1;
}
if (getcto(f, buf) < 0)
return -1;
@@ -79,8 +87,7 @@ static int F(Filter *f)
// try to detect 'real' calls only
if (jc < size)
{
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
return 1; // fail - buffer not restored
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U
set_be32(b+ic+1,jc+addvalue+cto);
#endif
+14 -7
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -57,10 +57,18 @@ static int F(Filter *f)
memset(buf,0,256);
for (ic = 0; ic < size - 5; ic++)
if (COND(b,ic,lastcall) && get_le32(b+ic+1)+ic+1 >= size)
{
if (!COND(b,ic,lastcall))
continue;
jc = get_le32(b+ic+1)+ic+1;
if (jc < size)
{
buf[b[ic+1]] |= 1;
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1;
}
else
buf[b[ic+1]] |= 1;
}
if (getcto(f, buf) < 0)
return -1;
@@ -78,8 +86,7 @@ static int F(Filter *f)
// try to detect 'real' calls only
if (jc < size)
{
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
return 1; // fail - buffer not restored
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U
set_be32(b+ic+1,jc+addvalue+cto);
#endif
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+14 -7
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -58,10 +58,18 @@ static int F(Filter *f)
memset(buf,0,256);
for (ic = 0; ic < size - 5; ic++)
if (COND(b,ic,lastcall,id) && get_le32(b+ic+1)+ic+1 >= size)
{
if (!COND(b,ic,lastcall,id))
continue;
jc = get_le32(b+ic+1)+ic+1;
if (jc < size)
{
buf[b[ic+1]] |= 1;
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1;
}
else
buf[b[ic+1]] |= 1;
}
if (getcto(f, buf) < 0)
return -1;
@@ -79,8 +87,7 @@ static int F(Filter *f)
// try to detect 'real' calls only
if (jc < size)
{
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
return 1; // fail - buffer not restored
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U
set_be32(b+ic+1,jc+addvalue+cto);
#endif
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+4 -4
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2004-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2004-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -58,7 +58,7 @@ static int F(Filter *f)
{
unsigned char buf[256];
unsigned short wbuf[256];
const size_t WW = (size_t)0 - (~(size_t)0) << W_CTO; // ???
const size_t WW = (size_t)0 - ((~(size_t)0) << W_CTO); // ???
memset(wbuf, 0, sizeof(wbuf));
memset(buf , 0, WW);
memset(buf + WW, 1, 256 - WW);
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -109,7 +109,7 @@ umin(unsigned const a, unsigned const b)
#define COND1(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
#define COND2(b,x,lc) (lc!=(x) && 0xf==b[(x)-1] && 0x80<=b[x] && b[x]<=0x8f)
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
#define F f_ctok32_e8e9_bswap_le
#define U u_ctok32_e8e9_bswap_le
#include "filter/ctok.h"
+137 -60
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -27,6 +27,9 @@
#include "conf.h"
#include "compress.h"
#include "packmast.h"
#include "packer.h"
/*************************************************************************
@@ -48,7 +51,7 @@ void show_head(void)
fg = con_fg(f,FG_GREEN);
con_fprintf(f,
" Ultimate Packer for eXecutables\n"
" Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006\n"
" Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007\n"
"UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n",
#if (ACC_OS_DOS16 || ACC_OS_DOS32)
V("d"),
@@ -88,7 +91,77 @@ void show_usage(void)
//
**************************************************************************/
void show_help(int x)
struct PackerNames
{
struct Entry {
const char* fname;
const char* sname;
};
Entry names[32];
size_t names_count;
const options_t *o;
PackerNames() : names_count(0), o(NULL) { }
void add(const Packer *p)
{
p->assertPacker();
assert(names_count < 32);
names[names_count].fname = p->getFullName(o);
names[names_count].sname = p->getName();
names_count++;
}
static Packer* visit(Packer *p, void *user)
{
PackerNames *self = (PackerNames *) user;
self->add(p);
return NULL;
}
static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) {
return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname);
}
static int __acc_cdecl_qsort cmp_sname(const void *a, const void *b) {
return strcmp(((const Entry *) a)->sname, ((const Entry *) b)->sname);
}
};
static void show_all_packers(FILE *f, int verbose)
{
options_t o; o.reset();
PackerNames pn; pn.o = &o;
PackMaster::visitAllPackers(pn.visit, NULL, &o, &pn);
qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), pn.cmp_fname);
size_t pos = 0;
for (size_t i = 0; i < pn.names_count; ++i)
{
const char *fn = pn.names[i].fname;
const char *sn = pn.names[i].sname;
if (verbose)
{
con_fprintf(f, " %-32s %s\n", fn, sn);
}
else
{
if (pos == 0) {
con_fprintf(f, " %s", fn);
pos = 2 + strlen(fn);
} else if (pos + 1 + strlen(fn) > 80) {
con_fprintf(f, "\n %s", fn);
pos = 2 + strlen(fn);
} else {
con_fprintf(f, " %s", fn);
pos += 1 + strlen(fn);
}
}
}
if (!verbose && pn.names_count)
con_fprintf(f, "\n");
}
/*************************************************************************
//
**************************************************************************/
void show_help(int verbose)
{
FILE *f = con_term;
int fg;
@@ -105,8 +178,8 @@ void show_help(int x)
" -d decompress -l list compressed file\n"
" -t test compressed file -V display version number\n"
" -h give %s help -L display software license\n%s",
x == 0 ? "" : " --best compress best (can be slow for big files)\n",
x == 0 ? "more" : "this", x == 0 ? "" : "\n");
verbose == 0 ? "" : " --best compress best (can be slow for big files)\n",
verbose == 0 ? "more" : "this", verbose == 0 ? "" : "\n");
fg = con_fg(f,FG_YELLOW);
con_fprintf(f,"Options:\n");
@@ -114,22 +187,29 @@ void show_help(int x)
con_fprintf(f,
" -q be quiet -v be verbose\n"
" -oFILE write output to `FILE'\n"
" -oFILE write output to 'FILE'\n"
//" -f force overwrite of output files and compression of suspicious files\n"
" -f force compression of suspicious files\n"
"%s%s"
, (x == 0) ? " -k keep backup files\n" : ""
, (verbose == 0) ? " -k keep backup files\n" : ""
#if 1
, (x > 0) ? " --no-color, --mono, --color, --no-progress change look\n" : ""
, (verbose > 0) ? " --no-color, --mono, --color, --no-progress change look\n" : ""
#else
, ""
#endif
);
if (x > 0)
if (verbose > 0)
{
fg = con_fg(f,FG_YELLOW);
con_fprintf(f,"\nBackup options:\n");
con_fprintf(f,"\nCompression tuning options:\n");
fg = con_fg(f,fg);
con_fprintf(f,
" --brute try all available compression methods & filters\n"
" --ultra-brute try even more compression variants\n"
"\n");
fg = con_fg(f,FG_YELLOW);
con_fprintf(f,"Backup options:\n");
fg = con_fg(f,fg);
con_fprintf(f,
" -k, --backup keep backup files\n"
@@ -221,7 +301,7 @@ void show_help(int x)
" --le produce LE output [default: EXE]\n"
"\n");
fg = con_fg(f,FG_YELLOW);
con_fprintf(f,"Options for win32/pe & rtm32/pe:\n");
con_fprintf(f,"Options for win32/pe, rtm32/pe & arm/pe:\n");
fg = con_fg(f,fg);
con_fprintf(f,
" --compress-exports=0 do not compress the export section\n"
@@ -229,6 +309,7 @@ void show_help(int x)
" --compress-icons=0 do not compress any icons\n"
" --compress-icons=1 compress all but the first icon\n"
" --compress-icons=2 compress all but the first icon directory [default]\n"
" --compress-icons=3 compress all icons\n"
" --compress-resources=0 do not compress any resources at all\n"
" --keep-resource=list do not compress resources specified by list\n"
" --strip-relocs=0 do not strip relocations\n"
@@ -238,43 +319,23 @@ void show_help(int x)
"\n");
}
con_fprintf(f,
"file.. executables to (de)compress\n"
"\n");
fg = con_fg(f,FG_YELLOW);
con_fprintf(f,"This version supports:\n");
fg = con_fg(f,fg);
con_fprintf(f," "
// TODO:
// support for mach/ppc32
// support for linux elf/ppc32
// support for linux elf/amd64
" arm/pe,"
" atari/tos,"
" bvmlinuz/386,"
" djgpp2/coff,"
" dos/com,"
" dos/exe,"
" dos/sys,"
"\n "
//" elks/8086,"
" linux/amd64,"
" linux/i386,"
" linux/ppc32,"
" mach/ppc32,"
" ps1/exe,"
" rtm32/pe,"
"\n "
" tmt/adam,"
" vmlinux/386,"
" vmlinuz/386,"
" watcom/le,"
//" win16/ne,"
" win32/pe"
"\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n"
// "\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details type `upx -L'.\n"
"");
con_fprintf(f, "file.. executables to (de)compress\n");
if (verbose > 0)
{
fg = con_fg(f,FG_YELLOW);
con_fprintf(f,"\nThis version supports:\n");
fg = con_fg(f,fg);
show_all_packers(f, verbose);
}
else
{
con_fprintf(f,"\nType '%s --help' for more detailed help.\n", progname);
}
con_fprintf(f,"\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n"
// "\nUPX comes with ABSOLUTELY NO WARRANTY; for details type 'upx -L'.\n"
"");
#if defined(DEBUG) || defined(TESTING)
fg = con_fg(f,FG_RED);
@@ -340,27 +401,43 @@ void show_license(void)
void show_version(int x)
{
FILE *f = stdout;
FILE *fp = stdout;
const char *v;
UNUSED(x);
UNUSED(v);
fprintf(f,"upx %s\n", UPX_VERSION_STRING);
fprintf(fp, "upx %s\n", UPX_VERSION_STRING);
#if defined(WITH_NRV)
fprintf(f,"NRV data compression library %s\n", nrv_version_string());
v = upx_nrv_version_string();
if (v != NULL && v[0])
fprintf(fp, "NRV data compression library %s\n", v);
#endif
#if defined(WITH_UCL)
fprintf(f,"UCL data compression library %s\n", ucl_version_string());
v = upx_ucl_version_string();
if (v != NULL && v[0])
fprintf(fp, "UCL data compression library %s\n", v);
#endif
#if 0 && defined(WITH_LZMA)
fprintf(f,"LZMA SDK version ???\n");
#if defined(WITH_ZLIB)
v = upx_zlib_version_string();
if (v != NULL && v[0])
fprintf(fp, "zlib data compression library %s\n", v);
#endif
fprintf(f,"Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n");
fprintf(f,"Copyright (C) 1996-2006 Laszlo Molnar\n");
fprintf(f,"Copyright (C) 2000-2006 John F. Reiser\n");
fprintf(f,"Copyright (C) 2002-2006 Jens Medoch\n");
#if defined(WITH_LZMA)
fprintf(f,"Copyright (C) 1999-2006 Igor Pavlov\n");
v = upx_lzma_version_string();
if (v != NULL && v[0])
fprintf(fp, "LZMA SDK version %s\n", v);
#endif
fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
fprintf(fp, "Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer\n");
fprintf(fp, "Copyright (C) 1996-2007 Laszlo Molnar\n");
fprintf(fp, "Copyright (C) 2000-2007 John F. Reiser\n");
fprintf(fp, "Copyright (C) 2002-2007 Jens Medoch\n");
#if defined(WITH_ZLIB)
fprintf(fp, "Copyright (C) 1995" "-2005 Jean-loup Gailly and Mark Adler\n");
#endif
#if defined(WITH_LZMA)
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
#endif
fprintf(fp, "UPX comes with ABSOLUTELY NO WARRANTY; for details type '%s -L'.\n", progname);
}
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+331 -161
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -29,7 +29,7 @@
#include "conf.h"
#include "linker.h"
static int hex(unsigned char c)
static unsigned hex(unsigned char c)
{
return (c & 0xf) + (c > '9' ? 9 : 0);
}
@@ -45,17 +45,20 @@ static bool update_capacity(unsigned size, unsigned *capacity)
return true;
}
/*************************************************************************
//
// Section
**************************************************************************/
ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a) :
name(strdup(n)), output(NULL), size(s), offset(0), align(a), next(NULL)
name(NULL), output(NULL), size(s), offset(0), p2align(a), next(NULL)
{
assert(name);
name = strdup(n);
assert(name != NULL);
input = malloc(s + 1);
assert(input);
assert(input != NULL);
memcpy(input, i, s);
((char *)input)[s] = 0;
}
ElfLinker::Section::~Section()
@@ -64,10 +67,17 @@ ElfLinker::Section::~Section()
free(input);
}
/*************************************************************************
// Symbol
**************************************************************************/
ElfLinker::Symbol::Symbol(const char *n, Section *s, unsigned o) :
name(strdup(n)), section(s), offset(o)
name(NULL), section(s), offset(o)
{
assert(name);
name = strdup(n);
assert(name != NULL);
assert(section != NULL);
}
ElfLinker::Symbol::~Symbol()
@@ -75,13 +85,111 @@ ElfLinker::Symbol::~Symbol()
free(name);
}
/*************************************************************************
// Relocation
**************************************************************************/
ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t,
const Symbol *v, unsigned a) :
section(s), offset(o), type(t), value(v), add(a)
{}
{
assert(section != NULL);
}
void ElfLinker::preprocessSections(char *start, const char *end)
/*************************************************************************
// ElfLinker
**************************************************************************/
ElfLinker::ElfLinker() :
bele(&N_BELE_RTP::le_policy),
input(NULL), output(NULL), head(NULL), tail(NULL),
sections(NULL), symbols(NULL), relocations(NULL),
nsections(0), nsections_capacity(0),
nsymbols(0), nsymbols_capacity(0),
nrelocations(0), nrelocations_capacity(0),
reloc_done(false)
{
}
ElfLinker::~ElfLinker()
{
delete [] input;
delete [] output;
unsigned ic;
for (ic = 0; ic < nsections; ic++)
delete sections[ic];
free(sections);
for (ic = 0; ic < nsymbols; ic++)
delete symbols[ic];
free(symbols);
for (ic = 0; ic < nrelocations; ic++)
delete relocations[ic];
free(relocations);
}
void ElfLinker::init(const void *pdata_v, int plen)
{
const upx_byte *pdata = (const upx_byte *) pdata_v;
if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0)
{
// decompress pre-compressed stub-loader
int method;
unsigned u_len, c_len;
if (pdata[4])
{
method = pdata[4];
u_len = get_le16(pdata + 5);
c_len = get_le16(pdata + 7);
pdata += 9;
assert(9 + c_len == (unsigned) plen);
}
else
{
method = pdata[5];
u_len = get_le32(pdata + 6);
c_len = get_le32(pdata + 10);
pdata += 14;
assert(14 + c_len == (unsigned) plen);
}
assert((unsigned) plen < u_len);
inputlen = u_len;
input = new upx_byte[inputlen + 1];
unsigned new_len = u_len;
int r = upx_decompress(pdata, c_len, input, &new_len, method, NULL);
if (r != 0 || new_len != u_len)
throwBadLoader();
}
else
{
inputlen = plen;
input = new upx_byte[inputlen + 1];
memcpy(input, pdata, inputlen);
}
input[inputlen] = 0; // NUL terminate
output = new upx_byte[inputlen];
outputlen = 0;
int pos = find(input, inputlen, "Sections:\n", 10);
assert(pos != -1);
char *psections = (char *) input + pos;
char *psymbols = strstr(psections, "SYMBOL TABLE:\n");
assert(psymbols != NULL);
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR ");
assert(prelocs != NULL);
preprocessSections(psections, psymbols);
preprocessSymbols(psymbols, prelocs);
preprocessRelocations(prelocs, (char*) input + inputlen);
addLoader("*UND*");
}
void ElfLinker::preprocessSections(char *start, char *end)
{
nsections = 0;
while (start < end)
@@ -107,36 +215,42 @@ void ElfLinker::preprocessSections(char *start, const char *end)
addSection("*UND*", NULL, 0, 0);
}
void ElfLinker::preprocessSymbols(char *start, const char *end)
void ElfLinker::preprocessSymbols(char *start, char *end)
{
nsymbols = 0;
while (start < end)
{
char section[1024];
char symbol[1024];
unsigned offset;
unsigned value, offset;
char *nextl = strchr(start, '\n');
assert(nextl != NULL);
if (sscanf(start, "%x%*8c %1024s %*x %1023s",
if (sscanf(start, "%x g *ABS* %x %1023s",
&value, &offset, symbol) == 3)
{
char *s = strstr(start, symbol);
s[strlen(symbol)] = 0;
addSymbol(s, "*ABS*", value);
assert(offset == 0);
}
else if (sscanf(start, "%x%*8c %1023s %*x %1023s",
&offset, section, symbol) == 3)
{
char *s = strstr(start, symbol);
s[strlen(symbol)] = 0;
if (strcmp(section, "*UND*") == 0)
offset = 0xdeaddead;
assert(strcmp(section, "*ABS*") != 0);
addSymbol(s, section, offset);
//printf("symbol %s preprocessed o=%x\n", s, offset);
}
start = nextl + 1;
}
}
void ElfLinker::preprocessRelocations(char *start, const char *end)
void ElfLinker::preprocessRelocations(char *start, char *end)
{
char sect[1024];
Section *section = NULL;
@@ -163,60 +277,80 @@ void ElfLinker::preprocessRelocations(char *start, const char *end)
unsigned add = 0;
if (char *p = strstr(symbol, "+0x"))
{
// Beware: sscanf("0xfffffffffffffffc", "%x", &add) ==> -1 == add
// because conversion stops after 32 bits for a non-long.
// Also, glibc-2.3.5 has a bug: even using "%lx" still gives -1 instead of -4.
long addend;
*p = 0; // terminate the symbol name
p+=3;
if ('f'==p[0] && 0==strncmp(p, "ffffffff", 8)) {
p+=8; // workaround a bug in glibc-2.3.5
p += 3;
if (strlen(p) == 16) {
// skip 8 leading chars if sign of char 9 matches
if (memcmp(p, "000000000", 9))
p += 8;
else if (memcmp(p, "fffffffff", 9))
p += 8;
}
sscanf(p, "%lx", &addend);
add = (unsigned)addend;
assert(strlen(p) == 8);
char *endptr = NULL;
unsigned long ul = strtoul(p, &endptr, 16);
add = (unsigned) ul;
assert(add == ul);
assert(endptr && *endptr == '\0');
}
addRelocation(section->name, offset, t, symbol, add);
//printf("relocation %s %x preprocessed\n", section->name, offset);
//printf("relocation %s %s %x %d preprocessed\n", section->name, symbol, offset, add);
}
start = nextl + 1;
}
}
ElfLinker::Section *ElfLinker::findSection(const char *name) const
ElfLinker::Section *ElfLinker::findSection(const char *name, bool fatal) const
{
for (unsigned ic = 0; ic < nsections; ic++)
if (strcmp(sections[ic]->name, name) == 0)
return sections[ic];
printf("unknown section %s\n", name);
abort();
if (fatal)
{
printf("unknown section %s\n", name);
abort();
}
return NULL;
}
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name) /*const*/
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name, bool fatal) const
{
for (unsigned ic = 0; ic < nsymbols; ic++)
if (strcmp(symbols[ic]->name, name) == 0)
return symbols[ic];
// FIXME: this should be a const method !
if ('*' == name[0]) // *ABS*
return addSymbol(name, name, 0);
printf("unknown symbol %s\n", name);
abort();
if (fatal)
{
printf("unknown symbol %s\n", name);
abort();
}
return NULL;
}
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
unsigned offset)
ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen, unsigned p2align)
{
//printf("addSection: %s len=%d align=%d\n", sname, slen, p2align);
if (update_capacity(nsections, &nsections_capacity))
sections = static_cast<Section **>(realloc(sections, nsections_capacity * sizeof(Section *)));
assert(sections);
assert(sname); assert(sname[0]); assert(sname[strlen(sname)-1] != ':');
assert(findSection(sname, false) == NULL);
Section *sec = new Section(sname, sdata, slen, p2align);
sections[nsections++] = sec;
return sec;
}
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
unsigned offset)
{
//printf("addSymbol: %s %s 0x%x\n", name, section, offset);
if (update_capacity(nsymbols, &nsymbols_capacity))
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
assert(symbols != NULL);
assert(name); assert(name[0]); assert(name[strlen(name)-1] != ':');
assert(findSymbol(name, false) == NULL);
Symbol *sym = new Symbol(name, findSection(section), offset);
symbols[nsymbols++] = sym;
return sym;
@@ -235,69 +369,18 @@ ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned of
return rel;
}
ElfLinker::ElfLinker() :
frozen(false), input(NULL), output(NULL), head(NULL), tail(NULL),
sections(NULL), symbols(NULL), relocations(NULL),
nsections(0), nsections_capacity(0),
nsymbols(0), nsymbols_capacity(0),
nrelocations(0), nrelocations_capacity(0)
{
}
ElfLinker::~ElfLinker()
{
delete [] input;
delete [] output;
unsigned ic;
for (ic = 0; ic < nsections; ic++)
delete sections[ic];
free(sections);
for (ic = 0; ic < nsymbols; ic++)
delete symbols[ic];
free(symbols);
for (ic = 0; ic < nrelocations; ic++)
delete relocations[ic];
free(relocations);
}
void ElfLinker::init(const void *pdata, int plen)
{
upx_byte *i = new upx_byte[plen + 1];
memcpy(i, pdata, plen);
input = i;
inputlen = plen;
output = new upx_byte[plen];
outputlen = 0;
int pos = find(input, plen, "Sections:", 9);
assert(pos != -1);
char *psections = pos + (char *) input;
char *psymbols = strstr(psections, "SYMBOL TABLE:");
assert(psymbols != NULL);
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR");
assert(prelocs != NULL);
input[plen] = 0;
preprocessSections(psections, psymbols);
preprocessSymbols(psymbols, prelocs);
preprocessRelocations(prelocs, (char*) input + inputlen);
addLoader("*UND*");
}
#if 0
void ElfLinker::setLoaderAlignOffset(int phase)
{
//assert(phase & 0);
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
}
#endif
int ElfLinker::addLoader(const char *sname)
{
assert(!frozen);
if (sname[0] == 0)
assert(sname != NULL);
if (!sname[0])
return outputlen;
char *begin = strdup(sname);
@@ -311,33 +394,35 @@ int ElfLinker::addLoader(const char *sname)
break;
}
if (*sect == '+') // alignment
if (sect[0] == '+') // alignment
{
assert(tail);
if (unsigned l = (hex(sect[2]) - tail->offset - tail->size)
% hex(sect[1]))
unsigned l = (hex(sect[2]) - tail->offset - tail->size) % hex(sect[1]);
if (l)
{
alignCode(l);
if (sect[3] == 'D')
alignData(l);
else
alignCode(l);
tail->size += l;
outputlen += l;
}
}
else
{
Section *section = findSection(sect);
if (section->align) {
unsigned const v = ~0u << section->align;
if (section->p2align) {
assert(tail);
if (unsigned const l = ~v & -(tail->offset + tail->size)) {
assert(tail != section);
unsigned const v = ~0u << section->p2align;
if (unsigned const l = ~v & (0u-(tail->offset + tail->size))) {
alignCode(l);
tail->size += l;
outputlen += l;
}
}
memcpy(output + outputlen, section->input, section->size);
section->output = output + outputlen;
//printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name);
outputlen += section->size;
//printf("section added: %s\n", sect);
if (head)
{
@@ -354,38 +439,22 @@ int ElfLinker::addLoader(const char *sname)
return outputlen;
}
void ElfLinker::addSection(const char *sname, const void *sdata, int slen, int align)
int ElfLinker::getSection(const char *sname, int *slen) const
{
assert(!frozen);
if (update_capacity(nsections, &nsections_capacity))
sections = static_cast<Section **>(realloc(sections, nsections_capacity * sizeof(Section *)));
assert(sections);
Section *sec = new Section(sname, sdata, slen, align);
sections[nsections++] = sec;
//return sec;
}
void ElfLinker::freeze()
{
if (frozen)
return;
frozen = true;
}
int ElfLinker::getSection(const char *sname, int *slen)
{
assert(frozen);
Section *section = findSection(sname);
const Section *section = findSection(sname);
if (slen)
*slen = section->size;
return section->output - output;
}
upx_byte *ElfLinker::getLoader(int *llen)
int ElfLinker::getSectionSize(const char *sname) const
{
assert(frozen);
const Section *section = findSection(sname);
return section->size;
}
upx_byte *ElfLinker::getLoader(int *llen) const
{
if (llen)
*llen = outputlen;
return output;
@@ -393,31 +462,40 @@ upx_byte *ElfLinker::getLoader(int *llen)
void ElfLinker::relocate()
{
assert(frozen);
assert(!reloc_done);
reloc_done = true;
for (unsigned ic = 0; ic < nrelocations; ic++)
{
Relocation *rel = relocations[ic];
const Relocation *rel = relocations[ic];
unsigned value;
if (rel->section->output == NULL)
continue;
if (rel->value->section->output == NULL)
if (strcmp(rel->value->section->name, "*ABS*") == 0)
{
value = rel->value->offset;
}
else if (strcmp(rel->value->section->name, "*UND*") == 0 &&
rel->value->offset == 0xdeaddead)
{
printf("undefined symbol '%s' referenced\n", rel->value->name);
abort();
}
else if (rel->value->section->output == NULL)
{
printf("can not apply reloc '%s:%x' without section '%s'\n",
rel->section->name, rel->offset,
rel->value->section->name);
abort();
}
if (strcmp(rel->value->section->name, "*UND*") == 0 &&
rel->value->offset == 0xdeaddead)
else
{
printf("undefined symbol '%s' referenced\n", rel->value->name);
abort();
value = rel->value->section->offset +
rel->value->offset + rel->add;
}
unsigned value = rel->value->section->offset +
rel->value->offset + rel->add;
upx_byte *location = rel->section->output + rel->offset;
//printf("%-28s %-28s %-10s 0x%08x 0x%08x\n", rel->section->name, rel->value->name, rel->type, value, value - rel->section->offset - rel->offset);
//printf(" %d %d %d %d %d : %d\n", value, rel->value->section->offset, rel->value->offset, rel->offset, rel->add, *location);
relocate1(rel, location, value, rel->type);
}
}
@@ -425,7 +503,12 @@ void ElfLinker::relocate()
void ElfLinker::defineSymbol(const char *name, unsigned value)
{
Symbol *symbol = findSymbol(name);
if (strcmp(symbol->section->name, "*UND*") == 0) // for undefined symbols
if (strcmp(symbol->section->name, "*ABS*") == 0)
{
printf("defineSymbol: symbol '%s' is *ABS*\n", name);
abort();
}
else if (strcmp(symbol->section->name, "*UND*") == 0) // for undefined symbols
symbol->offset = value;
else if (strcmp(symbol->section->name, name) == 0) // for sections
{
@@ -438,36 +521,57 @@ void ElfLinker::defineSymbol(const char *name, unsigned value)
}
else
{
printf("symbol '%s' already defined\n", name);
printf("defineSymbol: symbol '%s' already defined\n", name);
abort();
}
}
// debugging support
void ElfLinker::dumpSymbols(FILE *fp) const
void ElfLinker::dumpSymbol(const Symbol *symbol, unsigned flags, FILE *fp) const
{
if ((flags & 1) && symbol->section->output == NULL)
return;
fprintf(fp, "%-28s 0x%08x | %-28s 0x%08x\n",
symbol->name, symbol->offset, symbol->section->name, symbol->section->offset);
}
void ElfLinker::dumpSymbols(unsigned flags, FILE *fp) const
{
if (fp == NULL)
fp = stdout;
for (unsigned ic = 0; ic < nsymbols; ic++)
if ((flags & 2) == 0)
{
Symbol *symbol = symbols[ic];
fprintf(fp, "%-20s 0x%08x | %-20s 0x%08x\n",
symbol->name, symbol->offset, symbol->section->name, symbol->section->offset);
// default: dump symbols in used section order
for (const Section *section = head; section; section = section->next)
{
fprintf(fp, "%-42s%-28s 0x%08x\n", "", section->name, section->offset);
for (unsigned ic = 0; ic < nsymbols; ic++)
{
const Symbol *symbol = symbols[ic];
if (symbol->section == section && strcmp(symbol->name, section->name) != 0)
dumpSymbol(symbol, flags, fp);
}
}
}
else
{
// dump all symbols
for (unsigned ic = 0; ic < nsymbols; ic++)
dumpSymbol(symbols[ic], flags, fp);
}
}
unsigned ElfLinker::getSymbolOffset(const char *name) const
{
assert(frozen);
Symbol *symbol = const_cast<ElfLinker *>(this)->findSymbol(name);
const Symbol *symbol = findSymbol(name);
if (symbol->section->output == NULL)
return 0xdeaddead;
return symbol->section->offset + symbol->offset;
}
void ElfLinker::alignWithByte(unsigned len, upx_byte b)
void ElfLinker::alignWithByte(unsigned len, unsigned char b)
{
memset(output + outputlen, b, len);
outputlen += len;
}
void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
@@ -483,6 +587,23 @@ void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
// FIXME: add more displacment overflow checks
**************************************************************************/
#if 0 // FIXME
static void check8(const Relocation *rel, const upx_byte *location, int v, int d)
{
if (v < -128 || v > 127) {
printf("value out of range (%d) in reloc %s:%x\n",
v, rel->section->name, rel->offset);
abort();
}
if (d < -128 || d > 127) {
printf("displacement target out of range (%d) in reloc %s:%x\n",
v, rel->section->name, rel->offset);
abort();
}
}
#endif
void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
unsigned value, const char *type)
{
@@ -498,7 +619,11 @@ void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
if (strcmp(type, "8") == 0)
{
#if (ACC_CC_PGI)
int displ = * (signed char *) location + (int) value; // CBUG
#else
int displ = (signed char) *location + (int) value;
#endif
if (displ < -128 || displ > 127)
{
printf("target out of range (%d) in reloc %s:%x\n",
@@ -540,6 +665,9 @@ void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location,
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
//set_be32(location, get_be32(location) + value / 4);
}
else if (0==strcmp("R_ARM_ABS8", type)) {
*location += value;
}
else
super::relocate1(rel, location, value, type);
}
@@ -569,6 +697,9 @@ void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location,
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
//set_le32(location, get_le32(location) + value / 4);
}
else if (0==strcmp("R_ARM_ABS8", type)) {
*location += value;
}
else
super::relocate1(rel, location, value, type);
}
@@ -580,6 +711,7 @@ void ElfLinkerM68k::alignCode(unsigned len)
assert((outputlen & 1) == 0);
for (unsigned i = 0; i < len; i += 2)
set_be16(output + outputlen + i, 0x4e71); // "nop"
outputlen += len;
}
void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location,
@@ -594,17 +726,51 @@ void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location,
value -= rel->section->offset + rel->offset;
type += 2;
}
if (strcmp(type, "8") == 0)
if (strcmp(type, "8") == 0) {
*location += value;
else if (strcmp(type, "16") == 0)
}
else if (strcmp(type, "16") == 0) {
set_be16(location, get_be16(location) + value);
else if (strcmp(type, "32") == 0)
}
else if (strcmp(type, "32") == 0) {
set_be32(location, get_be32(location) + value);
}
else
super::relocate1(rel, location, value, type);
}
void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location,
unsigned value, const char *type)
{
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
#define MIPS_LO(a) ((a) & 0xffff)
#define MIPS_PC16(a) ((a) >> 2)
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
if (strcmp(type, "R_MIPS_HI16") == 0)
set_le16(location, get_le16(location) + MIPS_HI(value));
else if (strcmp(type, "R_MIPS_LO16") == 0)
set_le16(location, get_le16(location) + MIPS_LO(value));
else if (strcmp(type, "R_MIPS_PC16") == 0)
{
value -= rel->section->offset + rel->offset;
set_le16(location, get_le16(location) + MIPS_PC16(value));
}
else if (strcmp(type, "R_MIPS_26") == 0)
set_le32(location, get_le32(location) + MIPS_PC26(value));
else if (strcmp(type, "R_MIPS_32") == 0)
set_le32(location, get_le32(location) + value);
else
super::relocate1(rel, location, value, type);
#undef MIPS_HI
#undef MIPS_LO
#undef MIPS_PC16
#undef MIPS_PC26
}
void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location,
unsigned value, const char *type)
{
@@ -651,20 +817,24 @@ void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location,
return super::relocate1(rel, location, value, type);
type += 6;
int range_check = 0;
bool range_check = false;
if (strncmp(type, "PC", 2) == 0)
{
value -= rel->section->offset + rel->offset;
type += 2;
range_check = 1;
range_check = true;
}
if (strcmp(type, "8") == 0)
{
#if (ACC_CC_PGI)
int displ = * (signed char *) location + (int) value; // CBUG
#else
int displ = (signed char) *location + (int) value;
#endif
if (range_check && (displ < -128 || displ > 127)) {
printf("target out of range (%d) in reloc %s:%x\n",
displ, rel->section->name, rel->offset);
printf("target out of range (%d,%d,%d) in reloc %s:%x\n",
displ, *location, value, rel->section->name, rel->offset);
abort();
}
*location += value;
+40 -18
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -36,13 +36,14 @@
class ElfLinker : private nocopy
{
friend class Packer;
public:
const N_BELE_RTP::AbstractPolicy *bele;
protected:
struct Section;
struct Symbol;
struct Relocation;
bool frozen; // FIXME: can we remove this ?
upx_byte *input;
int inputlen;
upx_byte *output;
@@ -62,11 +63,14 @@ protected:
unsigned nrelocations;
unsigned nrelocations_capacity;
void preprocessSections(char *start, const char *end);
void preprocessSymbols(char *start, const char *end);
void preprocessRelocations(char *start, const char *end);
Section *findSection(const char *name) const;
Symbol *findSymbol(const char *name) /*const*/;
bool reloc_done;
protected:
void preprocessSections(char *start, char *end);
void preprocessSymbols(char *start, char *end);
void preprocessRelocations(char *start, char *end);
Section *findSection(const char *name, bool fatal=true) const;
Symbol *findSymbol(const char *name, bool fatal=true) const;
Symbol *addSymbol(const char *name, const char *section, unsigned offset);
Relocation *addRelocation(const char *section, unsigned off, const char *type,
@@ -77,21 +81,24 @@ public:
virtual ~ElfLinker();
virtual void init(const void *pdata, int plen);
virtual void setLoaderAlignOffset(int phase);
//virtual void setLoaderAlignOffset(int phase);
virtual int addLoader(const char *sname);
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
virtual void freeze();
virtual int getSection(const char *sname, int *slen=NULL);
virtual upx_byte *getLoader(int *llen=NULL);
virtual void relocate();
virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align);
virtual int getSection(const char *sname, int *slen=NULL) const;
virtual int getSectionSize(const char *sname) const;
virtual upx_byte *getLoader(int *llen=NULL) const;
virtual void defineSymbol(const char *name, unsigned value);
virtual unsigned getSymbolOffset(const char *) const;
virtual void dumpSymbols(FILE *fp=NULL) const;
void alignWithByte(unsigned len, upx_byte b);
virtual void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const;
virtual void dumpSymbols(unsigned flags=0, FILE *fp=NULL) const;
void alignWithByte(unsigned len, unsigned char b);
virtual void alignCode(unsigned len) { alignWithByte(len, 0); }
virtual void alignData(unsigned len) { alignWithByte(len, 0); }
protected:
virtual void relocate();
virtual void relocate1(const Relocation *, upx_byte *location,
unsigned value, const char *type);
};
@@ -104,7 +111,7 @@ struct ElfLinker::Section : private nocopy
upx_byte *output;
unsigned size;
unsigned offset;
unsigned char align; // log2
unsigned p2align; // log2
Section *next;
Section(const char *n, const void *i, unsigned s, unsigned a=0);
@@ -153,6 +160,8 @@ protected:
class ElfLinkerArmBE : public ElfLinker
{
typedef ElfLinker super;
public:
ElfLinkerArmBE() { bele = &N_BELE_RTP::be_policy; }
protected:
virtual void relocate1(const Relocation *, upx_byte *location,
unsigned value, const char *type);
@@ -171,6 +180,8 @@ protected:
class ElfLinkerM68k : public ElfLinker
{
typedef ElfLinker super;
public:
ElfLinkerM68k() { bele = &N_BELE_RTP::be_policy; }
protected:
virtual void alignCode(unsigned len);
virtual void relocate1(const Relocation *, upx_byte *location,
@@ -178,9 +189,20 @@ protected:
};
class ElfLinkerMipsLE : public ElfLinker
{
typedef ElfLinker super;
protected:
virtual void relocate1(const Relocation *, upx_byte *location,
unsigned value, const char *type);
};
class ElfLinkerPpc32 : public ElfLinker
{
typedef ElfLinker super;
public:
ElfLinkerPpc32() { bele = &N_BELE_RTP::be_policy; }
protected:
virtual void relocate1(const Relocation *, upx_byte *location,
unsigned value, const char *type);
+255 -124
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -43,15 +43,16 @@ int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
// options
**************************************************************************/
void init_options(struct options_t *o)
void options_t::reset()
{
options_t *o = this;
memset(o, 0, sizeof(*o));
o->crp.reset();
o->cmd = CMD_NONE;
o->method = -1;
o->method = M_NONE;
o->level = -1;
o->filter = -1;
o->filter = FT_NONE;
o->backup = -1;
o->overlay = -1;
@@ -76,8 +77,8 @@ void init_options(struct options_t *o)
o->win32_pe.keep_resource = "";
}
static struct options_t global_options;
struct options_t *opt = &global_options;
static options_t global_options;
options_t *opt = &global_options;
static int done_output_name = 0;
static int done_script_name = 0;
@@ -182,7 +183,7 @@ static void e_method(int m, int l)
static void e_optarg(const char *n)
{
fflush(con_term);
fprintf(stderr,"%s: invalid argument in option `%s'\n", argv0, n);
fprintf(stderr,"%s: invalid argument in option '%s'\n", argv0, n);
e_exit(EXIT_USAGE);
}
@@ -190,7 +191,7 @@ static void e_optarg(const char *n)
static void e_optval(const char *n)
{
fflush(con_term);
fprintf(stderr,"%s: invalid value for option `%s'\n", argv0, n);
fprintf(stderr,"%s: invalid value for option '%s'\n", argv0, n);
e_exit(EXIT_USAGE);
}
@@ -200,10 +201,10 @@ void e_envopt(const char *n)
{
fflush(con_term);
if (n)
fprintf(stderr,"%s: invalid string `%s' in environment variable `%s'\n",
fprintf(stderr,"%s: invalid string '%s' in environment variable '%s'\n",
argv0, n, OPTIONS_VAR);
else
fprintf(stderr,"%s: illegal option in environment variable `%s'\n",
fprintf(stderr,"%s: illegal option in environment variable '%s'\n",
argv0, OPTIONS_VAR);
e_exit(EXIT_USAGE);
}
@@ -226,7 +227,7 @@ void check_not_both(bool e1, bool e2, const char *c1, const char *c2)
if (e1 && e2)
{
fprintf(stderr,"%s: ",argv0);
fprintf(stderr,"cannot use both `%s' and `%s'\n", c1, c2);
fprintf(stderr,"cannot use both '%s' and '%s'\n", c1, c2);
e_usage();
}
}
@@ -236,12 +237,24 @@ void check_options(int i, int argc)
{
assert(i <= argc);
if (opt->cmd != CMD_COMPRESS)
{
// invalidate compression options
opt->method = 0;
opt->level = 0;
opt->exact = 0;
opt->small = 0;
opt->crp.reset();
}
// set default overlay action
if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))
opt->overlay = opt->COPY_OVERLAY;
else if (opt->overlay < 0)
opt->overlay = opt->COPY_OVERLAY;
check_not_both(opt->exact, opt->overlay == opt->STRIP_OVERLAY, "--exact", "--overlay=strip");
// set default backup option
if (opt->backup < 0)
opt->backup = 0;
@@ -251,14 +264,14 @@ void check_options(int i, int argc)
check_not_both(opt->to_stdout, opt->output_name != NULL, "--stdout", "-o");
if (opt->to_stdout && opt->cmd == CMD_COMPRESS)
{
fprintf(stderr,"%s: cannot use `--stdout' when compressing\n", argv0);
fprintf(stderr,"%s: cannot use '--stdout' when compressing\n", argv0);
e_usage();
}
if (opt->to_stdout || opt->output_name)
{
if (i + 1 != argc)
{
fprintf(stderr,"%s: need exactly one argument when using `%s'\n",
fprintf(stderr,"%s: need exactly one argument when using '%s'\n",
argv0, opt->to_stdout ? "--stdout" : "-o");
e_usage();
}
@@ -299,8 +312,14 @@ static bool set_method(int m, int l)
{
if (!Packer::isValidCompressionMethod(m))
return false;
opt->method = m;
opt->all_methods = false;
#if 1
// something like "--brute --lzma" should not disable "--brute"
if (!opt->all_methods)
#endif
{
opt->method = m;
opt->all_methods = false;
}
}
if (l > 0)
opt->level = l;
@@ -314,7 +333,7 @@ static void set_output_name(const char *n, bool allow_m)
#if 1
if (done_output_name > 0)
{
fprintf(stderr,"%s: option `-o' more than once given\n",argv0);
fprintf(stderr,"%s: option '-o' more than once given\n",argv0);
e_usage();
}
#endif
@@ -337,7 +356,7 @@ static void set_script_name(const char *n, bool allow_m)
#if 1
if (done_script_name > 0)
{
fprintf(stderr,"%s: option `--script' more than once given\n",argv0);
fprintf(stderr,"%s: option '--script' more than once given\n",argv0);
e_usage();
}
#endif
@@ -405,28 +424,58 @@ char* prepare_shortopts(char *buf, const char *n,
template <class T>
int getoptvar(T *var, const T minval, const T maxval)
int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal)
{
const char *p = mfx_optarg;
char *endptr;
int r = 0;
long n;
T v;
if (!p || !p[0])
return -1;
{ r = -1; goto error; }
// avoid interpretation as octal value
while (p[0] == '0' && isdigit(p[1]))
p++;
long n = strtol(p, &endptr, 0);
n = strtol(p, &endptr, 0);
if (*endptr != '\0')
return -2;
T v = (T) n;
if (v < minval)
return -3;
if (v > maxval)
return -4;
{ r = -2; goto error; }
v = (T) n;
if (v < min_value)
{ r = -3; goto error; }
if (v > max_value)
{ r = -4; goto error; }
*var = v;
return 0;
goto done;
error:
if (arg_fatal != NULL)
e_optval(arg_fatal);
done:
return r;
}
#if 1 && (ACC_CC_GNUC >= 0x030300)
template <class T, T default_value, T min_value, T max_value>
int getoptvar(OptVar<T,default_value,min_value,max_value> *var, const char *arg_fatal)
{
T v = default_value;
int r = getoptvar(&v, min_value, max_value, arg_fatal);
if (r == 0)
*var = v;
return r;
}
#else
template <class T>
int getoptvar(T *var, const char *arg_fatal)
{
typename T::Type v = T::default_value_c;
int r = getoptvar(&v, T::min_value_c, T::max_value_c, arg_fatal);
if (r == 0)
*var = v;
return r;
}
#endif
static int do_option(int optc, const char *arg)
{
@@ -450,7 +499,7 @@ static int do_option(int optc, const char *arg)
case 'f':
opt->force++;
break;
case 902:
case 909:
set_cmd(CMD_FILEINFO);
break;
case 'h':
@@ -459,10 +508,13 @@ static int do_option(int optc, const char *arg)
set_cmd(CMD_HELP);
break;
case 'h'+256:
#if 0
/* according to GNU standards */
set_term(stdout);
opt->console = CON_FILE;
#if 1
if (!acc_isatty(STDOUT_FILENO))
{
/* according to GNU standards */
set_term(stdout);
opt->console = CON_FILE;
}
#endif
show_help(1);
e_exit(EXIT_OK);
@@ -517,6 +569,11 @@ static int do_option(int optc, const char *arg)
if (!set_method(M_LZMA, -1))
e_method(M_LZMA, opt->level);
break;
case 722:
opt->all_methods_use_lzma = false;
if (M_IS_LZMA(opt->method))
opt->method = -1;
break;
// compression level
case '1':
@@ -532,6 +589,9 @@ static int do_option(int optc, const char *arg)
e_method(opt->method, optc);
break;
case 902: // --ultra-brute
opt->ultra_brute = true;
/* fallthrough */
case 901: // --brute
opt->all_methods = true;
opt->all_methods_use_lzma = true;
@@ -561,6 +621,9 @@ static int do_option(int optc, const char *arg)
e_optarg(arg);
opt->debug.dump_stub_loader = mfx_optarg;
break;
case 545:
opt->debug.disable_random_id = true;
break;
// misc
case 512:
@@ -585,7 +648,7 @@ static int do_option(int optc, const char *arg)
opt->small++;
break;
case 521: // --filter=
getoptvar(&opt->filter, 0, 255);
getoptvar(&opt->filter, 0, 255, arg);
opt->all_filters = false;
break;
case 522: // --no-filter
@@ -599,37 +662,64 @@ static int do_option(int optc, const char *arg)
break;
case 524: // --all-methods
opt->all_methods = true;
opt->all_methods_use_lzma = true;
opt->method = -1;
break;
case 525: // --exact
opt->exact = true;
break;
// compression runtime parameters
case 531:
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3);
case 801:
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
break;
case 532:
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2);
case 802:
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2, arg);
break;
case 533:
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1);
case 803:
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1, arg);
break;
case 534:
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7);
case 804:
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7, arg);
break;
case 535:
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u);
case 805:
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u, arg);
break;
case 536:
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u);
case 806:
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u, arg);
break;
case 537:
if (getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u) != 0)
e_optval("--crp-ms=");
case 807:
getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg);
break;
case 811:
getoptvar(&opt->crp.crp_lzma.pos_bits, arg);
break;
case 812:
getoptvar(&opt->crp.crp_lzma.lit_pos_bits, arg);
break;
case 813:
getoptvar(&opt->crp.crp_lzma.lit_context_bits, arg);
break;
case 814:
getoptvar(&opt->crp.crp_lzma.dict_size, arg);
break;
case 816:
getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg);
break;
case 821:
getoptvar(&opt->crp.crp_zlib.mem_level, arg);
break;
case 822:
getoptvar(&opt->crp.crp_zlib.window_bits, arg);
break;
case 823:
getoptvar(&opt->crp.crp_zlib.strategy, arg);
break;
// backup
case 'k':
opt->backup = 1;
break;
case 541:
if (opt->backup != 1) // do not overide `--backup'
if (opt->backup != 1) // do not overide '--backup'
opt->backup = 0;
break;
// overlay
@@ -687,18 +777,20 @@ static int do_option(int optc, const char *arg)
break;
case 630:
opt->win32_pe.compress_exports = 1;
getoptvar(&opt->win32_pe.compress_exports, 0, 1);
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_exports, 0, 1, arg);
//printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
break;
case 631:
opt->win32_pe.compress_icons = 1;
getoptvar(&opt->win32_pe.compress_icons, 0, 2);
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_icons, 0, 3, arg);
//printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
break;
case 632:
opt->win32_pe.compress_resources = true;
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
opt->win32_pe.compress_resources = false;
opt->win32_pe.compress_resources = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_resources, 0, 1, arg);
//printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
break;
case 633:
@@ -706,8 +798,8 @@ static int do_option(int optc, const char *arg)
break;
case 634:
opt->win32_pe.strip_relocs = 1;
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
opt->win32_pe.strip_relocs = 0;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.strip_relocs, 0, 1, arg);
//printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
break;
case 635:
@@ -719,7 +811,7 @@ static int do_option(int optc, const char *arg)
opt->atari_tos.split_segments = true;
break;
case 660:
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u);
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u, arg);
break;
case 661:
opt->o_unix.force_execve = true;
@@ -727,7 +819,7 @@ static int do_option(int optc, const char *arg)
case 662:
opt->o_unix.script_name = "/usr/local/lib/upx/upxX";
if (mfx_optarg && mfx_optarg[0])
set_script_name(mfx_optarg,1);
set_script_name(mfx_optarg, 1);
break;
case 663:
opt->o_unix.is_ptinterp = true;
@@ -769,7 +861,7 @@ static int do_option(int optc, const char *arg)
case ':':
return -2;
default:
fprintf(stderr,"%s: internal error in getopt (%d)\n",argv0,optc);
fprintf(stderr,"%s: internal error in getopt (%d)\n", argv0, optc);
return -3;
}
@@ -786,10 +878,11 @@ static const struct mfx_option longopts[] =
// commands
{"best", 0x10, 0, 900}, // compress best
{"brute", 0x10, 0, 901}, // compress best, brute force
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
{"decompress", 0, 0, 'd'}, // decompress
{"fast", 0x10, 0, '1'}, // compress faster
{"fileinfo", 0x10, 0, 902}, // display info about file
{"file-info", 0x10, 0, 902}, // display info about file
{"fileinfo", 0x10, 0, 909}, // display info about file
{"file-info", 0x10, 0, 909}, // display info about file
{"help", 0, 0, 'h'+256}, // give help
{"license", 0, 0, 'L'}, // display software license
{"list", 0, 0, 'l'}, // list compressed exe
@@ -818,18 +911,19 @@ static const struct mfx_option longopts[] =
{"dump-stub-loader" ,0x31, 0, 544}, // for internal debugging
{"fake-stub-version",0x31, 0, 542}, // for internal debugging
{"fake-stub-year" ,0x31, 0, 543}, // for internal debugging
{"disable-random-id",0x10, 0, 545}, // for internal debugging
// backup options
{"backup", 0, 0, 'k'},
{"keep", 0, 0, 'k'},
{"no-backup", 0, 0, 541},
{"backup", 0x10, 0, 'k'},
{"keep", 0x10, 0, 'k'},
{"no-backup", 0x10, 0, 541},
// overlay options
{"overlay", 0x31, 0, 551}, // --overlay=
{"skip-overlay", 0, 0, 552},
{"no-overlay", 0, 0, 552}, // old name
{"copy-overlay", 0, 0, 553},
{"strip-overlay", 0, 0, 554},
{"skip-overlay", 0x10, 0, 552},
{"no-overlay", 0x10, 0, 552}, // old name
{"copy-overlay", 0x10, 0, 553},
{"strip-overlay", 0x10, 0, 554},
// CPU options
{"cpu", 0x31, 0, 560}, // --cpu=
@@ -838,34 +932,53 @@ static const struct mfx_option longopts[] =
{"486", 0x10, 0, 564},
// color options
{"no-color", 0, 0, 512},
{"mono", 0, 0, 513},
{"color", 0, 0, 514},
{"no-color", 0x10, 0, 512},
{"mono", 0x10, 0, 513},
{"color", 0x10, 0, 514},
// compression method
{"nrv2b", 0x10, 0, 702}, // --nrv2b
{"nrv2d", 0x10, 0, 704}, // --nrv2d
{"nrv2e", 0x10, 0, 705}, // --nrv2e
{"lzma", 0x10, 0, 721}, // --lzma
{"no-lzma", 0x10, 0, 722}, // (disable all_methods_use_lzma)
// compression settings
{"all-filters", 0x10, 0, 523},
{"all-methods", 0x10, 0, 524},
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
{"filter", 0x31, 0, 521}, // --filter=
{"no-filter", 0x10, 0, 522},
{"small", 0x10, 0, 520},
// compression runtime parameters
{"crp-cf", 0x31, 0, 531},
{"crp-sl", 0x31, 0, 532},
{"crp-hl", 0x31, 0, 533},
{"crp-pl", 0x31, 0, 534},
{"crp-mo", 0x31, 0, 535},
{"crp-mm", 0x31, 0, 536},
{"crp-ms", 0x31, 0, 537},
{"crp-nrv-cf", 0x31, 0, 801},
{"crp-nrv-sl", 0x31, 0, 802},
{"crp-nrv-hl", 0x31, 0, 803},
{"crp-nrv-pl", 0x31, 0, 804},
{"crp-nrv-mo", 0x31, 0, 805},
{"crp-nrv-mm", 0x31, 0, 806},
{"crp-nrv-ms", 0x31, 0, 807},
{"crp-ucl-cf", 0x31, 0, 801},
{"crp-ucl-sl", 0x31, 0, 802},
{"crp-ucl-hl", 0x31, 0, 803},
{"crp-ucl-pl", 0x31, 0, 804},
{"crp-ucl-mo", 0x31, 0, 805},
{"crp-ucl-mm", 0x31, 0, 806},
{"crp-ucl-ms", 0x31, 0, 807},
{"crp-lzma-pb", 0x31, 0, 811},
{"crp-lzma-lp", 0x31, 0, 812},
{"crp-lzma-lc", 0x31, 0, 813},
{"crp-lzma-ds", 0x31, 0, 814},
{"crp-lzma-fb", 0x31, 0, 816},
{"crp-zlib-ml", 0x31, 0, 821},
{"crp-zlib-wb", 0x31, 0, 822},
{"crp-zlib-st", 0x31, 0, 823},
// [deprecated - only for compatibility with UPX 2.0x]
{"crp-ms", 0x31, 0, 807},
// atari/tos
{"split-segments", 0x10, 0, 650},
// djgpp2/coff
{"coff", 0, 0, 610}, // produce COFF output
{"coff", 0x10, 0, 610}, // produce COFF output
// dos/com
// dos/exe
//{"force-stub", 0x10, 0, 600},
@@ -877,15 +990,19 @@ static const struct mfx_option longopts[] =
#if 0
{"script", 0x31, 0, 662}, // --script=
#endif
{"is_ptinterp", 0, 0, 663}, // linux/elf386 PT_INTERP program
{"use_ptinterp", 0, 0, 664}, // linux/elf386 PT_INTERP program
{"make_ptinterp", 0, 0, 665}, // linux/elf386 PT_INTERP program
{"Linux", 0, 0, 666},
{"FreeBSD", 0, 0, 667},
{"NetBSD", 0, 0, 668},
{"OpenBSD", 0, 0, 669},
{"is_ptinterp", 0x10, 0, 663}, // linux/elf386 PT_INTERP program
{"use_ptinterp", 0x10, 0, 664}, // linux/elf386 PT_INTERP program
{"make_ptinterp", 0x10, 0, 665}, // linux/elf386 PT_INTERP program
{"Linux", 0x10, 0, 666},
{"linux", 0x10, 0, 666},
{"FreeBSD", 0x10, 0, 667},
{"freebsd", 0x10, 0, 667},
{"NetBSD", 0x10, 0, 668},
{"netbsd", 0x10, 0, 668},
{"OpenBSD", 0x10, 0, 669},
{"openbsd", 0x10, 0, 669},
// watcom/le
{"le", 0, 0, 620}, // produce LE output
{"le", 0x10, 0, 620}, // produce LE output
// win32/pe
{"compress-exports", 2, 0, 630},
{"compress-icons", 2, 0, 631},
@@ -930,6 +1047,7 @@ static const struct mfx_option longopts[] =
// commands
{"best", 0x10, 0, 900}, // compress best
{"brute", 0x10, 0, 901}, // compress best, brute force
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
{"fast", 0x10, 0, '1'}, // compress faster
// options
@@ -939,17 +1057,20 @@ static const struct mfx_option longopts[] =
{"silent", 0, 0, 'q'}, // quiet mode
{"verbose", 0, 0, 'v'}, // verbose mode
// debug options
{"disable-random-id",0x10, 0, 545}, // for internal debugging
// backup options
{"backup", 0, 0, 'k'},
{"keep", 0, 0, 'k'},
{"backup", 0x10, 0, 'k'},
{"keep", 0x10, 0, 'k'},
{"no-backup", 0x10, 0, 541},
// overlay options
{"overlay", 0x31, 0, 551}, // --overlay=
{"skip-overlay", 0, 0, 552},
{"no-overlay", 0, 0, 552}, // old name
{"copy-overlay", 0, 0, 553},
{"strip-overlay", 0, 0, 554},
{"skip-overlay", 0x10, 0, 552},
{"no-overlay", 0x10, 0, 552}, // old name
{"copy-overlay", 0x10, 0, 553},
{"strip-overlay", 0x10, 0, 554},
// CPU options
{"cpu", 0x31, 0, 560}, // --cpu=
@@ -958,18 +1079,14 @@ static const struct mfx_option longopts[] =
{"486", 0x10, 0, 564},
// color options
{"no-color", 0, 0, 512},
{"mono", 0, 0, 513},
{"color", 0, 0, 514},
{"no-color", 0x10, 0, 512},
{"mono", 0x10, 0, 513},
{"color", 0x10, 0, 514},
// compression settings
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
// compression runtime parameters
{"crp-cf", 0x31, 0, 531},
{"crp-sl", 0x31, 0, 532},
{"crp-hl", 0x31, 0, 533},
{"crp-pl", 0x31, 0, 534},
{"crp-mo", 0x31, 0, 535},
{"crp-mm", 0x31, 0, 536},
{"crp-ms", 0x31, 0, 537},
// win32/pe
{"compress-exports", 2, 0, 630},
@@ -1093,9 +1210,25 @@ static void first_options(int argc, char **argv)
**************************************************************************/
template <class T> struct TestBELE {
static int test(void)
static bool test(void)
{
COMPILE_TIME_ASSERT_ALIGNED1(T)
struct test1_t { char a; T b; } __attribute_packed;
struct test2_t { char a; T b[3]; } __attribute_packed;
test1_t t1[7]; UNUSED(t1); test2_t t2[7]; UNUSED(t2);
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7*sizeof(T))
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3*sizeof(T))
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21*sizeof(T))
#if defined(__acc_alignof)
COMPILE_TIME_ASSERT(__acc_alignof(t1) == 1)
COMPILE_TIME_ASSERT(__acc_alignof(t2) == 1)
#endif
#if 1 && !defined(xUPX_OFFICIAL_BUILD)
T allbits; allbits = 0; allbits -= 1;
//++allbits; allbits++; --allbits; allbits--;
T v1; v1 = 1; v1 *= 2; v1 -= 1;
T v2; v2 = 1;
assert( (v1 == v2)); assert(!(v1 != v2));
@@ -1109,7 +1242,9 @@ static int test(void)
assert(v1 == 1); assert(v2 == 0);
v1 <<= 1; v1 |= v2; v1 >>= 1; v2 &= v1; v2 /= v1; v2 *= v1;
assert(v1 == 1); assert(v2 == 0);
return (v1 ^ v2) == 1;
if ((v1 ^ v2) != 1) return false;
#endif
return true;
}};
@@ -1141,12 +1276,12 @@ void upx_sanity_check(void)
COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
COMPILE_TIME_ASSERT_ALIGNOF(BE16, char)
COMPILE_TIME_ASSERT_ALIGNOF(BE32, char)
COMPILE_TIME_ASSERT_ALIGNOF(BE64, char)
COMPILE_TIME_ASSERT_ALIGNOF(LE16, char)
COMPILE_TIME_ASSERT_ALIGNOF(LE32, char)
COMPILE_TIME_ASSERT_ALIGNOF(LE64, char)
COMPILE_TIME_ASSERT_ALIGNED1(BE16)
COMPILE_TIME_ASSERT_ALIGNED1(BE32)
COMPILE_TIME_ASSERT_ALIGNED1(BE64)
COMPILE_TIME_ASSERT_ALIGNED1(LE16)
COMPILE_TIME_ASSERT_ALIGNED1(LE32)
COMPILE_TIME_ASSERT_ALIGNED1(LE64)
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
assert(strlen(UPX_VERSION_STRING4) == 4);
@@ -1157,14 +1292,12 @@ void upx_sanity_check(void)
assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0);
#if 1
# if 1 && !defined(UPX_OFFICIAL_BUILD)
assert(TestBELE<LE16>::test());
assert(TestBELE<LE32>::test());
assert(TestBELE<LE64>::test());
assert(TestBELE<BE16>::test());
assert(TestBELE<BE32>::test());
assert(TestBELE<BE64>::test());
# endif
{
static const unsigned char dd[32] = { 0, 0, 0, 0, 0, 0, 0,
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
@@ -1188,6 +1321,7 @@ void upx_sanity_check(void)
assert(get_le24_signed(d) == -131329);
assert(get_le32(d) == 0xfcfdfeff);
assert(get_le32_signed(d) == -50462977);
assert(get_le64_signed(d) == ACC_INT64_C(-506097522914230529));
assert(find_be16(d, 2, 0xfffe) == 0);
assert(find_le16(d, 2, 0xfeff) == 0);
assert(find_be32(d, 4, 0xfffefdfc) == 0);
@@ -1196,6 +1330,7 @@ void upx_sanity_check(void)
assert(get_be16_signed(d) == 32638);
assert(get_be24_signed(d) == 8355453);
assert(get_be32_signed(d) == 2138996092);
assert(get_be64_signed(d) == ACC_INT64_C(9186918263483431288));
}
#endif
}
@@ -1207,6 +1342,10 @@ void upx_sanity_check(void)
#if !defined(WITH_GUI)
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
extern "C" { extern long _stksize; long _stksize = 256 * 1024L; }
#endif
int __acc_cdecl_main main(int argc, char *argv[])
{
int i;
@@ -1220,7 +1359,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
acc_wildargv(&argc, &argv);
upx_sanity_check();
init_options(opt);
opt->reset();
if (!argv[0] || !argv[0][0])
argv[0] = default_argv0;
@@ -1321,14 +1460,6 @@ int __acc_cdecl_main main(int argc, char *argv[])
break;
}
if (opt->cmd != CMD_COMPRESS)
{
// invalidate compression options
opt->method = 0;
opt->level = 0;
memset(&opt->crp, 0xff, sizeof(opt->crp));
}
/* check options */
if (argc == 1)
e_help();
@@ -1347,7 +1478,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
set_term(stdout);
do_files(i,argc,argv);
#if 0 && (UPX_VERSION_HEX < 0x020000)
#if 0 && (UPX_VERSION_HEX < 0x030000)
{
FILE *f = stdout;
int fg = con_fg(f,FG_RED);
+4 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -209,6 +209,8 @@ void MemBuffer::alloc(unsigned size)
}
else
b = p ;
//fill(0, b_size, (rand() & 0xff) | 1); // debug
}
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -38,7 +38,7 @@ class MemBuffer
{
public:
MemBuffer();
MemBuffer(unsigned size);
explicit MemBuffer(unsigned size);
~MemBuffer();
static unsigned getSizeForCompression(unsigned uncompressed_size, unsigned extra=0);
+264 -25
View File
@@ -2,6 +2,7 @@
This file is part of the UPX executable compressor.
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
@@ -37,7 +38,7 @@
#ifndef __ACC_H_INCLUDED
#define __ACC_H_INCLUDED 1
#define ACC_VERSION 20060823L
#define ACC_VERSION 20070112L
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
# define __CYGWIN__ __CYGWIN32__
#endif
@@ -1169,7 +1170,7 @@ extern "C" {
# define ACC_SIZEOF_LONG_LONG 8
#elif (ACC_ARCH_I386 && (ACC_CC_INTELC && defined(__linux__)))
# define ACC_SIZEOF_LONG_LONG 8
#elif (ACC_ARCH_I386 && (ACC_CC_MWERKS || ACC_CC_PELLESC || ACC_CC_PGI))
#elif (ACC_ARCH_I386 && (ACC_CC_MWERKS || ACC_CC_PELLESC || ACC_CC_PGI || ACC_CC_SUNPROC))
# define ACC_SIZEOF_LONG_LONG 8
#elif (ACC_ARCH_I386 && (ACC_CC_INTELC || ACC_CC_MSC))
# define ACC_SIZEOF___INT64 8
@@ -1634,6 +1635,15 @@ extern "C" {
# define ACC_UNUSED_LABEL(l) switch(0) case 1:goto l
# endif
#endif
#if !defined(ACC_DEFINE_UNINITIALIZED_VAR)
# if 0
# define ACC_DEFINE_UNINITIALIZED_VAR(type,var,init) type var
# elif 0 && (ACC_CC_GNUC)
# define ACC_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var
# else
# define ACC_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
# endif
#endif
#if !defined(ACC_COMPILE_TIME_ASSERT_HEADER)
# if (ACC_CC_AZTECC || ACC_CC_ZORTECHC)
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) extern int __acc_cta[1-!(e)];
@@ -2745,6 +2755,9 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
#if !defined(acc_signo_t)
# define acc_signo_t int
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if (ACC_BROKEN_CDECL_ALT_SYNTAX)
typedef void __acc_cdecl_sighandler (*acc_sighandler_t)(acc_signo_t);
#elif defined(RETSIGTYPE)
@@ -2752,6 +2765,9 @@ typedef RETSIGTYPE (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#else
typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#endif
#if defined(__cplusplus)
}
#endif
# if defined(ACC_CFG_NO_ACC_UA_H)
# else
#if (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020700ul))
@@ -3164,6 +3180,9 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
#if !defined(acc_signo_t)
# define acc_signo_t int
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if (ACC_BROKEN_CDECL_ALT_SYNTAX)
typedef void __acc_cdecl_sighandler (*acc_sighandler_t)(acc_signo_t);
#elif defined(RETSIGTYPE)
@@ -3171,6 +3190,9 @@ typedef RETSIGTYPE (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#else
typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#endif
#if defined(__cplusplus)
}
#endif
# if !defined(ACC_CFG_NO_ACC_UA_H)
#if (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020700ul))
#elif (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020800ul)) && defined(__cplusplus)
@@ -3968,32 +3990,42 @@ ACCLIB_EXTERN(void, acc_uclock_read) (acc_uclock_handle_p, acc_uclock_p);
ACCLIB_EXTERN(double, acc_uclock_get_elapsed) (acc_uclock_handle_p, const acc_uclock_p, const acc_uclock_p);
#endif
ACCLIB_EXTERN(int, acc_uclock_flush_cpu_cache) (acc_uclock_handle_p, unsigned);
typedef struct {
struct acc_getopt_t;
typedef struct acc_getopt_t acc_getopt_t;
#ifndef acc_getopt_p
#define acc_getopt_p acc_getopt_t *
#endif
struct acc_getopt_longopt_t;
typedef struct acc_getopt_longopt_t acc_getopt_longopt_t;
#ifndef acc_getopt_longopt_p
#define acc_getopt_longopt_p acc_getopt_longopt_t *
#endif
struct acc_getopt_longopt_t {
const char* name;
int has_arg;
int* flag;
int val;
} acc_getopt_longopt_t;
#ifndef acc_getopt_longopt_p
#define acc_getopt_longopt_p acc_getopt_longopt_t *
#endif
typedef struct {
int go_argc;
char** go_argv;
const char* go_shortopts;
const acc_getopt_longopt_p longopts;
#if (ACC_BROKEN_CDECL_ALT_SYNTAX)
int __acc_cdecl_va (*go_error)(const char *, ...);
#else
int (__acc_cdecl_va *go_error)(const char *, ...);
#endif
} acc_getopt_t;
#ifndef acc_getopt_p
#define acc_getopt_p acc_getopt_t *
#endif
ACCLIB_EXTERN(void, acc_getopt_init) (acc_getopt_p);
ACCLIB_EXTERN(int, acc_getopt) (acc_getopt_p);
ACCLIB_EXTERN(void, acc_getopt_close)(acc_getopt_p);
};
struct acc_getopt_t {
void *user;
char *optarg;
void (*opterr)(acc_getopt_p, const char*, void *);
int optind;
int optopt;
int errcount;
const char* progname;
int argc; char** argv;
int eof; int shortpos;
int pending_rotate_first, pending_rotate_middle;
};
enum { ACC_GETOPT_NO_ARG, ACC_GETOPT_REQUIRED_ARG, ACC_GETOPT_OPTIONAL_ARG, ACC_GETOPT_EXACT_ARG = 0x10 };
enum { ACC_GETOPT_PERMUTE, ACC_GETOPT_RETURN_IN_ORDER, ACC_GETOPT_REQUIRE_ORDER };
ACCLIB_EXTERN(void, acc_getopt_init) (acc_getopt_p g,
int start_argc, int argc, char** argv);
ACCLIB_EXTERN(int, acc_getopt) (acc_getopt_p g,
const char* shortopts,
const acc_getopt_longopt_p longopts,
int* longind);
typedef struct {
acc_uint32l_t seed;
} acc_rand31_t;
@@ -5245,6 +5277,213 @@ ACCLIB_PUBLIC(int, acc_dos_free) (void __far* p)
}
#endif
#endif
#if defined(ACC_WANT_ACCLIB_GETOPT)
# undef ACC_WANT_ACCLIB_GETOPT
#define __ACCLIB_GETOPT_CH_INCLUDED 1
#if !defined(ACCLIB_PUBLIC)
# define ACCLIB_PUBLIC(r,f) r __ACCLIB_FUNCNAME(f)
#endif
ACCLIB_PUBLIC(void, acc_getopt_init) (acc_getopt_p g,
int start_argc, int argc, char** argv)
{
memset(g, 0, sizeof(*g));
g->argc = argc;
g->argv = argv;
g->pending_rotate_first = g->pending_rotate_middle = g->optind = start_argc;
}
static int __ACCLIB_FUNCNAME(acc_getopt_rotate) (char **p, int first, int middle, int last)
{
char** a; char** b;
if (first >= middle || middle >= last) return 0;
for (a = p + first, b = p + middle - 1; a < b; ++a, --b) {
char* t = *a; *a = *b; *b = t;
}
for (a = p + middle, b = p + last - 1; a < b; ++a, --b) {
char* t = *a; *a = *b; *b = t;
}
for (a = p + first, b = p + last - 1; a < b; ++a, --b) {
char* t = *a; *a = *b; *b = t;
}
return middle - first;
}
static int __acc_getopt_x(acc_getopt_p g, int ret, int oo, int flags, const char *f, ...)
{
if (oo >= 0)
g->optopt = oo;
if (flags & 1)
{
if (g->shortpos == 0)
g->optind++;
else if (!g->argv[g->optind][++g->shortpos])
g->optind++, g->shortpos = 0;
}
if (f == NULL)
return ret;
if (g->opterr)
{
#if !defined(HAVE_STDARG_H)
g->opterr(g, f, NULL);
#else
va_list ap;
va_start(ap, f);
g->opterr(g, f, &ap);
va_end(ap);
#endif
}
g->errcount++;
return ret;
}
ACCLIB_PUBLIC(int, acc_getopt) (acc_getopt_p g,
const char* shortopts,
const acc_getopt_longopt_p longopts,
int* longind)
{
int ordering = ACC_GETOPT_PERMUTE;
char *a;
int has_arg = 0;
char *arg;
unsigned char sc;
int i;
if (shortopts && (*shortopts == '-' || *shortopts == '+'))
ordering = *shortopts++ == '-' ? ACC_GETOPT_RETURN_IN_ORDER : ACC_GETOPT_REQUIRE_ORDER;
g->optarg = NULL;
g->optopt = '?';
if (longind != NULL)
*longind = -1;
if (g->eof || g->optind >= g->argc || g->argv == NULL)
goto acc_label_eof;
if (g->shortpos)
goto acc_label_next_shortopt;
g->optind -= __ACCLIB_FUNCNAME(acc_getopt_rotate)(g->argv, g->pending_rotate_first, g->pending_rotate_middle, g->optind);
g->pending_rotate_first = g->pending_rotate_middle = g->optind;
if (ordering == ACC_GETOPT_PERMUTE)
{
while (g->optind < g->argc && !(g->argv[g->optind][0] == '-' && g->argv[g->optind][1]))
g->optind++;
g->pending_rotate_middle = g->optind;
}
if (g->optind >= g->argc)
{
g->optind = g->pending_rotate_first;
acc_label_eof:
g->optind -= __ACCLIB_FUNCNAME(acc_getopt_rotate)(g->argv, g->pending_rotate_first, g->pending_rotate_middle, g->optind);
g->pending_rotate_first = g->pending_rotate_middle = g->optind;
g->eof = 1;
return -1;
}
a = g->argv[g->optind];
if (strcmp(a, "--") == 0)
{
g->optind++;
goto acc_label_eof;
}
if (!(a[0] == '-' && a[1]))
{
if (ordering == ACC_GETOPT_REQUIRE_ORDER)
goto acc_label_eof;
if (ordering == ACC_GETOPT_RETURN_IN_ORDER)
{
g->optarg = a;
g->optind++;
return 1;
}
__acc_getopt_x(g, -1, -1, 0, "invalid ordering %d", ordering);
goto acc_label_eof;
}
if (a[1] == '-')
{
const acc_getopt_longopt_p lo = NULL;
size_t match_chars;
for (arg = a + 2; *arg && *arg != '=' && *arg != '#'; )
++arg;
match_chars = (size_t) (arg - (a + 2));
for (i = 0; longopts && longopts[i].name; ++i)
{
size_t n = match_chars;
size_t l = strlen(longopts[i].name);
if (longopts[i].has_arg & ACC_GETOPT_EXACT_ARG) n = l;
if (strncmp(a, longopts[i].name, n) != 0)
continue;
if (match_chars == l)
{
lo = &longopts[i];
break;
}
else if (lo == NULL)
lo = &longopts[i];
else
return __acc_getopt_x(g, '?', 0, 1, "option '%s' is ambiguous (could be '--%s' or '--%s')",
a, lo->name, longopts[i].name);
}
if (lo == NULL)
return __acc_getopt_x(g, '?', 0, 1, "unrecognized option '%s'", a);
switch (lo->has_arg & 0x2f)
{
case ACC_GETOPT_OPTIONAL_ARG:
break;
case ACC_GETOPT_REQUIRED_ARG:
if (*arg)
g->optarg = arg + 1;
else if (g->optind + 1 < g->argc)
g->optarg = g->argv[++g->optind];
else
return __acc_getopt_x(g, '?', 0, 1, "option '%s' requires an argument", lo->name);
g->optind++;
break;
case ACC_GETOPT_REQUIRED_ARG | 0x20:
break;
default:
if (*arg)
return __acc_getopt_x(g, '?', lo->val, 1, "option '%s' doesn't allow an argument", lo->name);
g->optind++;
break;
}
if (longind != NULL)
*longind = (int) (lo - longopts);
if (lo->flag != NULL)
{
*lo->flag = lo->val;
return 0;
}
return lo->val;
}
else
{
const char *sp;
g->shortpos = 1;
acc_label_next_shortopt:
a = g->argv[g->optind] + g->shortpos;
sp = NULL; sc = (unsigned char) *a;
if (shortopts)
sp = strchr(shortopts, sc);
if (!sp)
return __acc_getopt_x(g, '?', sc, 1, "invalid option '-%c'", sc);
if (sp[1] == ':') { has_arg++; if (sp[2] == ':') has_arg++; }
arg = a + 1;
switch (has_arg)
{
case ACC_GETOPT_OPTIONAL_ARG:
if (*arg)
g->optarg = arg + 1;
g->optind++, g->shortpos = 0;
break;
case ACC_GETOPT_REQUIRED_ARG:
if (*arg)
g->optarg = arg + 1;
else if (g->optind + 1 < g->argc)
g->optarg = g->argv[++g->optind];
else
return __acc_getopt_x(g, '?', 0, 1, "option '-%c' requires an argument", sc);
g->optind++, g->shortpos = 0;
break;
default:
__acc_getopt_x(g, 0, -1, 1, NULL);
break;
}
return sc;
}
}
#endif
#if defined(ACC_WANT_ACCLIB_HALLOC)
# undef ACC_WANT_ACCLIB_HALLOC
#define __ACCLIB_HALLOC_CH_INCLUDED 1
@@ -6161,7 +6400,7 @@ ACCLIB_PUBLIC(acclib_handle_t, acc_get_osfhandle) (int fd)
}
ACCLIB_PUBLIC(int, acc_set_binmode) (int fd, int binary)
{
#if (ACC_ARCH_M68K && ACC_OS_TOS && defined(__MINT__))
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
FILE* fp; int old_binary;
if (fd == STDIN_FILENO) fp = stdin;
else if (fd == STDOUT_FILENO) fp = stdout;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
+12 -27
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -49,10 +49,12 @@ struct options_t {
int method;
int level; // compression level 1..10
int filter; // preferred filter from Packer::getFilters()
bool ultra_brute;
bool all_methods; // try all available compression methods ?
bool all_methods_use_lzma;
bool all_filters; // try all available filters ?
bool no_filter; // force no filter
bool exact; // user requires byte-identical decompression
// other options
int backup;
@@ -70,6 +72,7 @@ struct options_t {
// debug options
struct {
int debug_level;
bool disable_random_id; // for Packer::getRandomId()
const char *dump_stub_loader;
char fake_stub_version[4+1]; // for internal debugging
char fake_stub_year[4+1]; // for internal debugging
@@ -83,32 +86,12 @@ struct options_t {
};
int overlay;
// compression runtime parameters - see struct ucl_compress_config_t
struct crp_lzma_t {
int dummy;
#if 0
unsigned pos_bits; // pb
unsigned lit_pos_bits; // lp
unsigned lit_context_bits; // lc
unsigned dict_size;
unsigned mf_passes;
#endif
void reset() { memset(this, 0, sizeof(*this)); }
};
struct crp_ucl_t {
unsigned max_offset;
unsigned max_match;
int s_level;
int h_level;
int p_level;
int c_flags;
unsigned m_size;
void reset() { memset(this, 0xff, sizeof(*this)); }
};
// compression runtime parameters - see struct XXX_compress_config_t
struct crp_t {
crp_lzma_t crp_lzma;
crp_ucl_t crp_ucl;
void reset() { crp_lzma.reset(); crp_ucl.reset(); }
lzma_compress_config_t crp_lzma;
ucl_compress_config_t crp_ucl;
zlib_compress_config_t crp_zlib;
void reset() { crp_lzma.reset(); crp_ucl.reset(); crp_zlib.reset(); }
};
crp_t crp;
@@ -162,6 +145,8 @@ struct options_t {
int strip_relocs;
const char *keep_resource;
} win32_pe;
void reset();
};
extern struct options_t *opt;
+61 -55
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -115,26 +115,25 @@ PackArmPe::~PackArmPe()
const int *PackArmPe::getCompressionMethods(int method, int level) const
{
static const int m_nrv2b[] = { M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_NRV2B_8, M_LZMA, M_END };
static const int m_all[] = { M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END };
static const int m_lzma[] = { M_LZMA, M_END };
static const int m_nrv2b[] = { M_NRV2B_8, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_END };
if (!use_thumb_stub)
return getDefaultCompressionMethods_8(method, level);
if (M_IS_NRV2B(method))
return m_nrv2b;
if (M_IS_NRV2E(method))
return m_nrv2e;
if (M_IS_LZMA(method))
return m_lzma;
if (method == M_ALL) return m_all;
if (M_IS_LZMA(method)) return m_lzma;
if (M_IS_NRV2B(method)) return m_nrv2b;
if (M_IS_NRV2E(method)) return m_nrv2e;
return m_nrv2e;
}
const int *PackArmPe::getFilters() const
{
static const int filters[] = { 0x50, -1 };
static const int filters[] = { 0x50, FT_END };
return filters;
}
@@ -292,7 +291,7 @@ unsigned PackArmPe::processImports() // pass 1
unsigned k32namepos = ptr_diff(dllnames,oimpdlls);
memcpy(importednames, llgpa, ALIGN_UP(sizeof(llgpa), 2));
memcpy(importednames, llgpa, ALIGN_UP((unsigned) sizeof(llgpa), 2u));
strcpy(dllnames,kernel32dll);
im->dllname = k32namepos;
im->iat = ptr_diff(ordinals,oimpdlls);
@@ -440,7 +439,7 @@ unsigned PackArmPe::processImports() // pass 1
void PackArmPe::processTls(Interval *) // pass 1
{
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4)) == 0)
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4u)) == 0)
return;
// never should happen on wince
@@ -462,10 +461,10 @@ bool PackArmPe::canPack()
}
int PackArmPe::buildLoader(const Filter *ft)
void PackArmPe::buildLoader(const Filter *ft)
{
const unsigned char *loader = use_thumb_stub ? nrv_loader_thumb : nrv_loader_arm;
unsigned size = use_thumb_stub ? sizeof(nrv_loader_thumb) : sizeof(nrv_loader_arm);
const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe;
unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe);
// prepare loader
initLoader(loader, size);
@@ -503,8 +502,6 @@ int PackArmPe::buildLoader(const Filter *ft)
addLoader("+40C,LZMA_DECODE,LZMA_DEC10", NULL);
addLoader("IDENTSTR,UPX1HEAD", NULL);
freezeLoader();
return getLoaderSize();
}
@@ -557,7 +554,7 @@ void PackArmPe::pack(OutputFile *fo)
if (ih.entry && ih.entry < rvamin)
throwCantPack("run a virus scanner on this file!");
if (!opt->force && ih.subsystem == 1)
throwCantPack("subsystem `native' is not supported (try --force)");
throwCantPack("subsystem 'native' is not supported (try --force)");
if (ih.filealign < 0x200)
throwCantPack("filealign < 0x200 is not yet supported");
@@ -700,20 +697,20 @@ void PackArmPe::pack(OutputFile *fo)
ft.buf_len = ih.codesize;
ft.addvalue = ih.codebase - rvamin;
// compress
int strategy = allow_filter ? 0 : -3;
int filter_strategy = allow_filter ? 0 : -3;
// disable filters for files with broken headers
if (ih.codebase + ih.codesize > ph.u_len)
{
ft.buf_len = 1;
strategy = -3;
filter_strategy = -3;
}
// limit stack size needed for runtime decompression
upx_compress_config_t cconf; cconf.reset();
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 2048, strategy,
NULL, &cconf, ih.codebase, rvamin);
compressWithFilters(&ft, 2048, &cconf, filter_strategy,
ih.codebase, rvamin, 0, NULL, 0);
// info: see buildLoader()
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
/*
@@ -729,13 +726,11 @@ void PackArmPe::pack(OutputFile *fo)
getLoaderSection("UPX1HEAD",(int*)&ic);
identsize += ic;
pe_section_t osection[3];
pe_section_t osection[4];
// section 0 : bss
// 1 : [ident + header] + packed_data + unpacker + tls
// 2 : not compressed data
// section 2 should start with the resource data, because lots of lame
// windoze codes assume that resources starts on the beginning of a section
// 3 : resource data -- wince 5 needs a new section for this
// identsplit - number of ident + (upx header) bytes to put into the PE header
int identsplit = pe_offset + sizeof(osection) + sizeof(oh);
@@ -750,7 +745,7 @@ void PackArmPe::pack(OutputFile *fo)
const unsigned c_len = ((ph.c_len + ic) & 15) == 0 ? ph.c_len : ph.c_len + 16 - ((ph.c_len + ic) & 15);
obuf.clear(ph.c_len, c_len - ph.c_len);
const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4) + sotls;
const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4u) + sotls;
const unsigned s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1;
const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1;
@@ -773,7 +768,7 @@ void PackArmPe::pack(OutputFile *fo)
memset(osection,0,sizeof(osection));
oh.entry = upxsection;
oh.objects = 3;
oh.objects = 4;
oh.chksum = 0;
// fill the data directory
@@ -802,12 +797,6 @@ void PackArmPe::pack(OutputFile *fo)
ODSIZE(PEDIR_RELOC) = soxrelocs;
ic += soxrelocs;
if (soresources)
processResources(&res,ic);
ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0;
ODSIZE(PEDIR_RESOURCE) = soresources;
ic += soresources;
processImports(ic, linker->getSymbolOffset("IATT") + upxsection);
ODADDR(PEDIR_IMPORT) = ic;
ODSIZE(PEDIR_IMPORT) = soimpdlls;
@@ -823,7 +812,15 @@ void PackArmPe::pack(OutputFile *fo)
}
ic += soexport;
const unsigned onam = ncsection + soxrelocs + soresources + ih.imagebase;
ic = (ic + oam1) &~ oam1;
const unsigned res_start = ic;
if (soresources)
processResources(&res,ic);
ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0;
ODSIZE(PEDIR_RESOURCE) = soresources;
ic += soresources;
const unsigned onam = ncsection + soxrelocs + ih.imagebase;
linker->defineSymbol("start_of_dll_names", onam);
linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
linker->defineSymbol("start_of_relocs", crelocs + rvamin + ih.imagebase);
@@ -835,54 +832,52 @@ void PackArmPe::pack(OutputFile *fo)
linker->defineSymbol("compressed_length", ph.c_len);
linker->defineSymbol("start_of_compressed", ih.imagebase + s1addr + identsize - identsplit);
defineDecompressorSymbols();
linker->relocate();
relocateLoader();
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
// this is computed here, because soxrelocs changes some lines above
const unsigned ncsize = soxrelocs + soresources + soimpdlls + soexport;
const unsigned ncsize = soxrelocs + soimpdlls + soexport;
const unsigned fam1 = oh.filealign - 1;
// fill the sections
strcpy(osection[0].name,"UPX0");
strcpy(osection[1].name,"UPX1");
// after some windoze debugging I found that the name of the sections
// DOES matter :( .rsrc is used by oleaut32.dll (TYPELIBS)
// and because of this lame dll, the resource stuff must be the
// first in the 3rd section - the author of this dll seems to be
// too idiot to use the data directories... M$ suxx 4 ever!
// ... even worse: exploder.exe in NiceTry also depends on this to
// locate version info
strcpy(osection[2].name,soresources ? ".rsrc" : "UPX2");
strcpy(osection[2].name, "UPX2");
strcpy(osection[3].name, ".rsrc");
osection[0].vaddr = rvamin;
osection[1].vaddr = s1addr;
osection[2].vaddr = ncsection;
osection[3].vaddr = res_start;
osection[0].size = 0;
osection[1].size = (s1size + fam1) &~ fam1;
osection[2].size = (ncsize + fam1) &~ fam1;
osection[3].size = (soresources + fam1) &~ fam1;
osection[0].vsize = osection[1].vaddr - osection[0].vaddr;
//osection[1].vsize = (osection[1].size + oam1) &~ oam1;
//osection[2].vsize = (osection[2].size + oam1) &~ oam1;
osection[1].vsize = osection[1].size;
osection[2].vsize = osection[2].size;
osection[3].vsize = osection[3].size;
osection[0].rawdataptr = 0;
osection[1].rawdataptr = (pe_offset + sizeof(oh) + sizeof(osection) + fam1) &~ fam1;
osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size;
osection[3].rawdataptr = osection[2].rawdataptr + osection[2].size;
osection[0].flags = (unsigned) (PEFL_BSS|PEFL_EXEC|PEFL_WRITE|PEFL_READ);
osection[1].flags = (unsigned) (PEFL_DATA|PEFL_EXEC|PEFL_WRITE|PEFL_READ);
osection[2].flags = (unsigned) (PEFL_DATA|PEFL_READ);
osection[3].flags = (unsigned) (PEFL_DATA|PEFL_READ);
oh.imagesize = (osection[2].vaddr + osection[2].vsize + oam1) &~ oam1;
oh.imagesize = (osection[3].vaddr + osection[3].vsize + oam1) &~ oam1;
oh.bsssize = osection[0].vsize;
oh.datasize = osection[2].vsize;
oh.datasize = osection[2].vsize + osection[3].vsize;
oh.database = osection[2].vaddr;
oh.codesize = osection[1].vsize;
oh.codebase = osection[1].vaddr;
@@ -900,6 +895,11 @@ void PackArmPe::pack(OutputFile *fo)
infoHeader("[Writing compressed file]");
if (soresources == 0)
{
oh.objects = 3;
memset(&osection[3], 0, sizeof(osection[3]));
}
// write loader + compressed file
fo->write(&oh,sizeof(oh));
fo->write(osection,sizeof(osection));
@@ -920,14 +920,17 @@ void PackArmPe::pack(OutputFile *fo)
if ((ic = fo->getBytesWritten() & 3) != 0)
fo->write(ibuf,4 - ic);
fo->write(otls,sotls);
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
if ((ic = fo->getBytesWritten() & fam1) != 0)
fo->write(ibuf,oh.filealign - ic);
fo->write(oxrelocs,soxrelocs);
fo->write(oresources,soresources);
fo->write(oimpdlls,soimpdlls);
fo->write(oexport,soexport);
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
if ((ic = fo->getBytesWritten() & fam1) != 0)
fo->write(ibuf,oh.filealign - ic);
fo->write(oresources,soresources);
if ((ic = fo->getBytesWritten() & fam1) != 0)
fo->write(ibuf,oh.filealign - ic);
#if 0
@@ -970,7 +973,7 @@ int PackArmPe::canUnpack()
fi->readx(isection,sizeof(pe_section_t)*objs);
if (ih.objects < 3)
return -1;
bool is_packed = (ih.objects == 3 &&
bool is_packed = ((ih.objects == 3 || ih.objects == 4) &&
(IDSIZE(15) || ih.entry > isection[1].vaddr));
bool found_ph = false;
if (memcmp(isection[0].name,"UPX",3) == 0)
@@ -1024,7 +1027,8 @@ int PackArmPe::canUnpack()
void PackArmPe::rebuildImports(upx_byte *& extrainfo)
{
if (ODADDR(PEDIR_IMPORT) == 0)
if (ODADDR(PEDIR_IMPORT) == 0
|| ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
return;
// const upx_byte * const idata = obuf + get_le32(extrainfo);
@@ -1042,6 +1046,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
for (p = idata; get_le32(p) != 0; ++p)
{
const upx_byte *dname = get_le32(p) + import;
ICHECK(dname, 1);
const unsigned dlen = strlen(dname);
ICHECK(dname, dlen + 1);
@@ -1054,7 +1059,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
else
p += 5;
}
sdllnames = ALIGN_UP(sdllnames,2);
sdllnames = ALIGN_UP(sdllnames,2u);
upx_byte * const Obuf = obuf - rvamin;
import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
@@ -1067,6 +1072,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
{
// restore the name of the dll
const upx_byte *dname = get_le32(p) + import;
ICHECK(dname, 1);
const unsigned dlen = strlen(dname);
ICHECK(dname, dlen + 1);
+5 -4
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -39,9 +39,10 @@ class PackArmPe : public PeFile
public:
PackArmPe(InputFile *f);
~PackArmPe();
virtual ~PackArmPe();
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
virtual const char *getName() const { return "arm/pe"; }
virtual const char *getFullName(const options_t *) const { return "arm-wince.pe"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -51,7 +52,7 @@ public:
virtual int canUnpack();
protected:
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
virtual unsigned processImports();
+13 -19
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -45,16 +45,11 @@ static const
const int *PackCom::getCompressionMethods(int method, int level) const
{
static const int m_nrv2b[] = { M_NRV2B_LE16, -1 };
if (M_IS_NRV2B(method))
return m_nrv2b;
static const int m_nrv2b[] = { M_NRV2B_LE16, M_END };
#if 0
// NOT IMPLEMENTED
static const int m_nrv2d[] = { M_NRV2D_LE16, -1 };
if (M_IS_NRV2D(method))
return m_nrv2d;
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
#endif
UNUSED(level);
UNUSED(method); UNUSED(level);
return m_nrv2b;
}
@@ -63,7 +58,7 @@ const int *PackCom::getFilters() const
{
static const int filters[] = {
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
-1 };
FT_END };
return filters;
}
@@ -101,7 +96,7 @@ void PackCom::patchLoader(OutputFile *fo,
{
const int e_len = getLoaderSectionStart("COMCUTPO");
const int d_len = lsize - e_len;
assert(e_len > 0 && e_len < 256);
assert(e_len > 0 && e_len < 128);
assert(d_len > 0 && d_len < 256);
const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100;
@@ -116,9 +111,10 @@ void PackCom::patchLoader(OutputFile *fo,
linker->defineSymbol("bytes_to_copy", ph.c_len + lsize);
linker->defineSymbol("copy_source", ph.c_len + lsize + 0x100);
linker->defineSymbol("copy_destination", upper_end);
linker->defineSymbol("COMCUTPO", ph.u_len + ph.overlap_overhead);
linker->defineSymbol("neg_e_len", 0 - e_len);
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead);
linker->relocate();
relocateLoader();
loader = getLoader();
// some day we could use the relocation stuff for patchPackHeader too
@@ -135,9 +131,9 @@ void PackCom::patchLoader(OutputFile *fo,
}
int PackCom::buildLoader(const Filter *ft)
void PackCom::buildLoader(const Filter *ft)
{
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
addLoader("COMMAIN1",
ph.first_offset_found == 1 ? "COMSBBBP" : "",
"COMPSHDI",
@@ -154,8 +150,6 @@ int PackCom::buildLoader(const Filter *ft)
assert(ft->calls > 0);
addFilter16(ft->id);
}
freezeLoader();
return getLoaderSize();
}
@@ -203,7 +197,7 @@ void PackCom::pack(OutputFile *fo)
ft.addvalue = getCallTrickOffset();
// compress
const unsigned overlap_range = ph.u_len < 0xFE00 - ft.addvalue ? 32 : 0;
compressWithFilters(&ft, overlap_range);
compressWithFilters(&ft, overlap_range, NULL_cconf);
const int lsize = getLoaderSize();
MemBuffer loader(lsize);
+5 -4
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -38,10 +38,11 @@ class PackCom : public Packer
{
typedef Packer super;
public:
PackCom(InputFile *f) : super(f) { }
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_DOS_COM; }
virtual const char *getName() const { return "dos/com"; }
virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.com" : "i286-dos16.com"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -56,7 +57,7 @@ protected:
virtual Linker* newLinker() const;
protected:
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
virtual void addFilter16(int filter_id);
};
+24 -47
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -46,13 +46,14 @@ static const
PackDjgpp2::PackDjgpp2(InputFile *f) :
super(f), coff_offset(0)
{
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40);
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8);
COMPILE_TIME_ASSERT(sizeof(stubify_stub) == 2048);
COMPILE_TIME_ASSERT_ALIGNOF(external_scnhdr_t, char)
COMPILE_TIME_ASSERT_ALIGNOF(coff_header_t, char)
COMPILE_TIME_ASSERT(STUBIFY_STUB_ADLER32 == 0xbf689ba8);
COMPILE_TIME_ASSERT(STUBIFY_STUB_CRC32 == 0x2ae982b2);
bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
COMPILE_TIME_ASSERT_ALIGNED1(external_scnhdr_t)
COMPILE_TIME_ASSERT_ALIGNED1(coff_header_t)
COMPILE_TIME_ASSERT(sizeof(stub_i386_dos32_djgpp2_stubify) == 2048)
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_ADLER32 == 0xbf689ba8)
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
}
@@ -67,8 +68,9 @@ const int *PackDjgpp2::getCompressionMethods(int method, int level) const
const int *PackDjgpp2::getFilters() const
{
static const int filters[] = {
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
-1 };
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters;
}
@@ -89,16 +91,16 @@ Linker* PackDjgpp2::newLinker() const
}
int PackDjgpp2::buildLoader(const Filter *ft)
void PackDjgpp2::buildLoader(const Filter *ft)
{
// prepare loader
initLoader(nrv_loader, sizeof(nrv_loader));
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
addLoader("IDENTSTR,DJ2MAIN1",
ft->id ? "DJCALLT1" : "",
"DJ2MAIN2",
ph.method == M_LZMA ? "LZMA_INIT_STACK" : "",
ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
getDecompressorSections(),
ph.method == M_LZMA ? "LZMA_DONE_STACK" : "",
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
"DJ2BSS00",
NULL
);
@@ -109,8 +111,6 @@ int PackDjgpp2::buildLoader(const Filter *ft)
addFilter32(ft->id);
}
addLoader("DJRETURN,+40C,UPX1HEAD", NULL);
freezeLoader();
return getLoaderSize();
}
@@ -130,8 +130,8 @@ void PackDjgpp2::handleStub(OutputFile *fo)
else
{
// "stubify" stub
info("Adding stub: %ld bytes", (long)sizeof(stubify_stub));
fo->write(stubify_stub, sizeof(stubify_stub));
info("Adding stub: %ld bytes", (long)sizeof(stub_i386_dos32_djgpp2_stubify));
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
}
}
}
@@ -235,29 +235,6 @@ void PackDjgpp2::stripDebug()
}
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
{
if (ft->id == 0)
return false;
assert(ft->calls > 0);
linker->defineSymbol("filter_cto", ft->cto);
linker->defineSymbol("filter_length",
(ft->id & 0xf) % 3 == 0 ? ft->calls :
ft->lastcall - ft->calls * 4);
#if 0
if (0x80==(ft->id & 0xF0)) {
int const mru = ph.n_mru ? 1+ ph.n_mru : 0;
if (mru && mru!=256) {
unsigned const is_pwr2 = (0==((mru -1) & mru));
patch_le32(0x80 + (char *)loader, lsize - 0x80, "NMRU", mru - is_pwr2);
}
}
#endif
return true;
}
/*************************************************************************
//
**************************************************************************/
@@ -326,7 +303,7 @@ void PackDjgpp2::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 512, 0, NULL, &cconf);
compressWithFilters(&ft, 512, &cconf);
// patch coff header #2
const unsigned lsize = getLoaderSize();
@@ -335,7 +312,7 @@ void PackDjgpp2::pack(OutputFile *fo)
data->size = ph.c_len; // new size of .data
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
stack = ALIGN_UP(stack, 16);
stack = ALIGN_UP(stack, 16u);
if (bss->size < stack) // give it a .bss
bss->size = stack;
@@ -351,7 +328,7 @@ void PackDjgpp2::pack(OutputFile *fo)
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
linker->defineSymbol("start_of_compressed", data->vaddr);
defineFilterSymbols(linker, &ft);
defineFilterSymbols(&ft);
// we should not overwrite our decompressor during unpacking
// the original coff header (which is put just before the
@@ -369,7 +346,7 @@ void PackDjgpp2::pack(OutputFile *fo)
data->size = ALIGN_UP(data->size, 4);
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
linker->relocate();
relocateLoader();
// prepare loader
MemBuffer loader(lsize);
+4 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -43,6 +43,7 @@ public:
virtual int getVersion() const { return 14; }
virtual int getFormat() const { return UPX_F_DJGPP2_COFF; }
virtual const char *getName() const { return "djgpp2/coff"; }
virtual const char *getFullName(const options_t *) const { return "i386-dos32.djgpp2"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -59,7 +60,7 @@ protected:
virtual unsigned findOverlapOverhead(const upx_bytep buf,
unsigned range = 0,
unsigned upper_limit = ~0u) const;
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
long coff_offset;
+247 -241
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -31,15 +31,34 @@
/*************************************************************************
// Some ELF type definitinons
// N_Elf
**************************************************************************/
namespace N_Elf {
// integral types
template <class THalf, class TWord, class TXword, class TAddr, class TOff>
struct ElfITypes
{
typedef THalf Half;
typedef TWord Word;
typedef TXword Xword;
typedef TAddr Addr;
typedef TOff Off;
typedef THalf Section;
typedef THalf Versym;
};
// The ELF file header. This appears at the start of every ELF file.
template <class Word, class Addr, class Off, class Half>
template <class TElfITypes>
struct Ehdr
{
typedef typename TElfITypes::Half Half;
typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off;
unsigned char e_ident[16]; /* Magic number and other info */
Half e_type; /* Object file type */
Half e_machine; /* Architecture */
@@ -55,76 +74,57 @@ struct Ehdr
Half e_shnum; /* Section header table entry count */
Half e_shstrndx; /* Section header string table index */
enum { // e_ident[]
EI_CLASS = 4,
EI_DATA = 5, /* Data encoding */
EI_VERSION = 6,
EI_OSABI = 7,
EI_ABIVERSION = 8,
};
enum { // e_ident[EI_CLASS]
ELFCLASS32 = 1, /* 32-bit objects */
ELFCLASS64 = 2, /* 64-bit objects */
};
enum { // e_ident[EI_DATA]
ELFDATA2LSB = 1, /* 2's complement, little endian */
ELFDATA2MSB = 2 /* 2's complement, big endian */
};
enum { // e_ident[EI_OSABI]
ELFOSABI_NONE = 0,
ELFOSABI_NETBSD = 2,
ELFOSABI_LINUX = 3,
ELFOSABI_FREEBSD = 9,
ELFOSABI_OPENBSD = 12,
ELFOSABI_ARM = 97
};
enum { // e_type
ET_NONE = 0, /* No file type */
ET_REL = 1, /* Relocatable file */
ET_EXEC = 2, /* Executable file */
ET_DYN = 3, /* Shared object file */
ET_CORE = 4, /* Core file */
};
enum { // e_machine
EM_386 = 3,
EM_PPC = 20,
EM_PPC64 = 21,
EM_ARM = 40,
EM_X86_64 = 62,
};
enum { // e_version
EV_CURRENT = 1,
};
# define WANT_EHDR_ENUM 1
# include "p_elf_enum.h"
}
__attribute_packed;
template <class Word, class Addr>
template <class TElfITypes>
struct Dyn
{
Word d_tag;
typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr;
Xword d_tag;
Addr d_val;
enum { // d_tag
DT_NULL = 0, /* End flag */
DT_NEEDED = 1, /* Name of needed library */
DT_HASH = 4, /* Hash table of symbol names */
DT_STRTAB = 5, /* String table */
DT_SYMTAB = 6, /* Symbol table */
DT_STRSZ = 10, /* Sizeof string table */
};
# define WANT_DYN_ENUM 1
# include "p_elf_enum.h"
}
__attribute_packed;
template <class TElfITypes>
struct External_Note
{
typedef typename TElfITypes::Word Word;
Word xn_namesz; // includes terminating '\0'
Word xn_datasz;
Word xn_type;
//char xn_name[N]; // terminate with '\0'
//char xn_data[M]; // aligned to 0 mod 4
}
__attribute_packed;
} // namespace N_Elf
/*************************************************************************
// N_Elf32
**************************************************************************/
namespace N_Elf32 {
// Program segment header.
template <class Word, class Addr, class Off>
template <class TElfITypes>
struct Phdr
{
typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off;
Word p_type; /* Segment type */
Off p_offset; /* Segment file offset */
Addr p_vaddr; /* Segment virtual address */
@@ -134,25 +134,19 @@ struct Phdr
Word p_flags; /* Segment flags */
Word p_align; /* Segment alignment */
enum { // p_type
PT_LOAD = 1, /* Loadable program segment */
PT_DYNAMIC = 2, /* Dynamic linking information */
PT_INTERP = 3, /* Name of program interpreter */
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
PT_PHDR = 6, /* Entry for header table itself */
};
enum { // p_flags
PF_X = 1, /* Segment is executable */
PF_W = 2, /* Segment is writable */
PF_R = 4, /* Segment is readable */
};
# define WANT_PHDR_ENUM 1
# include "p_elf_enum.h"
}
__attribute_packed;
template <class Word, class Addr, class Off>
template <class TElfITypes>
struct Shdr
{
typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off;
Word sh_name; /* Section name (string tbl index) */
Word sh_type; /* Section type */
Word sh_flags; /* Section flags */
@@ -164,94 +158,53 @@ struct Shdr
Word sh_addralign; /* Section alignment */
Word sh_entsize; /* Entry size if section holds table */
enum { // sh_type
SHT_NULL = 0, /* Section header table entry unused */
SHT_PROGBITS = 1, /* Program data */
SHT_SYMTAB = 2, /* Symbol table */
SHT_STRTAB = 3, /* String table */
SHT_RELA = 4, /* Relocation entries with addends */
SHT_HASH = 5, /* Symbol hash table */
SHT_DYNAMIC = 6, /* Dynamic linking information */
SHT_NOTE = 7, /* Notes */
SHT_NOBITS = 8, /* Program space with no data (bss) */
SHT_REL = 9, /* Relocation entries, no addends */
SHT_SHLIB = 10, /* Reserved */
SHT_DYNSYM = 11, /* Dynamic linker symbol table */
/* 12, 13 hole */
SHT_INIT_ARRAY = 14, /* Array of constructors */
SHT_FINI_ARRAY = 15, /* Array of destructors */
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
SHT_GROUP = 17, /* Section group */
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
};
enum { // sh_flags
SHF_WRITE = (1 << 0), /* Writable */
SHF_ALLOC = (1 << 1), /* Occupies memory during execution */
SHF_EXECINSTR = (1 << 2), /* Executable */
SHF_MERGE = (1 << 4), /* Might be merged */
SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */
SHF_INFO_LINK = (1 << 6), /* `sh_info' contains SHT index */
SHF_LINK_ORDER = (1 << 7), /* Preserve order after combining */
};
# define WANT_SHDR_ENUM 1
# include "p_elf_enum.h"
}
__attribute_packed;
template <class TT16, class TT32>
template <class TElfITypes>
struct Sym
{
TT32 st_name; /* symbol name (index into string table) */
TT32 st_value; /* symbol value */
TT32 st_size; /* symbol size */
typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Section Section;
Word st_name; /* symbol name (index into string table) */
Addr st_value; /* symbol value */
Word st_size; /* symbol size */
unsigned char st_info; /* symbol type and binding */
unsigned char st_other; /* symbol visibility */
TT16 st_shndx; /* section index */
Section st_shndx; /* section index */
unsigned int st_bind(unsigned int x) const { return 0xf & (x>>4); }
unsigned int st_type(unsigned int x) const { return 0xf & x ; }
unsigned char St_info(unsigned bind, unsigned type) const { return (bind<<4) + (0xf & type); }
# define WANT_SYM_ENUM 1
# include "p_elf_enum.h"
enum { // st_bind (high 4 bits of st_info)
STB_LOCAL = 0, /* Local symbol */
STB_GLOBAL = 1, /* Global symbol */
STB_WEAK = 2, /* Weak symbol */
};
enum { // st_type (low 4 bits of st_info)
STT_NOTYPE = 0, /* Symbol type is unspecified */
STT_OBJECT = 1, /* Symbol is a data object */
STT_FUNC = 2, /* Symbol is a code object */
STT_SECTION = 3, /* Symbol associated with a section */
STT_FILE = 4, /* Symbol's name is file name */
STT_COMMON = 5, /* Symbol is a common data object */
STT_TLS = 6, /* Symbol is thread-local data object*/
};
enum { // st_other (visibility)
STV_DEFAULT = 0, /* Default symbol visibility rules */
STV_INTERNAL = 1, /* Processor specific hidden class */
STV_HIDDEN = 2, /* Sym unavailable in other modules */
STV_PROTECTED= 3, /* Not preemptible, not exported */
};
enum { // st_shndx
SHN_UNDEF = 0, /* Undefined section */
SHN_ABS = 0xfff1, /* Associated symbol is absolute */
SHN_COMMON = 0xfff2, /* Associated symbol is common */
};
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
}
__attribute_packed;
} // namespace N_Elf32
/*************************************************************************
// N_Elf64
**************************************************************************/
namespace N_Elf64 {
// Program segment header.
template <class Word, class Xword, class Addr, class Off>
template <class TElfITypes>
struct Phdr
{
typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off;
Word p_type; /* Segment type */
Word p_flags; /* Segment flags */
Off p_offset; /* Segment file offset */
@@ -261,24 +214,20 @@ struct Phdr
Xword p_memsz; /* Segment size in memory */
Xword p_align; /* Segment alignment */
enum { // p_type
PT_LOAD = 1, /* Loadable program segment */
PT_DYNAMIC = 2, /* Dynamic linking information */
PT_INTERP = 3, /* Name of program interpreter */
PT_PHDR = 6, /* Entry for header table itself */
};
enum { // p_flags
PF_X = 1, /* Segment is executable */
PF_W = 2, /* Segment is writable */
PF_R = 4, /* Segment is readable */
};
# define WANT_PHDR_ENUM 1
# include "p_elf_enum.h"
}
__attribute_packed;
template <class Word, class Xword, class Addr, class Off>
template <class TElfITypes>
struct Shdr
{
typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off;
Word sh_name; /* Section name (string tbl index) */
Word sh_type; /* Section type */
Xword sh_flags; /* Section flags */
@@ -290,115 +239,172 @@ struct Shdr
Xword sh_addralign; /* Section alignment */
Xword sh_entsize; /* Entry size if section holds table */
enum { // sh_type
SHT_NULL = 0, /* Section header table entry unused */
SHT_PROGBITS = 1, /* Program data */
SHT_SYMTAB = 2, /* Symbol table */
SHT_STRTAB = 3, /* String table */
SHT_RELA = 4, /* Relocation entries with addends */
SHT_HASH = 5, /* Symbol hash table */
SHT_DYNAMIC = 6, /* Dynamic linking information */
SHT_NOTE = 7, /* Notes */
SHT_NOBITS = 8, /* Program space with no data (bss) */
SHT_REL = 9, /* Relocation entries, no addends */
SHT_SHLIB = 10, /* Reserved */
SHT_DYNSYM = 11, /* Dynamic linker symbol table */
/* 12, 13 hole */
SHT_INIT_ARRAY = 14, /* Array of constructors */
SHT_FINI_ARRAY = 15, /* Array of destructors */
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
SHT_GROUP = 17, /* Section group */
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
};
# define WANT_SHDR_ENUM 1
# include "p_elf_enum.h"
}
__attribute_packed;
template <class TElfITypes>
struct Sym
{
typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Section Section;
Word st_name; /* symbol name (index into string table) */
unsigned char st_info; /* symbol type and binding */
unsigned char st_other; /* symbol visibility */
Section st_shndx; /* section index */
Addr st_value; /* symbol value */
Xword st_size; /* symbol size */
# define WANT_SYM_ENUM 1
# include "p_elf_enum.h"
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
}
__attribute_packed;
} // namespace N_Elf64
/*************************************************************************
// now for the actual types
// aggregate types into an ElfClass
**************************************************************************/
#define P N_BELE_CTP::HostPolicy
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf32_Ehdr;
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf32_Phdr;
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf32_Shdr;
typedef N_Elf ::Dyn <P::U32,P::U32> Elf32_Dyn;
typedef N_Elf32::Sym <P::U16,P::U32> Elf32_Sym;
#undef P
namespace N_Elf {
#define P N_BELE_CTP::BEPolicy
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_BE32_Ehdr;
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_BE32_Phdr;
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_BE32_Shdr;
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_BE32_Dyn;
typedef N_Elf32::Sym <P::U16,P::U32> Elf_BE32_Sym;
#undef P
template <class TP>
struct ElfClass_32
{
typedef TP BeLePolicy;
#define P N_BELE_CTP::LEPolicy
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_LE32_Ehdr;
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_LE32_Phdr;
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_LE32_Shdr;
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_LE32_Dyn;
typedef N_Elf32::Sym <P::U16,P::U32> Elf_LE32_Sym;
#undef P
// integral types
typedef typename TP::U16 U16;
typedef typename TP::U32 U32;
typedef typename TP::U64 U64;
typedef N_Elf::ElfITypes<U16, U32, U32, U32, U32> ElfITypes;
#define P N_BELE_CTP::HostPolicy
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf64_Ehdr;
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf64_Phdr;
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf64_Shdr;
typedef N_Elf ::Dyn <P::U64,P::U64> Elf64_Dyn;
#undef P
// ELF types
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
typedef N_Elf32::Phdr<ElfITypes> Phdr;
typedef N_Elf32::Shdr<ElfITypes> Shdr;
typedef N_Elf ::Dyn <ElfITypes> Dyn;
typedef N_Elf32::Sym <ElfITypes> Sym;
typedef N_Elf ::External_Note<ElfITypes> External_Note;
#define P N_BELE_CTP::BEPolicy
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_BE64_Ehdr;
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Phdr;
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Shdr;
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_BE64_Dyn;
#undef P
#define P N_BELE_CTP::LEPolicy
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_LE64_Ehdr;
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Phdr;
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Shdr;
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_LE64_Dyn;
#undef P
static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions();
COMPILE_TIME_ASSERT(sizeof(Ehdr) == 52)
COMPILE_TIME_ASSERT(sizeof(Phdr) == 32)
COMPILE_TIME_ASSERT(sizeof(Shdr) == 40)
COMPILE_TIME_ASSERT(sizeof(Dyn) == 8)
COMPILE_TIME_ASSERT(sizeof(Sym) == 16)
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
}
};
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
template <class TP>
struct ElfClass_64
{
typedef TP BeLePolicy;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Shdr) == 40)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Dyn) == 8)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Sym) == 16)
// integral types
typedef typename TP::U16 U16;
typedef typename TP::U32 U32;
typedef typename TP::U64 U64;
typedef N_Elf::ElfITypes<U16, U32, U64, U64, U64> ElfITypes;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
// ELF types
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
typedef N_Elf64::Phdr<ElfITypes> Phdr;
typedef N_Elf64::Shdr<ElfITypes> Shdr;
typedef N_Elf ::Dyn <ElfITypes> Dyn;
typedef N_Elf64::Sym <ElfITypes> Sym;
typedef N_Elf ::External_Note<ElfITypes> External_Note;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Ehdr) == 64)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16)
static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions();
COMPILE_TIME_ASSERT(sizeof(Ehdr) == 64)
COMPILE_TIME_ASSERT(sizeof(Phdr) == 56)
COMPILE_TIME_ASSERT(sizeof(Shdr) == 64)
COMPILE_TIME_ASSERT(sizeof(Dyn) == 16)
COMPILE_TIME_ASSERT(sizeof(Sym) == 24)
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
}
};
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Ehdr) == 64)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Phdr) == 56)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Shdr) == 64)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Dyn) == 16)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Ehdr) == 64)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Phdr) == 56)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Shdr) == 64)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Dyn) == 16)
} // namespace N_Elf
typedef N_Elf::ElfClass_32<N_BELE_CTP::HostPolicy> ElfClass_Host32;
typedef N_Elf::ElfClass_64<N_BELE_CTP::HostPolicy> ElfClass_Host64;
typedef N_Elf::ElfClass_32<N_BELE_CTP::BEPolicy> ElfClass_BE32;
typedef N_Elf::ElfClass_64<N_BELE_CTP::BEPolicy> ElfClass_BE64;
typedef N_Elf::ElfClass_32<N_BELE_CTP::LEPolicy> ElfClass_LE32;
typedef N_Elf::ElfClass_64<N_BELE_CTP::LEPolicy> ElfClass_LE64;
/*************************************************************************
// shortcuts
**************************************************************************/
typedef ElfClass_Host32::Ehdr Elf32_Ehdr;
typedef ElfClass_Host32::Phdr Elf32_Phdr;
typedef ElfClass_Host32::Shdr Elf32_Shdr;
typedef ElfClass_Host32::Dyn Elf32_Dyn;
typedef ElfClass_Host32::Sym Elf32_Sym;
typedef ElfClass_Host32::External_Note Elf32_External_Note;
typedef ElfClass_Host64::Ehdr Elf64_Ehdr;
typedef ElfClass_Host64::Phdr Elf64_Phdr;
typedef ElfClass_Host64::Shdr Elf64_Shdr;
typedef ElfClass_Host64::Dyn Elf64_Dyn;
typedef ElfClass_Host64::Sym Elf64_Sym;
typedef ElfClass_Host64::External_Note Elf64_External_Note;
typedef ElfClass_BE32::Ehdr Elf_BE32_Ehdr;
typedef ElfClass_BE32::Phdr Elf_BE32_Phdr;
typedef ElfClass_BE32::Shdr Elf_BE32_Shdr;
typedef ElfClass_BE32::Dyn Elf_BE32_Dyn;
typedef ElfClass_BE32::Sym Elf_BE32_Sym;
typedef ElfClass_BE32::External_Note Elf_BE32_External_Note;
typedef ElfClass_BE64::Ehdr Elf_BE64_Ehdr;
typedef ElfClass_BE64::Phdr Elf_BE64_Phdr;
typedef ElfClass_BE64::Shdr Elf_BE64_Shdr;
typedef ElfClass_BE64::Dyn Elf_BE64_Dyn;
typedef ElfClass_BE64::Sym Elf_BE64_Sym;
typedef ElfClass_BE64::External_Note Elf_BE64_External_Note;
typedef ElfClass_LE32::Ehdr Elf_LE32_Ehdr;
typedef ElfClass_LE32::Phdr Elf_LE32_Phdr;
typedef ElfClass_LE32::Shdr Elf_LE32_Shdr;
typedef ElfClass_LE32::Dyn Elf_LE32_Dyn;
typedef ElfClass_LE32::Sym Elf_LE32_Sym;
typedef ElfClass_LE32::External_Note Elf_LE32_External_Note;
typedef ElfClass_LE64::Ehdr Elf_LE64_Ehdr;
typedef ElfClass_LE64::Phdr Elf_LE64_Phdr;
typedef ElfClass_LE64::Shdr Elf_LE64_Shdr;
typedef ElfClass_LE64::Dyn Elf_LE64_Dyn;
typedef ElfClass_LE64::Sym Elf_LE64_Sym;
typedef ElfClass_LE64::External_Note Elf_LE64_External_Note;
#endif /* already included */
+185
View File
@@ -0,0 +1,185 @@
/* p_elf_enum.h --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
markus@oberhumer.com ml1050@users.sourceforge.net
*/
/*************************************************************************
// Use the preprocessor to work around
// - that the types embedding these enums have to be PODs, and
// deriving from an empty base class (which is the ususal C++ way
// of "importing" enums) does not yield a POD any more
// - that older compilers do not correctly perform EBCO
**************************************************************************/
#ifdef WANT_EHDR_ENUM
#undef WANT_EHDR_ENUM
enum { // e_ident[]
EI_CLASS = 4,
EI_DATA = 5, /* Data encoding */
EI_VERSION = 6,
EI_OSABI = 7,
EI_ABIVERSION = 8
};
enum { // e_ident[EI_CLASS]
ELFCLASS32 = 1, /* 32-bit objects */
ELFCLASS64 = 2 /* 64-bit objects */
};
enum { // e_ident[EI_DATA]
ELFDATA2LSB = 1, /* 2's complement, little endian */
ELFDATA2MSB = 2 /* 2's complement, big endian */
};
enum { // e_ident[EI_OSABI]
ELFOSABI_NONE = 0, // == ELFOSABI_SYSV
ELFOSABI_NETBSD = 2,
ELFOSABI_LINUX = 3,
ELFOSABI_FREEBSD = 9,
ELFOSABI_OPENBSD = 12,
ELFOSABI_ARM = 97
};
enum { // e_type
ET_NONE = 0, /* No file type */
ET_REL = 1, /* Relocatable file */
ET_EXEC = 2, /* Executable file */
ET_DYN = 3, /* Shared object file */
ET_CORE = 4 /* Core file */
};
enum { // e_machine
EM_386 = 3,
EM_PPC = 20,
EM_PPC64 = 21,
EM_ARM = 40,
EM_X86_64 = 62
};
enum { // e_version
EV_CURRENT = 1
};
#endif
#ifdef WANT_PHDR_ENUM
#undef WANT_PHDR_ENUM
enum { // p_type
PT_LOAD = 1, /* Loadable program segment */
PT_DYNAMIC = 2, /* Dynamic linking information */
PT_INTERP = 3, /* Name of program interpreter */
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
PT_PHDR = 6 /* Entry for header table itself */
};
enum { // p_flags
PF_X = 1, /* Segment is executable */
PF_W = 2, /* Segment is writable */
PF_R = 4 /* Segment is readable */
};
#endif
#ifdef WANT_SHDR_ENUM
#undef WANT_SHDR_ENUM
enum { // sh_type
SHT_NULL = 0, /* Section header table entry unused */
SHT_PROGBITS = 1, /* Program data */
SHT_SYMTAB = 2, /* Symbol table */
SHT_STRTAB = 3, /* String table */
SHT_RELA = 4, /* Relocation entries with addends */
SHT_HASH = 5, /* Symbol hash table */
SHT_DYNAMIC = 6, /* Dynamic linking information */
SHT_NOTE = 7, /* Notes */
SHT_NOBITS = 8, /* Program space with no data (bss) */
SHT_REL = 9, /* Relocation entries, no addends */
SHT_SHLIB = 10, /* Reserved */
SHT_DYNSYM = 11, /* Dynamic linker symbol table */
/* 12, 13 hole */
SHT_INIT_ARRAY = 14, /* Array of constructors */
SHT_FINI_ARRAY = 15, /* Array of destructors */
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
SHT_GROUP = 17, /* Section group */
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
SHT_GNU_LIBLIST = 0x6ffffff7 /* Prelink library list */
};
enum { // sh_flags
SHF_WRITE = (1 << 0), /* Writable */
SHF_ALLOC = (1 << 1), /* Occupies memory during execution */
SHF_EXECINSTR = (1 << 2), /* Executable */
SHF_MERGE = (1 << 4), /* Might be merged */
SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */
SHF_INFO_LINK = (1 << 6), /* 'sh_info' contains SHT index */
SHF_LINK_ORDER = (1 << 7) /* Preserve order after combining */
};
#endif
#ifdef WANT_DYN_ENUM
#undef WANT_DYN_ENUM
enum { // d_tag
DT_NULL = 0, /* End flag */
DT_NEEDED = 1, /* Name of needed library */
DT_HASH = 4, /* Hash table of symbol names */
DT_STRTAB = 5, /* String table */
DT_SYMTAB = 6, /* Symbol table */
DT_STRSZ = 10 /* Sizeof string table */
};
#endif
#ifdef WANT_SYM_ENUM
#undef WANT_SYM_ENUM
enum { // st_bind (high 4 bits of st_info)
STB_LOCAL = 0, /* Local symbol */
STB_GLOBAL = 1, /* Global symbol */
STB_WEAK = 2 /* Weak symbol */
};
enum { // st_type (low 4 bits of st_info)
STT_NOTYPE = 0, /* Symbol type is unspecified */
STT_OBJECT = 1, /* Symbol is a data object */
STT_FUNC = 2, /* Symbol is a code object */
STT_SECTION = 3, /* Symbol associated with a section */
STT_FILE = 4, /* Symbol's name is file name */
STT_COMMON = 5, /* Symbol is a common data object */
STT_TLS = 6 /* Symbol is thread-local data object*/
};
enum { // st_other (visibility)
STV_DEFAULT = 0, /* Default symbol visibility rules */
STV_INTERNAL = 1, /* Processor specific hidden class */
STV_HIDDEN = 2, /* Sym unavailable in other modules */
STV_PROTECTED= 3 /* Not preemptible, not exported */
};
enum { // st_shndx
SHN_UNDEF = 0, /* Undefined section */
SHN_ABS = 0xfff1, /* Associated symbol is absolute */
SHN_COMMON = 0xfff2 /* Associated symbol is common */
};
#endif
/*
vi:ts=4:et
*/
+8 -10
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -94,14 +94,12 @@ void PackElks8086::readKernel()
//
**************************************************************************/
int PackElks8086::buildLoader(const Filter *ft)
void PackElks8086::buildLoader(const Filter *ft)
{
// prepare loader
initLoader(nrv_loader, sizeof(nrv_loader));
// FIXME
UNUSED(ft);
freezeLoader();
return getLoaderSize();
}
@@ -114,7 +112,7 @@ void PackElks8086::pack(OutputFile *fo)
ft.buf_len = ph.u_len;
ft.addvalue = kernel_entry;
// compress
compressWithFilters(&ft, overlap_range);
compressWithFilters(&ft, overlap_range, NULL_cconf);
const unsigned lsize = getLoaderSize();
MemBuffer loader(lsize);
@@ -123,11 +121,11 @@ void PackElks8086::pack(OutputFile *fo)
patchPackHeader(loader, lsize);
#if 0
// FIXME
defineFilterSymbols();
defineFilterSymbols(&ft);
defineDecompressorSymbols();
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
patch_le32(loader, lsize, "KEIP", kernel_entry);
patch_le32(loader, lsize, "STAK", stack_during_uncompression);
//patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
//patch_le32(loader, lsize, "KEIP", kernel_entry);
//patch_le32(loader, lsize, "STAK", stack_during_uncompression);
#endif
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
+22 -9
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -50,6 +50,7 @@ static const
PackExe::PackExe(InputFile *f) :
super(f)
{
bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
ih_exesize = ih_imagesize = ih_overlay = 0;
}
@@ -57,8 +58,19 @@ PackExe::PackExe(InputFile *f) :
const int *PackExe::getCompressionMethods(int method, int level) const
{
static const int m_all[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_END };
static const int m_nrv2b[] = { M_NRV2B_8, M_END };
static const int m_nrv2d[] = { M_NRV2D_8, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_END };
if (method == M_ALL) return m_all;
if (M_IS_NRV2B(method)) return m_nrv2b;
if (M_IS_NRV2D(method)) return m_nrv2d;
if (M_IS_NRV2E(method)) return m_nrv2e;
bool small = ih_imagesize <= 256*1024;
return Packer::getDefaultCompressionMethods_8(method, level, small);
if (level == 1 || small)
return m_nrv2b;
return m_nrv2e;
}
@@ -101,13 +113,13 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
}
int PackExe::buildLoader(const Filter *)
void PackExe::buildLoader(const Filter *)
{
struct exe_header_t tmp_oh;
int flag = fillExeHeader(&tmp_oh);
// prepare loader
initLoader(nrv_loader,sizeof(nrv_loader));
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
if (device_driver)
addLoader("DEVICEENTRY", NULL);
addLoader("EXEENTRY",
@@ -177,8 +189,6 @@ int PackExe::buildLoader(const Filter *)
"EXERETIP",
NULL
);
freezeLoader();
return getLoaderSize();
}
@@ -237,6 +247,9 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
const upx_byte *relocs, const unsigned nrelocs,
upx_byte *crel, bool *has_9a)
{
if (opt->exact)
throwCantPackExact();
upx_byte * const crel_save = crel;
unsigned i;
unsigned seg_high = 0;
@@ -416,7 +429,7 @@ void PackExe::pack(OutputFile *fo)
// compress (max_match = 8192)
upx_compress_config_t cconf; cconf.reset();
cconf.conf_ucl.max_match = MAXMATCH;
compressWithFilters(&ft, 32, 0, NULL, &cconf);
compressWithFilters(&ft, 32, &cconf);
if (ph.max_run_found + ph.max_match_found > 0x8000)
throwCantPack("decompressor limit exceeded, send a bugreport");
@@ -530,7 +543,7 @@ void PackExe::pack(OutputFile *fo)
oh.ip = device_driver ? getLoaderSection("EXEENTRY") - 2 : 0;
linker->relocate();
relocateLoader();
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader,e_len);
+4 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -42,6 +42,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_DOS_EXE; }
virtual const char *getName() const { return "dos/exe"; }
virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.exe" : "i286-dos16.exe"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -68,7 +69,7 @@ protected:
virtual int readFileHeader(void);
virtual int fillExeHeader(struct exe_header_t *) const;
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
struct exe_header_t
+81 -209
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -249,8 +249,8 @@ int const *
PackLinuxElf32ppc::getFilters() const
{
static const int filters[] = {
0xd0, -1
};
0xd0,
FT_END };
return filters;
}
@@ -258,8 +258,8 @@ int const *
PackLinuxElf64amd::getFilters() const
{
static const int filters[] = {
0x49, -1
};
0x49,
FT_END };
return filters;
}
@@ -431,7 +431,7 @@ void PackLinuxElf32x86::defineSymbols(Filter const *const ft)
}
}
int
void
PackLinuxElf32::buildLinuxLoader(
upx_byte const *const proto,
unsigned const szproto,
@@ -464,7 +464,7 @@ PackLinuxElf32::buildLinuxLoader(
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
throwInternalError("loader compression failed");
#if 0 //{ debugging only
if (M_LZMA==ph.method) {
if (M_IS_LZMA(ph.method)) {
ucl_uint tmp_len = h.sz_unc; // LZMA uses this as EOF
unsigned char *tmp = new unsigned char[tmp_len];
memset(tmp, 0, tmp_len);
@@ -488,13 +488,11 @@ PackLinuxElf32::buildLinuxLoader(
addStubEntrySections(ft);
freezeLoader();
defineSymbols(ft);
linker->relocate();
return getLoaderSize();
relocateLoader();
}
int
void
PackLinuxElf64::buildLinuxLoader(
upx_byte const *const proto,
unsigned const szproto,
@@ -538,10 +536,8 @@ PackLinuxElf64::buildLinuxLoader(
addStubEntrySections(ft);
freezeLoader();
defineSymbols(ft);
linker->relocate();
return getLoaderSize();
relocateLoader();
}
void
@@ -567,7 +563,7 @@ PackLinuxElf64amd::defineSymbols(Filter const *)
#define PAGE_MASK (~0u<<12)
#define PAGE_SIZE (-PAGE_MASK)
lsize = /*getLoaderSize()*/ 64 * 1024; // upper bound; avoid circularity
acc_uint64l_t lo_va_stub = elfout.phdr[0].p_vaddr;
acc_uint64l_t lo_va_stub = get_native64(&elfout.phdr[0].p_vaddr);
acc_uint64l_t adrc;
acc_uint64l_t adrm;
acc_uint64l_t adru;
@@ -629,15 +625,15 @@ static const
static const
#include "stub/i386-linux.elf-fold.h"
int
void
PackLinuxElf32x86::buildLoader(const Filter *ft)
{
unsigned char tmp[sizeof(linux_i386elf_fold)];
memcpy(tmp, linux_i386elf_fold, sizeof(linux_i386elf_fold));
unsigned char tmp[sizeof(stub_i386_linux_elf_fold)];
memcpy(tmp, stub_i386_linux_elf_fold, sizeof(stub_i386_linux_elf_fold));
checkPatch(NULL, 0, 0, 0); // reset
if (opt->o_unix.is_ptinterp) {
unsigned j;
for (j = 0; j < sizeof(linux_i386elf_fold)-1; ++j) {
for (j = 0; j < sizeof(stub_i386_linux_elf_fold)-1; ++j) {
if (0x60==tmp[ j]
&& 0x47==tmp[1+j] ) {
/* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
@@ -647,9 +643,9 @@ PackLinuxElf32x86::buildLoader(const Filter *ft)
}
}
}
return buildLinuxLoader(
linux_i386elf_loader, sizeof(linux_i386elf_loader),
tmp, sizeof(linux_i386elf_fold), ft );
buildLinuxLoader(
stub_i386_linux_elf_entry, sizeof(stub_i386_linux_elf_entry),
tmp, sizeof(stub_i386_linux_elf_fold), ft );
}
static const
@@ -657,15 +653,15 @@ static const
static const
#include "stub/i386-bsd.elf-fold.h"
int
void
PackBSDElf32x86::buildLoader(const Filter *ft)
{
unsigned char tmp[sizeof(bsd_i386elf_fold)];
memcpy(tmp, bsd_i386elf_fold, sizeof(bsd_i386elf_fold));
unsigned char tmp[sizeof(stub_i386_bsd_elf_fold)];
memcpy(tmp, stub_i386_bsd_elf_fold, sizeof(stub_i386_bsd_elf_fold));
checkPatch(NULL, 0, 0, 0); // reset
if (opt->o_unix.is_ptinterp) {
unsigned j;
for (j = 0; j < sizeof(bsd_i386elf_fold)-1; ++j) {
for (j = 0; j < sizeof(stub_i386_bsd_elf_fold)-1; ++j) {
if (0x60==tmp[ j]
&& 0x47==tmp[1+j] ) {
/* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
@@ -675,9 +671,9 @@ PackBSDElf32x86::buildLoader(const Filter *ft)
}
}
}
return buildLinuxLoader(
bsd_i386elf_loader, sizeof(bsd_i386elf_loader),
tmp, sizeof(bsd_i386elf_fold), ft );
buildLinuxLoader(
stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
tmp, sizeof(stub_i386_bsd_elf_fold), ft);
}
#if 0 //{ re-use for OpenBSD, too
@@ -687,15 +683,15 @@ static const
static const
#include "stub/i386-openbsd.elf-fold.h"
int
void
PackOpenBSDElf32x86::buildLoader(const Filter *ft)
{
unsigned char tmp[sizeof(openbsd_i386elf_fold)];
memcpy(tmp, openbsd_i386elf_fold, sizeof(openbsd_i386elf_fold));
unsigned char tmp[sizeof(stub_i386_openbsd_elf_fold)];
memcpy(tmp, stub_i386_openbsd_elf_fold, sizeof(stub_i386_openbsd_elf_fold));
checkPatch(NULL, 0, 0, 0); // reset
if (opt->o_unix.is_ptinterp) {
unsigned j;
for (j = 0; j < sizeof(openbsd_i386elf_fold)-1; ++j) {
for (j = 0; j < sizeof(stub_i386_openbsd_elf_fold)-1; ++j) {
if (0x60==tmp[ j]
&& 0x47==tmp[1+j] ) {
/* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
@@ -705,9 +701,9 @@ PackOpenBSDElf32x86::buildLoader(const Filter *ft)
}
}
}
return buildLinuxLoader(
bsd_i386elf_loader, sizeof(bsd_i386elf_loader),
tmp, sizeof(openbsd_i386elf_fold), ft );
buildLinuxLoader(
stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
tmp, sizeof(stub_i386_openbsd_elf_fold), ft);
}
static const
@@ -715,78 +711,27 @@ static const
static const
#include "stub/arm-linux.elf-fold.h"
static const
#include "stub/armeb-linux.elf-entry.h"
static const
#include "stub/armeb-linux.elf-fold.h"
#include "mem.h"
static void brev(
unsigned char *const dst,
unsigned char const *const src,
unsigned len
)
{
assert(0==(3 & len));
// Detect overlap which over-writes src before it is used.
assert(!((4+ src)<=dst && dst < (len + src)));
for (unsigned j = 0; j < len; j += 4) {
// Simple way (and somewhat slow) to allow in-place brev().
unsigned char tmp[4];
memcpy(tmp, j + src, 4);
dst[0+ j] = tmp[3];
dst[1+ j] = tmp[2];
dst[2+ j] = tmp[1];
dst[3+ j] = tmp[0];
}
}
static void
ehdr_bele(Elf_BE32_Ehdr *const ehdr_be, Elf_LE32_Ehdr const *const ehdr_le)
{
memcpy(&ehdr_be->e_ident, &ehdr_le->e_ident, sizeof(ehdr_be->e_ident));
ehdr_be->e_ident[Elf32_Ehdr::EI_DATA] = Elf32_Ehdr::ELFDATA2MSB;
ehdr_be->e_type = ehdr_le->e_type;
ehdr_be->e_machine = ehdr_le->e_machine;
ehdr_be->e_version = ehdr_le->e_version;
ehdr_be->e_entry = ehdr_le->e_entry;
ehdr_be->e_phoff = ehdr_le->e_phoff;
ehdr_be->e_shoff = ehdr_le->e_shoff;
ehdr_be->e_flags = ehdr_le->e_flags;
ehdr_be->e_ehsize = ehdr_le->e_ehsize;
ehdr_be->e_phentsize = ehdr_le->e_phentsize;
ehdr_be->e_phnum = ehdr_le->e_phnum;
ehdr_be->e_shentsize = ehdr_le->e_shentsize;
ehdr_be->e_shnum = ehdr_le->e_shnum;
ehdr_be->e_shstrndx = ehdr_le->e_shstrndx;
}
static void
ehdr_lebe(Elf_LE32_Ehdr *const ehdr_le, Elf_BE32_Ehdr const *const ehdr_be)
{
memcpy(&ehdr_le->e_ident, &ehdr_be->e_ident, sizeof(ehdr_le->e_ident));
ehdr_le->e_ident[Elf32_Ehdr::EI_DATA] = Elf32_Ehdr::ELFDATA2LSB;
ehdr_le->e_type = ehdr_be->e_type;
ehdr_le->e_machine = ehdr_be->e_machine;
ehdr_le->e_version = ehdr_be->e_version;
ehdr_le->e_entry = ehdr_be->e_entry;
ehdr_le->e_phoff = ehdr_be->e_phoff;
ehdr_le->e_shoff = ehdr_be->e_shoff;
ehdr_le->e_flags = ehdr_be->e_flags;
ehdr_le->e_ehsize = ehdr_be->e_ehsize;
ehdr_le->e_phentsize = ehdr_be->e_phentsize;
ehdr_le->e_phnum = ehdr_be->e_phnum;
ehdr_le->e_shentsize = ehdr_be->e_shentsize;
ehdr_le->e_shnum = ehdr_be->e_shnum;
ehdr_le->e_shstrndx = ehdr_be->e_shstrndx;
}
int
void
PackLinuxElf32armBe::buildLoader(Filter const *ft)
{
return ARM_buildLoader(ft, true);
buildLinuxLoader(
stub_armeb_linux_elf_entry, sizeof(stub_armeb_linux_elf_entry),
stub_armeb_linux_elf_fold, sizeof(stub_armeb_linux_elf_fold), ft);
}
int
void
PackLinuxElf32armLe::buildLoader(Filter const *ft)
{
return ARM_buildLoader(ft, false);
buildLinuxLoader(
stub_arm_linux_elf_entry, sizeof(stub_arm_linux_elf_entry),
stub_arm_linux_elf_fold, sizeof(stub_arm_linux_elf_fold), ft);
}
static const
@@ -794,12 +739,12 @@ static const
static const
#include "stub/powerpc-linux.elf-fold.h"
int
void
PackLinuxElf32ppc::buildLoader(const Filter *ft)
{
return buildLinuxLoader(
linux_elfppc32_loader, sizeof(linux_elfppc32_loader),
linux_elfppc32_fold, sizeof(linux_elfppc32_fold), ft );
buildLinuxLoader(
stub_powerpc_linux_elf_entry, sizeof(stub_powerpc_linux_elf_entry),
stub_powerpc_linux_elf_fold, sizeof(stub_powerpc_linux_elf_fold), ft);
}
static const
@@ -807,12 +752,12 @@ static const
static const
#include "stub/amd64-linux.elf-fold.h"
int
void
PackLinuxElf64amd::buildLoader(const Filter *ft)
{
return buildLinuxLoader(
linux_elf64amd_loader, sizeof(linux_elf64amd_loader),
linux_elf64amd_fold, sizeof(linux_elf64amd_fold), ft );
buildLinuxLoader(
stub_amd64_linux_elf_entry, sizeof(stub_amd64_linux_elf_entry),
stub_amd64_linux_elf_fold, sizeof(stub_amd64_linux_elf_fold), ft);
}
bool PackLinuxElf32::canPack()
@@ -831,12 +776,12 @@ bool PackLinuxElf32::canPack()
// additional requirements for linux/elf386
if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) {
throwCantPack("invalid Ehdr e_ehsize; try `--force-execve'");
throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
return false;
}
unsigned const e_phoff = get_native32(&ehdr->e_phoff);
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
throwCantPack("non-contiguous Ehdr/Phdr; try `--force-execve'");
throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
return false;
}
@@ -849,7 +794,7 @@ bool PackLinuxElf32::canPack()
return false;
if (1!=exetype && phdr->PT_LOAD32 == get_native32(&phdr->p_type)) {
if (phdr->p_offset != 0) {
throwCantPack("invalid Phdr p_offset; try `--force-execve'");
throwCantPack("invalid Phdr p_offset; try '--force-execve'");
return false;
}
exetype = 1;
@@ -918,7 +863,7 @@ bool PackLinuxElf32::canPack()
// elf_lookup() returns 0 if any required table is missing.
Elf32_Sym const *const lsm = elf_lookup(run_start[j]);
if (lsm && get_native16(&lsm->st_shndx)==Elf32_Sym::SHN_UNDEF
&& get_native16(&lsm->st_info)==lsm->Elf32_Sym::St_info(Elf32_Sym::STB_GLOBAL, Elf32_Sym::STT_FUNC)
&& get_native16(&lsm->st_info)==lsm->Elf32_Sym::make_st_info(Elf32_Sym::STB_GLOBAL, Elf32_Sym::STT_FUNC)
&& get_native16(&lsm->st_other)==Elf32_Sym::STV_DEFAULT ) {
break;
}
@@ -956,25 +901,25 @@ PackLinuxElf64amd::canPack()
// additional requirements for linux/elf386
if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) {
throwCantPack("invalid Ehdr e_ehsize; try `--force-execve'");
throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
return false;
}
acc_uint64l_t const e_phoff = get_native64(&ehdr->e_phoff);
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
throwCantPack("non-contiguous Ehdr/Phdr; try `--force-execve'");
throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
return false;
}
// The first PT_LOAD64 must cover the beginning of the file (0==p_offset).
unsigned const e_phnum = get_native16(&ehdr->e_phnum);
Elf64_Phdr const *phdr = (Elf64_Phdr const *)(buf + e_phoff);
Elf64_Phdr const *phdr = (Elf64_Phdr const *)(buf + (unsigned) e_phoff);
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
if (j >= 14)
return false;
if (phdr->PT_LOAD64 == get_native32(&phdr->p_type)) {
// Just avoid the "rewind" when unpacking?
//if (phdr->p_offset != 0) {
// throwCantPack("invalid Phdr p_offset; try `--force-execve'");
// throwCantPack("invalid Phdr p_offset; try '--force-execve'");
// return false;
//}
exetype = 1;
@@ -1053,7 +998,7 @@ PackLinuxElf32::generateElfHdr(
h2->ehdr.e_shoff = 0;
assert(get_native16(&h2->ehdr.e_ehsize) == sizeof(Elf32_Ehdr));
assert(get_native16(&h2->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
h2->ehdr.e_shentsize = 0;
set_native16(&h2->ehdr.e_shentsize, sizeof(Elf32_Shdr));
h2->ehdr.e_shnum = 0;
h2->ehdr.e_shstrndx = 0;
@@ -1103,7 +1048,7 @@ PackOpenBSDElf32x86::generateElfHdr(
h3->ehdr.e_shoff = 0;
assert(get_native16(&h3->ehdr.e_ehsize) == sizeof(Elf32_Ehdr));
assert(get_native16(&h3->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
h3->ehdr.e_shentsize = 0;
set_native16(&h3->ehdr.e_shentsize, sizeof(Elf32_Shdr));
h3->ehdr.e_shnum = 0;
h3->ehdr.e_shstrndx = 0;
@@ -1165,7 +1110,7 @@ PackLinuxElf64::generateElfHdr(
h2->ehdr.e_shoff = 0;
assert(get_native16(&h2->ehdr.e_ehsize) == sizeof(Elf64_Ehdr));
assert(get_native16(&h2->ehdr.e_phentsize) == sizeof(Elf64_Phdr));
h2->ehdr.e_shentsize = 0;
set_native16(&h2->ehdr.e_shentsize, sizeof(Elf64_Shdr));
h2->ehdr.e_shnum = 0;
h2->ehdr.e_shstrndx = 0;
@@ -1217,52 +1162,35 @@ void PackLinuxElf32::pack1(OutputFile */*fo*/, Filter &/*ft*/)
void PackLinuxElf32x86::pack1(OutputFile *fo, Filter &ft)
{
PackLinuxElf32::pack1(fo, ft);
generateElfHdr(fo, linux_i386elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
generateElfHdr(fo, stub_i386_linux_elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
}
void PackBSDElf32x86::pack1(OutputFile *fo, Filter &ft)
{
PackLinuxElf32::pack1(fo, ft);
generateElfHdr(fo, bsd_i386elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
}
void PackLinuxElf32::ARM_pack1(OutputFile *fo, bool const isBE)
{
Elf32_Ehdr const *const fold = (Elf32_Ehdr const *)&linux_elf32arm_fold;
cprElfHdr3 h3;
// We need Elf32_Ehdr and Elf32_Phdr with byte gender of target.
// The stub may have been compiled differently.
if (this->ei_data==fold->e_ident[Elf32_Ehdr::EI_DATA]) {
memcpy(&h3, (void const *)linux_elf32arm_fold,
sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr) );
}
else {
(isBE ? (void (*)(void *, void const *))ehdr_bele
: (void (*)(void *, void const *))ehdr_lebe)
((void *)&h3.ehdr, (void const *)linux_elf32arm_fold);
brev((unsigned char *)&h3.phdr[0],
sizeof(Elf32_Ehdr) + (unsigned char const *)&linux_elf32arm_fold,
3*sizeof(Elf32_Phdr) );
}
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
generateElfHdr(fo, stub_i386_bsd_elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
}
void PackLinuxElf32armLe::pack1(OutputFile *fo, Filter &ft)
{
super::pack1(fo, ft);
ARM_pack1(fo, false);
cprElfHdr3 h3;
memcpy(&h3, stub_arm_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
}
void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft) // FIXME
void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft)
{
super::pack1(fo, ft);
ARM_pack1(fo, true);
cprElfHdr3 h3;
memcpy(&h3, stub_armeb_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
}
void PackLinuxElf32ppc::pack1(OutputFile *fo, Filter &ft)
{
super::pack1(fo, ft);
generateElfHdr(fo, linux_elfppc32_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
generateElfHdr(fo, stub_powerpc_linux_elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
}
void PackLinuxElf64::pack1(OutputFile */*fo*/, Filter &/*ft*/)
@@ -1284,7 +1212,7 @@ void PackLinuxElf64::pack1(OutputFile */*fo*/, Filter &/*ft*/)
void PackLinuxElf64amd::pack1(OutputFile *fo, Filter &ft)
{
super::pack1(fo, ft);
generateElfHdr(fo, linux_elf64amd_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
generateElfHdr(fo, stub_amd64_linux_elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
}
// Determine length of gap between PT_LOAD phdr[k] and closest PT_LOAD
@@ -1496,9 +1424,9 @@ using namespace N_BELE_CTP;
static const int *
ARM_getFilters(bool const isBE)
{
static const int f50[] = { 0x50, -1 };
static const int f51[] = { 0x51, -1 };
if (HostPolicy::isBE ^ isBE)
static const int f50[] = { 0x50, FT_END };
static const int f51[] = { 0x51, FT_END };
if (isBE)
return f51;
return f50;
}
@@ -1515,62 +1443,6 @@ PackLinuxElf32armLe::getFilters() const
return ARM_getFilters(false);
}
int
PackLinuxElf32::ARM_buildLoader(const Filter *ft, bool const isBE)
{
unsigned const sz_loader = sizeof(linux_elf32arm_loader);
unsigned const sz_fold = sizeof(linux_elf32arm_fold);
// Was ARM code assembled for same endianness as the target?
bool const asm_brev = (this->ei_data
!= ((Elf32_Ehdr const *)linux_elf32arm_fold)->e_ident[Elf32_Ehdr::EI_DATA] );
MemBuffer tmp_fold(sz_fold);
memcpy(tmp_fold, linux_elf32arm_fold, sz_fold);
// 0xe3530050 is "cmp fid,#0x50" with fid .req r3
if (HostPolicy::isBE ^ isBE) { // change filter 0x50 to filter 0x51
if (HostPolicy::isBE ^ isBE ^ asm_brev) { // find 0xe3530050 big-endian
checkPatch(NULL,0,0,0); // reset
patch_be32(tmp_fold, sz_fold, "\xe3\x53\x00\x50", 0xe3530051);
checkPatch(NULL,0,0,0); // reset
}
else { // find 0xe3530050 little-endian
checkPatch(NULL,0,0,0); // reset
patch_le32(tmp_fold, sz_fold, "\x50\x00\x53\xe3", 0xe3530051);
checkPatch(NULL,0,0,0); // reset
}
}
if (!asm_brev) { // was assembled to match target
return buildLinuxLoader(linux_elf32arm_loader, sz_loader,
tmp_fold, sz_fold, ft );
}
else { // was assembled brev() from target
// linux_elf32arm_loader[] is all instructions, except for two strings
// at the end: the copyright message, and the SELinux message.
// The copyright message begins and ends with '\n', and the SELinux
// message ends with '\n'. So copy back to the third '\n' from the end,
// and apply brev() only before that point.
MemBuffer brev_loader(sz_loader);
int nl = 0;
int j;
for (j= sz_loader; --j>=0; ) {
unsigned char const c = linux_elf32arm_loader[j];
brev_loader[j] = c;
if ('\n'==c) {
if (3==++nl) {
break;
}
}
}
brev(brev_loader, linux_elf32arm_loader, j);
(isBE ? (void (*)(void *, void const *))ehdr_bele
: (void (*)(void *, void const *))ehdr_lebe)
(tmp_fold.getVoidPtr(), (void const *)linux_elf32arm_fold);
return buildLinuxLoader(brev_loader, sz_loader, tmp_fold, sz_fold, ft);
}
}
void PackLinuxElf32::ARM_defineSymbols(Filter const * /*ft*/)
{
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
@@ -1985,7 +1857,7 @@ PackLinuxElf32x86::getFilters() const
0x82, 0x85,
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
#endif
-1 };
FT_END };
return filters;
}
+43 -19
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -40,7 +40,7 @@ class PackLinuxElf : public PackUnix
public:
PackLinuxElf(InputFile *f);
virtual ~PackLinuxElf();
/*virtual int buildLoader(const Filter *);*/
/*virtual void buildLoader(const Filter *);*/
virtual bool canUnpackVersion(int version) const { return (version >= 11); }
protected:
@@ -90,10 +90,8 @@ protected:
// These ARM routines are essentially common to big/little endian,
// but the class hierarchy splits after this class.
virtual int ARM_buildLoader(Filter const *ft, bool isBE);
virtual void ARM_defineSymbols(Filter const *ft);
virtual void ARM_updateLoader(OutputFile *);
virtual void ARM_pack1(OutputFile *, bool isBE);
virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual void pack2(OutputFile *, Filter &); // append compressed data
@@ -106,7 +104,7 @@ protected:
void const *proto,
unsigned const brka
);
virtual int buildLinuxLoader(
virtual void buildLinuxLoader(
upx_byte const *const proto, // assembly-only sections
unsigned const szproto,
upx_byte const *const fold, // linked assembly + C section
@@ -163,6 +161,15 @@ protected:
char text[0x18 - 4*4]; // "OpenBSD"
unsigned end; // 0
} elfnote;
static void compileTimeAssertions() {
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 52 + 1*32 + 12)
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 52 + 2*32 + 12)
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 52 + 3*32 + 12)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
}
};
@@ -172,7 +179,7 @@ class PackLinuxElf64 : public PackLinuxElf
public:
PackLinuxElf64(InputFile *f);
virtual ~PackLinuxElf64();
/*virtual int buildLoader(const Filter *);*/
/*virtual void buildLoader(const Filter *);*/
protected:
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
@@ -188,7 +195,7 @@ protected:
void const *proto,
unsigned const brka
);
virtual int buildLinuxLoader(
virtual void buildLinuxLoader(
upx_byte const *const proto, // assembly-only sections
unsigned const szproto,
upx_byte const *const fold, // linked assembly + C section
@@ -227,13 +234,22 @@ protected:
__attribute_packed;
cprElfHdr3 elfout;
static void compileTimeAssertions() {
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 64 + 1*56 + 12)
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 64 + 2*56 + 12)
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 64 + 3*56 + 12)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
}
};
class PackLinuxElf32Be : public PackLinuxElf32
{
typedef PackLinuxElf32 super;
protected:
PackLinuxElf32Be(InputFile *f) : super(f) { }
PackLinuxElf32Be(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; }
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
@@ -247,7 +263,7 @@ class PackLinuxElf32Le : public PackLinuxElf32
{
typedef PackLinuxElf32 super;
protected:
PackLinuxElf32Le(InputFile *f) : super(f) { }
PackLinuxElf32Le(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
@@ -261,7 +277,7 @@ class PackLinuxElf64Le : public PackLinuxElf64
{
typedef PackLinuxElf64 super;
protected:
PackLinuxElf64Le(InputFile *f) : super(f) { }
PackLinuxElf64Le(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
@@ -283,12 +299,13 @@ public:
virtual ~PackLinuxElf64amd();
virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; }
virtual const char *getName() const { return "linux/ElfAMD"; }
virtual const char *getFullName(const options_t *) const { return "amd64-linux.elf"; }
virtual const int *getFilters() const;
virtual bool canPack();
protected:
virtual void pack1(OutputFile *, Filter &); // generate executable header
//virtual void pack3(OutputFile *, Filter &); // append loader
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
virtual Linker* newLinker() const;
virtual void defineSymbols(Filter const *);
};
@@ -305,10 +322,11 @@ public:
virtual ~PackLinuxElf32ppc();
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
virtual const char *getName() const { return "linux/ElfPPC"; }
virtual const char *getFullName(const options_t *) const { return "powerpc-linux.elf"; }
virtual const int *getFilters() const;
protected:
virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
virtual Linker* newLinker() const;
};
@@ -324,6 +342,7 @@ public:
virtual ~PackLinuxElf32x86();
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
virtual const char *getName() const { return "linux/elf386"; }
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf"; }
virtual const int *getFilters() const;
virtual void unpack(OutputFile *fo);
@@ -331,7 +350,7 @@ public:
protected:
virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
virtual void addStubEntrySections(Filter const *);
virtual Linker* newLinker() const;
virtual void defineSymbols(Filter const *);
@@ -349,7 +368,7 @@ public:
protected:
virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
};
class PackFreeBSDElf32x86 : public PackBSDElf32x86
@@ -358,6 +377,7 @@ class PackFreeBSDElf32x86 : public PackBSDElf32x86
public:
PackFreeBSDElf32x86(InputFile *f);
virtual ~PackFreeBSDElf32x86();
virtual const char *getFullName(const options_t *) const { return "i386-freebsd.elf"; }
};
class PackNetBSDElf32x86 : public PackBSDElf32x86
@@ -366,6 +386,7 @@ class PackNetBSDElf32x86 : public PackBSDElf32x86
public:
PackNetBSDElf32x86(InputFile *f);
virtual ~PackNetBSDElf32x86();
virtual const char *getFullName(const options_t *) const { return "i386-netbsd.elf"; }
};
class PackOpenBSDElf32x86 : public PackBSDElf32x86
@@ -374,9 +395,10 @@ class PackOpenBSDElf32x86 : public PackBSDElf32x86
public:
PackOpenBSDElf32x86(InputFile *f);
virtual ~PackOpenBSDElf32x86();
virtual const char *getFullName(const options_t *) const { return "i386-openbsd.elf"; }
protected:
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual void generateElfHdr(
OutputFile *,
void const *proto,
@@ -396,13 +418,14 @@ public:
virtual ~PackLinuxElf32armLe();
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
virtual const char *getName() const { return "linux/armLE"; }
virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; }
virtual const int *getFilters() const;
protected:
virtual const int *getCompressionMethods(int method, int level) const;
virtual Linker* newLinker() const;
virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
virtual void updateLoader(OutputFile *);
virtual void defineSymbols(Filter const *);
};
@@ -415,13 +438,14 @@ public:
virtual ~PackLinuxElf32armBe();
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; }
virtual const char *getName() const { return "linux/armBE"; }
virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; }
virtual const int *getFilters() const;
protected:
virtual const int *getCompressionMethods(int method, int level) const;
virtual Linker* newLinker() const;
virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
virtual void updateLoader(OutputFile *);
virtual void defineSymbols(Filter const *);
};
+26 -25
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2001-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2001-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -57,6 +57,7 @@
PackLinuxI386::PackLinuxI386(InputFile *f) : super(f),
ei_osabi(Elf32_Ehdr::ELFOSABI_LINUX), osabi_note(NULL)
{
bele = &N_BELE_RTP::le_policy;
}
PackBSDI386::PackBSDI386(InputFile *f) : super(f)
@@ -99,7 +100,7 @@ const int *PackLinuxI386::getFilters() const
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
#endif
-1 };
FT_END };
return filters;
}
@@ -182,7 +183,7 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
// create a pseudo-unique program id for our paranoid stub
progid = getRandomId();
generateElfHdr(fo, linux_i386exec_fold, 0);
generateElfHdr(fo, stub_i386_linux_elf_execve_fold, 0);
}
void
@@ -191,7 +192,7 @@ PackBSDI386::pack1(OutputFile *fo, Filter &)
// create a pseudo-unique program id for our paranoid stub
progid = getRandomId();
generateElfHdr(fo, bsd_i386exec_fold, 0);
generateElfHdr(fo, stub_i386_bsd_elf_execve_fold, 0);
}
void
@@ -203,7 +204,7 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
unsigned nw = fo->getBytesWritten();
elfout.phdr[0].p_filesz = nw;
nw = -(-elfout.phdr[0].p_align & -nw); // ALIGN_UP
nw = 0u-((0u-elfout.phdr[0].p_align) & (0u-nw)); // ALIGN_UP
super::pack4(fo, ft); // write PackHeader and overlay_offset
set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);
@@ -292,7 +293,7 @@ Linker *PackLinuxI386::newLinker() const
return new ElfLinkerX86;
}
int
void
PackLinuxI386::buildLinuxLoader(
upx_byte const *const proto,
unsigned const szproto,
@@ -372,13 +373,14 @@ PackLinuxI386::buildLinuxLoader(
addLoader("IDENTSTR", NULL);
addLoader("LEXEC020", NULL);
addLoader("FOLDEXEC", NULL);
freezeLoader();
if (ph.method == M_LZMA) {
if (M_IS_LZMA(ph.method)) {
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
unsigned const properties = // lc, lp, pb, dummy
acc_uint32e_t properties = // lc, lp, pb, dummy
(res->lit_context_bits << 0) |
(res->lit_pos_bits << 8) |
(res->pos_bits << 16);
if (linker->bele->isBE()) // big endian - bswap32
acc_swab32s(&properties);
linker->defineSymbol("lzma_properties", properties);
// -2 for properties
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
@@ -393,16 +395,15 @@ PackLinuxI386::buildLinuxLoader(
linker->defineSymbol("NMRU", mru - is_pwr2);
}
}
linker->relocate();
return getLoaderSize();
relocateLoader();
}
int
void
PackLinuxI386::buildLoader(Filter const *ft)
{
unsigned const sz_fold = sizeof(linux_i386exec_fold);
unsigned const sz_fold = sizeof(stub_i386_linux_elf_execve_fold);
MemBuffer buf(sz_fold);
memcpy(buf, linux_i386exec_fold, sz_fold);
memcpy(buf, stub_i386_linux_elf_execve_fold, sz_fold);
// patch loader
// note: we only can use /proc/<pid>/fd when exetype > 0.
@@ -412,17 +413,17 @@ PackLinuxI386::buildLoader(Filter const *ft)
patch_le32(buf,sz_fold,"UPX3",progid);
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
return buildLinuxLoader(
linux_i386exec_loader, sizeof(linux_i386exec_loader),
buildLinuxLoader(
stub_i386_linux_elf_execve_entry, sizeof(stub_i386_linux_elf_execve_entry),
buf, sz_fold, ft );
}
int
void
PackBSDI386::buildLoader(Filter const *ft)
{
unsigned const sz_fold = sizeof(bsd_i386exec_fold);
unsigned const sz_fold = sizeof(stub_i386_bsd_elf_execve_fold);
MemBuffer buf(sz_fold);
memcpy(buf, bsd_i386exec_fold, sz_fold);
memcpy(buf, stub_i386_bsd_elf_execve_fold, sz_fold);
// patch loader
// note: we only can use /proc/<pid>/fd when exetype > 0.
@@ -432,8 +433,8 @@ PackBSDI386::buildLoader(Filter const *ft)
patch_le32(buf,sz_fold,"UPX3",progid);
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
return buildLinuxLoader(
bsd_i386exec_loader, sizeof(bsd_i386exec_loader),
buildLinuxLoader(
stub_i386_bsd_elf_execve_entry, sizeof(stub_i386_bsd_elf_execve_entry),
buf, sz_fold, ft );
}
@@ -449,7 +450,7 @@ int PackLinuxI386::getLoaderPrefixSize() const
**************************************************************************/
// basic check of an Linux ELF Ehdr
int PackLinuxI386::checkEhdr(const Elf32_Ehdr *ehdr) const
int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
{
const unsigned char * const buf = ehdr->e_ident;
@@ -499,7 +500,7 @@ bool PackLinuxI386::canPack()
if (exetype != 0)
return super::canPack();
Elf32_Ehdr ehdr;
Elf_LE32_Ehdr ehdr;
unsigned char *buf = ehdr.e_ident;
fi->seek(0, SEEK_SET);
+17 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -49,9 +49,10 @@ public:
);
virtual int getFormat() const { return UPX_F_LINUX_i386; }
virtual const char *getName() const { return "linux/386"; }
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.execve"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
virtual bool canPack();
@@ -64,7 +65,7 @@ protected:
// loader util
virtual Linker* newLinker() const;
virtual int getLoaderPrefixSize() const;
virtual int buildLinuxLoader(
virtual void buildLinuxLoader(
upx_byte const *const proto, // assembly-only sections
unsigned const szproto,
upx_byte const *const fold, // linked assembly + C section
@@ -78,7 +79,7 @@ protected:
virtual void updateLoader(OutputFile *);
// ELF util
virtual int checkEhdr(const Elf32_Ehdr *ehdr) const;
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const;
enum {
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
@@ -119,6 +120,15 @@ protected:
unsigned char ei_osabi;
char const *osabi_note;
static void compileTimeAssertions() {
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 52 + 1*32 + 12)
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 52 + 2*32 + 12)
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 52 + 3*32 + 12)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
}
};
@@ -129,11 +139,12 @@ public:
PackBSDI386(InputFile *f);
virtual int getFormat() const { return UPX_F_BSD_i386; }
virtual const char *getName() const { return "*BSD/386"; }
virtual const char *getFullName(const options_t *) const { return "i386-bsd.elf.execve"; }
protected:
virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
};
#endif /* already included */
+8 -9
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -147,8 +147,8 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
}
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
if (opt->o_unix.make_ptinterp) {
initLoader(linux_i386pti_loader, sizeof(linux_i386pti_loader));
linker->addSection("FOLDEXEC", linux_i386pti_fold, sizeof(linux_i386pti_fold), 0);
initLoader(stub_i386_linux_elf_interp_entry, sizeof(stub_i386_linux_elf_interp_entry));
linker->addSection("FOLDEXEC", stub_i386_linux_elf_interp_fold, sizeof(stub_i386_linux_elf_interp_fold), 0);
addLoader("LXPTI000", NULL);
@@ -164,9 +164,9 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL);
addLoader("LXPTI090", NULL);
addLoader("LXPTI043", NULL);
ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
addLoader("LXPTI090", NULL);
//addLoader("LXPTI043", NULL);
//ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
//addLoader("LXPTI090", NULL);
addLoader("LXPTI091", NULL);
@@ -182,7 +182,6 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
addLoader("LXPTI200", NULL);
addLoader("FOLDEXEC", NULL);
freezeLoader();
upx_byte const *p = getLoader();
lsize = getLoaderSize();
updateLoader(fo);
+4 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -47,6 +47,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
virtual const char *getName() const { return "linux/elfi386"; }
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.interp"; }
virtual bool canPack();
virtual void unpack(OutputFile *fo);
+10 -10
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -71,12 +71,12 @@ umax(unsigned a, unsigned b)
return a;
}
int
void
PackLinuxI386sh::buildLoader(Filter const *ft)
{
unsigned const sz_fold = sizeof(linux_i386sh_fold);
unsigned const sz_fold = sizeof(stub_i386_linux_elf_shell_fold);
MemBuffer buf(sz_fold);
memcpy(buf, linux_i386sh_fold, sz_fold);
memcpy(buf, stub_i386_linux_elf_shell_fold, sz_fold);
checkPatch(NULL, 0, 0, 0); // reset
patch_le32(buf,sz_fold,"UPX3",l_shname);
@@ -85,7 +85,7 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
// get fresh filter
Filter fold_ft = *ft;
fold_ft.init(ft->id, ft->addvalue);
int preferred_ctos[2] = {ft->cto, -1};
int preferred_ctos[2] = { ft->cto, -1 };
fold_ft.preferred_ctos = preferred_ctos;
// filter
@@ -99,8 +99,8 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
UNUSED(success);
return buildLinuxLoader(
linux_i386sh_loader, sizeof(linux_i386sh_loader),
buildLinuxLoader(
stub_i386_linux_elf_shell_entry, sizeof(stub_i386_linux_elf_shell_entry),
buf, sz_fold, ft );
}
@@ -158,7 +158,7 @@ bool PackLinuxI386sh::canPack()
void
PackLinuxI386sh::pack1(OutputFile *fo, Filter &)
{
generateElfHdr(fo, linux_i386sh_fold, 0x08048000);
generateElfHdr(fo, stub_i386_linux_elf_shell_fold, 0x08048000);
}
void
+5 -4
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2000-2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -47,8 +47,9 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_LINUX_SH_i386; }
virtual const char *getName() const { return "linux/sh386"; }
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.shell"; }
virtual const int *getFilters() const { return NULL; }
virtual int buildLoader(const Filter *);
virtual void buildLoader(const Filter *);
virtual void pack1(OutputFile *fo, Filter &ft);
virtual void pack3(OutputFile *fo, Filter &ft);
+11 -13
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor.
Copyright (C) 2004-2006 John Reiser
Copyright (C) 2004-2007 John Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -53,14 +53,14 @@ PackMachPPC32::~PackMachPPC32()
const int *PackMachPPC32::getCompressionMethods(int /*method*/, int /*level*/) const
{
// There really is no LE bias in M_NRV2E_LE32.
static const int m_nrv2e[] = { M_NRV2E_LE32, -1 };
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
return m_nrv2e;
}
const int *PackMachPPC32::getFilters() const
{
static const int filters[] = { 0xd0, -1 };
static const int filters[] = { 0xd0, FT_END };
return filters;
}
@@ -90,7 +90,7 @@ void PackMachPPC32::defineSymbols(Filter const *)
}
int
void
PackMachPPC32::buildMachLoader(
upx_byte const *const proto,
unsigned const szproto,
@@ -131,18 +131,16 @@ PackMachPPC32::buildMachLoader(
addStubEntrySections(ft);
freezeLoader();
defineSymbols(ft);
linker->relocate();
return getLoaderSize();
relocateLoader();
}
int
void
PackMachPPC32::buildLoader(const Filter *ft)
{
return buildMachLoader(
l_mac_ppc32_loader, sizeof(l_mac_ppc32_loader),
fold_machppc32, sizeof(fold_machppc32), ft );
buildMachLoader(
stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry),
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
}
void PackMachPPC32::patchLoader() { }
void PackMachPPC32::updateLoader(OutputFile *) {}
@@ -197,8 +195,8 @@ PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
BE32 disp;
unsigned const zero = 0;
unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& -len);
len += (3& -len) + sizeof(disp);
fo->write(&zero, 3& (0u-len));
len += (3& (0u-len)) + sizeof(disp);
set_be32(&disp, 4+ len - sz_mach_headers); // 4: sizeof(instruction)
fo->write(&disp, sizeof(disp));
+7 -5
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -135,7 +135,8 @@ struct Mach_ppc_thread_state {
BE32 mq; /* MQ register (601 only) */
BE32 vrsave; /* Vector Save Register */
};
}
__attribute_packed;
struct Mach_thread_command {
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
@@ -165,6 +166,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
virtual const char *getName() const { return "Mach/ppc32"; }
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -180,12 +182,12 @@ public:
virtual unsigned find_SEGMENT_gap(unsigned const k);
protected:
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
virtual void patchLoader();
virtual void patchLoaderChecksum();
virtual void updateLoader(OutputFile *);
virtual int buildMachLoader(
virtual void buildMachLoader(
upx_byte const *const proto,
unsigned const szproto,
upx_byte const *const fold,
+56 -76
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2002-2006 Jens Medoch
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2002-2007 Jens Medoch
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -53,7 +53,7 @@ static const
#define K0_BS (0x80000000)
#define K1_BS (0xa0000000)
#define EXE_BS (ih.epc & K0_BS)
#define FIX_PSVR (K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS)
#define FIX_PSVR ((K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS))
// lui / addiu
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
@@ -61,6 +61,7 @@ static const
#define MIPS_PC16(a) ((a) >> 2)
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
/*************************************************************************
// ps1 exe looks like this:
// 1. <header> 2048 bytes
@@ -81,16 +82,18 @@ PackPs1::PackPs1(InputFile *f) :
buildPart2(0), foundBss(0), sa_cnt(0), overlap(0), sz_lunc(0), sz_lcpr(0),
pad_code(0), bss_start(0), bss_end(0)
{
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136);
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44);
COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5);
bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136)
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44)
COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5)
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_t)
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_hb_t)
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_chb_t)
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t))
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40)
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
#if 0 // 1 || defined(WITH_NRV)
COMPILE_TIME_ASSERT(sizeof(nrv_loader) == 14812);
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0);
#endif
fdata_size = file_size - PS_HDR_SIZE;
ram_size = !opt->ps1_exe.do_8mb ? 0x200000 : 0x800000;
}
@@ -110,30 +113,6 @@ const int *PackPs1::getFilters() const
Linker* PackPs1::newLinker() const
{
class ElfLinkerMipsLE : public ElfLinker
{
typedef ElfLinker super;
virtual void relocate1(const Relocation *rel, upx_byte *location,
unsigned value, const char *type)
{
if (strcmp(type, "R_MIPS_HI16") == 0)
set_le16(location, get_le16(location) + MIPS_HI(value));
else if (strcmp(type, "R_MIPS_LO16") == 0)
set_le16(location, get_le16(location) + MIPS_LO(value));
else if (strcmp(type, "R_MIPS_PC16") == 0)
{
value -= rel->section->offset + rel->offset;
set_le16(location, get_le16(location) + MIPS_PC16(value));
}
else if (strcmp(type, "R_MIPS_26") == 0)
set_le32(location, get_le32(location) + MIPS_PC26(value));
else if (strcmp(type, "R_MIPS_32") == 0)
set_le32(location, get_le32(location) + value);
else
super::relocate1(rel, location, value, type);
}
};
return new ElfLinkerMipsLE;
}
@@ -173,15 +152,15 @@ bool PackPs1::readBkupHeader()
}
#define INIT_BH_BKUP(p, l) {(p)->id = '1'; (p)->len = l;}
#define ADLER16(a) ((a) >> 16 ^ ((a) & 0xffff))
#define ADLER16(a) (((a) >> 16) ^ ((a) & 0xffff))
void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len)
{
unsigned sz_cbh;
unsigned sz_cbh = MemBuffer::getSizeForCompression(SZ_IH_BKUP);
if (src && dst)
{
unsigned char *cpr_bh = new unsigned char[MemBuffer::getSizeForCompression(SZ_IH_BKUP)];
unsigned char *cpr_bh = new unsigned char[sz_cbh];
memset(cpr_bh, 0, sizeof(bh));
ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh;
@@ -191,7 +170,7 @@ void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsign
if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP)
throwInternalError("header compression failed");
INIT_BH_BKUP(p, sz_cbh);
*len = ALIGN_UP(sz_cbh + sizeof(ps1_exe_chb_t) - 1, 4);
*len = ALIGN_UP(sz_cbh + (unsigned) sizeof(ps1_exe_chb_t) - 1, 4u);
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
memcpy(dst, cpr_bh, SZ_IH_BKUP);
delete [] cpr_bh;
@@ -300,7 +279,7 @@ bool PackPs1::canPack()
//
**************************************************************************/
int PackPs1::buildLoader(const Filter *)
void PackPs1::buildLoader(const Filter *)
{
const char *method = NULL;
@@ -322,7 +301,7 @@ int PackPs1::buildLoader(const Filter *)
else if (ph.method == M_NRV2E_LE32)
method = isCon ? "nrv2e.small,32bit.sub,nrv.done" :
"nrv2e.32bit,nrv.done";
else if (ph.method == M_LZMA)
else if (M_IS_LZMA(ph.method))
method = "nrv2b.small,8bit.sub,nrv.done,lzma.prep";
else
throwInternalError("unknown compression method");
@@ -336,14 +315,14 @@ int PackPs1::buildLoader(const Filter *)
throwCantPack("packed data overlap (try --force)");
}
else
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp),4);
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp), 4u);
}
foundBss = findBssSection();
if (ph.method == M_LZMA && !buildPart2)
if (M_IS_LZMA(ph.method) && !buildPart2)
{
initLoader(nrv_loader, sizeof(nrv_loader));
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
addLoader("decompressor.start",
isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short",
@@ -351,7 +330,7 @@ int PackPs1::buildLoader(const Filter *)
}
else
{
if (ph.method == M_LZMA && buildPart2)
if (M_IS_LZMA(ph.method) && buildPart2)
{
sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc);
unsigned char *cprLoader = new unsigned char[sz_lcpr];
@@ -359,20 +338,22 @@ int PackPs1::buildLoader(const Filter *)
NULL, M_NRV2B_8, 10, NULL, NULL );
if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
throwInternalError("loader compression failed");
initLoader(nrv_loader, sizeof(nrv_loader),
(ph.method != M_LZMA || isCon) ? 0 : 1);
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1),
isCon || !M_IS_LZMA(ph.method) ? 0 : 1);
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
delete [] cprLoader;
}
else
initLoader(nrv_loader, sizeof(nrv_loader));
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4);
linker->addSection("pad.code", &pad_code, pad_code, 0);
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4u);
assert(pad_code < 4);
static const unsigned char pad_buffer[4] = { 0, 0, 0, 0 };
linker->addSection("pad.code", pad_buffer, pad_code, 0);
if (isCon)
{
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
addLoader(!foundBss ? "con.start" : "bss.con.start",
method,
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
@@ -388,7 +369,7 @@ int PackPs1::buildLoader(const Filter *)
}
else
{
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"lzma.exec", NULL);
@@ -402,8 +383,6 @@ int PackPs1::buildLoader(const Filter *)
}
addLoader("UPX1HEAD", "IDENTSTR", NULL);
}
freezeLoader();
return getLoaderSize();
}
#define OPTYPE(x) (((x) >> 13) & 0x7)
@@ -411,7 +390,7 @@ int PackPs1::buildLoader(const Filter *)
#define REG1(x) (((x) >> 5) & 0x1f)
#define REG2(x) ((x) & 0x1f)
#define MIPS_IMM(a,b) (((a) - (((b) & 0x8000) >> 15) << 16) | (b))
#define MIPS_IMM(a,b) ((((a) - (((b) & 0x8000) >> 15)) << 16) | (b))
// Type
#define REGIMM 1
@@ -461,12 +440,12 @@ bool PackPs1::findBssSection()
bss_start = MIPS_IMM(p->hi1, p->lo1);
bss_end = MIPS_IMM(p->hi2, p->lo2);
if (0 < ALIGN_DOWN(bss_end - bss_start, 4) )
if (0 < ALIGN_DOWN(bss_end - bss_start, 4u))
{
unsigned wkmem_sz = (ph.method == M_LZMA) ? 32768 : 800;
unsigned wkmem_sz = M_IS_LZMA(ph.method) ? 32768 : 800;
unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
if (bss_end > (end_offs + wkmem_sz))
return (isCon || (!isCon && (ph.method == M_LZMA)));
return isCon || (!isCon && M_IS_LZMA(ph.method));
else
return false;
}
@@ -500,9 +479,9 @@ void PackPs1::pack(OutputFile *fo)
while (!(*--p_scan)) { if (sa_cnt++ > (0x10000 << 5) || sa_cnt >= fdata_size - 1024) break; }
if (sa_cnt > (0x10000 << 2))
sa_cnt = ALIGN_DOWN(sa_cnt,32);
sa_cnt = ALIGN_DOWN(sa_cnt, 32u);
else
sa_cnt = ALIGN_DOWN(sa_cnt,4);
sa_cnt = ALIGN_DOWN(sa_cnt, 4u);
// prepare packheader
ph.u_len = (fdata_size - sa_cnt);
@@ -513,7 +492,7 @@ void PackPs1::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset();
cconf.conf_ucl.max_match = 65535;
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, sa_cnt, 0, NULL, &cconf);
compressWithFilters(&ft, sa_cnt, &cconf);
if (overlap)
{
@@ -529,7 +508,7 @@ void PackPs1::pack(OutputFile *fo)
unsigned lzma_init = 0;
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
{
sz_lunc = getLoaderSize();
@@ -538,7 +517,7 @@ void PackPs1::pack(OutputFile *fo)
linker->defineSymbol("entry", ih.epc);
linker->defineSymbol("SC",
sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);
linker->relocate();
relocateLoader();
buildPart2 = true;
buildLoader(&ft);
@@ -558,8 +537,6 @@ void PackPs1::pack(OutputFile *fo)
oh.bs_ptr = oh.bs_len = 0;
const int lsize = getLoaderSize();
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
unsigned filelen = ALIGN_UP(ih.tx_len, 4);
@@ -577,7 +554,7 @@ void PackPs1::pack(OutputFile *fo)
}
else
{
d_len = (lsize - h_len) - getLoaderSectionStart((ph.method == M_LZMA) ? "cdb.entry.lzma" : "cdb.entry");
d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? "cdb.entry.lzma" : "cdb.entry");
e_len = (lsize - d_len) - h_len;
}
@@ -585,10 +562,10 @@ void PackPs1::pack(OutputFile *fo)
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
sa_cnt >> 5 : sa_cnt >> 2));
linker->defineSymbol("DECO", decomp_data_start);
linker->defineSymbol("ldr_sz", (ph.method == M_LZMA ? sz_lunc + 16 : (d_len-pad_code)));
linker->defineSymbol("ldr_sz", M_IS_LZMA(ph.method) ? sz_lunc + 16 : (d_len-pad_code));
if (foundBss)
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
- (sz_lunc + 16));
else
@@ -612,7 +589,7 @@ void PackPs1::pack(OutputFile *fo)
ibuf.clear(0,fdata_size);
upx_bytep paddata = ibuf;
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
{
linker->defineSymbol("lzma_init_off", lzma_init);
linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));
@@ -624,7 +601,7 @@ void PackPs1::pack(OutputFile *fo)
if (isCon)
{
linker->defineSymbol("PAD", pad_code);
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
else
linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
@@ -633,16 +610,19 @@ void PackPs1::pack(OutputFile *fo)
{
linker->defineSymbol("PSVR", FIX_PSVR);
linker->defineSymbol("CPDO", comp_data_start);
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
- getLoaderSectionStart("cdb.entry.lzma"));
}
linker->relocate();
relocateLoader();
//linker->dumpSymbols();
MemBuffer loader(lsize);
assert(lsize == getLoaderSize());
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
if (!isCon && ph.method == M_LZMA && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
if (!isCon && M_IS_LZMA(ph.method) && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
throwInternalError("lzma --boot-only loader > 2048");
// ps1_exe_t structure
@@ -676,7 +656,7 @@ void PackPs1::pack(OutputFile *fo)
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
unsigned char i = 0;
if (isCon) { if (foundBss) i = 1; }
else { i = 2; if (ph.method == M_LZMA) { if (!foundBss) i = 3; else i = 4; } }
else { i = 2; if (M_IS_LZMA(ph.method)) { if (!foundBss) i = 3; else i = 4; } }
const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
+6 -5
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2002-2006 Jens Medoch
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
Copyright (C) 2002-2007 Jens Medoch
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -46,6 +46,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_PS1_EXE; }
virtual const char *getName() const { return "ps1/exe"; }
virtual const char *getFullName(const options_t *) const { return "mipsel.r3000-ps1"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -59,7 +60,7 @@ protected:
virtual void putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len);
virtual bool getBkupHeader(unsigned char *src, unsigned char * dst);
virtual bool readBkupHeader();
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual bool findBssSection();
virtual Linker* newLinker() const;
@@ -111,7 +112,7 @@ protected:
}
__attribute_packed;
typedef struct bss_nfo
struct bss_nfo
{
LE16 hi1, op1, lo1, op2;
LE16 hi2, op3, lo2, op4;
+7 -8
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -70,7 +70,7 @@ void PackSys::patchLoader(OutputFile *fo,
{
const int e_len = getLoaderSectionStart("SYSCUTPO");
const int d_len = lsize - e_len;
assert(e_len > 0 && e_len < 256);
assert(e_len > 0 && e_len < 128);
assert(d_len > 0 && d_len < 256);
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
@@ -85,10 +85,11 @@ void PackSys::patchLoader(OutputFile *fo,
linker->defineSymbol("calltrick_calls", calls);
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
linker->defineSymbol("copy_destination", copy_to);
linker->defineSymbol("neg_e_len", 0 - e_len);
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead + 1);
linker->defineSymbol("original_strategy", get_le16(ibuf + 6));
linker->relocate();
relocateLoader();
loader = getLoader();
patchPackHeader(loader,e_len);
@@ -99,9 +100,9 @@ void PackSys::patchLoader(OutputFile *fo,
}
int PackSys::buildLoader(const Filter *ft)
void PackSys::buildLoader(const Filter *ft)
{
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
initLoader(stub_i086_dos16_sys, sizeof(stub_i086_dos16_sys));
addLoader("SYSMAIN1",
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
"SYSMAIN2",
@@ -122,8 +123,6 @@ int PackSys::buildLoader(const Filter *ft)
"SYSJUMP1",
NULL
);
freezeLoader();
return getLoaderSize();
}
+4 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -42,6 +42,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_DOS_SYS; }
virtual const char *getName() const { return "dos/sys"; }
virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.sys" : "i286-dos16.sys"; }
virtual bool canPack();
@@ -49,7 +50,7 @@ protected:
virtual unsigned getCallTrickOffset() const { return 0; }
protected:
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
};
+18 -26
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -45,6 +45,7 @@ static const
PackTmt::PackTmt(InputFile *f) : super(f)
{
bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44);
}
@@ -58,8 +59,9 @@ const int *PackTmt::getCompressionMethods(int method, int level) const
const int *PackTmt::getFilters() const
{
static const int filters[] = {
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x12, 0x15,
-1 };
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters;
}
@@ -81,11 +83,13 @@ Linker* PackTmt::newLinker() const
}
int PackTmt::buildLoader(const Filter *ft)
void PackTmt::buildLoader(const Filter *ft)
{
// prepare loader
initLoader(nrv_loader,sizeof(nrv_loader));
initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt));
addLoader("IDENTSTR,TMTMAIN1",
ph.first_offset_found == 1 ? "TMTMAIN1A" : "",
"TMTMAIN1B",
ft->id ? "TMTCALT1" : "",
"TMTMAIN2,UPX1HEAD,TMTCUTPO",
NULL);
@@ -105,8 +109,6 @@ int PackTmt::buildLoader(const Filter *ft)
"RELOC32J,TMTJUMP1",
NULL
);
freezeLoader();
return getLoaderSize();
}
@@ -169,7 +171,7 @@ int PackTmt::readFileHeader()
fi->seek(adam_offset,SEEK_SET);
fi->readx(&ih,sizeof(ih));
// FIXME: should add some checks for the values in `ih'
// FIXME: should add some checks for the values in 'ih'
return UPX_F_TMT_ADAM;
#undef H4
@@ -185,19 +187,6 @@ bool PackTmt::canPack()
}
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
{
if (ft->id == 0)
return false;
assert(ft->calls > 0);
linker->defineSymbol("filter_cto", ft->cto);
linker->defineSymbol("filter_length",
(ft->id & 0xf) % 3 == 0 ? ft->calls :
ft->lastcall - ft->calls * 4);
return true;
}
/*************************************************************************
//
**************************************************************************/
@@ -250,7 +239,10 @@ void PackTmt::pack(OutputFile *fo)
Filter ft(ph.level);
ft.buf_len = usize;
// compress
compressWithFilters(&ft, 512);
upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 512, &cconf);
const unsigned lsize = getLoaderSize();
const unsigned s_point = getLoaderSection("TMTMAIN1");
@@ -260,17 +252,17 @@ void PackTmt::pack(OutputFile *fo)
// patch loader
linker->defineSymbol("original_entry", ih.entry);
defineFilterSymbols(linker, &ft);
defineDecompressorSymbols();
defineFilterSymbols(&ft);
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len);
linker->defineSymbol("copy_dest", ph.u_len + ph.overlap_overhead + d_len - 1);
linker->defineSymbol("copy_dest", 0u - (ph.u_len + ph.overlap_overhead + d_len - 1));
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n",
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead);
linker->relocate();
relocateLoader();
MemBuffer loader(lsize);
memcpy(loader,getLoader(),lsize);
+4 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -42,6 +42,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_TMT_ADAM; }
virtual const char *getName() const { return "tmt/adam"; }
virtual const char *getFullName(const options_t *) const { return "i386-dos32.tmt"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -57,7 +58,7 @@ protected:
virtual unsigned findOverlapOverhead(const upx_bytep buf,
unsigned range = 0,
unsigned upper_limit = ~0u) const;
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
unsigned adam_offset;
+332 -260
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -37,7 +37,7 @@
static const
#include "stub/m68k-atari.tos.h"
// #define TESTING
//#define TESTING 1
/*************************************************************************
@@ -49,6 +49,7 @@ static const
PackTos::PackTos(InputFile *f) :
super(f)
{
bele = &N_BELE_RTP::be_policy;
COMPILE_TIME_ASSERT(FH_SIZE == 28);
}
@@ -72,42 +73,171 @@ Linker* PackTos::newLinker() const
}
int PackTos::buildLoader(const Filter *ft)
void PackTos::LinkerSymbols::LoopInfo::init(unsigned count_, bool allow_dbra)
{
count = value = count_;
if (count == 0)
mode = LOOP_NONE;
else if (count <= 65536 && allow_dbra)
{
mode = LOOP_DBRA;
value -= 1;
value &= 0xffff;
}
else if (count <= 65536)
{
mode = LOOP_SUBQ_W;
value &= 0xffff;
}
else
mode = LOOP_SUBQ_L;
}
unsigned PackTos::getDecomprOffset(int method, int small) const
{
UNUSED(small);
if (M_IS_NRV2B(method))
return 2; // FIXME: do not hardcode this value
else if (M_IS_NRV2D(method))
return 2; // FIXME: do not hardcode this value
else if (M_IS_NRV2E(method))
return 2; // FIXME: do not hardcode this value
else if (M_IS_LZMA(method))
return linker->getSectionSize("__mulsi3");
else
throwBadLoader();
return 0;
}
void PackTos::buildLoader(const Filter *ft)
{
assert(ft->id == 0);
const unsigned char *p = NULL;
size_t l = 0;
initLoader(stub_m68k_atari_tos, sizeof(stub_m68k_atari_tos));
//linker->dumpSymbols();
//
// part 1a
//
addLoader("entry");
if (symbols.up21_a6 <= 32767)
addLoader("set_up21_a6.w");
else if (symbols.up21_d4 <= 32767)
addLoader("set_up21_d4.w");
else
addLoader("set_up21_d4.l");
assert(symbols.loop1.count || symbols.loop2.count);
if (symbols.loop1.count)
{
if (symbols.loop1.value <= 127)
addLoader("loop1_set_count.b");
else if (symbols.loop1.value <= 65535)
addLoader("loop1_set_count.w");
else
addLoader("loop1_set_count.l");
addLoader("loop1_label");
addLoader(opt->small ? "loop1.small" : "loop1.fast");
if (symbols.loop1.mode == symbols.LOOP_SUBQ_L)
addLoader("loop1_subql");
else if (symbols.loop1.mode == symbols.LOOP_SUBQ_W)
addLoader("loop1_subqw");
else if (symbols.loop1.mode == symbols.LOOP_DBRA)
addLoader("loop1_dbra");
else
throwBadLoader();
}
if (symbols.loop2.count)
{
assert(symbols.loop2.mode == symbols.LOOP_DBRA);
addLoader(opt->small ? "loop2.small" : "loop2.fast");
}
addLoader("copy_to_stack");
if (M_IS_NRV2B(ph.method))
addLoader("nrv2b.init");
else if (M_IS_NRV2D(ph.method))
addLoader("nrv2d.init");
else if (M_IS_NRV2E(ph.method))
addLoader("nrv2e.init");
else if (M_IS_LZMA(ph.method))
addLoader("lzma.init");
else
throwBadLoader();
symbols.up31_d4 = symbols.up31_base_d4 + getDecomprOffset(ph.method, opt->small);
symbols.up31_a6 = symbols.up31_base_a6 + getDecomprOffset(ph.method, opt->small);
if (symbols.up31_a6 <= 32767)
addLoader("jmp_decompressor_a6.w");
else if (symbols.up31_d4 <= 32767)
addLoader("jmp_decompressor_d4.w");
else if (symbols.up31_a6 <= 65534)
addLoader("jmp_decompressor_a6.w2");
else
addLoader("jmp_decompressor_d4.l");
//
// part 1b
//
addLoader("code_on_stack");
addLoader("clear_dirty_bss");
addLoader("loop3_label");
addLoader(opt->small ? "loop3.small" : "loop3.fast");
if (symbols.loop3.mode == symbols.LOOP_SUBQ_L)
addLoader("loop3_subql");
else if (symbols.loop3.mode == symbols.LOOP_SUBQ_W)
addLoader("loop3_subqw");
else if (symbols.loop3.mode == symbols.LOOP_DBRA)
addLoader("loop3_dbra");
else
throwBadLoader();
addLoader("flush_cache");
addLoader("restore_stack");
#if 0
addLoader("clear_dirty_stack");
#endif
addLoader("start_program");
addLoader("IDENTSTR,+40D,UPX1HEAD,CUTPOINT");
//
// part 2
//
p = nrv_loader;
if (M_IS_NRV2B(ph.method)) {
// p = opt->small ? nrv2b_loader_small : nrv2b_loader;
// l = opt->small ? sizeof(nrv2b_loader_small) : sizeof(nrv2b_loader);
addLoader(opt->small ? "nrv2b_8.small" : "nrv2b_8.fast");
} else if (M_IS_NRV2D(ph.method)) {
addLoader(opt->small ? "nrv2d_8.small" : "nrv2d_8.fast");
} else if (M_IS_NRV2E(ph.method)) {
addLoader(opt->small ? "nrv2e_8.small" : "nrv2e_8.fast");
} else if (M_IS_LZMA(ph.method)) {
addLoader("__mulsi3");
addLoader(opt->small ? "lzma.small" : "lzma.fast");
addLoader("lzma.finish");
}
if (M_IS_NRV2D(ph.method)) {
// p = opt->small ? nrv2d_loader_small : nrv2d_loader;
// l = opt->small ? sizeof(nrv2d_loader_small) : sizeof(nrv2d_loader);
}
if (M_IS_NRV2E(ph.method)) {
// p = opt->small ? nrv2e_loader_small : nrv2e_loader;
// l = opt->small ? sizeof(nrv2e_loader_small) : sizeof(nrv2e_loader);
}
initLoader(p, l);
else
throwBadLoader();
addLoader("tos0",
true ? "subql_1d0" : "subqw_1d0",
"s_bneloop0",
true ? "subql_1d6" : "subqw_1d6",
"s_bneloop3",
"IDENTSTR,+40,UPX1HEAD",
"CUTPOINT",
true ? "reloc" : "",
"jmpastack",
NULL
);
if (symbols.need_reloc)
addLoader("reloc");
freezeLoader();
return getLoaderSize();
assert(symbols.loop3.count);
if (symbols.loop3.value <= 127)
addLoader("loop3_set_count.b");
else if (symbols.loop3.value <= 65535)
addLoader("loop3_set_count.w");
else
addLoader("loop3_set_count.l");
addLoader("jmp_stack");
}
@@ -177,142 +307,25 @@ bool PackTos::checkFileHeader()
if ((f & F_PROTMODE) != F_PROT_P)
{
if (opt->force < 1)
throwCantPack("no private memory protection; use option `-f' to force packing");
throwCantPack("no private memory protection; use option '-f' to force packing");
}
if (f & F_SHTEXT)
{
if (opt->force < 1)
throwCantPack("shared text segment; use option `-f' to force packing");
throwCantPack("shared text segment; use option '-f' to force packing");
}
#if 0
// fh_reserved seems to be unused
if (ih.fh_reserved != 0)
{
if (opt->force < 1)
throwCantPack("reserved header field set; use option `-f' to force packing");
throwCantPack("reserved header field set; use option '-f' to force packing");
}
#endif
return true;
}
/*************************************************************************
// some 68000 opcodes for patching
**************************************************************************/
#if 0
enum m68k_reg_t {
REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7
};
static unsigned OP_DBRA(int d_reg)
{
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
return 0x51c8 | (d_reg & 7);
}
static unsigned OP_JMP(int a_reg)
{
// jmp (a0)
assert(a_reg >= REG_A0 && a_reg <= REG_A7);
return 0x4ed0 | (a_reg & 7);
}
static unsigned OP_MOVEI_L(int d_reg)
{
// movei.l #XXXXXXXX,d0
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
return 0x203c | ((d_reg & 7) << 9);
}
static unsigned OP_MOVEQ(int value, int d_reg)
{
// moveq.l #0,d0
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
assert(value >= -128 && value <= 127);
return 0x7000 | ((d_reg & 7) << 9) | (value & 0xff);
}
static unsigned OP_SUBQ_L(int value, int d_reg)
{
// subq.l #X,d0
assert(value >= 1 && value <= 8);
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
return 0x5180 | ((value & 7) << 9) | (d_reg & 7);
}
static unsigned OP_SUBQ_W(int value, int d_reg)
{
// subq.w #X,d0
assert(value >= 1 && value <= 8);
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
return 0x5140 | ((value & 7) << 9) | (d_reg & 7);
}
/*************************************************************************
//
**************************************************************************/
unsigned PackTos::patch_d_subq(void *b, int blen,
int d_reg, unsigned d_value,
const char *subq_marker)
{
// patch a "subq.l #1,d0" or "subq.w #1,d0".
// also convert into "dbra" if possible
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
assert((int)d_value > 0);
int boff = find_be16(b, blen, get_be16(subq_marker));
if (boff < 0)
throwBadLoader();
upx_byte *p = (upx_byte *)b + boff;
if (p[2] == 0x66) // bne.b XXX
checkPatch(b, blen, boff, 4);
else
checkPatch(b, blen, boff, 2);
if (d_value > 65536)
{
set_be16(p, OP_SUBQ_L(1, d_reg)); // subq.l #1,d0
}
else
{
if (p[2] == 0x66) // bne.b XXX
{
set_be16(p, OP_DBRA(d_reg)); // dbra d0,XXX
// adjust and extend branch from 8 to 16 bits
int branch = (signed char) p[3];
set_be16(p+2, branch+2);
// adjust d0
d_value -= 1;
}
else
{
set_be16(p, OP_SUBQ_W(1, d_reg)); // subq.w #1,d0
}
d_value &= 0xffff;
}
return d_value;
}
unsigned PackTos::patch_d_loop(void *b, int blen,
int d_reg, unsigned d_value,
const char *d_marker, const char *subq_marker)
{
d_value = patch_d_subq(b, blen, d_reg, d_value, subq_marker);
int boff = find_be32(b, blen, get_be32(d_marker));
checkPatch(b, blen, boff, 4);
upx_byte *p = (upx_byte *)b + boff;
assert(get_be16(p - 2) == OP_MOVEI_L(d_reg)); // move.l #XXXXXXXX,d0
set_be32(p, d_value);
return d_value;
}
#endif
/*************************************************************************
// relocs
**************************************************************************/
@@ -366,18 +379,6 @@ static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
bool PackTos::canPack()
{
#if 0 // debug
# define p(x) printf("%-30s 0x%04x\n", #x, x)
p(OP_DBRA(REG_D0));
p(OP_MOVEI_L(REG_D0));
p(OP_MOVEQ(-1, REG_D0));
p(OP_MOVEQ(1, REG_D2));
p(OP_MOVEQ(1, REG_D3));
p(OP_SUBQ_W(1, REG_D0));
p(OP_SUBQ_L(1, REG_D0));
# undef p
#endif
if (!readFileHeader())
return false;
@@ -409,7 +410,6 @@ void PackTos::fileInfo()
void PackTos::pack(OutputFile *fo)
{
throwInternalError("atari/tos is currenty broken; this will get fixed in UPX 2.91");
unsigned t;
unsigned nrelocs = 0;
unsigned relocsize = 0;
@@ -421,6 +421,15 @@ void PackTos::pack(OutputFile *fo)
const unsigned i_bss = ih.fh_bss;
symbols.reset();
symbols.need_reloc = false;
// prepare symbols for buildLoader() - worst case
symbols.loop1.init(65536 + 1);
symbols.loop2.init((160 - 1) / 4);
symbols.loop3.init(65536 + 1);
symbols.up21_d4 = 65536 + 1;
symbols.up21_a6 = 65536 + 1;
symbols.up31_base_d4 = 65536 + 1;
symbols.up31_base_a6 = 65536 + 1;
// read file
const unsigned isize = file_size - i_sym;
@@ -430,6 +439,8 @@ void PackTos::pack(OutputFile *fo)
t = i_text + i_data;
fi->readx(ibuf,t);
// skip symbols
if (i_sym && opt->exact)
throwCantPackExact();
fi->seek(i_sym,SEEK_CUR);
// read relocations + overlay
overlay = file_size - (FH_SIZE + i_text + i_data + i_sym);
@@ -443,7 +454,6 @@ void PackTos::pack(OutputFile *fo)
// Check relocs (see load_and_reloc() in freemint/sys/memory.c).
// Must work around TOS bugs and lots of broken programs.
int r = 0;
if (overlay < 4)
{
// Bug workaround: Whatever this is, silently keep it in
@@ -459,15 +469,17 @@ void PackTos::pack(OutputFile *fo)
}
else if (ih.fh_reloc != 0)
relocsize = 0;
else
r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
else {
int r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
if (r != 0)
throwCantPack("bad relocation table");
symbols.need_reloc = true;
}
#if 0 || defined(TESTING)
printf("xx2: %d relocs: %d, overlay: %d, t: %d\n", nrelocs, relocsize, overlay, t);
#endif
if (r != 0)
throwCantPack("bad relocation table");
checkOverlay(overlay);
// Append original fileheader.
@@ -485,8 +497,8 @@ void PackTos::pack(OutputFile *fo)
// After compression this will become the first part of the
// data segement. The second part will be the decompressor.
// alloc buffer (2048 is for decompressor and the various alignments)
obuf.allocForCompression(t, 2048);
// alloc buffer (4096 is for decompressor and the various alignments)
obuf.allocForCompression(t, 4096);
// prepare packheader
ph.u_len = t;
@@ -495,102 +507,163 @@ void PackTos::pack(OutputFile *fo)
// compress (max_match = 65535)
upx_compress_config_t cconf; cconf.reset();
cconf.conf_ucl.max_match = 65535;
compressWithFilters(&ft, 512, 0, NULL, &cconf);
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 512, &cconf);
// get loader
const unsigned lsize = getLoaderSize();
const unsigned e_len = getLoaderSectionStart("CUTPOINT");
const unsigned d_len = lsize - e_len;
const unsigned decomp_offset = linker->getSymbolOffset("decompr_start") - e_len;
assert(decomp_offset != 0xdeaddead);
assert((e_len & 3) == 0 && (d_len & 1) == 0);
//
// multipass buildLoader()
//
// The decompressed data will now get placed at this offset:
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
// save initial loader
const unsigned initial_lsize = getLoaderSize();
unsigned last_lsize = initial_lsize;
MemBuffer last_loader(last_lsize);
memcpy(last_loader, getLoader(), last_lsize);
// compute addresses
unsigned o_text, o_data, o_bss;
o_text = e_len;
o_data = ph.c_len;
o_bss = i_bss;
// word align len of compressed data
while (o_data & 1)
unsigned e_len, d_len, d_off;
for (;;)
{
obuf[o_data++] = 0;
offset++;
}
// The decompressed data will now get placed at this offset:
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
// append decompressor (part 2 of loader)
const unsigned d_off = o_data;
o_data += d_len;
// get loader
const unsigned lsize = getLoaderSize();
e_len = getLoaderSectionStart("CUTPOINT");
d_len = lsize - e_len;
assert((e_len & 3) == 0 && (d_len & 1) == 0);
// dword align the len of the final data segment
while (o_data & 3)
{
obuf[o_data++] = 0;
offset++;
}
// dword align offset
while (offset & 3)
offset++;
// compute section sizes
o_text = e_len;
o_data = ph.c_len;
o_bss = i_bss;
// new bss
if (i_text + i_data + i_bss > o_text + o_data + o_bss)
o_bss = (i_text + i_data + i_bss) - (o_text + o_data);
// dirty bss
unsigned dirty_bss = (o_data + offset) - (i_text + i_data);
//printf("real dirty_bss: %d\n", dirty_bss);
// dword align (or 16 - for speedup when clearing the dirty bss)
const unsigned dirty_bss_align = opt->small ? 4 : 16;
while (dirty_bss & (dirty_bss_align - 1))
dirty_bss++;
// adjust bss, assert room for some stack
if (dirty_bss + 512 > o_bss)
o_bss = dirty_bss + 512;
// dword align the len of the final bss segment
while (o_bss & 3)
o_bss++;
// patch "subq.l #1,d6" or "subq.w #1,d6" - see "up41" below
const unsigned dirty_bss_d6 = dirty_bss / dirty_bss_align;
// FIXME patch_d_subq(loader, o_text, REG_D6, dirty_bss / dirty_bss_align, "u4");
linker->defineSymbol("up31", d_off + offset + decomp_offset);
if (opt->small)
; // patch_d_loop(loader, o_text, REG_D0, o_data/4, "up22", "u1");
else
{
if (o_data <= 160)
throwNotCompressible();
unsigned loop1 = o_data / 160;
unsigned loop2 = o_data % 160;
if (loop2 == 0)
// word align len of compressed data
while (o_data & 1)
{
loop1--;
loop2 = 160;
obuf[o_data++] = 0;
offset++;
}
linker->defineSymbol("copy_remain", loop2 / 4 - 1);
//patch_be16(loader, o_text, "u2", OP_MOVEQ(loop2/4-1, REG_D0)); // moveq.l #X,d0
//patch_d_loop(loader, o_text, REG_D0, loop1, "up22", "u1");
// append decompressor (part 2 of loader)
d_off = o_data;
////memcpy(obuf + d_off, getLoader() + e_len, d_len); // must be done after relocation
o_data += d_len;
// dword align the len of the final data segment
while (o_data & 3)
{
obuf[o_data++] = 0;
offset++;
}
// dword align offset
while (offset & 3)
offset++;
// new bss
if (i_text + i_data + i_bss > o_text + o_data + o_bss)
o_bss = (i_text + i_data + i_bss) - (o_text + o_data);
// dirty bss
unsigned dirty_bss = (o_data + offset) - (i_text + i_data);
//printf("real dirty_bss: %d\n", dirty_bss);
// dword align (or 16 - for speedup when clearing the dirty bss)
const unsigned dirty_bss_align = opt->small ? 4 : 16;
while (dirty_bss & (dirty_bss_align - 1))
dirty_bss++;
// adjust bss, assert room for some stack
unsigned stack = 512 + getDecompressorWrkmemSize();
if (dirty_bss + stack > o_bss)
o_bss = dirty_bss + stack;
// dword align the len of the final bss segment
while (o_bss & 3)
o_bss++;
// update symbols for buildLoader()
if (opt->small)
{
symbols.loop1.init(o_data / 4);
symbols.loop2.init(0);
}
else
{
symbols.loop1.init(o_data / 160);
symbols.loop2.init((o_data % 160) / 4);
}
symbols.loop3.init(dirty_bss / dirty_bss_align);
symbols.up21_d4 = o_data + offset;
symbols.up31_base_d4 = d_off + offset;
symbols.up21_a6 = symbols.up21_d4 - (i_text + i_data);
symbols.up31_base_a6 = symbols.up31_base_d4 - (i_text + i_data);
assert((int)symbols.up21_a6 > 0);
assert((int)symbols.up31_base_a6 > 0);
const unsigned c = linker->getSymbolOffset("code_on_stack");
unsigned d;
d = linker->getSymbolOffset("flush_cache_rts") - c;
symbols.flush_cache_rts_offset = d;
d = linker->getSymbolOffset("clear_dirty_stack_loop") - c;
symbols.clear_dirty_stack_len = (d + 3) / 4 + 32 - 1;
d = linker->getSymbolOffset("code_on_stack_end") - c;
symbols.copy_to_stack_len = d / 2 - 1;
// now re-build loader
buildLoader(&ft);
unsigned new_lsize = getLoaderSize();
//printf("buildLoader %d %d\n", new_lsize, initial_lsize);
assert(new_lsize <= initial_lsize);
if (new_lsize == last_lsize && memcmp(getLoader(), last_loader, last_lsize) == 0)
break;
last_lsize = new_lsize;
memcpy(last_loader, getLoader(), last_lsize);
}
linker->defineSymbol("up22", opt->small ? o_data / 4 : (o_data - 1) / 160);
linker->defineSymbol("up21", o_data + offset);
linker->defineSymbol("up13", i_bss); // p_blen
linker->defineSymbol("up12", i_data); // p_dlen
linker->defineSymbol("up11", i_text); // p_tlen
const unsigned clear_size = linker->getSymbolOffset("clear_bss_end") -
linker->getSymbolOffset("clear_bss");
linker->defineSymbol("copy_to_stack_len", clear_size / 2 - 1);
linker->defineSymbol("clear_bss_size_p4", clear_size + 4);
//
// define symbols and reloc
//
// patch decompressor
//upx_byte *p = obuf + d_off;
// patch "moveq.l #1,d5" or "jmp (ASTACK)"
//patch_be16(p, d_len, "u3", (nrelocs > 0) ? OP_MOVEQ(1, REG_D5) : OP_JMP(REG_A7));
linker->defineSymbol("up41", dirty_bss_d6);
defineDecompressorSymbols();
linker->defineSymbol("loop1_count", symbols.loop1.value);
linker->defineSymbol("loop2_count", symbols.loop2.value);
linker->defineSymbol("loop3_count", symbols.loop3.value);
linker->defineSymbol("orig_p_tlen", i_text);
linker->defineSymbol("orig_p_dlen", i_data);
linker->defineSymbol("orig_p_blen", i_bss);
if (symbols.up21_a6 <= 32767)
linker->defineSymbol("up21_a6", symbols.up21_a6);
else
linker->defineSymbol("up21_d4", symbols.up21_d4);
if (symbols.up31_a6 <= 32767)
linker->defineSymbol("up31_a6", symbols.up31_a6);
else if (symbols.up31_d4 <= 32767)
linker->defineSymbol("up31_d4", symbols.up31_d4);
else if (symbols.up31_a6 <= 65534)
linker->defineSymbol("up31_a6", symbols.up31_a6 - 32767);
else
linker->defineSymbol("up31_d4", symbols.up31_d4);
#if 0
printf("relocsize = %d\n", relocsize);
printf("upx21(d4) = %d\n", symbols.up21_d4);
printf("upx21(a6) = %d\n", symbols.up21_a6);
printf("upx31(d4) = %d\n", symbols.up31_d4);
printf("upx31(a6) = %d\n", symbols.up31_a6);
#endif
linker->defineSymbol("flush_cache_rts_offset", symbols.flush_cache_rts_offset);
linker->defineSymbol("copy_to_stack_len", symbols.copy_to_stack_len);
linker->defineSymbol("clear_dirty_stack_len", symbols.clear_dirty_stack_len);
relocateLoader();
//
// write
//
// set new file_hdr
memcpy(&oh, &ih, FH_SIZE);
@@ -616,16 +689,14 @@ void PackTos::pack(OutputFile *fo)
#if 0 || defined(TESTING)
printf("old text: %6d, data: %6d, bss: %6d, reloc: %d, overlay: %d\n",
i_text, i_data, i_bss, relocsize, overlay);
printf("new text: %6d, data: %6d, bss: %6d, dirty_bss: %d, flag=0x%x\n",
o_text, o_data, o_bss, dirty_bss, (int)oh.fh_flag);
printf("new text: %6d, data: %6d, bss: %6d, flag=0x%x\n",
o_text, o_data, o_bss, (int)oh.fh_flag);
linker->dumpSymbols();
#endif
linker->relocate();
// prepare loader
MemBuffer loader(o_text);
memcpy(loader, getLoader(), o_text);
memcpy(obuf+d_off, getLoader() + e_len, d_len);
patchPackHeader(loader, o_text);
// write new file header, loader and compressed file
@@ -633,10 +704,11 @@ void PackTos::pack(OutputFile *fo)
fo->write(loader, o_text); // entry
if (opt->debug.dump_stub_loader)
OutputFile::dump(opt->debug.dump_stub_loader, loader, o_text);
memcpy(obuf + d_off, getLoader() + e_len, d_len); // copy decompressor
fo->write(obuf, o_data); // compressed + decompressor
// write empty relocation fixup
fo->write("\x00\x00\x00\x00",4);
fo->write("\x00\x00\x00\x00", 4);
// verify
verifyOverlappingDecompression();
+25 -16
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -42,6 +42,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_ATARI_TOS; }
virtual const char *getName() const { return "atari/tos"; }
virtual const char *getFullName(const options_t *) const { return "m68k-atari.tos"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -55,7 +56,8 @@ public:
protected:
virtual Linker* newLinker() const;
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
unsigned getDecomprOffset(int method, int small) const;
virtual int readFileHeader();
virtual bool checkFileHeader();
@@ -75,27 +77,34 @@ protected:
tos_header_t ih, oh;
// symbols for buildLoader()
struct LinkerSymbols
{
enum { LOOP_UNKNOWN, LOOP_SUBQ_L, LOOP_SUBQ_W, LOOP_DBRA };
// before linker->relocate()
unsigned loop1_count; int loop1_mode;
unsigned loop2_count; int loop2_mode;
unsigned loop3_count; int loop3_mode;
// after linker->relocate()
unsigned copy_to_stack_len;
enum { LOOP_NONE, LOOP_SUBQ_L, LOOP_SUBQ_W, LOOP_DBRA };
struct LoopInfo {
unsigned mode; unsigned count; unsigned value;
void init(unsigned count, bool allow_dbra=true);
};
// buildLoader() input
bool need_reloc;
LoopInfo loop1;
LoopInfo loop2;
LoopInfo loop3;
unsigned up21_d4;
unsigned up21_a6;
unsigned up31_base_d4;
unsigned up31_base_a6;
// buildLoader() output
unsigned up31_d4;
unsigned up31_a6;
// currently not used by buildLoader()
unsigned flush_cache_rts_offset;
unsigned clear_bss_size_p4;
unsigned clear_dirty_stack_len;
// FIXME: up11 etc.
unsigned copy_to_stack_len;
void reset() { memset(this, 0, sizeof(*this)); }
};
LinkerSymbols symbols;
protected:
unsigned patch_d_subq(void *l, int llen, int, unsigned, const char*);
unsigned patch_d_loop(void *l, int llen, int, unsigned, const char*, const char*);
};
+12 -13
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -62,7 +62,7 @@ bool PackUnix::canPack()
#if defined(__unix__)
// must be executable by owner
if ((fi->st.st_mode & S_IXUSR) == 0)
throwCantPack("file not executable; try `chmod +x'");
throwCantPack("file not executable; try 'chmod +x'");
#endif
if (file_size < 4096)
throwCantPack("file is too small");
@@ -125,8 +125,8 @@ int PackUnix::getStrategy(Filter &/*ft*/)
// Called just before reading and compressing each block.
// Might want to adjust blocksize, etc.
// If user specified the filter, then use it (-2==strategy).
// Else try the first two filters, and pick the better (2==strategy).
// If user specified the filter, then use it (-2==filter_strategy).
// Else try the first two filters, and pick the better (2==filter_strategy).
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
}
@@ -151,9 +151,9 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
// which assumes it has free choice on each call [block].
// And if the choices aren't the same on each block,
// then un-filtering will give incorrect results.
int strategy = getStrategy(ft);
int filter_strategy = getStrategy(ft);
if (file_size > (off_t)blocksize)
strategy = -3; // no filters
filter_strategy = -3; // no filters
int l = fi->readx(ibuf, UPX_MIN(blocksize, remaining));
remaining -= l;
@@ -170,7 +170,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
// that is, AFTER filtering. We want BEFORE filtering,
// so that decompression checks the end-to-end checksum.
unsigned const end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler);
compressWithFilters(&ft, OVERHEAD, strategy);
compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy);
if (ph.c_len < ph.u_len) {
ph.overlap_overhead = OVERHEAD;
@@ -318,7 +318,7 @@ void PackUnix::packExtent(
}
fi->seek(x.offset, SEEK_SET);
for (off_t rest = x.size; 0 != rest; ) {
int const strategy = getStrategy(*ft);
int const filter_strategy = getStrategy(*ft);
int l = fi->readx(ibuf, UPX_MIN(rest, (off_t)blocksize));
if (l == 0) {
break;
@@ -345,12 +345,11 @@ void PackUnix::packExtent(
ft->id = 0;
ft->cto = 0;
compressWithFilters(ft, OVERHEAD, strategy,
NULL, NULL, 0, 0, // those 4 args are the defaults
hdr_ibuf, hdr_u_len);
compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy,
0, 0, 0, hdr_ibuf, hdr_u_len);
}
else {
(void) compress(ibuf, obuf); // ignore return value
(void) compress(ibuf, ph.u_len, obuf); // ignore return value
}
if (ph.c_len < ph.u_len) {
+7 -7
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -111,9 +111,9 @@ protected:
}
__attribute_packed;
struct l_info { // 12-byte trailer in header for loader
unsigned l_checksum;
unsigned l_magic;
unsigned short l_lsize;
LE32 l_checksum;
LE32 l_magic;
LE16 l_lsize;
unsigned char l_version;
unsigned char l_format;
}
@@ -141,7 +141,7 @@ class PackUnixBe32 : public PackUnix
{
typedef PackUnix super;
protected:
PackUnixBe32(InputFile *f) : super(f) { }
PackUnixBe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; }
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
virtual unsigned get_native16(const void *b) const { return get_be16(b); }
@@ -182,7 +182,7 @@ class PackUnixLe32 : public PackUnix
{
typedef PackUnix super;
protected:
PackUnixLe32(InputFile *f) : super(f) { }
PackUnixLe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
+662 -254
View File
File diff suppressed because it is too large Load Diff
+124 -25
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -31,42 +31,141 @@
#include "p_elf.h"
/*************************************************************************
// vmlinx/i386 (bare binary Linux kernel image)
**************************************************************************/
class PackVmlinuxI386 : public Packer
template <class TElfClass>
class PackVmlinuxBase : public Packer
{
typedef Packer super;
protected:
typedef TElfClass ElfClass;
typedef typename ElfClass::BeLePolicy BeLePolicy;
typedef typename ElfClass::ElfITypes ElfITypes;
// integral types
typedef typename ElfClass::U16 U16;
typedef typename ElfClass::U32 U32;
typedef typename ElfClass::U64 U64;
typedef typename ElfITypes::Addr Addr;
// ELF types
typedef typename ElfClass::Ehdr Ehdr;
typedef typename ElfClass::Shdr Shdr;
typedef typename ElfClass::Phdr Phdr;
typedef typename ElfClass::Dyn Dyn;
typedef typename ElfClass::Sym Sym;
public:
PackVmlinuxI386(InputFile *f);
virtual ~PackVmlinuxI386();
PackVmlinuxBase(InputFile *, unsigned, unsigned, unsigned, char const *);
virtual ~PackVmlinuxBase();
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_VMLINUX_i386; }
virtual const char *getName() const { return "vmlinux/386"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
virtual void pack(OutputFile *fo);
virtual void unpack(OutputFile *fo);
virtual bool canPack();
virtual int canUnpack();
protected:
virtual int buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
// virtual const upx_byte *getLoader() const;
// virtual int getLoaderSize() const;
unsigned int const my_e_machine;
unsigned char const my_elfclass;
unsigned char const my_elfdata;
char const *const my_boot_label;
int n_ptload;
unsigned sz_ptload;
Elf_LE32_Phdr *phdri; // from input file
Elf_LE32_Shdr *shdri; // from input file
Elf_LE32_Shdr *p_text;
Elf_LE32_Shdr *p_note0;
Elf_LE32_Shdr *p_note1;
Elf_LE32_Ehdr ehdri; // from input file
unsigned paddr_min;
Phdr *phdri; // from input file
Shdr *shdri; // from input file
char *shstrtab; // from input file
Shdr *p_text;
Shdr *p_note0;
Shdr *p_note1;
Ehdr ehdri; // from input file
virtual Shdr const *getElfSections();
virtual int getStrategy(Filter &/*ft*/);
virtual bool is_valid_e_entry(Addr) = 0;
virtual bool has_valid_vmlinux_head() = 0;
virtual bool canPack();
virtual void pack(OutputFile *fo);
virtual int canUnpack(); // bool, except -1: format known, but not packed
virtual void unpack(OutputFile *fo);
virtual unsigned write_vmlinux_head(
OutputFile *const fo,
Shdr *const stxt
) = 0;
static int __acc_cdecl_qsort compare_Phdr(void const *aa, void const *bb);
};
class PackVmlinuxI386 : public PackVmlinuxBase<ElfClass_LE32>
{
typedef PackVmlinuxBase<ElfClass_LE32> super;
public:
PackVmlinuxI386(InputFile *f) : super(f, Ehdr::EM_386,
Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "startup_32") { }
virtual int getFormat() const { return UPX_F_VMLINUX_i386; }
virtual const char *getName() const { return "vmlinux/386"; }
virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.vmlinux"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
protected:
virtual void buildLoader(const Filter *ft);
virtual void defineDecompressorSymbols();
virtual Linker* newLinker() const;
virtual bool is_valid_e_entry(Addr);
virtual bool has_valid_vmlinux_head();
virtual unsigned write_vmlinux_head(
OutputFile *const fo,
Shdr *const stxt
);
};
class PackVmlinuxARM : public PackVmlinuxBase<ElfClass_LE32>
{
typedef PackVmlinuxBase<ElfClass_LE32> super;
public:
PackVmlinuxARM(InputFile *f) : super(f, Ehdr::EM_ARM,
Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "decompress_kernel") { }
virtual int getFormat() const { return UPX_F_VMLINUX_ARM; }
virtual const char *getName() const { return "vmlinux/ARM"; }
virtual const char *getFullName(const options_t *) const { return "arm-linux.kernel.vmlinux"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
protected:
virtual void buildLoader(const Filter *ft);
virtual void defineDecompressorSymbols();
virtual Linker* newLinker() const;
virtual bool is_valid_e_entry(Addr);
virtual bool has_valid_vmlinux_head();
virtual unsigned write_vmlinux_head(
OutputFile *const fo,
Shdr *const stxt
);
};
class PackVmlinuxAMD64 : public PackVmlinuxBase<ElfClass_LE64>
{
typedef PackVmlinuxBase<ElfClass_LE64> super;
public:
PackVmlinuxAMD64(InputFile *f) : super(f, Ehdr::EM_X86_64,
Ehdr::ELFCLASS64, Ehdr::ELFDATA2LSB, "startup_32") { }
virtual int getFormat() const { return UPX_F_VMLINUX_AMD64; }
virtual const char *getName() const { return "vmlinux/AMD64"; }
virtual const char *getFullName(const options_t *) const { return "amd64-linux.kernel.vmlinux"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
protected:
virtual void buildLoader(const Filter *ft);
virtual void defineDecompressorSymbols();
virtual Linker* newLinker() const;
virtual bool is_valid_e_entry(Addr);
virtual bool has_valid_vmlinux_head();
virtual unsigned write_vmlinux_head(
OutputFile *const fo,
Shdr *const stxt
);
};
+58 -57
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -38,7 +38,6 @@
static const
#include "stub/i386-linux.kernel.vmlinuz.h"
static const unsigned kernel_entry = 0x100000;
static const unsigned stack_offset_during_uncompression = 0x9000;
// add to "real mode pointer" in %esi; total 0x99000 is typical
@@ -52,8 +51,9 @@ static const unsigned bzimage_offset = 0x100000;
**************************************************************************/
PackVmlinuzI386::PackVmlinuzI386(InputFile *f) :
super(f)
super(f), physical_start(0x100000)
{
bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(boot_sect_t) == 0x218);
}
@@ -67,9 +67,9 @@ const int *PackVmlinuzI386::getCompressionMethods(int method, int level) const
const int *PackVmlinuzI386::getFilters() const
{
static const int filters[] = {
0x49,
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
-1 };
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters;
}
@@ -100,7 +100,7 @@ int PackVmlinuzI386::readFileHeader()
return 0;
int format = UPX_F_VMLINUZ_i386;
unsigned sys_size = ALIGN_UP(file_size, 16) - setup_size;
unsigned sys_size = ALIGN_UP((unsigned) file_size, 16u) - setup_size;
const unsigned char *p = (const unsigned char *) &h + 0x1e3;
@@ -133,7 +133,17 @@ int PackVmlinuzI386::decompressKernel()
fi->seek(0, SEEK_SET);
fi->readx(obuf, file_size);
checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, 1024));
// Find "ljmp $__BOOT_CS,$__PHYSICAL_START" if any.
// See startup_32: in linux/arch/i386/boot/compressed/head.S
char const *p = (char const *)&obuf[setup_size];
for (int j= 0; j < 0x200; ++j, ++p)
if (0==memcmp("\xEA\x00\x00", p, 3) && 0==(0xf & p[3]) && 0==p[4]) {
/* whole megabyte < 16MB */
physical_start = get_le32(1+ p);
break;
}
checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024));
for (int gzoff = setup_size; gzoff < file_size; gzoff++)
{
@@ -198,7 +208,7 @@ int PackVmlinuzI386::decompressKernel()
if (fd_pos != file_size)
{
//printf("fd_pos: %ld, file_size: %ld\n", (long)fd_pos, (long)file_size);
throwCantPack("trailing bytes after kernel image; use option `-f' to force packing");
throwCantPack("trailing bytes after kernel image; use option '-f' to force packing");
}
@@ -209,8 +219,15 @@ int PackVmlinuzI386::decompressKernel()
if (memcmp(ibuf, "\xFC\x0F\x01", 3) == 0) goto head_ok;
// 2.6.x+grsecurity+strongswan+openwall+trustix: ljmp $0x10,...
if (ibuf[0] == 0xEA && memcmp(ibuf+5, "\x10\x00", 2) == 0) goto head_ok;
// x86_64 2.6.x
if (0xB8==ibuf[0] // mov $...,%eax
&& 0x8E==ibuf[5] && 0xD8==ibuf[6] // mov %eax,%ds
&& 0x0F==ibuf[7] && 0x01==ibuf[8] && 020==(070 & ibuf[9]) // lgdtl
&& 0xB8==ibuf[14] // mov $...,%eax
&& 0x0F==ibuf[19] && 0xA2==ibuf[20] // cpuid
) goto head_ok;
throwCantPack("unrecognized kernel architecture; use option `-f' to force packing");
throwCantPack("unrecognized kernel architecture; use option '-f' to force packing");
head_ok:
// FIXME: more checks for special magic bytes in ibuf ???
@@ -253,11 +270,12 @@ Linker* PackVmlinuzI386::newLinker() const
// vmlinuz specific
**************************************************************************/
int PackVmlinuzI386::buildLoader(const Filter *ft)
void PackVmlinuzI386::buildLoader(const Filter *ft)
{
// prepare loader
initLoader(nrv_loader, sizeof(nrv_loader));
initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz));
addLoader("LINUZ000",
ph.first_offset_found == 1 ? "LINUZ001" : "",
ft->id ? "LZCALLT1" : "",
"LZIMAGE0",
getDecompressorSections(),
@@ -270,24 +288,9 @@ int PackVmlinuzI386::buildLoader(const Filter *ft)
addFilter32(ft->id);
}
addLoader("LINUZ990,IDENTSTR,UPX1HEAD", NULL);
freezeLoader();
return getLoaderSize();
}
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
{
if (ft->id == 0)
return false;
assert(ft->calls > 0);
linker->defineSymbol("filter_cto", ft->cto);
linker->defineSymbol("filter_length",
(ft->id & 0xf) % 3 == 0 ? ft->calls :
ft->lastcall - ft->calls * 4);
return true;
}
void PackVmlinuzI386::pack(OutputFile *fo)
{
readKernel();
@@ -295,29 +298,29 @@ void PackVmlinuzI386::pack(OutputFile *fo)
// prepare filter
Filter ft(ph.level);
ft.buf_len = ph.u_len;
ft.addvalue = kernel_entry; // saves 4 bytes in unfilter code
ft.addvalue = physical_start; // saves 4 bytes in unfilter code
// compress
upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 512, 0, NULL, &cconf);
compressWithFilters(&ft, 512, &cconf);
const unsigned lsize = getLoaderSize();
defineFilterSymbols(linker, &ft);
defineDecompressorSymbols();
defineFilterSymbols(&ft);
linker->defineSymbol("src_for_decompressor", zimage_offset + lsize);
linker->defineSymbol("original_entry", kernel_entry);
linker->defineSymbol("original_entry", physical_start);
linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
linker->relocate();
relocateLoader();
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16) / 16;
bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16u) / 16;
fo->write(setup_buf, setup_buf.getSize());
fo->write(loader, lsize);
@@ -341,11 +344,12 @@ void PackVmlinuzI386::pack(OutputFile *fo)
// bvmlinuz specific
**************************************************************************/
int PackBvmlinuzI386::buildLoader(const Filter *ft)
void PackBvmlinuzI386::buildLoader(const Filter *ft)
{
// prepare loader
initLoader(nrv_loader, sizeof(nrv_loader));
initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz));
addLoader("LINUZ000",
ph.first_offset_found == 1 ? "LINUZ001" : "",
(0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""),
"LBZIMAGE,IDENTSTR",
"+40", // align the stuff to 4 byte boundary
@@ -371,8 +375,6 @@ int PackBvmlinuzI386::buildLoader(const Filter *ft)
addFilter32(ft->id);
}
addLoader("LINUZ990", NULL);
freezeLoader();
return getLoaderSize();
}
@@ -383,26 +385,28 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
// prepare filter
Filter ft(ph.level);
ft.buf_len = ph.u_len;
ft.addvalue = kernel_entry; // saves 4 bytes in unfilter code
ft.addvalue = physical_start; // saves 4 bytes in unfilter code
upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 512, 0, NULL, &cconf);
compressWithFilters(&ft, 512, &cconf);
// align everything to dword boundary - it is easier to handle
unsigned c_len = ph.c_len;
memset(obuf + c_len, 0, 4);
c_len = ALIGN_UP(c_len, 4);
c_len = ALIGN_UP(c_len, 4u);
const unsigned lsize = getLoaderSize();
if (ph.method == M_LZMA) {
if (M_IS_LZMA(ph.method)) {
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
unsigned const properties = // lc, lp, pb, dummy
acc_uint32e_t properties = // lc, lp, pb, dummy
(res->lit_context_bits << 0) |
(res->lit_pos_bits << 8) |
(res->pos_bits << 16);
if (linker->bele->isBE()) // big endian - bswap32
acc_swab32s(&properties);
linker->defineSymbol("lzma_properties", properties);
// -2 for properties
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
@@ -414,33 +418,30 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
const int e_len = getLoaderSectionStart("LZCUTPOI");
assert(e_len > 0);
const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4);
const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16);
const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4u);
const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16u);
const unsigned copy_size = c_len + d_len4;
const unsigned edi = decompr_pos + d_len4 - 4; // copy to
const unsigned esi = ALIGN_UP(c_len + lsize, 4) - 4; // copy from
const unsigned esi = ALIGN_UP(c_len + lsize, 4u) - 4; // copy from
linker->defineSymbol("decompressor", decompr_pos);
linker->defineSymbol("src_for_decompressor", bzimage_offset + decompr_pos - c_len);
linker->defineSymbol("decompressor", decompr_pos - bzimage_offset + physical_start);
linker->defineSymbol("src_for_decompressor", physical_start + decompr_pos - c_len);
linker->defineSymbol("words_to_copy", copy_size / 4);
linker->defineSymbol("copy_dest", bzimage_offset + edi);
linker->defineSymbol("copy_dest", physical_start + edi);
linker->defineSymbol("copy_source", bzimage_offset + esi);
defineFilterSymbols(linker, &ft);
if (0x40==(0xf0 & ft.id)) {
linker->defineSymbol("filter_length", ph.u_len); // redefine
}
defineFilterSymbols(&ft);
defineDecompressorSymbols();
linker->defineSymbol("original_entry", kernel_entry);
linker->defineSymbol("original_entry", physical_start);
linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
linker->relocate();
relocateLoader();
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
bs->sys_size = (ALIGN_UP(lsize + c_len, 16) / 16) & 0xffff;
bs->sys_size = (ALIGN_UP(lsize + c_len, 16u) / 16) & 0xffff;
fo->write(setup_buf, setup_buf.getSize());
fo->write(loader, e_len);
@@ -493,7 +494,7 @@ void PackVmlinuzI386::unpack(OutputFile *fo)
// unfilter
Filter ft(ph.level);
ft.init(ph.filter, kernel_entry);
ft.init(ph.filter, physical_start);
ft.cto = (unsigned char) ph.filter_cto;
ft.unfilter(obuf, ph.u_len);
+9 -5
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -42,6 +42,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_VMLINUZ_i386; }
virtual const char *getName() const { return "vmlinuz/386"; }
virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.vmlinuz"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -56,7 +57,7 @@ protected:
virtual int decompressKernel();
virtual void readKernel();
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
// virtual const upx_byte *getLoader() const;
@@ -86,6 +87,7 @@ protected:
MemBuffer setup_buf;
int setup_size;
unsigned physical_start;
};
@@ -100,11 +102,12 @@ public:
PackBvmlinuzI386(InputFile *f) : super(f) { }
virtual int getFormat() const { return UPX_F_BVMLINUZ_i386; }
virtual const char *getName() const { return "bvmlinuz/386"; }
virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.bvmlinuz"; }
virtual void pack(OutputFile *fo);
protected:
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
};
@@ -119,6 +122,7 @@ public:
PackElks8086(InputFile *f) : super(f) { }
virtual int getFormat() const { return UPX_F_ELKS_8086; }
virtual const char *getName() const { return "elks/8086"; }
virtual const char *getFullName(const options_t *) const { return "i086-elks ???"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -131,7 +135,7 @@ protected:
virtual int decompressKernel();
virtual void readKernel();
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
};
+4 -4
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -39,7 +39,7 @@ class PackVxd : public PackWcle
typedef PackWcle super;
public:
PackVxd(InputFile *f);
~PackVxd();
virtual ~PackVxd();
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_VXD_LE; }
virtual const char *getName() const { return "vxd/le"; }
@@ -59,7 +59,7 @@ protected:
virtual void encodeFixups();
virtual void decodeFixups();
virtual void encodeImage(const Filter *ft);
virtual void encodeImage(Filter *ft);
virtual void decodeImage();
};
+4 -5
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -41,6 +41,7 @@
PackW16Ne::PackW16Ne(InputFile *f) :
super(f)
{
bele = &N_BELE_RTP::le_policy;
}
@@ -57,7 +58,7 @@ const int *PackW16Ne::getFilters() const
}
int PackW16Ne::buildLoader(const Filter *ft)
void PackW16Ne::buildLoader(const Filter *ft)
{
// prepare loader
// initLoader(nrv_loader,sizeof(nrv_loader));
@@ -68,8 +69,6 @@ int PackW16Ne::buildLoader(const Filter *ft)
// addLoader("...");
}
//
freezeLoader();
return getLoaderSize();
}
+4 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -42,6 +42,7 @@ public:
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_WIN16_NE; }
virtual const char *getName() const { return "win16/ne"; }
virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_286 ? "i286-win16.ne" : "i386-win16.ne"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -54,7 +55,7 @@ public:
protected:
virtual int readFileHeader(void);
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
};
+40 -57
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -120,6 +120,7 @@ PackW32Pe::PackW32Pe(InputFile *f) : super(f)
{
oloadconf = NULL;
soloadconf = 0;
isrtm = false;
use_dep_hack = true;
use_clear_dirty_stack = true;
}
@@ -141,8 +142,9 @@ const int *PackW32Pe::getCompressionMethods(int method, int level) const
const int *PackW32Pe::getFilters() const
{
static const int filters[] = {
0x26, 0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
-1 };
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters;
}
@@ -167,20 +169,6 @@ int PackW32Pe::readFileHeader()
}
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
{
if (ft->id == 0)
return false;
assert(ft->calls > 0);
linker->defineSymbol("filter_cto", ft->cto);
linker->defineSymbol("filter_length",
(ft->id & 0xf) % 3 == 0 ? ft->calls :
ft->lastcall - ft->calls * 4);
return true;
}
/*************************************************************************
// import handling
**************************************************************************/
@@ -529,13 +517,13 @@ void PackW32Pe::processLoadConf(Reloc *rel, const Interval *iv,
bool PackW32Pe::canPack()
{
if (!readFileHeader())
if (!readFileHeader() || ih.cpu < 0x14c || ih.cpu > 0x150)
return false;
return true;
}
int PackW32Pe::buildLoader(const Filter *ft)
void PackW32Pe::buildLoader(const Filter *ft)
{
// recompute tlsindex (see pack() below)
unsigned tmp_tlsindex = tlsindex;
@@ -545,12 +533,13 @@ int PackW32Pe::buildLoader(const Filter *ft)
tmp_tlsindex = 0;
// prepare loader
initLoader(nrv_loader, sizeof(nrv_loader), 2);
initLoader(stub_i386_win32_pe, sizeof(stub_i386_win32_pe), 2);
addLoader(isdll ? "PEISDLL1" : "",
"PEMAIN01",
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
tmp_tlsindex ? "PETLSHAK" : "",
"PEMAIN02",
ph.first_offset_found == 1 ? "PEMAIN03" : "",
getDecompressorSections(),
/*multipass ? "PEMULTIP" : */ "",
"PEMAIN10",
@@ -598,8 +587,6 @@ int PackW32Pe::buildLoader(const Filter *ft)
"IDENTSTR,UPX1HEAD",
NULL
);
freezeLoader();
return getLoaderSize();
}
@@ -650,7 +637,7 @@ void PackW32Pe::pack(OutputFile *fo)
if (ih.entry && ih.entry < rvamin)
throwCantPack("run a virus scanner on this file!");
if (!opt->force && ih.subsystem == 1)
throwCantPack("subsystem `native' is not supported (try --force)");
throwCantPack("subsystem 'native' is not supported (try --force)");
if (ih.filealign < 0x200)
throwCantPack("filealign < 0x200 is not yet supported");
@@ -723,9 +710,9 @@ void PackW32Pe::pack(OutputFile *fo)
const unsigned dllstrings = processImports();
processTls(&tlsiv); // call before processRelocs!!
processLoadConf(&loadconfiv);
processResources(&res);
processExports(&xport);
processLoadConf(&loadconfiv);
processRelocs();
//OutputFile::dump("x1", ibuf, usize);
@@ -795,17 +782,17 @@ void PackW32Pe::pack(OutputFile *fo)
ft.buf_len = ih.codesize;
ft.addvalue = ih.codebase - rvamin;
// compress
int strategy = allow_filter ? 0 : -3;
int filter_strategy = allow_filter ? 0 : -3;
// disable filters for files with broken headers
if (ih.codebase + ih.codesize > ph.u_len)
{
ft.buf_len = 1;
strategy = -3;
filter_strategy = -3;
}
compressWithFilters(&ft, 2048, strategy,
NULL, NULL, ih.codebase, rvamin);
compressWithFilters(&ft, 2048, NULL_cconf, filter_strategy,
ih.codebase, rvamin, 0, NULL, 0);
// info: see buildLoader()
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
@@ -819,12 +806,14 @@ void PackW32Pe::pack(OutputFile *fo)
pe_section_t osection[3];
// section 0 : bss
// 1 : [ident + header] + packed_data + unpacker + tls
// 1 : [ident + header] + packed_data + unpacker + tls + loadconf
// 2 : not compressed data
// section 2 should start with the resource data, because lots of lame
// windoze codes assume that resources starts on the beginning of a section
// note: there should be no data in section 2 which needs fixup
// identsplit - number of ident + (upx header) bytes to put into the PE header
int identsplit = pe_offset + sizeof(osection) + sizeof(oh);
if ((identsplit & 0x1ff) == 0)
@@ -838,7 +827,7 @@ void PackW32Pe::pack(OutputFile *fo)
const unsigned c_len = ((ph.c_len + ic) & 15) == 0 ? ph.c_len : ph.c_len + 16 - ((ph.c_len + ic) & 15);
obuf.clear(ph.c_len, c_len - ph.c_len);
const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4) + sotls;
const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4u) + sotls + soloadconf;
const unsigned s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1;
const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1;
@@ -866,13 +855,6 @@ void PackW32Pe::pack(OutputFile *fo)
// rva of the most significant byte of member "flags" in section "UPX0"
const unsigned swri = pe_offset + sizeof(oh) + sizeof(pe_section_t) - 1;
#if 0
if (swri >= 0x1000)
throwCantPack("swri >= 0x1000! Send a bug report please!");
patch_le32(loader, codesize, "SWRI", swri);
patch_le32(loader, codesize, "IMGL", 0x1000); // one page
patch_le32(loader, codesize, "IMGB", 0u - rvamin);
#else
// make sure we only touch the minimum number of pages
const unsigned addr = 0u - rvamin + swri;
linker->defineSymbol("swri", addr & 0xfff); // page offset
@@ -881,7 +863,6 @@ void PackW32Pe::pack(OutputFile *fo)
linker->defineSymbol("vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ?
0x2000 : 0x1000); // 2 pages or 1 page
linker->defineSymbol("vp_base", addr &~ 0xfff); // page mask
#endif
linker->defineSymbol("VirtualProtect", myimport + get_le32(oimpdlls + 16) + 8);
}
linker->defineSymbol("reloc_delt", 0u - (unsigned) ih.imagebase - rvamin);
@@ -892,15 +873,14 @@ void PackW32Pe::pack(OutputFile *fo)
linker->defineSymbol("LoadLibraryA", myimport + get_le32(oimpdlls + 16));
linker->defineSymbol("start_of_imports", myimport);
linker->defineSymbol("compressed_imports", cimports);
#if 0
patch_le32(loader, codesize, "VALL", myimport + get_le32(oimpdlls + 16) + 12);
patch_le32(loader, codesize, "VFRE", myimport + get_le32(oimpdlls + 16) + 16);
linker->defineSymbol("VirtualAlloc", myimport + get_le32(oimpdlls + 16) + 12);
linker->defineSymbol("VirtualFree", myimport + get_le32(oimpdlls + 16) + 16);
#endif
defineFilterSymbols(linker, &ft);
linker->defineSymbol("filter_buffer_start", ih.codebase - rvamin);
defineDecompressorSymbols();
defineFilterSymbols(&ft);
linker->defineSymbol("filter_buffer_start", ih.codebase - rvamin);
// in case of overlapping decompression, this hack is needed,
// because windoze zeroes the word pointed by tlsindex before
@@ -917,7 +897,8 @@ void PackW32Pe::pack(OutputFile *fo)
linker->defineSymbol("start_of_compressed", esi0 + ih.imagebase);
linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);
linker->relocate();
//linker->dumpSymbols();
relocateLoader();
const unsigned lsize = getLoaderSize();
MemBuffer loader(lsize);
@@ -944,14 +925,19 @@ void PackW32Pe::pack(OutputFile *fo)
ODADDR(PEDIR_BOUNDIM) = 0;
ODSIZE(PEDIR_BOUNDIM) = 0;
// tls is put into section 1
// tls & loadconf are put into section 1
ic = s1addr + s1size - sotls;
ic = s1addr + s1size - sotls - soloadconf;
processTls(&rel,&tlsiv,ic);
ODADDR(PEDIR_TLS) = sotls ? ic : 0;
ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0;
ic += sotls;
processLoadConf(&rel, &loadconfiv, ic);
ODADDR(PEDIR_LOADCONF) = soloadconf ? ic : 0;
ODSIZE(PEDIR_LOADCONF) = soloadconf;
ic += soloadconf;
// these are put into section 2
ic = ncsection;
@@ -976,19 +962,13 @@ void PackW32Pe::pack(OutputFile *fo)
}
ic += soexport;
processLoadConf(&rel, &loadconfiv, ic);
ODADDR(PEDIR_LOADCONF) = soloadconf ? ic : 0;
ODSIZE(PEDIR_LOADCONF) = soloadconf;
ic += soloadconf;
processRelocs(&rel);
ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0;
ODSIZE(PEDIR_RELOC) = soxrelocs;
ic += soxrelocs;
// this is computed here, because soxrelocs changes some lines above
const unsigned ncsize = soresources + soimpdlls + soexport + soloadconf
+ soxrelocs;
const unsigned ncsize = soresources + soimpdlls + soexport + soxrelocs;
ic = oh.filealign - 1;
// this one is tricky: it seems windoze touches 4 bytes after
@@ -1070,12 +1050,12 @@ void PackW32Pe::pack(OutputFile *fo)
if ((ic = fo->getBytesWritten() & 3) != 0)
fo->write(ibuf,4 - ic);
fo->write(otls,sotls);
fo->write(oloadconf, soloadconf);
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
fo->write(ibuf,oh.filealign - ic);
fo->write(oresources,soresources);
fo->write(oimpdlls,soimpdlls);
fo->write(oexport,soexport);
fo->write(oloadconf, soloadconf);
fo->write(oxrelocs,soxrelocs);
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
@@ -1175,7 +1155,8 @@ int PackW32Pe::canUnpack()
void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
{
if (ODADDR(PEDIR_IMPORT) == 0)
if (ODADDR(PEDIR_IMPORT) == 0
|| ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
return;
// const upx_byte * const idata = obuf + get_le32(extrainfo);
@@ -1193,6 +1174,7 @@ void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
for (p = idata; get_le32(p) != 0; ++p)
{
const upx_byte *dname = get_le32(p) + import;
ICHECK(dname, 1);
const unsigned dlen = strlen(dname);
ICHECK(dname, dlen + 1);
@@ -1205,7 +1187,7 @@ void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
else
p += 5;
}
sdllnames = ALIGN_UP(sdllnames,2);
sdllnames = ALIGN_UP(sdllnames, 2u);
upx_byte * const Obuf = obuf - rvamin;
import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
@@ -1218,6 +1200,7 @@ void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
{
// restore the name of the dll
const upx_byte *dname = get_le32(p) + import;
ICHECK(dname, 1);
const unsigned dlen = strlen(dname);
ICHECK(dname, dlen + 1);
+7 -7
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -35,13 +35,14 @@
class PackW32Pe : public PeFile
{
typedef PeFile super;;
typedef PeFile super;
public:
PackW32Pe(InputFile *f);
~PackW32Pe();
virtual ~PackW32Pe();
virtual int getFormat() const { return UPX_F_WIN32_PE; }
virtual const char *getName() const { return isrtm ? "rtm32/pe" : "win32/pe"; }
virtual const char *getFullName(const options_t *) const { return "i386-win32.pe"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
@@ -53,11 +54,9 @@ public:
protected:
virtual int readFileHeader();
virtual int buildLoader(const Filter *ft);
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
bool isrtm;
virtual unsigned processImports();
virtual void processImports(unsigned, unsigned);
virtual void rebuildImports(upx_byte *&);
@@ -67,6 +66,7 @@ protected:
upx_byte *oloadconf;
unsigned soloadconf;
bool isrtm;
bool use_dep_hack;
bool use_clear_dirty_stack;
};
+34 -42
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2007 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@@ -76,8 +76,9 @@ const int *PackWcle::getCompressionMethods(int method, int level) const
const int *PackWcle::getFilters() const
{
static const int filters[] = {
0x26, 0x24, 0x14, 0x11, 0x16, 0x13, 0x25, 0x12, 0x15,
-1 };
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters;
}
@@ -88,11 +89,13 @@ Linker* PackWcle::newLinker() const
}
int PackWcle::buildLoader(const Filter *ft)
void PackWcle::buildLoader(const Filter *ft)
{
// prepare loader
initLoader(nrv_loader,sizeof(nrv_loader));
addLoader("IDENTSTR,WCLEMAIN,UPX1HEAD,WCLECUTP", NULL);
initLoader(stub_i386_dos32_watcom_le, sizeof(stub_i386_dos32_watcom_le));
addLoader("IDENTSTR,WCLEMAIN",
ph.first_offset_found == 1 ? "WCLEMAIN02" : "",
"WCLEMAIN03,UPX1HEAD,WCLECUTP", NULL);
// fake alignment for the start of the decompressor
linker->defineSymbol("WCLECUTP", 0x1000);
@@ -118,8 +121,6 @@ int PackWcle::buildLoader(const Filter *ft)
"WCLEMAI4",
NULL
);
freezeLoader();
return getLoaderSize();
}
@@ -142,20 +143,6 @@ bool PackWcle::canPack()
}
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
{
if (ft->id == 0)
return false;
assert(ft->calls > 0);
linker->defineSymbol("filter_cto", ft->cto);
linker->defineSymbol("filter_length",
(ft->id & 0xf) % 3 == 0 ? ft->calls :
ft->lastcall - ft->calls * 4);
return true;
}
/*************************************************************************
//
**************************************************************************/
@@ -430,7 +417,7 @@ void PackWcle::preprocessFixups()
#define RESERVED 0x1000
void PackWcle::encodeImage(const Filter *ft)
void PackWcle::encodeImage(Filter *ft)
{
// concatenate image & preprocessed fixups
unsigned isize = soimage + sofixups;
@@ -440,19 +427,23 @@ void PackWcle::encodeImage(const Filter *ft)
delete[] ifixups; ifixups = NULL;
// compress
oimage.allocForCompression(isize, RESERVED+512);
ph.filter = ft->id;
ph.filter_cto = ft->cto;
// prepare packheader
ph.u_len = isize;
// reserve RESERVED bytes for the decompressor
if (!compress(ibuf,oimage+RESERVED))
throwNotCompressible();
ph.overlap_overhead = findOverlapOverhead(oimage+RESERVED, 512);
buildLoader(ft);
// prepare filter [already done]
// compress
upx_compress_config_t cconf; cconf.reset();
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(ibuf, isize,
oimage + RESERVED,
ibuf + ft->addvalue, ft->buf_len,
NULL, 0,
ft, 512, &cconf, 0);
ibuf.dealloc();
soimage = (ph.c_len + 3) &~ 3;
soimage = ph.c_len;
while (soimage & 3)
oimage[RESERVED + soimage++] = 0;
}
@@ -506,15 +497,13 @@ void PackWcle::pack(OutputFile *fo)
ifixups[sofixups+12] = (unsigned char) (unsigned) objects;
sofixups += 13;
// filter
// prepare filter
Filter ft(ph.level);
tryFilters(&ft, iimage+text_vaddr, text_size, text_vaddr);
ft.buf_len = text_size;
ft.addvalue = text_vaddr;
// compress
encodeImage(&ft);
// verify filter
ft.verifyUnfilter();
const unsigned lsize = getLoaderSize();
neweip = getLoaderSection("WCLEMAIN");
int e_len = getLoaderSectionStart("WCLECUTP");
@@ -546,16 +535,16 @@ void PackWcle::pack(OutputFile *fo)
linker->defineSymbol("original_stack", ih.init_esp_offset +
IOT(ih.init_ss_object - 1, my_base_address));
linker->defineSymbol("start_of_relocs", mps*pages);
defineFilterSymbols(linker, &ft);
linker->defineSymbol("filter_buffer_start", text_vaddr);
defineDecompressorSymbols();
defineFilterSymbols(&ft);
linker->defineSymbol("filter_buffer_start", text_vaddr);
unsigned jpos = (((ph.c_len + 3) &~ 3) + d_len + 3) / 4;
linker->defineSymbol("words_to_copy", jpos);
linker->defineSymbol("copy_dest", ((ic + d_len + 3) &~ 3) - 4);
linker->defineSymbol("copy_source", e_len + jpos * 4 - 4);
linker->relocate();
relocateLoader();
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
@@ -566,6 +555,9 @@ void PackWcle::pack(OutputFile *fo)
writeFile(fo, opt->watcom_le.le);
// verify
verifyOverlappingDecompression(oimage + e_len, oimage.getSize() - e_len);
// copy the overlay
const unsigned overlaystart = ih.data_pages_offset + exe_offset
+ getImageSize();

Some files were not shown because too many files have changed in this diff Show More