Compare commits

...

181 Commits

Author SHA1 Message Date
Markus F.X.J. Oberhumer f37a7811f9 Merge. 2007-03-08 03:00:00 +01:00
László Molnár 9173c10239 yet another spelling fix 2007-03-07 17:00:18 +01:00
László Molnár 318b31550d spelling fixes 2007-03-07 14:22:37 +01:00
Markus F.X.J. Oberhumer c18ebc63a6 dos/exe: enable optimized code paths. 2007-03-06 18:14:32 +01:00
Markus F.X.J. Oberhumer d704694272 Merge. 2007-03-06 15:57:13 +01:00
Markus F.X.J. Oberhumer 1cfec3bdf7 dos/exe: enable one small optimization. 2007-03-06 15:56:51 +01:00
John Reiser fe6ea6bc10 merge 2007-03-06 06:44:26 -08:00
Markus F.X.J. Oberhumer d29c8df45e dos/exe improvements, not enabled yet. 2007-03-06 15:08:24 +01:00
John Reiser 71f996af95 spelling 2007-03-05 21:26:36 -08:00
Markus F.X.J. Oberhumer d9722ad6b3 dos/exe: make sure minsp is even. 2007-03-04 19:27:04 +01:00
Markus F.X.J. Oberhumer 398fd8028c Spelling fixes. 2007-03-04 17:39:21 +01:00
Markus F.X.J. Oberhumer 1345a3cfd3 Bump tentative release date. 2007-03-04 17:13:11 +01:00
Markus F.X.J. Oberhumer 7eb0b195b8 dos/exe: don't clear the dirty stack - DOS does not do this either 2007-03-04 17:10:32 +01:00
Markus F.X.J. Oberhumer 009caee82d docs: typo fixes. 2007-03-04 17:01:50 +01:00
Markus F.X.J. Oberhumer 3bdc805a22 dos/exe: only use bx_magic when needed. 2007-03-04 17:01:32 +01:00
Markus F.X.J. Oberhumer ac457792b4 Minor dos/exe stub optimizations. 2007-03-04 16:47:13 +01:00
Markus F.X.J. Oberhumer 1377b54b9e dos/exe: optimize M_PIA_small. 2007-03-04 15:20:09 +01:00
Markus F.X.J. Oberhumer 66418ffc8c Reorganize dos/exe. No stub changes. 2007-03-04 15:14:44 +01:00
László Molnár b4c4b1fb70 dos/exe: fixed a bug in relocation handling 2007-03-01 16:57:12 +01:00
Markus F.X.J. Oberhumer ffe4a4b047 dos/exe: clear the dirty stack. 2007-02-26 13:55:12 +01:00
László Molnár 753ce45310 dos/exe: better minsp approximation 2007-02-26 12:54:49 +01:00
Markus F.X.J. Oberhumer fece0d73e7 Update NEWS. Bump version date. 2007-02-26 01:37:03 +01:00
Markus F.X.J. Oberhumer edce076e68 Minor Makefile updates. 2007-02-26 01:33:08 +01:00
Markus F.X.J. Oberhumer 675d0a009a Use M_IS_LZMA. 2007-02-26 01:32:36 +01:00
Markus F.X.J. Oberhumer 5d41b5a4db Fix shld macro. 2007-02-26 00:52:18 +01:00
László Molnár fe53b135eb pe: better icon compression handling 2007-02-24 23:25:11 +01:00
László Molnár 5b1c154ee2 NEWS update 2007-02-23 13:46:52 +01:00
László Molnár 816d882611 dos/exe: nrv2b compressed lzma decompressor added 2007-02-23 13:34:12 +01:00
Markus F.X.J. Oberhumer 12bcb09051 Small Makefile updates. 2007-02-21 17:11:42 +01:00
László Molnár c59c69a85f p_exe.cpp: added some comments 2007-02-20 13:49:18 +01:00
Markus F.X.J. Oberhumer bdd0daaf6f Added ElfLinker::addLoaderVA(). 2007-02-20 07:36:34 +01:00
Markus F.X.J. Oberhumer cfad7c8356 Small cleanups. 2007-02-19 03:52:33 +01:00
John Reiser b2b8a128d0 merge 2007-02-18 10:10:17 -08:00
Markus F.X.J. Oberhumer 1cfad80ca2 Introduce a special "ignore_reloc_overflow" section. 2007-02-18 18:29:26 +01:00
John Reiser a5a80e41b8 merge 2007-02-18 09:09:17 -08:00
Markus F.X.J. Oberhumer 152f8e92bf Yet some more Watcom optimizations. 2007-02-18 05:43:31 +01:00
Markus F.X.J. Oberhumer 0323560b49 More Watcom optimizations. 2007-02-18 04:41:33 +01:00
Markus F.X.J. Oberhumer d3bc84a2f7 Some Watcom optimizations. 2007-02-18 03:55:46 +01:00
Markus F.X.J. Oberhumer 8a82c259bd Switching back to using Watcom C - this seems to work. 2007-02-18 03:02:00 +01:00
Markus F.X.J. Oberhumer 46009c7658 i086 Makefile.extra update. 2007-02-18 02:32:47 +01:00
Markus F.X.J. Oberhumer 6f760308bd Some cleanasm.py updates. 2007-02-18 01:32:30 +01:00
John Reiser c346f8f17d merge 2007-02-16 08:06:37 -08:00
John Reiser af1d059fff PackUnix::getLoader() result is not 'const' 2007-02-16 08:05:10 -08:00
John Reiser 5562b21a20 PackMach* checkAlreadyPacked() 2007-02-16 08:02:59 -08:00
Markus F.X.J. Oberhumer 8f68f31877 Use Wine + Digital Mars C/C++ in small model. Does not work yet. 2007-02-16 15:22:01 +01:00
Markus F.X.J. Oberhumer ce7e94030c Added i086/l_test.c. Cleanups. 2007-02-16 08:52:31 +01:00
Markus F.X.J. Oberhumer ccf5a1b972 Add some more funcs to cc_test.c. 2007-02-13 09:48:37 +01:00
Markus F.X.J. Oberhumer 0d5ae77efc Some more dos/exe updates. 2007-02-13 02:25:32 +01:00
Markus F.X.J. Oberhumer 1695096d18 Commit rebuilt files as well. 2007-02-13 00:39:43 +01:00
Markus F.X.J. Oberhumer 6db0b7cf18 lzma for dos/exe works! 2007-02-13 00:39:15 +01:00
John Reiser 575b43b0d4 NEWS: Mach/i386 and Mach/fat 2007-02-12 15:22:22 -08:00
László Molnár 7b39b05894 lzma for dos/exe seems to work with tainted watcom macros 2007-02-12 18:28:24 +01:00
László Molnár 8bea9e0a5e fixed some watcom support macros 2007-02-12 15:38:47 +01:00
László Molnár 2255b32e45 LZMA for dos/exe integration work. Does not work yet. 2007-02-12 15:12:36 +01:00
Markus F.X.J. Oberhumer b62573ae8f More work on lzma for dos/exe. 2007-02-11 21:20:00 +01:00
Markus F.X.J. Oberhumer 44ed84f5cf Added lzma for dos/exe. Glue code and integration is still missing. 2007-02-11 07:54:16 +01:00
Markus F.X.J. Oberhumer d008c834be Merge. 2007-02-11 04:52:53 +01:00
Markus F.X.J. Oberhumer 2d3a914aee Some i086 updates. 2007-02-11 04:52:33 +01:00
John Reiser 7324f4c3d1 PackMach* filters only the [1st] largest executable LC_SEGMNET 2007-02-10 17:47:04 -08:00
Markus F.X.J. Oberhumer 50c8860a50 Added first version of a clean-room wcc support library implementation. 2007-02-11 01:06:37 +01:00
Markus F.X.J. Oberhumer 6456de7188 i086: added cc_test for examining internal compiler library calls. 2007-02-11 01:02:36 +01:00
John Reiser 23c629f2aa i386-darwin.macho works! 2007-02-10 13:14:27 -08:00
John Reiser 2bf154f74f i386-darwin.macho: decompressor overrun, bswap Mach_fat_header 2007-02-10 10:57:02 -08:00
John Reiser b598ad1bc0 i386-darwin.macho runtime stub 2007-02-10 09:16:49 -08:00
Markus F.X.J. Oberhumer ace24ad68e Minor portability fixes. 2007-02-08 16:17:32 +01:00
Markus F.X.J. Oberhumer 750c1a0f27 Avoid compiler warnings. 2007-02-08 15:00:42 +01:00
John Reiser 52d89bd66b PackMachFat has trouble with --fileinfo 2007-02-07 22:24:42 -08:00
John Reiser 8cfb9d35e9 fix ui report after PackMachFat::unpack 2007-02-07 22:03:15 -08:00
John Reiser 2f529158a0 OutputFile::unset_extent() sets bytes_written 2007-02-07 22:02:28 -08:00
John Reiser 6e68ab6d9e canUnpack() and unpack() for PackMachBase, PackMachFat 2007-02-07 21:30:18 -08:00
John Reiser 7a3c55af35 fix SEEK_END when set_extent() 2007-02-07 21:21:19 -08:00
John Reiser fb39d6304a Enable --lzma for PackMach*. 2007-02-07 11:23:21 -08:00
John Reiser 4cb57d9059 OutputFile::unset_extent(); endianness in Mach_fat_* and PackMachBase::b_info 2007-02-06 13:11:31 -08:00
John Reiser 42d69bd0e5 debug PackMachFat 2007-02-05 22:34:23 -08:00
John Reiser f27b399f81 PackMachFat 2007-02-05 14:00:41 -08:00
John Reiser a545a3938f FileBase::set_extent(offset, length) constrains seek() and tell() 2007-02-03 13:31:44 -08:00
John Reiser d1e352c9ee PackMachI386 2007-02-03 11:40:25 -08:00
John Reiser 99be1e798b PackMachPPC32 2007-02-03 11:04:57 -08:00
John Reiser 2132a28a17 UPX_F_MACH_i386 and skeleton stub. (Much of PackMachI386 is incomplete.) 2007-02-02 13:51:51 -08:00
John Reiser 8b1cc28783 templates to prepare for Mach-O i386 and Universal ("fat") executables 2007-01-31 20:25:13 -08:00
Markus F.X.J. Oberhumer 78364ac830 Small Watcom updates. 2007-01-31 14:28:15 +01:00
Markus F.X.J. Oberhumer 6e5f5732b5 brandelf.py: do not write "Linux" any longer as newer ldd's (e.g.
from glibc-common-2.5-10.fc6) do not like this.
2007-01-31 05:58:17 +01:00
Markus F.X.J. Oberhumer 87844254d1 Minor Makefile updates. 2007-01-31 05:53:38 +01:00
Markus F.X.J. Oberhumer 08ef9f69fb Very minor portability fixes. 2007-01-30 20:36:59 +01:00
Markus F.X.J. Oberhumer 5fbd1b78e7 Added non-working experimental infrastructure for using OpenWatcom 1.6
to support i086 + lzma.
2007-01-30 20:25:20 +01:00
Markus F.X.J. Oberhumer 39f5eb753f Bump version for next release. 2007-01-23 22:17:02 +01:00
Markus F.X.J. Oberhumer f4cbe3f300 Added tag for RELEASE_292. 2007-01-23 22:13:01 +01:00
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
343 changed files with 38532 additions and 19432 deletions
+3
View File
@@ -2,11 +2,14 @@ syntax: regexp
^\.bzr ^\.bzr
^ChangeLog ^ChangeLog
^Makevars.global
^build ^build
^maint ^maint
syntax: glob syntax: glob
Makevars.local
*.a *.a
*.dll *.dll
*.lib *.lib
+2
View File
@@ -2,7 +2,9 @@
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190 223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194 2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196 2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200 70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201 a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193 a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195 b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables 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 http://upx.sourceforge.net
+14 -15
View File
@@ -1,8 +1,8 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. 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 General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by 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. your programs, too.
When we speak of free software, we are referring to freedom, not 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 The precise terms and conditions for copying, distribution and
modification follow. modification follow.
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 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 License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on does not normally print such an announcement, your work based on
the Program is not required to print an announcement.) the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program, identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in 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 access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not distribution of the source code, even though third parties are not
compelled to copy the source along with the object code. compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program 4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is 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 This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License. be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in 8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License 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. POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest 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. 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.> <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 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 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 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License along
along with this program; if not, write to the Free Software with this program; if not, write to the Free Software Foundation, Inc.,
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail. 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 If the program is interactive, make it output a short notice like this
when it starts in an interactive mode: 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'. Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details. 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 This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the 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. Public License instead of this License.
+5 -5
View File
@@ -8,6 +8,7 @@ export SHELL = /bin/sh
srcdir = . srcdir = .
top_srcdir = . top_srcdir = .
-include $(top_srcdir)/Makevars.global ./Makevars.local
# info: src/stub needs GNU make 3.81 and special build tools # info: src/stub needs GNU make 3.81 and special build tools
@@ -33,15 +34,14 @@ endif
$(MAKE) -C src $@ $(MAKE) -C src $@
$(MAKE) -C doc $@ $(MAKE) -C doc $@
# automatically generate ChangeLog from Mercurial repo
ChangeLog:
ifneq ($(wildcard .hg/data/.),) ifneq ($(wildcard .hg/data/.),)
# automatically generate ChangeLog from local Mercurial repo
ChangeLog:
hg log --style=changelog > $@ hg log --style=changelog > $@
else .PHONY: ChangeLog
@echo "UPX info: no hg repo found"
endif endif
.PHONY: default all mostlyclean clean distclean maintainer-clean .PHONY: default all mostlyclean clean distclean maintainer-clean
.PHONY: ChangeLog
+21 -3
View File
@@ -2,6 +2,22 @@
User visible changes for UPX User visible changes for UPX
================================================================== ==================================================================
Changes in 2.93 beta (08 Mar 2007):
* new formats Mach/i386 and Mach/fat support Mac OS X i686 and
Universal binaries [i686 and PowerPC only]
* dos/exe: LZMA is now also supported for 16-bit dos/exe. Please note that
you have to explicitly use '--lzma' even for '--ultra-brute' here
because runtime decompression is about 30 times slower than NRV -
which is really noticeable on old machines.
* dos/exe: fixed a rarely occuring bug in relocation handling
* win32/pe & arm/pe: better icon compression handling
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): Changes in 2.91 beta (29 Nov 2006):
* assorted bug fixes * assorted bug fixes
* arm/pe: fix "missing" icon & version info resource problem for wince 5 * arm/pe: fix "missing" icon & version info resource problem for wince 5
@@ -296,8 +312,8 @@ Changes in 0.80 (03 Aug 1999)
* win32/pe: even better TLS support * win32/pe: even better TLS support
* win32/pe: versioninfo works on NT * win32/pe: versioninfo works on NT
* win32/pe: import by ordinal from kernel32.dll works * win32/pe: import by ordinal from kernel32.dll works
* win32/pe: other import improvements: importing a nonexistant DLL * win32/pe: other import improvements: importing a nonexistent DLL
results in a usual Windows message, importing a nonexistant function results in a usual Windows message, importing a nonexistent function
results in program exit (instead of crash ;-) results in program exit (instead of crash ;-)
* win32/pe: new option: '--compress-resources=0' * win32/pe: new option: '--compress-resources=0'
* win32/pe: reduced memory requirement during uncompression, some * win32/pe: reduced memory requirement during uncompression, some
@@ -349,7 +365,7 @@ Changes in 0.60 (06 Mar 1999)
* win32/pe: fixed file corruption when the size of the export data is invalid * win32/pe: fixed file corruption when the size of the export data is invalid
* win32/pe: fixed a problem with empty resource data * win32/pe: fixed a problem with empty resource data
* win32/pe: compressed file alignment set to minimum value * win32/pe: compressed file alignment set to minimum value
* win32/pe: made all compressed sections writeable * win32/pe: made all compressed sections writable
* fixed some other win32/pe bugs * fixed some other win32/pe bugs
* fixed an address optimization problem for some not Watcom LE files * fixed an address optimization problem for some not Watcom LE files
* fixed a bug which could make UPX hang when an exe header contained * fixed a bug which could make UPX hang when an exe header contained
@@ -390,3 +406,5 @@ Changes in 0.20 (05 Jul 1998)
Changes in 0.05 (26 May 1998) Changes in 0.05 (26 May 1998)
* first public beta release * first public beta release
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables 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 http://upx.sourceforge.net
+5 -5
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables 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 http://upx.sourceforge.net
@@ -96,7 +96,7 @@ THE FUTURE
- We will *NOT* add any sort of protection and/or encryption. - We will *NOT* add any sort of protection and/or encryption.
This only gives people a false feeling of security because This only gives people a false feeling of security because
by definition all protectors/compressors can be broken. by definition all protectors/compressors can be broken.
And don't trust any advertisment of authors of other executable And don't trust any advertisement of authors of other executable
compressors about this topic - just do a websearch on "unpackers"... compressors about this topic - just do a websearch on "unpackers"...
- Fix all remaining bugs - keep your reports coming ;-) - Fix all remaining bugs - keep your reports coming ;-)
@@ -108,9 +108,9 @@ THE FUTURE
COPYRIGHT 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
This program may be used freely, and you are welcome to This program may be used freely, and you are welcome to
redistribute it under certain conditions. redistribute it under certain conditions.
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables 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 http://upx.sourceforge.net
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables 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 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: 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 - implement `--cpu=486' option to use bswap on the 32-bit formats
(if cpu >= 486) (if cpu >= 486)
- consider removing "or ebp,-1" when not needed
FORMAT DJGPP2/COFF FORMAT DJGPP2/COFF
================== ==================
@@ -86,10 +84,6 @@ FORMAT WATCOM/LE
- handle holes in the file - handle holes in the file
- implement compressWithFilters()
- add a call to verifyOverlappingDecompression()
FORMAT WIN16/NE FORMAT WIN16/NE
=============== ===============
+2 -2
View File
@@ -1,5 +1,5 @@
Decompressing ELF Directly to Memory on Linux/x86 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: References:
<elf.h> definitions for the ELF file format <elf.h> definitions for the ELF file format
@@ -57,7 +57,7 @@ Subroutine do_xmap() of src/stub/l_lx_elf.c performs the
"virtual execve()" using the compressed data as source, and stores "virtual execve()" using the compressed data as source, and stores
the decompressed bytes directly into the appropriate virtual addresses. the decompressed bytes directly into the appropriate virtual addresses.
Before transfering control to the PT_INTERP "program interpreter", Before transferring control to the PT_INTERP "program interpreter",
minor tricks are required to setup the Elf32_auxv_t entries, minor tricks are required to setup the Elf32_auxv_t entries,
clear the free portion of the stack (to compensate for ld-linux.so.2 clear the free portion of the stack (to compensate for ld-linux.so.2
assuming that its automatic stack variables are initialized to zero), assuming that its automatic stack variables are initialized to zero),
+1 -1
View File
@@ -45,6 +45,6 @@ These symbols can be defined later in C++ using
linker->defineSymbol("xx", yy) linker->defineSymbol("xx", yy)
This functionality (we could say it's a simple linker) is achived by This functionality (we could say it's a simple linker) is achieved by
compiling the assembly into an ELF object file which a little C++ compiling the assembly into an ELF object file which a little C++
module (src/linker.cpp) can interpret and work with. module (src/linker.cpp) can interpret and work with.
+27 -52
View File
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
=head1 ABSTRACT =head1 ABSTRACT
The Ultimate Packer for eXecutables 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 http://upx.sourceforge.net
@@ -175,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 files, but you definitely should use it when releasing a final version
of your program. of your program.
Quick start for achieving the best compression ratio: Quick info for achieving the best compression ratio:
=over 4
Try B<upx --brute myfile.exe>.
=back
Details for achieving the best compression ratio:
=over 4 =over 4
=item * =item *
Use the compression level B<--best>. Try B<upx --brute myfile.exe> or even B<upx --ultra-brute myfile.exe>.
=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>>.
=item * =item *
@@ -222,7 +197,7 @@ For win32/pe programs there's B<--strip-relocs=0>. See notes below.
=head1 OVERLAY HANDLING OPTIONS =head1 OVERLAY HANDLING OPTIONS
Info: An "overlay" means auxillary data atached after the logical end of Info: An "overlay" means auxiliary data attached after the logical end of
an executable, and it often contains application specific data an executable, and it often contains application specific data
(this is a common practice to avoid an extra data file, though (this is a common practice to avoid an extra data file, though
it would be better to use resource sections). it would be better to use resource sections).
@@ -370,7 +345,7 @@ Extra options available for this executable format:
First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has
the very bad habit of replacing your stub with its own (outdated) version. the very bad habit of replacing your stub with its own (outdated) version.
Additionally B<UPX> corrects a bug/feature in strip v2.8.x: it Additionally B<UPX> corrects a bug/feature in strip v2.8.x: it
will fix the 4 KByte aligment of the stub. will fix the 4 KByte alignment of the stub.
B<UPX> includes the full functionality of stubify. This means it will B<UPX> includes the full functionality of stubify. This means it will
automatically stubify your COFF files. Use the option B<--coff> to automatically stubify your COFF files. Use the option B<--coff> to
@@ -405,7 +380,7 @@ Extra options available for this executable format:
Introduction Introduction
Linux/386 support in UPX consists of 3 different executable formats, Linux/386 support in UPX consists of 3 different executable formats,
one optimized for ELF excutables ("linux/elf386"), one optimized one optimized for ELF executables ("linux/elf386"), one optimized
for shell scripts ("linux/sh386"), and one generic format for shell scripts ("linux/sh386"), and one generic format
("linux/386"). ("linux/386").
@@ -433,14 +408,14 @@ General user's overview
or network I/O. or network I/O.
Depending on the statistics of usage and access, and the relative Depending on the statistics of usage and access, and the relative
speeds of CPU, RAM, swap space, /tmp, and filesystem storage, then speeds of CPU, RAM, swap space, /tmp, and file system storage, then
invoking and running a compressed executable can be faster than invoking and running a compressed executable can be faster than
directly running the corresponding uncompressed program. directly running the corresponding uncompressed program.
The operating system might perfrom fewer expensive I/O operations The operating system might perform fewer expensive I/O operations
to invoke the compressed program. Paging to or from swap space to invoke the compressed program. Paging to or from swap space
or /tmp might be faster than paging from the general filesystem. or /tmp might be faster than paging from the general file system.
``Medium-sized'' programs which access about 1/3 to 1/2 of their ``Medium-sized'' programs which access about 1/3 to 1/2 of their
stored program bytes can do particulary well with compression. stored program bytes can do particularly well with compression.
Small programs tend not to benefit as much because the absolute Small programs tend not to benefit as much because the absolute
savings is less. Big programs tend not to benefit proportionally savings is less. Big programs tend not to benefit proportionally
because each invocation may use only a small fraction of the program, because each invocation may use only a small fraction of the program,
@@ -449,7 +424,7 @@ General user's overview
then compression may win anyway. then compression may win anyway.
Currently, executables compressed by UPX do not share RAM at runtime Currently, executables compressed by UPX do not share RAM at runtime
in the way that executables mapped from a filesystem do. As a in the way that executables mapped from a file system do. As a
result, if the same program is run simultaneously by more than one result, if the same program is run simultaneously by more than one
process, then using the compressed version will require more RAM and/or process, then using the compressed version will require more RAM and/or
swap space. So, shell programs (bash, csh, etc.) and ``make'' swap space. So, shell programs (bash, csh, etc.) and ``make''
@@ -538,7 +513,7 @@ The linux/elf386 format decompresses directly into RAM,
uses only one exec, does not use space in /tmp, uses only one exec, does not use space in /tmp,
and does not use /proc. and does not use /proc.
Linux/elf386 is automatically selected for Linux ELF exectuables. Linux/elf386 is automatically selected for Linux ELF executables.
Packed programs will be byte-identical to the original after uncompression. Packed programs will be byte-identical to the original after uncompression.
@@ -627,7 +602,7 @@ Extra options available for this executable format:
Please read the general Linux description first. Please read the general Linux description first.
The generic linux/386 format decompresses to /tmp and needs The generic linux/386 format decompresses to /tmp and needs
/proc filesystem support. It starts the decompressed program /proc file system support. It starts the decompressed program
via the execve() syscall. via the execve() syscall.
Linux/386 is only selected if the specialized linux/elf386 Linux/386 is only selected if the specialized linux/elf386
@@ -639,11 +614,11 @@ How it works:
For files which are not ELF and not a script for a known "-c" shell, For files which are not ELF and not a script for a known "-c" shell,
UPX uses kernel execve(), which first requires decompressing to a UPX uses kernel execve(), which first requires decompressing to a
temporary file in the filesystem. Interestingly - temporary file in the file system. Interestingly -
because of the good memory management of the Linux kernel - this because of the good memory management of the Linux kernel - this
often does not introduce a noticable delay, and in fact there often does not introduce a noticeable delay, and in fact there
will be no disk access at all if you have enough free memory as will be no disk access at all if you have enough free memory as
the entire process takes places within the filesystem buffers. the entire process takes places within the file system buffers.
A compressed executable consists of the UPX stub and an overlay A compressed executable consists of the UPX stub and an overlay
which contains the original program in a compressed form. which contains the original program in a compressed form.
@@ -669,7 +644,7 @@ Specific drawbacks:
decompression, but you still need it for the full execution time decompression, but you still need it for the full execution time
of the program. of the program.
- You must have /proc filesystem support as the stub wants to open - You must have /proc file system support as the stub wants to open
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you /proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
cannot compress programs that are used during the boot sequence cannot compress programs that are used during the boot sequence
before /proc is mounted. before /proc is mounted.
@@ -681,7 +656,7 @@ Specific drawbacks:
- Because of temporary decompression to disk the decompression speed - Because of temporary decompression to disk the decompression speed
is not as fast as with the other executable formats. Still, I can see is not as fast as with the other executable formats. Still, I can see
no noticable delay when starting programs like my ~3 MB emacs (which no noticeable delay when starting programs like my ~3 MB emacs (which
is less than 1 MB when compressed :-). is less than 1 MB when compressed :-).
Extra options available for this executable format: Extra options available for this executable format:
@@ -708,7 +683,7 @@ Notes:
- UPX creates as default a suitable executable for CD-Mastering - UPX creates as default a suitable executable for CD-Mastering
and console transfer. For a CD-Master main executable you could also try and console transfer. For a CD-Master main executable you could also try
the special option "--boot-only" as descriped below. the special option "--boot-only" as described below.
- Normally the packed files use the same memory areas like the uncompressed - Normally the packed files use the same memory areas like the uncompressed
versions, so they will not override other memory areas while unpacking. versions, so they will not override other memory areas while unpacking.
@@ -784,7 +759,7 @@ Benefits:
- Better compression (but note that the kernel was already compressed, - Better compression (but note that the kernel was already compressed,
so the improvement is not as large as with other formats). so the improvement is not as large as with other formats).
Still, the bytes saved may be essential for special needs like Still, the bytes saved may be essential for special needs like
bootdisks. boot disks.
For example, this is what I get for my 2.2.16 kernel: For example, this is what I get for my 2.2.16 kernel:
1589708 vmlinux 1589708 vmlinux
@@ -831,13 +806,13 @@ Extra options available for this executable format:
=head2 NOTES FOR WIN32/PE =head2 NOTES FOR WIN32/PE
The PE support in B<UPX> is quite stable now, but probably there are The PE support in B<UPX> is quite stable now, but probably there are
still some incompabilities with some files. still some incompatibilities with some files.
Because of the way B<UPX> (and other packers for this format) works, you Because of the way B<UPX> (and other packers for this format) works, you
can see increased memory usage of your compressed files because the whole can see increased memory usage of your compressed files because the whole
program is loaded into memory at startup. program is loaded into memory at startup.
If you start several instances of huge compressed programs you're If you start several instances of huge compressed programs you're
wasting memory because the common segements of the program won't wasting memory because the common segments of the program won't
get shared across the instances. get shared across the instances.
On the other hand if you're compressing only smaller programs, or On the other hand if you're compressing only smaller programs, or
running only one instance of larger programs, then this penalty is running only one instance of larger programs, then this penalty is
@@ -855,7 +830,7 @@ Screensavers are supported, with the restriction that the filename
must end with ".scr" (as screensavers are handled slightly different must end with ".scr" (as screensavers are handled slightly different
than normal exe files). 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 10 - 30 kbytes range) which can be seen by specifying the "-i" command
line switch during compression. line switch during compression.
@@ -951,13 +926,13 @@ Please report all bugs immediately to the authors.
=head1 COPYRIGHT =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 This program may be used freely, and you are welcome to
redistribute it under certain conditions. redistribute it under certain conditions.
+10 -4
View File
@@ -7,9 +7,15 @@ MAKEFLAGS += -rR
export SHELL = /bin/sh export SHELL = /bin/sh
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1) override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
srcdir ?= $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))) ifndef srcdir
ifneq ($(srcdir),./) srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,') srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
endif
ifndef top_srcdir
top_srcdir := $(srcdir)/..
endif
-include $(top_srcdir)/Makevars.global ./Makevars.local
ifneq ($(srcdir),.)
##$(info Info: using VPATH . $(srcdir)) ##$(info Info: using VPATH . $(srcdir))
VPATH := . $(srcdir) VPATH := . $(srcdir)
endif endif
@@ -17,7 +23,7 @@ endif
ifeq ($(CXX),) ifeq ($(CXX),)
CXX = g++ CXX = g++
endif endif
ifeq ($(firstword $(CXX)),g++) ifneq ($(findstring $(firstword $(CXX)),g++),)
USE_GNUC ?= 1 USE_GNUC ?= 1
endif endif
ifeq ($(USE_GNUC),1) ifeq ($(USE_GNUC),1)
@@ -48,7 +54,7 @@ endif
LIBS += -lucl -lz LIBS += -lucl -lz
# you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2 # you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),) ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
DEFS += -DWITH_LZMA DEFS += -DWITH_LZMA=1
INCLUDES += -I$(UPX_LZMADIR) INCLUDES += -I$(UPX_LZMADIR)
endif endif
+95 -20
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -183,65 +183,69 @@ inline void set_le64(void *p, acc_uint64l_t v)
// get signed values, i.e. sign-extend // 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); const unsigned sign_bit = 1u << (bits - 1);
v |= 0u - (v & sign_bit); v &= sign_bit | (sign_bit - 1);
return v; //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); const acc_uint64l_t sign_bit = ACC_UINT64_C(1) << (bits - 1);
v |= ACC_UINT64_C(0) - (v & sign_bit); v &= sign_bit | (sign_bit - 1);
return v; //v = (v ^ sign_bit) - sign_bit;
v |= 0 - (v & sign_bit);
return (acc_int64l_t) v;
} }
inline int get_be16_signed(const void *p) inline int get_be16_signed(const void *p)
{ {
int v = get_be16(p); unsigned v = get_be16(p);
return sign_extend(v, 16); return sign_extend(v, 16);
} }
inline int get_be24_signed(const void *p) inline int get_be24_signed(const void *p)
{ {
int v = get_be24(p); unsigned v = get_be24(p);
return sign_extend(v, 24); return sign_extend(v, 24);
} }
inline int get_be32_signed(const void *p) inline int get_be32_signed(const void *p)
{ {
int v = get_be32(p); unsigned v = get_be32(p);
return sign_extend(v, 32); return sign_extend(v, 32);
} }
inline acc_int64l_t get_be64_signed(const void *p) 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); return sign_extend(v, 64);
} }
inline int get_le16_signed(const void *p) inline int get_le16_signed(const void *p)
{ {
int v = get_le16(p); unsigned v = get_le16(p);
return sign_extend(v, 16); return sign_extend(v, 16);
} }
inline int get_le24_signed(const void *p) inline int get_le24_signed(const void *p)
{ {
int v = get_le24(p); unsigned v = get_le24(p);
return sign_extend(v, 24); return sign_extend(v, 24);
} }
inline int get_le32_signed(const void *p) inline int get_le32_signed(const void *p)
{ {
int v = get_le32(p); unsigned v = get_le32(p);
return sign_extend(v, 32); return sign_extend(v, 32);
} }
inline acc_int64l_t get_le64_signed(const void *p) 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); return sign_extend(v, 64);
} }
@@ -304,12 +308,18 @@ inline void acc_ua_swab32s(void *p)
// Important: these classes must be PODs (Plain Old Data), i.e. no // Important: these classes must be PODs (Plain Old Data), i.e. no
// constructor, no destructor, no virtual functions and no default // constructor, no destructor, no virtual functions and no default
// assignment operator, and all fields must be public(!). // 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 struct BE16
{ {
unsigned char d[2]; 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, 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; }
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; }
@@ -330,6 +340,9 @@ struct BE32
{ {
unsigned char d[4]; 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, 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; }
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; }
@@ -350,6 +363,9 @@ struct BE64
{ {
unsigned char d[8]; 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, 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; }
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; }
@@ -370,6 +386,9 @@ struct LE16
{ {
unsigned char d[2]; 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, 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; }
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; }
@@ -390,6 +409,9 @@ struct LE32
{ {
unsigned char d[4]; 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, 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; }
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; }
@@ -410,6 +432,9 @@ struct LE64
{ {
unsigned char d[8]; 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, 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; }
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; }
@@ -469,11 +494,47 @@ template <class T> T* operator + (const LE64& v, T* ptr);
template <class T> T* operator - (T* ptr, const LE64& v); 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 // misc
**************************************************************************/ **************************************************************************/
// for use with qsort() // for use with qsort()
extern "C" {
int __acc_cdecl_qsort be16_compare(const void *, const void *); int __acc_cdecl_qsort be16_compare(const void *, const void *);
int __acc_cdecl_qsort be24_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 *); int __acc_cdecl_qsort be32_compare(const void *, const void *);
@@ -490,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 le24_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le32_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 *); int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
} // extern "C"
// just for testing... // just for testing...
@@ -538,26 +600,39 @@ int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
// forward declarations // forward declarations
namespace N_BELE_CTP { namespace N_BELE_CTP {
class BEPolicy; class LEPolicy; class BEPolicy; class LEPolicy;
extern const BEPolicy be_policy;
extern const LEPolicy le_policy;
} }
namespace N_BELE_RTP { namespace N_BELE_RTP {
class AbstractPolicy; class AbstractPolicy;
class BEPolicy; class LEPolicy; class BEPolicy; class LEPolicy;
extern const BEPolicy be_policy;
extern const LEPolicy le_policy;
} }
namespace N_BELE_CTP { namespace N_BELE_CTP {
#define BELE_CTP 1 #define BELE_CTP 1
#include "bele_policy.h" #include "bele_policy.h"
#undef BELE_CTP #undef BELE_CTP
extern const BEPolicy be_policy;
extern const LEPolicy le_policy;
} }
namespace N_BELE_RTP { namespace N_BELE_RTP {
#define BELE_RTP 1 #define BELE_RTP 1
#include "bele_policy.h" #include "bele_policy.h"
#undef BELE_RTP #undef BELE_RTP
extern const BEPolicy be_policy; }
extern const LEPolicy le_policy;
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; }
} }
+16 -18
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -53,8 +53,8 @@
#if defined(BELE_RTP) #if defined(BELE_RTP)
struct AbstractPolicy struct AbstractPolicy
{ {
AbstractPolicy() {} inline AbstractPolicy() { }
virtual inline ~AbstractPolicy() {} virtual inline ~AbstractPolicy() { }
V bool isBE() C = 0; V bool isBE() C = 0;
V bool isLE() C = 0; V bool isLE() C = 0;
@@ -94,15 +94,14 @@ struct BEPolicy
: public AbstractPolicy : public AbstractPolicy
#endif #endif
{ {
BEPolicy() {} inline BEPolicy() { }
#if defined(BELE_CTP) #if defined(BELE_CTP)
typedef N_BELE_RTP::BEPolicy RTP_Policy; typedef N_BELE_RTP::BEPolicy RTP_Policy;
enum { isBE = 1, isLE = 0 };
#elif defined(BELE_RTP) #elif defined(BELE_RTP)
typedef N_BELE_CTP::BEPolicy CTP_Policy; typedef N_BELE_CTP::BEPolicy CTP_Policy;
V bool isBE() C { return CTP_Policy::isBE; }
V bool isLE() C { return CTP_Policy::isLE; }
#endif #endif
V bool isBE() C { return true; }
V bool isLE() C { return false; }
typedef BE16 U16; typedef BE16 U16;
typedef BE32 U32; typedef BE32 U32;
@@ -157,9 +156,9 @@ struct BEPolicy
COMPILE_TIME_ASSERT(sizeof(U16) == 2) COMPILE_TIME_ASSERT(sizeof(U16) == 2)
COMPILE_TIME_ASSERT(sizeof(U32) == 4) COMPILE_TIME_ASSERT(sizeof(U32) == 4)
COMPILE_TIME_ASSERT(sizeof(U64) == 8) COMPILE_TIME_ASSERT(sizeof(U64) == 8)
COMPILE_TIME_ASSERT_ALIGNOF(U16, char) COMPILE_TIME_ASSERT_ALIGNED1(U16)
COMPILE_TIME_ASSERT_ALIGNOF(U32, char) COMPILE_TIME_ASSERT_ALIGNED1(U32)
COMPILE_TIME_ASSERT_ALIGNOF(U64, char) COMPILE_TIME_ASSERT_ALIGNED1(U64)
} }
// disable dynamic allocation // disable dynamic allocation
@@ -172,15 +171,14 @@ struct LEPolicy
: public AbstractPolicy : public AbstractPolicy
#endif #endif
{ {
LEPolicy() {} inline LEPolicy() { }
#if defined(BELE_CTP) #if defined(BELE_CTP)
typedef N_BELE_RTP::LEPolicy RTP_Policy; typedef N_BELE_RTP::LEPolicy RTP_Policy;
enum { isBE = 0, isLE = 1 };
#elif defined(BELE_RTP) #elif defined(BELE_RTP)
typedef N_BELE_CTP::LEPolicy CTP_Policy; typedef N_BELE_CTP::LEPolicy CTP_Policy;
V bool isBE() C { return CTP_Policy::isBE; }
V bool isLE() C { return CTP_Policy::isLE; }
#endif #endif
V bool isBE() C { return false; }
V bool isLE() C { return true; }
typedef LE16 U16; typedef LE16 U16;
typedef LE32 U32; typedef LE32 U32;
@@ -235,9 +233,9 @@ struct LEPolicy
COMPILE_TIME_ASSERT(sizeof(U16) == 2) COMPILE_TIME_ASSERT(sizeof(U16) == 2)
COMPILE_TIME_ASSERT(sizeof(U32) == 4) COMPILE_TIME_ASSERT(sizeof(U32) == 4)
COMPILE_TIME_ASSERT(sizeof(U64) == 8) COMPILE_TIME_ASSERT(sizeof(U64) == 8)
COMPILE_TIME_ASSERT_ALIGNOF(U16, char) COMPILE_TIME_ASSERT_ALIGNED1(U16)
COMPILE_TIME_ASSERT_ALIGNOF(U32, char) COMPILE_TIME_ASSERT_ALIGNED1(U32)
COMPILE_TIME_ASSERT_ALIGNOF(U64, char) COMPILE_TIME_ASSERT_ALIGNED1(U64)
} }
// disable dynamic allocation // disable dynamic allocation
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+51 -39
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -107,49 +107,49 @@ int compress_lzma_dummy = 0;
namespace MyLzma { namespace MyLzma {
struct InStreamRam: public ISequentialInStream, public CMyUnknownImp struct InStream: public ISequentialInStream, public CMyUnknownImp
{ {
MY_UNKNOWN_IMP 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) { 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); 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; size_t remain = b_size - b_pos;
if (size > remain) size = remain; if (size > remain) size = (UInt32) remain;
memmove(data, Data + Pos, size); memcpy(data, b_buf + b_pos, size);
Pos += size; b_pos += size;
if (processedSize != NULL) *processedSize = size; if (processedSize != NULL) *processedSize = size;
return S_OK; return S_OK;
} }
struct OutStreamRam : public ISequentialOutStream, public CMyUnknownImp struct OutStream : public ISequentialOutStream, public CMyUnknownImp
{ {
MY_UNKNOWN_IMP 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) { 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) { HRESULT WriteByte(Byte c) {
if (Pos >= Size) { Overflow = true; return E_FAIL; } if (b_pos >= b_size) { overflow = true; return E_FAIL; }
Data[Pos++] = b; b_buf[b_pos++] = c;
return S_OK; return S_OK;
} }
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 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; size_t remain = b_size - b_pos;
for (i = 0; i < size && Pos < Size; i++) if (size > remain) size = (UInt32) remain, overflow = true;
Data[Pos++] = ((const Byte *)data)[i]; memcpy(b_buf + b_pos, data, size);
if (processedSize != NULL) *processedSize = i; b_pos += size;
if (i != size) { Overflow = true; return E_FAIL; } if (processedSize != NULL) *processedSize = size;
return S_OK; return overflow ? E_FAIL : S_OK;
} }
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
@@ -169,6 +169,10 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
} // namespace } // namespace
#if (ACC_CC_INTELC) && defined(__linux__)
# pragma warning(disable: 424) // #424: extra ";" ignored
#endif
#include "C/Common/Alloc.cpp" #include "C/Common/Alloc.cpp"
#include "C/Common/CRC.cpp" #include "C/Common/CRC.cpp"
//#include "C/7zip/Common/InBuffer.cpp" //#include "C/7zip/Common/InBuffer.cpp"
@@ -189,7 +193,7 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
const upx_compress_config_t *cconf_parm, const upx_compress_config_t *cconf_parm,
upx_compress_result_t *cresult ) upx_compress_result_t *cresult )
{ {
assert(method == M_LZMA); assert(M_IS_LZMA(method));
assert(level > 0); assert(cresult != NULL); assert(level > 0); assert(cresult != NULL);
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
@@ -197,8 +201,8 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL; const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL;
lzma_compress_result_t *res = &cresult->result_lzma; lzma_compress_result_t *res = &cresult->result_lzma;
MyLzma::InStreamRam is; is.AddRef(); MyLzma::InStream is; is.AddRef();
MyLzma::OutStreamRam os; os.AddRef(); MyLzma::OutStream os; os.AddRef();
is.Init(src, src_len); is.Init(src, src_len);
os.Init(dst, *dst_len); os.Init(dst, *dst_len);
@@ -241,6 +245,12 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
pr[3].uintVal = lzma_compress_config_t::dict_size_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; pr[5].uintVal = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
#endif #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 #if 0
// DEBUG - set sizes so that we use a maxmimum amount of stack. // DEBUG - set sizes so that we use a maxmimum amount of stack.
// These settings cause res->num_probs == 3147574, i.e. we will // These settings cause res->num_probs == 3147574, i.e. we will
@@ -342,16 +352,16 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
goto error; goto error;
if (enc.WriteCoderProperties(&os) != S_OK) if (enc.WriteCoderProperties(&os) != S_OK)
goto error; goto error;
if (os.Overflow) { if (os.overflow) {
//r = UPX_E_OUTPUT_OVERRUN; //r = UPX_E_OUTPUT_OVERRUN;
r = UPX_E_NOT_COMPRESSIBLE; r = UPX_E_NOT_COMPRESSIBLE;
goto error; goto error;
} }
assert(os.Pos == 5); assert(os.b_pos == 5);
#if defined(USE_LZMA_PROPERTIES) #if defined(USE_LZMA_PROPERTIES)
os.Pos = 1; os.b_pos = 1;
#else #else
os.Pos = 0; os.b_pos = 0;
// extra stuff in first byte: 5 high bits convenience for stub decompressor // extra stuff in first byte: 5 high bits convenience for stub decompressor
unsigned t = res->lit_context_bits + res->lit_pos_bits; unsigned t = res->lit_context_bits + res->lit_pos_bits;
os.WriteByte((t << 3) | res->pos_bits); os.WriteByte((t << 3) | res->pos_bits);
@@ -361,27 +371,29 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
rh = enc.Code(&is, &os, NULL, NULL, &progress); rh = enc.Code(&is, &os, NULL, NULL, &progress);
#ifndef _NO_EXCEPTIONS #ifndef _NO_EXCEPTIONS
} catch(...) { return UPX_E_OUT_OF_MEMORY; } } catch (...) { rh = E_OUTOFMEMORY; }
#endif #endif
assert(is.Pos <= src_len); assert(is.b_pos <= src_len);
assert(os.Pos <= *dst_len); assert(os.b_pos <= *dst_len);
if (rh == E_OUTOFMEMORY) if (rh == E_OUTOFMEMORY)
r = UPX_E_OUT_OF_MEMORY; 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_OUTPUT_OVERRUN;
r = UPX_E_NOT_COMPRESSIBLE; r = UPX_E_NOT_COMPRESSIBLE;
} }
else if (rh == S_OK) else if (rh == S_OK)
{ {
assert(is.Pos == src_len); assert(is.b_pos == src_len);
r = UPX_E_OK; r = UPX_E_OK;
} }
error: 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; return r;
} }
@@ -402,7 +414,7 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
int method, int method,
const upx_compress_result_t *cresult ) const upx_compress_result_t *cresult )
{ {
assert(method == M_LZMA); assert(M_IS_LZMA(method));
// see res->num_probs above // see res->num_probs above
COMPILE_TIME_ASSERT(sizeof(CProb) == 2) COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846) COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
@@ -479,7 +491,7 @@ int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
int method, int method,
const upx_compress_result_t *cresult ) const upx_compress_result_t *cresult )
{ {
assert(method == M_LZMA); assert(M_IS_LZMA(method));
// FIXME - implement this // FIXME - implement this
// Note that Packer::verifyOverlappingDecompression() will // Note that Packer::verifyOverlappingDecompression() will
+9 -4
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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) static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
{ {
if (state != -1 && state != 3) return; if (state != -1 && state != 3) return;
upx_callback_p cb = (upx_callback_p) user; upx_callback_p cb = (upx_callback_p) user;
if (cb && cb->nprogress) if (cb && cb->nprogress)
cb->nprogress(cb, a, b); cb->nprogress(cb, a, b);
} }}
/************************************************************************* /*************************************************************************
@@ -135,7 +136,7 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
// prepare bit-buffer settings // prepare bit-buffer settings
cconf.bb_endian = 0; cconf.bb_endian = 0;
cconf.bb_size = 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}; static const unsigned char sizes[3] = {32, 8, 16};
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3]; cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
@@ -165,6 +166,10 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
return UPX_E_ERROR; return UPX_E_ERROR;
} }
// make sure first_offset_found is set
if (res[6] == 0)
res[6] = 1;
return convert_errno_from_ucl(r); return convert_errno_from_ucl(r);
} }
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+132 -82
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -104,6 +104,8 @@
# if (_MSC_VER >= 1400) # if (_MSC_VER >= 1400)
# pragma warning(disable: 4996) // W1: 'function': was declared deprecated # pragma warning(disable: 4996) // W1: 'function': was declared deprecated
# endif # endif
#elif (ACC_CC_SUNPROC)
//# pragma error_messages(off,"badargtype2w") // FIXME
#elif (ACC_CC_WATCOMC) #elif (ACC_CC_WATCOMC)
# if (__WATCOMC__ < 1100) # if (__WATCOMC__ < 1100)
# error "need Watcom C++ 11.0c or newer" # error "need Watcom C++ 11.0c or newer"
@@ -187,32 +189,6 @@
#define upx_byte unsigned char #define upx_byte unsigned char
#define upx_bytep upx_byte * #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
{
upx_progress_func_t nprogress;
void * user1;
};
/************************************************************************* /*************************************************************************
@@ -316,18 +292,6 @@ struct upx_callback_t
#undef PAGE_MASK #undef PAGE_MASK
#undef PAGE_SIZE #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) #if !defined(O_BINARY)
# define O_BINARY 0 # define O_BINARY 0
#endif #endif
@@ -337,6 +301,19 @@ struct upx_callback_t
#endif #endif
#undef __attribute_packed
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
# if (ACC_ARCH_I386) && (ACC_CC_INTELC && (__INTEL_COMPILER < 800))
# elif (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386))
# else
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
# endif
#endif
#if !defined(__attribute_packed)
# define __attribute_packed
#endif
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -344,36 +321,53 @@ struct upx_callback_t
#define UNUSED(var) ACC_UNUSED(var) #define UNUSED(var) ACC_UNUSED(var)
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e) #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; \ 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; \ 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) == 8*sizeof(b)+sizeof(a)) \ 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) #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_ALIGNOF_SIZEOF(a,b) \
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b)) COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b))
#else #else
# define COMPILE_TIME_ASSERT_ALIGNOF(a,b) \ # define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b)
#endif #endif
#define COMPILE_TIME_ASSERT_ALIGNED1(a) __COMPILE_TIME_ASSERT_ALIGNOF(a,char)
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0]))) #define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0])))
#if 0
#define ALIGN_DOWN(a,b) (((a) / (b)) * (b)) #define ALIGN_DOWN(a,b) (((a) / (b)) * (b))
#define ALIGN_UP(a,b) ALIGN_DOWN((a) + ((b) - 1), b) #define ALIGN_UP(a,b) ALIGN_DOWN((a) + ((b) - 1), b)
#define ALIGN_GAP(a,b) (ALIGN_UP(a,b) - (a)) #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_MAX(a,b) ((a) >= (b) ? (a) : (b))
#define UPX_MIN(a,b) ((a) <= (b) ? (a) : (b)) #define UPX_MIN(a,b) ((a) <= (b) ? (a) : (b))
#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
// An Array allocates memory on the heap, but automatically // An Array allocates memory on the heap, but automatically
@@ -412,30 +406,23 @@ private:
#define EXIT_INTERNAL 1 #define EXIT_INTERNAL 1
// compression methods - DO NOT CHANGE // magic constants for patching
#define M_SKIP (-2) #define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
#define M_END (-1) #define UPX_MAGIC2_LE32 0xD5D0D8A1
#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) // upx_compress() error codes
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16) #define UPX_E_OK (0)
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16) #define UPX_E_ERROR (-1)
#define M_IS_LZMA(x) ((x) == M_LZMA) #define UPX_E_OUT_OF_MEMORY (-2)
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE) #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. // Executable formats. Note: big endian types are >= 128.
@@ -466,6 +453,10 @@ private:
#define UPX_F_BSD_ELF_i386 25 #define UPX_F_BSD_ELF_i386 25
#define UPX_F_BSD_SH_i386 26 #define UPX_F_BSD_SH_i386 26
#define UPX_F_VMLINUX_AMD64 27
#define UPX_F_VMLINUX_ARM 28
#define UPX_F_MACH_i386 29
#define UPX_F_PLAIN_TEXT 127 #define UPX_F_PLAIN_TEXT 127
#define UPX_F_ATARI_TOS 129 #define UPX_F_ATARI_TOS 129
@@ -473,10 +464,68 @@ private:
#define UPX_F_MACH_PPC32 131 #define UPX_F_MACH_PPC32 131
#define UPX_F_LINUX_ELFPPC32 132 #define UPX_F_LINUX_ELFPPC32 132
#define UPX_F_LINUX_ELF32_ARMBE 133 #define UPX_F_LINUX_ELF32_ARMBE 133
#define UPX_F_MACH_FAT 134
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */ // compression methods
#define UPX_MAGIC2_LE32 0xD5D0D8A1 #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)); }
};
/************************************************************************* /*************************************************************************
@@ -521,15 +570,15 @@ struct OptVar
// optional assignments // optional assignments
template <class T> void oassign(T& self, const T& other) { template <class T> inline void oassign(T& self, const T& other) {
if (other.is_set) { self.v = other.v; self.is_set += 1; } if (other.is_set) { self.v = other.v; self.is_set += 1; }
} }
#if 0 #if 0
template <class V, class T> void oassign(V& v, const T& other) { template <class V, class T> inline void oassign(V& v, const T& other) {
if (other.is_set) { v = other.v; } if (other.is_set) { v = other.v; }
} }
#else #else
template <class T> void oassign(unsigned& v, const T& other) { template <class T> inline void oassign(unsigned& v, const T& other) {
if (other.is_set) { v = other.v; } if (other.is_set) { v = other.v; }
} }
#endif #endif
@@ -585,6 +634,8 @@ struct upx_compress_config_t
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); } void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); }
}; };
#define NULL_cconf ((upx_compress_config_t *) NULL)
/************************************************************************* /*************************************************************************
// compression - result_t // compression - result_t
@@ -661,7 +712,6 @@ typedef ElfLinker Linker;
// main.cpp // main.cpp
extern const char *progname; extern const char *progname;
void init_options(struct options_t *o);
bool set_ec(int ec); bool set_ec(int ec);
#if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE) #if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
void e_exit(int ec) __attribute__((__noreturn__)); void e_exit(int ec) __attribute__((__noreturn__));
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+77 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -69,7 +69,7 @@ void File::unlink(const char *name)
**************************************************************************/ **************************************************************************/
FileBase::FileBase() : FileBase::FileBase() :
_fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL) _fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL), _offset(0), _length(0)
{ {
memset(&st,0,sizeof(st)); memset(&st,0,sizeof(st));
} }
@@ -104,6 +104,10 @@ void FileBase::sopen()
assert(0); assert(0);
#endif #endif
} }
if (!(_fd < 0)) {
::fstat(_fd, &st);
_length = st.st_size;
}
} }
@@ -117,6 +121,8 @@ bool FileBase::close()
_flags = 0; _flags = 0;
_mode = 0; _mode = 0;
_name = NULL; _name = NULL;
_offset = 0;
_length = 0;
return ok; return ok;
} }
@@ -164,10 +170,17 @@ void FileBase::seek(off_t off, int whence)
{ {
if (!isOpen()) if (!isOpen())
throwIOException("bad seek 1"); throwIOException("bad seek 1");
if (whence == SEEK_SET && off < 0) if (whence == SEEK_SET) {
if (off < 0)
throwIOException("bad seek 2"); throwIOException("bad seek 2");
if (whence == SEEK_END && off > 0) off += _offset;
}
if (whence == SEEK_END) {
if (off > 0)
throwIOException("bad seek 3"); throwIOException("bad seek 3");
off += _offset + _length;
whence = SEEK_SET;
}
if (::lseek(_fd,off,whence) < 0) if (::lseek(_fd,off,whence) < 0)
throwIOException("seek error",errno); throwIOException("seek error",errno);
} }
@@ -180,7 +193,19 @@ off_t FileBase::tell() const
off_t l = ::lseek(_fd, 0, SEEK_CUR); off_t l = ::lseek(_fd, 0, SEEK_CUR);
if (l < 0) if (l < 0)
throwIOException("tell error",errno); throwIOException("tell error",errno);
return l; return l - _offset;
}
void FileBase::set_extent(off_t offset, off_t length)
{
_offset = offset;
_length = length;
}
off_t FileBase::st_size() const
{
return _length;
} }
@@ -205,6 +230,8 @@ void InputFile::sopen(const char *name, int flags, int shflags)
_flags = flags; _flags = flags;
_shflags = shflags; _shflags = shflags;
_mode = 0; _mode = 0;
_offset = 0;
_length = 0;
FileBase::sopen(); FileBase::sopen();
if (!isOpen()) if (!isOpen())
{ {
@@ -289,6 +316,8 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
_flags = flags; _flags = flags;
_shflags = shflags; _shflags = shflags;
_mode = mode; _mode = mode;
_offset = 0;
_length = 0;
FileBase::sopen(); FileBase::sopen();
if (!isOpen()) if (!isOpen())
{ {
@@ -316,6 +345,8 @@ bool OutputFile::openStdout(int flags, bool force)
_flags = flags; _flags = flags;
_shflags = -1; _shflags = -1;
_mode = 0; _mode = 0;
_offset = 0;
_length = 0;
if (flags && acc_set_binmode(fd, 1) == -1) if (flags && acc_set_binmode(fd, 1) == -1)
throwIOException(_name, errno); throwIOException(_name, errno);
_fd = fd; _fd = fd;
@@ -329,6 +360,16 @@ void OutputFile::write(const void *buf, int len)
bytes_written += len; bytes_written += len;
} }
off_t OutputFile::st_size() const
{
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
return bytes_written; // too big if seek()+write() instead of rewrite()
}
struct stat my_st;
::fstat(_fd, &my_st);
return my_st.st_size;
}
void OutputFile::write(const MemBuffer *buf, int len) void OutputFile::write(const MemBuffer *buf, int len)
{ {
@@ -343,6 +384,36 @@ void OutputFile::write(const MemBuffer &buf, int len)
write(&buf, len); write(&buf, len);
} }
void OutputFile::rewrite(const void *buf, int len)
{
assert(!opt->to_stdout);
write(buf, len);
bytes_written -= len; // restore
}
void OutputFile::seek(off_t off, int whence)
{
assert(!opt->to_stdout);
super::seek(off,whence);
}
void OutputFile::set_extent(off_t offset, off_t length)
{
super::set_extent(offset, length);
bytes_written = 0;
if (0==offset && (off_t)~0u==length) {
::fstat(_fd, &st);
_length = st.st_size - offset;
}
}
off_t OutputFile::unset_extent()
{
_offset = 0;
_length = ::lseek(_fd, 0, SEEK_END);
bytes_written = _length;
return _length;
}
void OutputFile::dump(const char *name, const void *buf, int len, int flags) void OutputFile::dump(const char *name, const void *buf, int len, int flags)
{ {
+12 -14
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -59,6 +59,8 @@ public:
virtual bool isOpen() const { return _fd >= 0; } virtual bool isOpen() const { return _fd >= 0; }
int getFd() const { return _fd; } int getFd() const { return _fd; }
const char *getName() const { return _name; } const char *getName() const { return _name; }
virtual off_t st_size() const; // { return _length; }
virtual void set_extent(off_t offset, off_t length);
protected: protected:
void sopen(); void sopen();
@@ -73,6 +75,8 @@ protected:
int _shflags; int _shflags;
int _mode; int _mode;
const char *_name; const char *_name;
off_t _offset;
off_t _length;
public: public:
struct stat st; struct stat st;
}; };
@@ -128,21 +132,15 @@ public:
virtual void write(const void *buf, int len); virtual void write(const void *buf, int len);
virtual void write(const MemBuffer *buf, int len); virtual void write(const MemBuffer *buf, int len);
virtual void write(const MemBuffer &buf, int len); virtual void write(const MemBuffer &buf, int len);
virtual void set_extent(off_t offset, off_t length);
virtual off_t unset_extent(); // returns actual length
off_t getBytesWritten() const { return bytes_written; } off_t getBytesWritten() const { return bytes_written; }
virtual off_t st_size() const; // { return _length; }
// 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) virtual void seek(off_t off, int whence);
{ virtual void rewrite(const void *buf, int len);
assert(!opt->to_stdout);
super::seek(off,whence);
}
virtual void rewrite(const void *buf, int len)
{
assert(!opt->to_stdout);
write(buf, len);
bytes_written -= len; // restore
}
// util // util
static void dump(const char *name, const void *buf, int len, int flags=-1); static void dump(const char *name, const void *buf, int len, int flags=-1);
+20 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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)); memset(filter_map, 0xff, sizeof(filter_map));
for (int i = 0; i < n_filters; i++) for (int i = 0; i < n_filters; i++)
{ {
int fid = filters[i].id; int filter_id = filters[i].id;
assert(fid >= 0 && fid <= 255); assert(filter_id >= 0 && filter_id <= 255);
assert(filter_map[fid] == 0xff); assert(filter_map[filter_id] == 0xff);
filter_map[fid] = (unsigned char) i; filter_map[filter_id] = (unsigned char) i;
} }
done = true; done = true;
} }
@@ -85,6 +85,20 @@ bool Filter::isValidFilter(int filter_id)
return fe != NULL; 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 // high level API
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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); bool scan(const upx_byte *buf, unsigned buf_len);
static bool isValidFilter(int filter_id); static bool isValidFilter(int filter_id);
static bool isValidFilter(int filter_id, const int *allowed_filters);
public: public:
// Will be set by each call to filter()/unfilter(). // 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+12 -5
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -58,8 +58,16 @@ static int F(Filter *f)
// must not conflict with the mark. // must not conflict with the mark.
// Note that unsigned comparison checks both edges of buffer. // Note that unsigned comparison checks both edges of buffer.
for (ic = 0; ic < size - 5; ic++) 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)
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1;
}
else
buf[b[ic+1]] |= 1; buf[b[ic+1]] |= 1;
} }
@@ -79,8 +87,7 @@ static int F(Filter *f)
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size)
{ {
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
return 1; // fail - buffer not restored
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b+ic+1,jc+addvalue+cto);
#endif #endif
+13 -6
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -57,8 +57,16 @@ static int F(Filter *f)
memset(buf,0,256); memset(buf,0,256);
for (ic = 0; ic < size - 5; ic++) 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)
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1;
}
else
buf[b[ic+1]] |= 1; buf[b[ic+1]] |= 1;
} }
@@ -78,8 +86,7 @@ static int F(Filter *f)
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size)
{ {
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
return 1; // fail - buffer not restored
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b+ic+1,jc+addvalue+cto);
#endif #endif
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+13 -6
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -58,8 +58,16 @@ static int F(Filter *f)
memset(buf,0,256); memset(buf,0,256);
for (ic = 0; ic < size - 5; ic++) 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)
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1;
}
else
buf[b[ic+1]] |= 1; buf[b[ic+1]] |= 1;
} }
@@ -79,8 +87,7 @@ static int F(Filter *f)
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size)
{ {
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
return 1; // fail - buffer not restored
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b+ic+1,jc+addvalue+cto);
#endif #endif
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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) 2004-2006 John F. Reiser Copyright (C) 2004-2007 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 char buf[256];
unsigned short wbuf[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(wbuf, 0, sizeof(wbuf));
memset(buf , 0, WW); memset(buf , 0, WW);
memset(buf + WW, 1, 256 - WW); memset(buf + WW, 1, 256 - WW);
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+115 -55
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -28,6 +28,8 @@
#include "conf.h" #include "conf.h"
#include "compress.h" #include "compress.h"
#include "packmast.h"
#include "packer.h"
/************************************************************************* /*************************************************************************
@@ -49,7 +51,7 @@ void show_head(void)
fg = con_fg(f,FG_GREEN); fg = con_fg(f,FG_GREEN);
con_fprintf(f, con_fprintf(f,
" Ultimate Packer for eXecutables\n" " 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", "UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n",
#if (ACC_OS_DOS16 || ACC_OS_DOS32) #if (ACC_OS_DOS16 || ACC_OS_DOS32)
V("d"), V("d"),
@@ -89,7 +91,77 @@ void show_usage(void)
// //
**************************************************************************/ **************************************************************************/
void show_help(int x/*verbose*/) 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; FILE *f = con_term;
int fg; int fg;
@@ -106,8 +178,8 @@ void show_help(int x/*verbose*/)
" -d decompress -l list compressed file\n" " -d decompress -l list compressed file\n"
" -t test compressed file -V display version number\n" " -t test compressed file -V display version number\n"
" -h give %s help -L display software license\n%s", " -h give %s help -L display software license\n%s",
x == 0 ? "" : " --best compress best (can be slow for big files)\n", verbose == 0 ? "" : " --best compress best (can be slow for big files)\n",
x == 0 ? "more" : "this", x == 0 ? "" : "\n"); verbose == 0 ? "more" : "this", verbose == 0 ? "" : "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f,FG_YELLOW);
con_fprintf(f,"Options:\n"); con_fprintf(f,"Options:\n");
@@ -115,22 +187,29 @@ void show_help(int x/*verbose*/)
con_fprintf(f, con_fprintf(f,
" -q be quiet -v be verbose\n" " -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 overwrite of output files and compression of suspicious files\n"
" -f force compression of suspicious files\n" " -f force compression of suspicious files\n"
"%s%s" "%s%s"
, (x == 0) ? " -k keep backup files\n" : "" , (verbose == 0) ? " -k keep backup files\n" : ""
#if 1 #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 #else
, "" , ""
#endif #endif
); );
if (x > 0) if (verbose > 0)
{ {
fg = con_fg(f,FG_YELLOW); 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); fg = con_fg(f,fg);
con_fprintf(f, con_fprintf(f,
" -k, --backup keep backup files\n" " -k, --backup keep backup files\n"
@@ -222,7 +301,7 @@ void show_help(int x/*verbose*/)
" --le produce LE output [default: EXE]\n" " --le produce LE output [default: EXE]\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); 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); fg = con_fg(f,fg);
con_fprintf(f, con_fprintf(f,
" --compress-exports=0 do not compress the export section\n" " --compress-exports=0 do not compress the export section\n"
@@ -230,6 +309,7 @@ void show_help(int x/*verbose*/)
" --compress-icons=0 do not compress any icons\n" " --compress-icons=0 do not compress any icons\n"
" --compress-icons=1 compress all but the first icon\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=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" " --compress-resources=0 do not compress any resources at all\n"
" --keep-resource=list do not compress resources specified by list\n" " --keep-resource=list do not compress resources specified by list\n"
" --strip-relocs=0 do not strip relocations\n" " --strip-relocs=0 do not strip relocations\n"
@@ -239,43 +319,23 @@ void show_help(int x/*verbose*/)
"\n"); "\n");
} }
con_fprintf(f, con_fprintf(f, "file.. executables to (de)compress\n");
"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"
"");
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) #if defined(DEBUG) || defined(TESTING)
fg = con_fg(f,FG_RED); fg = con_fg(f,FG_RED);
@@ -367,17 +427,17 @@ void show_version(int x)
if (v != NULL && v[0]) if (v != NULL && v[0])
fprintf(fp, "LZMA SDK version %s\n", v); fprintf(fp, "LZMA SDK version %s\n", v);
#endif #endif
fprintf(fp, "Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n"); fprintf(fp, "Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer\n");
fprintf(fp, "Copyright (C) 1996-2006 Laszlo Molnar\n"); fprintf(fp, "Copyright (C) 1996-2007 Laszlo Molnar\n");
fprintf(fp, "Copyright (C) 2000-2006 John F. Reiser\n"); fprintf(fp, "Copyright (C) 2000-2007 John F. Reiser\n");
fprintf(fp, "Copyright (C) 2002-2006 Jens Medoch\n"); fprintf(fp, "Copyright (C) 2002-2007 Jens Medoch\n");
#if defined(WITH_ZLIB) #if defined(WITH_ZLIB)
fprintf(fp, "Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler\n"); fprintf(fp, "Copyright (C) 1995" "-2005 Jean-loup Gailly and Mark Adler\n");
#endif #endif
#if defined(WITH_LZMA) #if defined(WITH_LZMA)
fprintf(fp, "Copyright (C) 1999-2006 Igor Pavlov\n"); fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
#endif #endif
fprintf(fp, "UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname); 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+45 -11
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -173,14 +173,14 @@ void ElfLinker::init(const void *pdata_v, int plen)
output = new upx_byte[inputlen]; output = new upx_byte[inputlen];
outputlen = 0; outputlen = 0;
int pos = find(input, inputlen, "Sections:", 9); int pos = find(input, inputlen, "Sections:\n", 10);
assert(pos != -1); assert(pos != -1);
char *psections = (char *) input + pos; char *psections = (char *) input + pos;
char *psymbols = strstr(psections, "SYMBOL TABLE:"); char *psymbols = strstr(psections, "SYMBOL TABLE:\n");
assert(psymbols != NULL); assert(psymbols != NULL);
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR"); char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR ");
assert(prelocs != NULL); assert(prelocs != NULL);
preprocessSections(psections, psymbols); preprocessSections(psections, psymbols);
@@ -189,7 +189,7 @@ void ElfLinker::init(const void *pdata_v, int plen)
addLoader("*UND*"); addLoader("*UND*");
} }
void ElfLinker::preprocessSections(char *start, const char *end) void ElfLinker::preprocessSections(char *start, char *end)
{ {
nsections = 0; nsections = 0;
while (start < end) while (start < end)
@@ -215,7 +215,7 @@ void ElfLinker::preprocessSections(char *start, const char *end)
addSection("*UND*", NULL, 0, 0); addSection("*UND*", NULL, 0, 0);
} }
void ElfLinker::preprocessSymbols(char *start, const char *end) void ElfLinker::preprocessSymbols(char *start, char *end)
{ {
nsymbols = 0; nsymbols = 0;
while (start < end) while (start < end)
@@ -250,7 +250,7 @@ void ElfLinker::preprocessSymbols(char *start, const char *end)
} }
} }
void ElfLinker::preprocessRelocations(char *start, const char *end) void ElfLinker::preprocessRelocations(char *start, char *end)
{ {
char sect[1024]; char sect[1024];
Section *section = NULL; Section *section = NULL;
@@ -369,11 +369,13 @@ ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned of
return rel; return rel;
} }
#if 0
void ElfLinker::setLoaderAlignOffset(int phase) void ElfLinker::setLoaderAlignOffset(int phase)
{ {
//assert(phase & 0); //assert(phase & 0);
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase); printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
} }
#endif
int ElfLinker::addLoader(const char *sname) int ElfLinker::addLoader(const char *sname)
{ {
@@ -412,7 +414,7 @@ int ElfLinker::addLoader(const char *sname)
assert(tail); assert(tail);
assert(tail != section); assert(tail != section);
unsigned const v = ~0u << section->p2align; unsigned const v = ~0u << section->p2align;
if (unsigned const l = ~v & -(tail->offset + tail->size)) { if (unsigned const l = ~v & (0u-(tail->offset + tail->size))) {
alignCode(l); alignCode(l);
tail->size += l; tail->size += l;
} }
@@ -437,6 +439,23 @@ int ElfLinker::addLoader(const char *sname)
return outputlen; return outputlen;
} }
void ElfLinker::addLoader(const char *s, va_list ap)
{
while (s != NULL)
{
addLoader(s);
s = va_arg(ap, const char *);
}
}
void __acc_cdecl_va ElfLinker::addLoaderVA(const char *s, ...)
{
va_list ap;
va_start(ap, s);
addLoader(s, ap);
va_end(ap);
}
int ElfLinker::getSection(const char *sname, int *slen) const int ElfLinker::getSection(const char *sname, int *slen) const
{ {
const Section *section = findSection(sname); const Section *section = findSection(sname);
@@ -583,6 +602,7 @@ void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
/************************************************************************* /*************************************************************************
// ElfLinker arch subclasses // ElfLinker arch subclasses
// FIXME: add more displacment overflow checks // FIXME: add more displacment overflow checks
// FIXME: add support for our special "ignore_reloc_overflow" section
**************************************************************************/ **************************************************************************/
#if 0 // FIXME #if 0 // FIXME
@@ -617,7 +637,11 @@ void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
if (strcmp(type, "8") == 0) 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; int displ = (signed char) *location + (int) value;
#endif
if (displ < -128 || displ > 127) if (displ < -128 || displ > 127)
{ {
printf("target out of range (%d) in reloc %s:%x\n", printf("target out of range (%d) in reloc %s:%x\n",
@@ -659,6 +683,9 @@ void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location,
//(b, 0xF000 + ((v - 1) / 2) * 0x10000); //(b, 0xF000 + ((v - 1) / 2) * 0x10000);
//set_be32(location, get_be32(location) + value / 4); //set_be32(location, get_be32(location) + value / 4);
} }
else if (0==strcmp("R_ARM_ABS8", type)) {
*location += value;
}
else else
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
@@ -688,6 +715,9 @@ void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location,
//(b, 0xF000 + ((v - 1) / 2) * 0x10000); //(b, 0xF000 + ((v - 1) / 2) * 0x10000);
//set_le32(location, get_le32(location) + value / 4); //set_le32(location, get_le32(location) + value / 4);
} }
else if (0==strcmp("R_ARM_ABS8", type)) {
*location += value;
}
else else
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
@@ -815,10 +845,14 @@ void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location,
if (strcmp(type, "8") == 0) 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; int displ = (signed char) *location + (int) value;
#endif
if (range_check && (displ < -128 || displ > 127)) { if (range_check && (displ < -128 || displ > 127)) {
printf("target out of range (%d) in reloc %s:%x\n", printf("target out of range (%d,%d,%d) in reloc %s:%x\n",
displ, rel->section->name, rel->offset); displ, *location, value, rel->section->name, rel->offset);
abort(); abort();
} }
*location += value; *location += value;
+12 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -66,9 +66,9 @@ protected:
bool reloc_done; bool reloc_done;
protected: protected:
void preprocessSections(char *start, const char *end); void preprocessSections(char *start, char *end);
void preprocessSymbols(char *start, const char *end); void preprocessSymbols(char *start, char *end);
void preprocessRelocations(char *start, const char *end); void preprocessRelocations(char *start, char *end);
Section *findSection(const char *name, bool fatal=true) const; Section *findSection(const char *name, bool fatal=true) const;
Symbol *findSymbol(const char *name, bool fatal=true) const; Symbol *findSymbol(const char *name, bool fatal=true) const;
@@ -81,8 +81,14 @@ public:
virtual ~ElfLinker(); virtual ~ElfLinker();
virtual void init(const void *pdata, int plen); 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 int addLoader(const char *sname);
void addLoader(const char *s, va_list ap);
#if 1 && (ACC_CC_GNUC >= 0x040100)
void __acc_cdecl_va addLoaderVA(const char *s, ...) __attribute__((__sentinel__));
#else
void __acc_cdecl_va addLoaderVA(const char *s, ...);
#endif
virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align); 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 getSection(const char *sname, int *slen=NULL) const;
virtual int getSectionSize(const char *sname) const; virtual int getSectionSize(const char *sname) const;
+64 -32
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -50,9 +50,9 @@ void options_t::reset()
o->crp.reset(); o->crp.reset();
o->cmd = CMD_NONE; o->cmd = CMD_NONE;
o->method = -1; o->method = M_NONE;
o->level = -1; o->level = -1;
o->filter = -1; o->filter = FT_NONE;
o->backup = -1; o->backup = -1;
o->overlay = -1; o->overlay = -1;
@@ -77,8 +77,8 @@ void options_t::reset()
o->win32_pe.keep_resource = ""; o->win32_pe.keep_resource = "";
} }
static struct options_t global_options; static options_t global_options;
struct options_t *opt = &global_options; options_t *opt = &global_options;
static int done_output_name = 0; static int done_output_name = 0;
static int done_script_name = 0; static int done_script_name = 0;
@@ -183,7 +183,7 @@ static void e_method(int m, int l)
static void e_optarg(const char *n) static void e_optarg(const char *n)
{ {
fflush(con_term); 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); e_exit(EXIT_USAGE);
} }
@@ -191,7 +191,7 @@ static void e_optarg(const char *n)
static void e_optval(const char *n) static void e_optval(const char *n)
{ {
fflush(con_term); 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); e_exit(EXIT_USAGE);
} }
@@ -201,10 +201,10 @@ void e_envopt(const char *n)
{ {
fflush(con_term); fflush(con_term);
if (n) 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); argv0, n, OPTIONS_VAR);
else else
fprintf(stderr,"%s: illegal option in environment variable `%s'\n", fprintf(stderr,"%s: illegal option in environment variable '%s'\n",
argv0, OPTIONS_VAR); argv0, OPTIONS_VAR);
e_exit(EXIT_USAGE); e_exit(EXIT_USAGE);
} }
@@ -227,7 +227,7 @@ void check_not_both(bool e1, bool e2, const char *c1, const char *c2)
if (e1 && e2) if (e1 && e2)
{ {
fprintf(stderr,"%s: ",argv0); 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(); e_usage();
} }
} }
@@ -264,14 +264,14 @@ void check_options(int i, int argc)
check_not_both(opt->to_stdout, opt->output_name != NULL, "--stdout", "-o"); check_not_both(opt->to_stdout, opt->output_name != NULL, "--stdout", "-o");
if (opt->to_stdout && opt->cmd == CMD_COMPRESS) 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(); e_usage();
} }
if (opt->to_stdout || opt->output_name) if (opt->to_stdout || opt->output_name)
{ {
if (i + 1 != argc) 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"); argv0, opt->to_stdout ? "--stdout" : "-o");
e_usage(); e_usage();
} }
@@ -333,7 +333,7 @@ static void set_output_name(const char *n, bool allow_m)
#if 1 #if 1
if (done_output_name > 0) 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(); e_usage();
} }
#endif #endif
@@ -356,7 +356,7 @@ static void set_script_name(const char *n, bool allow_m)
#if 1 #if 1
if (done_script_name > 0) 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(); e_usage();
} }
#endif #endif
@@ -499,7 +499,7 @@ static int do_option(int optc, const char *arg)
case 'f': case 'f':
opt->force++; opt->force++;
break; break;
case 902: case 909:
set_cmd(CMD_FILEINFO); set_cmd(CMD_FILEINFO);
break; break;
case 'h': case 'h':
@@ -508,10 +508,13 @@ static int do_option(int optc, const char *arg)
set_cmd(CMD_HELP); set_cmd(CMD_HELP);
break; break;
case 'h'+256: case 'h'+256:
#if 0 #if 1
if (!acc_isatty(STDOUT_FILENO))
{
/* according to GNU standards */ /* according to GNU standards */
set_term(stdout); set_term(stdout);
opt->console = CON_FILE; opt->console = CON_FILE;
}
#endif #endif
show_help(1); show_help(1);
e_exit(EXIT_OK); e_exit(EXIT_OK);
@@ -550,25 +553,30 @@ static int do_option(int optc, const char *arg)
// method // method
case 702: case 702:
opt->method_nrv2b_seen = true;
if (!set_method(M_NRV2B_LE32, -1)) if (!set_method(M_NRV2B_LE32, -1))
e_method(M_NRV2B_LE32, opt->level); e_method(M_NRV2B_LE32, opt->level);
break; break;
case 704: case 704:
opt->method_nrv2d_seen = true;
if (!set_method(M_NRV2D_LE32, -1)) if (!set_method(M_NRV2D_LE32, -1))
e_method(M_NRV2D_LE32, opt->level); e_method(M_NRV2D_LE32, opt->level);
break; break;
case 705: case 705:
opt->method_nrv2e_seen = true;
if (!set_method(M_NRV2E_LE32, -1)) if (!set_method(M_NRV2E_LE32, -1))
e_method(M_NRV2E_LE32, opt->level); e_method(M_NRV2E_LE32, opt->level);
break; break;
case 721: case 721:
opt->method_lzma_seen = true;
opt->all_methods_use_lzma = true; opt->all_methods_use_lzma = true;
if (!set_method(M_LZMA, -1)) if (!set_method(M_LZMA, -1))
e_method(M_LZMA, opt->level); e_method(M_LZMA, opt->level);
break; break;
case 722: case 722:
opt->method_lzma_seen = false;
opt->all_methods_use_lzma = false; opt->all_methods_use_lzma = false;
if (opt->method == M_LZMA) if (M_IS_LZMA(opt->method))
opt->method = -1; opt->method = -1;
break; break;
@@ -586,6 +594,9 @@ static int do_option(int optc, const char *arg)
e_method(opt->method, optc); e_method(opt->method, optc);
break; break;
case 902: // --ultra-brute
opt->ultra_brute = true;
/* fallthrough */
case 901: // --brute case 901: // --brute
opt->all_methods = true; opt->all_methods = true;
opt->all_methods_use_lzma = true; opt->all_methods_use_lzma = true;
@@ -656,6 +667,7 @@ static int do_option(int optc, const char *arg)
break; break;
case 524: // --all-methods case 524: // --all-methods
opt->all_methods = true; opt->all_methods = true;
opt->all_methods_use_lzma = true;
opt->method = -1; opt->method = -1;
break; break;
case 525: // --exact case 525: // --exact
@@ -712,7 +724,7 @@ static int do_option(int optc, const char *arg)
opt->backup = 1; opt->backup = 1;
break; break;
case 541: case 541:
if (opt->backup != 1) // do not overide `--backup' if (opt->backup != 1) // do not overide '--backup'
opt->backup = 0; opt->backup = 0;
break; break;
// overlay // overlay
@@ -871,10 +883,11 @@ static const struct mfx_option longopts[] =
// commands // commands
{"best", 0x10, 0, 900}, // compress best {"best", 0x10, 0, 900}, // compress best
{"brute", 0x10, 0, 901}, // compress best, brute force {"brute", 0x10, 0, 901}, // compress best, brute force
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
{"decompress", 0, 0, 'd'}, // decompress {"decompress", 0, 0, 'd'}, // decompress
{"fast", 0x10, 0, '1'}, // compress faster {"fast", 0x10, 0, '1'}, // compress faster
{"fileinfo", 0x10, 0, 902}, // display info about file {"fileinfo", 0x10, 0, 909}, // display info about file
{"file-info", 0x10, 0, 902}, // display info about file {"file-info", 0x10, 0, 909}, // display info about file
{"help", 0, 0, 'h'+256}, // give help {"help", 0, 0, 'h'+256}, // give help
{"license", 0, 0, 'L'}, // display software license {"license", 0, 0, 'L'}, // display software license
{"list", 0, 0, 'l'}, // list compressed exe {"list", 0, 0, 'l'}, // list compressed exe
@@ -1039,6 +1052,7 @@ static const struct mfx_option longopts[] =
// commands // commands
{"best", 0x10, 0, 900}, // compress best {"best", 0x10, 0, 900}, // compress best
{"brute", 0x10, 0, 901}, // compress best, brute force {"brute", 0x10, 0, 901}, // compress best, brute force
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
{"fast", 0x10, 0, '1'}, // compress faster {"fast", 0x10, 0, '1'}, // compress faster
// options // options
@@ -1201,9 +1215,25 @@ static void first_options(int argc, char **argv)
**************************************************************************/ **************************************************************************/
template <class T> struct TestBELE { 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; T allbits; allbits = 0; allbits -= 1;
//++allbits; allbits++; --allbits; allbits--;
T v1; v1 = 1; v1 *= 2; v1 -= 1; T v1; v1 = 1; v1 *= 2; v1 -= 1;
T v2; v2 = 1; T v2; v2 = 1;
assert( (v1 == v2)); assert(!(v1 != v2)); assert( (v1 == v2)); assert(!(v1 != v2));
@@ -1217,7 +1247,9 @@ static int test(void)
assert(v1 == 1); assert(v2 == 0); assert(v1 == 1); assert(v2 == 0);
v1 <<= 1; v1 |= v2; v1 >>= 1; v2 &= v1; v2 /= v1; v2 *= v1; v1 <<= 1; v1 |= v2; v1 >>= 1; v2 &= v1; v2 /= v1; v2 *= v1;
assert(v1 == 1); assert(v2 == 0); assert(v1 == 1); assert(v2 == 0);
return (v1 ^ v2) == 1; if ((v1 ^ v2) != 1) return false;
#endif
return true;
}}; }};
@@ -1249,12 +1281,12 @@ void upx_sanity_check(void)
COMPILE_TIME_ASSERT(sizeof(LE32) == 4) COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
COMPILE_TIME_ASSERT(sizeof(LE64) == 8) COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
COMPILE_TIME_ASSERT_ALIGNOF(BE16, char) COMPILE_TIME_ASSERT_ALIGNED1(BE16)
COMPILE_TIME_ASSERT_ALIGNOF(BE32, char) COMPILE_TIME_ASSERT_ALIGNED1(BE32)
COMPILE_TIME_ASSERT_ALIGNOF(BE64, char) COMPILE_TIME_ASSERT_ALIGNED1(BE64)
COMPILE_TIME_ASSERT_ALIGNOF(LE16, char) COMPILE_TIME_ASSERT_ALIGNED1(LE16)
COMPILE_TIME_ASSERT_ALIGNOF(LE32, char) COMPILE_TIME_ASSERT_ALIGNED1(LE32)
COMPILE_TIME_ASSERT_ALIGNOF(LE64, char) COMPILE_TIME_ASSERT_ALIGNED1(LE64)
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1) COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
assert(strlen(UPX_VERSION_STRING4) == 4); assert(strlen(UPX_VERSION_STRING4) == 4);
@@ -1265,14 +1297,12 @@ void upx_sanity_check(void)
assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0); assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0);
#if 1 #if 1
# if 1 && !defined(UPX_OFFICIAL_BUILD)
assert(TestBELE<LE16>::test()); assert(TestBELE<LE16>::test());
assert(TestBELE<LE32>::test()); assert(TestBELE<LE32>::test());
assert(TestBELE<LE64>::test()); assert(TestBELE<LE64>::test());
assert(TestBELE<BE16>::test()); assert(TestBELE<BE16>::test());
assert(TestBELE<BE32>::test()); assert(TestBELE<BE32>::test());
assert(TestBELE<BE64>::test()); assert(TestBELE<BE64>::test());
# endif
{ {
static const unsigned char dd[32] = { 0, 0, 0, 0, 0, 0, 0, static const unsigned char dd[32] = { 0, 0, 0, 0, 0, 0, 0,
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
@@ -1296,6 +1326,7 @@ void upx_sanity_check(void)
assert(get_le24_signed(d) == -131329); assert(get_le24_signed(d) == -131329);
assert(get_le32(d) == 0xfcfdfeff); assert(get_le32(d) == 0xfcfdfeff);
assert(get_le32_signed(d) == -50462977); assert(get_le32_signed(d) == -50462977);
assert(get_le64_signed(d) == ACC_INT64_C(-506097522914230529));
assert(find_be16(d, 2, 0xfffe) == 0); assert(find_be16(d, 2, 0xfffe) == 0);
assert(find_le16(d, 2, 0xfeff) == 0); assert(find_le16(d, 2, 0xfeff) == 0);
assert(find_be32(d, 4, 0xfffefdfc) == 0); assert(find_be32(d, 4, 0xfffefdfc) == 0);
@@ -1304,6 +1335,7 @@ void upx_sanity_check(void)
assert(get_be16_signed(d) == 32638); assert(get_be16_signed(d) == 32638);
assert(get_be24_signed(d) == 8355453); assert(get_be24_signed(d) == 8355453);
assert(get_be32_signed(d) == 2138996092); assert(get_be32_signed(d) == 2138996092);
assert(get_be64_signed(d) == ACC_INT64_C(9186918263483431288));
} }
#endif #endif
} }
@@ -1451,7 +1483,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
set_term(stdout); set_term(stdout);
do_files(i,argc,argv); do_files(i,argc,argv);
#if 0 && (UPX_VERSION_HEX < 0x020000) #if 0 && (UPX_VERSION_HEX < 0x030000)
{ {
FILE *f = stdout; FILE *f = stdout;
int fg = con_fg(f,FG_RED); int fg = con_fg(f,FG_RED);
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+265 -26
View File
@@ -2,6 +2,7 @@
This file is part of the UPX executable compressor. 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) 2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
@@ -37,7 +38,7 @@
#ifndef __ACC_H_INCLUDED #ifndef __ACC_H_INCLUDED
#define __ACC_H_INCLUDED 1 #define __ACC_H_INCLUDED 1
#define ACC_VERSION 20060823L #define ACC_VERSION 20070113L
#if defined(__CYGWIN32__) && !defined(__CYGWIN__) #if defined(__CYGWIN32__) && !defined(__CYGWIN__)
# define __CYGWIN__ __CYGWIN32__ # define __CYGWIN__ __CYGWIN32__
#endif #endif
@@ -1169,7 +1170,7 @@ extern "C" {
# define ACC_SIZEOF_LONG_LONG 8 # define ACC_SIZEOF_LONG_LONG 8
#elif (ACC_ARCH_I386 && (ACC_CC_INTELC && defined(__linux__))) #elif (ACC_ARCH_I386 && (ACC_CC_INTELC && defined(__linux__)))
# define ACC_SIZEOF_LONG_LONG 8 # 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 # define ACC_SIZEOF_LONG_LONG 8
#elif (ACC_ARCH_I386 && (ACC_CC_INTELC || ACC_CC_MSC)) #elif (ACC_ARCH_I386 && (ACC_CC_INTELC || ACC_CC_MSC))
# define ACC_SIZEOF___INT64 8 # define ACC_SIZEOF___INT64 8
@@ -1301,7 +1302,7 @@ extern "C" {
#elif !defined(ACC_ABI_BIG_ENDIAN) && !defined(ACC_ABI_LITTLE_ENDIAN) #elif !defined(ACC_ABI_BIG_ENDIAN) && !defined(ACC_ABI_LITTLE_ENDIAN)
#if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP) #if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
# define ACC_ABI_BIG_ENDIAN 1 # define ACC_ABI_BIG_ENDIAN 1
#elif (ACC_ARCH_ALPHA || ACC_ARCH_AMD64 || ACC_ARCH_CRIS || ACC_ARCH_I086 || ACC_ARCH_I386 || ACC_ARCH_MSP430) #elif (ACC_ARCH_ALPHA || ACC_ARCH_AMD64 || ACC_ARCH_BLACKFIN || ACC_ARCH_CRIS || ACC_ARCH_I086 || ACC_ARCH_I386 || ACC_ARCH_MSP430)
# define ACC_ABI_LITTLE_ENDIAN 1 # define ACC_ABI_LITTLE_ENDIAN 1
#elif (ACC_ARCH_M68K || ACC_ARCH_S390) #elif (ACC_ARCH_M68K || ACC_ARCH_S390)
# define ACC_ABI_BIG_ENDIAN 1 # define ACC_ABI_BIG_ENDIAN 1
@@ -1634,6 +1635,15 @@ extern "C" {
# define ACC_UNUSED_LABEL(l) switch(0) case 1:goto l # define ACC_UNUSED_LABEL(l) switch(0) case 1:goto l
# endif # endif
#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 !defined(ACC_COMPILE_TIME_ASSERT_HEADER)
# if (ACC_CC_AZTECC || ACC_CC_ZORTECHC) # if (ACC_CC_AZTECC || ACC_CC_ZORTECHC)
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) extern int __acc_cta[1-!(e)]; # 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) #if !defined(acc_signo_t)
# define acc_signo_t int # define acc_signo_t int
#endif #endif
#if defined(__cplusplus)
extern "C" {
#endif
#if (ACC_BROKEN_CDECL_ALT_SYNTAX) #if (ACC_BROKEN_CDECL_ALT_SYNTAX)
typedef void __acc_cdecl_sighandler (*acc_sighandler_t)(acc_signo_t); typedef void __acc_cdecl_sighandler (*acc_sighandler_t)(acc_signo_t);
#elif defined(RETSIGTYPE) #elif defined(RETSIGTYPE)
@@ -2752,6 +2765,9 @@ typedef RETSIGTYPE (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#else #else
typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t); typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#endif #endif
#if defined(__cplusplus)
}
#endif
# if defined(ACC_CFG_NO_ACC_UA_H) # if defined(ACC_CFG_NO_ACC_UA_H)
# else # else
#if (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020700ul)) #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) #if !defined(acc_signo_t)
# define acc_signo_t int # define acc_signo_t int
#endif #endif
#if defined(__cplusplus)
extern "C" {
#endif
#if (ACC_BROKEN_CDECL_ALT_SYNTAX) #if (ACC_BROKEN_CDECL_ALT_SYNTAX)
typedef void __acc_cdecl_sighandler (*acc_sighandler_t)(acc_signo_t); typedef void __acc_cdecl_sighandler (*acc_sighandler_t)(acc_signo_t);
#elif defined(RETSIGTYPE) #elif defined(RETSIGTYPE)
@@ -3171,6 +3190,9 @@ typedef RETSIGTYPE (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#else #else
typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t); typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#endif #endif
#if defined(__cplusplus)
}
#endif
# if !defined(ACC_CFG_NO_ACC_UA_H) # if !defined(ACC_CFG_NO_ACC_UA_H)
#if (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020700ul)) #if (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020700ul))
#elif (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020800ul)) && defined(__cplusplus) #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); ACCLIB_EXTERN(double, acc_uclock_get_elapsed) (acc_uclock_handle_p, const acc_uclock_p, const acc_uclock_p);
#endif #endif
ACCLIB_EXTERN(int, acc_uclock_flush_cpu_cache) (acc_uclock_handle_p, unsigned); 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; const char* name;
int has_arg; int has_arg;
int* flag; int* flag;
int val; int val;
} acc_getopt_longopt_t; };
#ifndef acc_getopt_longopt_p struct acc_getopt_t {
#define acc_getopt_longopt_p acc_getopt_longopt_t * void *user;
#endif char *optarg;
typedef struct { void (*opterr)(acc_getopt_p, const char*, void *);
int go_argc; int optind;
char** go_argv; int optopt;
const char* go_shortopts; int errcount;
const acc_getopt_longopt_p longopts; const char* progname;
#if (ACC_BROKEN_CDECL_ALT_SYNTAX) int argc; char** argv;
int __acc_cdecl_va (*go_error)(const char *, ...); int eof; int shortpos;
#else int pending_rotate_first, pending_rotate_middle;
int (__acc_cdecl_va *go_error)(const char *, ...); };
#endif enum { ACC_GETOPT_NO_ARG, ACC_GETOPT_REQUIRED_ARG, ACC_GETOPT_OPTIONAL_ARG, ACC_GETOPT_EXACT_ARG = 0x10 };
} acc_getopt_t; enum { ACC_GETOPT_PERMUTE, ACC_GETOPT_RETURN_IN_ORDER, ACC_GETOPT_REQUIRE_ORDER };
#ifndef acc_getopt_p ACCLIB_EXTERN(void, acc_getopt_init) (acc_getopt_p g,
#define acc_getopt_p acc_getopt_t * int start_argc, int argc, char** argv);
#endif ACCLIB_EXTERN(int, acc_getopt) (acc_getopt_p g,
ACCLIB_EXTERN(void, acc_getopt_init) (acc_getopt_p); const char* shortopts,
ACCLIB_EXTERN(int, acc_getopt) (acc_getopt_p); const acc_getopt_longopt_p longopts,
ACCLIB_EXTERN(void, acc_getopt_close)(acc_getopt_p); int* longind);
typedef struct { typedef struct {
acc_uint32l_t seed; acc_uint32l_t seed;
} acc_rand31_t; } acc_rand31_t;
@@ -5245,6 +5277,213 @@ ACCLIB_PUBLIC(int, acc_dos_free) (void __far* p)
} }
#endif #endif
#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) #if defined(ACC_WANT_ACCLIB_HALLOC)
# undef ACC_WANT_ACCLIB_HALLOC # undef ACC_WANT_ACCLIB_HALLOC
#define __ACCLIB_HALLOC_CH_INCLUDED 1 #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) 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; FILE* fp; int old_binary;
if (fd == STDIN_FILENO) fp = stdin; if (fd == STDIN_FILENO) fp = stdin;
else if (fd == STDOUT_FILENO) fp = stdout; else if (fd == STDOUT_FILENO) fp = stdout;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -47,8 +47,13 @@ struct options_t {
// compression options // compression options
int method; int method;
bool method_lzma_seen;
bool method_nrv2b_seen;
bool method_nrv2d_seen;
bool method_nrv2e_seen;
int level; // compression level 1..10 int level; // compression level 1..10
int filter; // preferred filter from Packer::getFilters() int filter; // preferred filter from Packer::getFilters()
bool ultra_brute;
bool all_methods; // try all available compression methods ? bool all_methods; // try all available compression methods ?
bool all_methods_use_lzma; bool all_methods_use_lzma;
bool all_filters; // try all available filters ? bool all_filters; // try all available filters ?
+24 -22
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 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_all[] = { 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_lzma[] = { 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) if (!use_thumb_stub)
return getDefaultCompressionMethods_8(method, level); return getDefaultCompressionMethods_8(method, level);
if (M_IS_NRV2B(method)) if (method == M_ALL) return m_all;
return m_nrv2b; if (M_IS_LZMA(method)) return m_lzma;
if (M_IS_NRV2E(method)) if (M_IS_NRV2B(method)) return m_nrv2b;
return m_nrv2e; if (M_IS_NRV2E(method)) return m_nrv2e;
if (M_IS_LZMA(method))
return m_lzma;
return m_nrv2e; return m_nrv2e;
} }
const int *PackArmPe::getFilters() const const int *PackArmPe::getFilters() const
{ {
static const int filters[] = { 0x50, -1 }; static const int filters[] = { 0x50, FT_END };
return filters; return filters;
} }
@@ -292,7 +291,7 @@ unsigned PackArmPe::processImports() // pass 1
unsigned k32namepos = ptr_diff(dllnames,oimpdlls); 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); strcpy(dllnames,kernel32dll);
im->dllname = k32namepos; im->dllname = k32namepos;
im->iat = ptr_diff(ordinals,oimpdlls); im->iat = ptr_diff(ordinals,oimpdlls);
@@ -440,7 +439,7 @@ unsigned PackArmPe::processImports() // pass 1
void PackArmPe::processTls(Interval *) // 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; return;
// never should happen on wince // never should happen on wince
@@ -555,7 +554,7 @@ void PackArmPe::pack(OutputFile *fo)
if (ih.entry && ih.entry < rvamin) if (ih.entry && ih.entry < rvamin)
throwCantPack("run a virus scanner on this file!"); throwCantPack("run a virus scanner on this file!");
if (!opt->force && ih.subsystem == 1) 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) if (ih.filealign < 0x200)
throwCantPack("filealign < 0x200 is not yet supported"); throwCantPack("filealign < 0x200 is not yet supported");
@@ -633,7 +632,7 @@ void PackArmPe::pack(OutputFile *fo)
//OutputFile::dump("x1", ibuf, usize); //OutputFile::dump("x1", ibuf, usize);
// some checks for broken linkers - disable filter if neccessary // some checks for broken linkers - disable filter if necessary
bool allow_filter = true; bool allow_filter = true;
if (ih.codebase == ih.database if (ih.codebase == ih.database
|| ih.codebase + ih.codesize > ih.imagesize || ih.codebase + ih.codesize > ih.imagesize
@@ -698,20 +697,20 @@ void PackArmPe::pack(OutputFile *fo)
ft.buf_len = ih.codesize; ft.buf_len = ih.codesize;
ft.addvalue = ih.codebase - rvamin; ft.addvalue = ih.codebase - rvamin;
// compress // compress
int strategy = allow_filter ? 0 : -3; int filter_strategy = allow_filter ? 0 : -3;
// disable filters for files with broken headers // disable filters for files with broken headers
if (ih.codebase + ih.codesize > ph.u_len) if (ih.codebase + ih.codesize > ph.u_len)
{ {
ft.buf_len = 1; ft.buf_len = 1;
strategy = -3; filter_strategy = -3;
} }
// limit stack size needed for runtime decompression // limit stack size needed for runtime decompression
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 2048, strategy, compressWithFilters(&ft, 2048, &cconf, filter_strategy,
NULL, &cconf, ih.codebase, rvamin); ih.codebase, rvamin, 0, NULL, 0);
// info: see buildLoader() // info: see buildLoader()
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1; newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
/* /*
@@ -746,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); 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); 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 s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1;
const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1; const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1;
@@ -1028,7 +1027,8 @@ int PackArmPe::canUnpack()
void PackArmPe::rebuildImports(upx_byte *& extrainfo) void PackArmPe::rebuildImports(upx_byte *& extrainfo)
{ {
if (ODADDR(PEDIR_IMPORT) == 0) if (ODADDR(PEDIR_IMPORT) == 0
|| ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
return; return;
// const upx_byte * const idata = obuf + get_le32(extrainfo); // const upx_byte * const idata = obuf + get_le32(extrainfo);
@@ -1046,6 +1046,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
for (p = idata; get_le32(p) != 0; ++p) for (p = idata; get_le32(p) != 0; ++p)
{ {
const upx_byte *dname = get_le32(p) + import; const upx_byte *dname = get_le32(p) + import;
ICHECK(dname, 1);
const unsigned dlen = strlen(dname); const unsigned dlen = strlen(dname);
ICHECK(dname, dlen + 1); ICHECK(dname, dlen + 1);
@@ -1058,7 +1059,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
else else
p += 5; p += 5;
} }
sdllnames = ALIGN_UP(sdllnames,2); sdllnames = ALIGN_UP(sdllnames,2u);
upx_byte * const Obuf = obuf - rvamin; upx_byte * const Obuf = obuf - rvamin;
import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT)); import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
@@ -1071,6 +1072,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
{ {
// restore the name of the dll // restore the name of the dll
const upx_byte *dname = get_le32(p) + import; const upx_byte *dname = get_le32(p) + import;
ICHECK(dname, 1);
const unsigned dlen = strlen(dname); const unsigned dlen = strlen(dname);
ICHECK(dname, dlen + 1); ICHECK(dname, dlen + 1);
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -42,6 +42,7 @@ public:
virtual ~PackArmPe(); virtual ~PackArmPe();
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; } virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
+7 -12
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 const int *PackCom::getCompressionMethods(int method, int level) const
{ {
static const int m_nrv2b[] = { M_NRV2B_LE16, -1 }; static const int m_nrv2b[] = { M_NRV2B_LE16, M_END };
if (M_IS_NRV2B(method))
return m_nrv2b;
#if 0 #if 0
// NOT IMPLEMENTED static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
static const int m_nrv2d[] = { M_NRV2D_LE16, -1 };
if (M_IS_NRV2D(method))
return m_nrv2d;
#endif #endif
UNUSED(level); UNUSED(method); UNUSED(level);
return m_nrv2b; return m_nrv2b;
} }
@@ -63,7 +58,7 @@ const int *PackCom::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x06, 0x03, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
-1 }; FT_END };
return filters; return filters;
} }
@@ -202,7 +197,7 @@ void PackCom::pack(OutputFile *fo)
ft.addvalue = getCallTrickOffset(); ft.addvalue = getCallTrickOffset();
// compress // compress
const unsigned overlap_range = ph.u_len < 0xFE00 - ft.addvalue ? 32 : 0; 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(); const int lsize = getLoaderSize();
MemBuffer loader(lsize); MemBuffer loader(lsize);
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_DOS_COM; } virtual int getFormat() const { return UPX_F_DOS_COM; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
+16 -38
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -47,11 +47,11 @@ PackDjgpp2::PackDjgpp2(InputFile *f) :
super(f), coff_offset(0) super(f), coff_offset(0)
{ {
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40); COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8); COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
COMPILE_TIME_ASSERT_ALIGNOF(external_scnhdr_t, char) COMPILE_TIME_ASSERT_ALIGNED1(external_scnhdr_t)
COMPILE_TIME_ASSERT_ALIGNOF(coff_header_t, char) COMPILE_TIME_ASSERT_ALIGNED1(coff_header_t)
COMPILE_TIME_ASSERT(sizeof(stub_i386_dos32_djgpp2_stubify) == 2048); 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_ADLER32 == 0xbf689ba8)
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2) COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub))); //printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
@@ -68,8 +68,9 @@ const int *PackDjgpp2::getCompressionMethods(int method, int level) const
const int *PackDjgpp2::getFilters() const const int *PackDjgpp2::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12, 0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
-1 }; FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters; return filters;
} }
@@ -96,10 +97,10 @@ void PackDjgpp2::buildLoader(const Filter *ft)
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2)); initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
addLoader("IDENTSTR,DJ2MAIN1", addLoader("IDENTSTR,DJ2MAIN1",
ft->id ? "DJCALLT1" : "", ft->id ? "DJCALLT1" : "",
"DJ2MAIN2", ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
ph.method == M_LZMA ? "LZMA_INIT_STACK" : "", M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
getDecompressorSections(), getDecompressorSections(),
ph.method == M_LZMA ? "LZMA_DONE_STACK" : "", M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
"DJ2BSS00", "DJ2BSS00",
NULL NULL
); );
@@ -234,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;
}
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -325,7 +303,7 @@ void PackDjgpp2::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression // limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack 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 // patch coff header #2
const unsigned lsize = getLoaderSize(); const unsigned lsize = getLoaderSize();
@@ -334,7 +312,7 @@ void PackDjgpp2::pack(OutputFile *fo)
data->size = ph.c_len; // new size of .data data->size = ph.c_len; // new size of .data
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize(); 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 if (bss->size < stack) // give it a .bss
bss->size = stack; bss->size = stack;
@@ -350,7 +328,7 @@ void PackDjgpp2::pack(OutputFile *fo)
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size); linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize); linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
linker->defineSymbol("start_of_compressed", data->vaddr); linker->defineSymbol("start_of_compressed", data->vaddr);
defineFilterSymbols(linker, &ft); defineFilterSymbols(&ft);
// we should not overwrite our decompressor during unpacking // we should not overwrite our decompressor during unpacking
// the original coff header (which is put just before the // the original coff header (which is put just before the
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 14; }
virtual int getFormat() const { return UPX_F_DJGPP2_COFF; } virtual int getFormat() const { return UPX_F_DJGPP2_COFF; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
+247 -241
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 { 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. // 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 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 */ unsigned char e_ident[16]; /* Magic number and other info */
Half e_type; /* Object file type */ Half e_type; /* Object file type */
Half e_machine; /* Architecture */ Half e_machine; /* Architecture */
@@ -55,76 +74,57 @@ struct Ehdr
Half e_shnum; /* Section header table entry count */ Half e_shnum; /* Section header table entry count */
Half e_shstrndx; /* Section header string table index */ Half e_shstrndx; /* Section header string table index */
enum { // e_ident[] # define WANT_EHDR_ENUM 1
EI_CLASS = 4, # include "p_elf_enum.h"
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,
};
} }
__attribute_packed; __attribute_packed;
template <class Word, class Addr> template <class TElfITypes>
struct Dyn struct Dyn
{ {
Word d_tag; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr;
Xword d_tag;
Addr d_val; Addr d_val;
enum { // d_tag # define WANT_DYN_ENUM 1
DT_NULL = 0, /* End flag */ # include "p_elf_enum.h"
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 */
};
} }
__attribute_packed; __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 } // namespace N_Elf
/*************************************************************************
// N_Elf32
**************************************************************************/
namespace N_Elf32 { namespace N_Elf32 {
// Program segment header. template <class TElfITypes>
template <class Word, class Addr, class Off>
struct Phdr struct Phdr
{ {
typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off;
Word p_type; /* Segment type */ Word p_type; /* Segment type */
Off p_offset; /* Segment file offset */ Off p_offset; /* Segment file offset */
Addr p_vaddr; /* Segment virtual address */ Addr p_vaddr; /* Segment virtual address */
@@ -134,25 +134,19 @@ struct Phdr
Word p_flags; /* Segment flags */ Word p_flags; /* Segment flags */
Word p_align; /* Segment alignment */ Word p_align; /* Segment alignment */
enum { // p_type # define WANT_PHDR_ENUM 1
PT_LOAD = 1, /* Loadable program segment */ # include "p_elf_enum.h"
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 */
};
} }
__attribute_packed; __attribute_packed;
template <class Word, class Addr, class Off>
template <class TElfITypes>
struct Shdr 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_name; /* Section name (string tbl index) */
Word sh_type; /* Section type */ Word sh_type; /* Section type */
Word sh_flags; /* Section flags */ Word sh_flags; /* Section flags */
@@ -164,94 +158,53 @@ struct Shdr
Word sh_addralign; /* Section alignment */ Word sh_addralign; /* Section alignment */
Word sh_entsize; /* Entry size if section holds table */ Word sh_entsize; /* Entry size if section holds table */
enum { // sh_type # define WANT_SHDR_ENUM 1
SHT_NULL = 0, /* Section header table entry unused */ # include "p_elf_enum.h"
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 */
};
} }
__attribute_packed; __attribute_packed;
template <class TT16, class TT32>
template <class TElfITypes>
struct Sym struct Sym
{ {
TT32 st_name; /* symbol name (index into string table) */ typedef typename TElfITypes::Word Word;
TT32 st_value; /* symbol value */ typedef typename TElfITypes::Addr Addr;
TT32 st_size; /* symbol size */ 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_info; /* symbol type and binding */
unsigned char st_other; /* symbol visibility */ 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); } # define WANT_SYM_ENUM 1
unsigned int st_type(unsigned int x) const { return 0xf & x ; } # include "p_elf_enum.h"
unsigned char St_info(unsigned bind, unsigned type) const { return (bind<<4) + (0xf & type); }
enum { // st_bind (high 4 bits of st_info) static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
STB_LOCAL = 0, /* Local symbol */ static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
STB_GLOBAL = 1, /* Global symbol */ static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
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 */
};
} }
__attribute_packed; __attribute_packed;
} // namespace N_Elf32 } // namespace N_Elf32
/*************************************************************************
// N_Elf64
**************************************************************************/
namespace N_Elf64 { namespace N_Elf64 {
// Program segment header. template <class TElfITypes>
template <class Word, class Xword, class Addr, class Off>
struct Phdr 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_type; /* Segment type */
Word p_flags; /* Segment flags */ Word p_flags; /* Segment flags */
Off p_offset; /* Segment file offset */ Off p_offset; /* Segment file offset */
@@ -261,24 +214,20 @@ struct Phdr
Xword p_memsz; /* Segment size in memory */ Xword p_memsz; /* Segment size in memory */
Xword p_align; /* Segment alignment */ Xword p_align; /* Segment alignment */
enum { // p_type # define WANT_PHDR_ENUM 1
PT_LOAD = 1, /* Loadable program segment */ # include "p_elf_enum.h"
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 */
};
} }
__attribute_packed; __attribute_packed;
template <class Word, class Xword, class Addr, class Off>
template <class TElfITypes>
struct Shdr 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_name; /* Section name (string tbl index) */
Word sh_type; /* Section type */ Word sh_type; /* Section type */
Xword sh_flags; /* Section flags */ Xword sh_flags; /* Section flags */
@@ -290,115 +239,172 @@ struct Shdr
Xword sh_addralign; /* Section alignment */ Xword sh_addralign; /* Section alignment */
Xword sh_entsize; /* Entry size if section holds table */ Xword sh_entsize; /* Entry size if section holds table */
enum { // sh_type # define WANT_SHDR_ENUM 1
SHT_NULL = 0, /* Section header table entry unused */ # include "p_elf_enum.h"
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 */
};
} }
__attribute_packed; __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 } // namespace N_Elf64
/************************************************************************* /*************************************************************************
// now for the actual types // aggregate types into an ElfClass
**************************************************************************/ **************************************************************************/
#define P N_BELE_CTP::HostPolicy namespace N_Elf {
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
#define P N_BELE_CTP::BEPolicy template <class TP>
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_BE32_Ehdr; struct ElfClass_32
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 TP BeLePolicy;
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_BE32_Dyn;
typedef N_Elf32::Sym <P::U16,P::U32> Elf_BE32_Sym;
#undef P
#define P N_BELE_CTP::LEPolicy // integral types
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_LE32_Ehdr; typedef typename TP::U16 U16;
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_LE32_Phdr; typedef typename TP::U32 U32;
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_LE32_Shdr; typedef typename TP::U64 U64;
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_LE32_Dyn; typedef N_Elf::ElfITypes<U16, U32, U32, U32, U32> ElfITypes;
typedef N_Elf32::Sym <P::U16,P::U32> Elf_LE32_Sym;
#undef P
#define P N_BELE_CTP::HostPolicy // ELF types
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf64_Ehdr; typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf64_Phdr; typedef N_Elf32::Phdr<ElfITypes> Phdr;
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf64_Shdr; typedef N_Elf32::Shdr<ElfITypes> Shdr;
typedef N_Elf ::Dyn <P::U64,P::U64> Elf64_Dyn; typedef N_Elf ::Dyn <ElfITypes> Dyn;
#undef P typedef N_Elf32::Sym <ElfITypes> Sym;
typedef N_Elf ::External_Note<ElfITypes> External_Note;
#define P N_BELE_CTP::BEPolicy static void compileTimeAssertions() {
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_BE64_Ehdr; BeLePolicy::compileTimeAssertions();
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Phdr; COMPILE_TIME_ASSERT(sizeof(Ehdr) == 52)
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Shdr; COMPILE_TIME_ASSERT(sizeof(Phdr) == 32)
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_BE64_Dyn; COMPILE_TIME_ASSERT(sizeof(Shdr) == 40)
#undef P COMPILE_TIME_ASSERT(sizeof(Dyn) == 8)
COMPILE_TIME_ASSERT(sizeof(Sym) == 16)
#define P N_BELE_CTP::LEPolicy COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_LE64_Ehdr; COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Phdr; COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Shdr; COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_LE64_Dyn; COMPILE_TIME_ASSERT_ALIGNED1(Sym)
#undef P }
};
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52) template <class TP>
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32) struct ElfClass_64
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40) {
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8) typedef TP BeLePolicy;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52) // integral types
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32) typedef typename TP::U16 U16;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Shdr) == 40) typedef typename TP::U32 U32;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Dyn) == 8) typedef typename TP::U64 U64;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Sym) == 16) typedef N_Elf::ElfITypes<U16, U32, U64, U64, U64> ElfITypes;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52) // ELF types
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32) typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40) typedef N_Elf64::Phdr<ElfITypes> Phdr;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8) typedef N_Elf64::Shdr<ElfITypes> Shdr;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16) 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) static void compileTimeAssertions() {
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56) BeLePolicy::compileTimeAssertions();
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64) COMPILE_TIME_ASSERT(sizeof(Ehdr) == 64)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16) 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) } // namespace N_Elf
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) 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 */ #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 usual 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
*/
+4 -4
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -112,7 +112,7 @@ void PackElks8086::pack(OutputFile *fo)
ft.buf_len = ph.u_len; ft.buf_len = ph.u_len;
ft.addvalue = kernel_entry; ft.addvalue = kernel_entry;
// compress // compress
compressWithFilters(&ft, overlap_range); compressWithFilters(&ft, overlap_range, NULL_cconf);
const unsigned lsize = getLoaderSize(); const unsigned lsize = getLoaderSize();
MemBuffer loader(lsize); MemBuffer loader(lsize);
@@ -121,7 +121,7 @@ void PackElks8086::pack(OutputFile *fo)
patchPackHeader(loader, lsize); patchPackHeader(loader, lsize);
#if 0 #if 0
// FIXME // FIXME
defineFilterSymbols(); defineFilterSymbols(&ft);
defineDecompressorSymbols(); defineDecompressorSymbols();
//patch_le32(loader, lsize, "ESI1", zimage_offset + lsize); //patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
//patch_le32(loader, lsize, "KEIP", kernel_entry); //patch_le32(loader, lsize, "KEIP", kernel_entry);
+200 -58
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -53,25 +53,19 @@ PackExe::PackExe(InputFile *f) :
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32); COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
ih_exesize = ih_imagesize = ih_overlay = 0; ih_exesize = ih_imagesize = ih_overlay = 0;
stack_for_lzma = 0;
use_clear_dirty_stack = false;
// disable lzma for "--brute" unless explicitly given "--lzma"
if (opt->all_methods_use_lzma && !opt->method_lzma_seen)
opt->all_methods_use_lzma = false;
} }
const int *PackExe::getCompressionMethods(int method, int level) const const int *PackExe::getCompressionMethods(int method, int level) const
{ {
static const int m_nrv2b[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_END };
static const int m_nrv2d[] = { M_NRV2D_8, M_NRV2B_8, M_NRV2E_8, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_NRV2B_8, M_NRV2D_8, M_END };
bool small = ih_imagesize <= 256*1024; bool small = ih_imagesize <= 256*1024;
if (M_IS_NRV2B(method)) return Packer::getDefaultCompressionMethods_8(method, level, small);
return m_nrv2b;
if (M_IS_NRV2D(method))
return m_nrv2d;
if (M_IS_NRV2E(method))
return m_nrv2e;
if (level == 1 || small)
return m_nrv2b;
return m_nrv2e;
} }
@@ -86,7 +80,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
#define oh (*eh) #define oh (*eh)
// fill new exe header // fill new exe header
int flag = 0; int flag = 0;
if (!opt->dos_exe.no_reloc) if (!opt->dos_exe.no_reloc && !M_IS_LZMA(ph.method))
flag |= USEJUMP; flag |= USEJUMP;
if (ih.relocs == 0) if (ih.relocs == 0)
flag |= NORELOC; flag |= NORELOC;
@@ -95,7 +89,16 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
oh.ident = 'M' + 'Z' * 256; oh.ident = 'M' + 'Z' * 256;
oh.headsize16 = 2; oh.headsize16 = 2;
oh.sp = ih.sp > 0x200 ? (unsigned) ih.sp : 0x200; unsigned minsp = 0x200;
if (M_IS_LZMA(ph.method))
minsp = stack_for_lzma;
minsp = ALIGN_UP(minsp, 16u);
assert(minsp < 0xff00);
if (oh.sp > minsp)
minsp = oh.sp;
if (minsp < 0xff00 - 2)
minsp = ALIGN_UP(minsp, 2u);
oh.sp = minsp;
unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16; unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16;
oh.ss = ph.c_len/16 + destpara; oh.ss = ph.c_len/16 + destpara;
@@ -107,27 +110,118 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
if (oh.ss != ih.ss) if (oh.ss != ih.ss)
flag |= SS; flag |= SS;
if (oh.sp != ih.sp) if (oh.sp != ih.sp || M_IS_LZMA(ph.method))
flag |= SP; flag |= SP;
return flag; return flag;
#undef oh #undef oh
} }
void PackExe::addLoaderEpilogue(int flag)
{
addLoader("EXEMAIN5", NULL);
if (relocsize)
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
"EXERELO1",
has_9a ? "EXEREL9A" : "",
"EXERELO2",
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
"EXERELO3",
NULL
);
addLoader("EXEMAIN8",
device_driver ? "DEVICEEND" : "",
(flag & SS) ? "EXESTACK" : "",
(flag & SP) ? "EXESTASP" : "",
(flag & USEJUMP) ? "EXEJUMPF" : "",
NULL
);
if (!(flag & USEJUMP))
addLoader(ih.cs ? "EXERCSPO" : "",
"EXERETIP",
NULL
);
linker->defineSymbol("original_cs", ih.cs);
linker->defineSymbol("original_ip", ih.ip);
linker->defineSymbol("original_sp", ih.sp);
linker->defineSymbol("original_ss", ih.ss);
linker->defineSymbol("reloc_size",
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
>= relocsize ? 0 : MAXRELOCS) - relocsize);
}
void PackExe::buildLoader(const Filter *) void PackExe::buildLoader(const Filter *)
{ {
struct exe_header_t tmp_oh; // get flag
int flag = fillExeHeader(&tmp_oh); exe_header_t dummy_oh;
int flag = fillExeHeader(&dummy_oh);
// prepare loader
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe)); initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
if (M_IS_LZMA(ph.method))
{
addLoader("LZMA_DEC00",
opt->small ? "LZMA_DEC10" : "LZMA_DEC20",
"LZMA_DEC30",
use_clear_dirty_stack ? "LZMA_DEC31" : "",
"LZMA_DEC32",
ph.u_len > 0xffff ? "LZMA_DEC33" : "",
NULL
);
addLoaderEpilogue(flag);
defineDecompressorSymbols();
const unsigned lsize0 = getLoaderSize();
// Lzma decompression code starts at ss:0x10, and its size is
// lsize bytes. It also needs getDecompressorWrkmemSize() bytes
// during uncompression. It also uses some stack, so 0x100
// more bytes are allocated
stack_for_lzma = 0x10 + lsize0 + getDecompressorWrkmemSize() + 0x100;
stack_for_lzma = ALIGN_UP(stack_for_lzma, 16u);
unsigned clear_dirty_stack_low = 0x10 + lsize0;
clear_dirty_stack_low = ALIGN_UP(clear_dirty_stack_low, 2u);
if (use_clear_dirty_stack)
linker->defineSymbol("clear_dirty_stack_low", clear_dirty_stack_low);
relocateLoader();
const unsigned lsize = getLoaderSize();
assert(lsize0 == lsize);
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
MemBuffer compressed_lzma;
compressed_lzma.allocForCompression(lsize);
unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize);
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma,
NULL, M_NRV2B_LE16, 9, NULL, NULL);
assert(r == UPX_E_OK); assert(c_len_lzma < lsize);
info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma);
// reinit the loader
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
// prepare loader
if (device_driver) if (device_driver)
addLoader("DEVICEENTRY", NULL); addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", NULL);
linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0);
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2",
NULL);
}
else if (device_driver)
addLoader("DEVICEENTRY,DEVICEENTRY2", NULL);
addLoader("EXEENTRY", addLoader("EXEENTRY",
device_driver ? "DEVICESUB" : "EXESUB", M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
"JNCDOCOPY", "JNCDOCOPY",
relocsize ? "EXERELPU" : "", relocsize ? "EXERELPU" : "",
"EXEMAIN4,+G5DXXXX,UPX1HEAD,EXECUTPO", "EXEMAIN4",
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B",
"EXEMAIN4C",
M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "",
"+G5DXXXX,UPX1HEAD,EXECUTPO",
NULL NULL
); );
if (ph.method == M_NRV2B_8) if (ph.method == M_NRV2B_8)
@@ -166,30 +260,12 @@ void PackExe::buildLoader(const Filter *)
"NRV2EEX9", "NRV2EEX9",
NULL NULL
); );
else if M_IS_LZMA(ph.method)
return;
else else
throwInternalError("unknown compression method"); throwInternalError("unknown compression method");
addLoader("EXEMAIN5", NULL);
if (relocsize) addLoaderEpilogue(flag);
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
"EXERELO1",
has_9a ? "EXEREL9A" : "",
"EXERELO2",
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
"EXERELO3",
NULL
);
addLoader("EXEMAIN8",
device_driver ? "DEVICEEND" : "",
(flag & SS) ? "EXESTACK" : "",
(flag & SP) ? "EXESTASP" : "",
(flag & USEJUMP) ? "EXEJUMPF" : "",
NULL
);
if (!(flag & USEJUMP))
addLoader(ih.cs ? "EXERCSPO" : "",
"EXERETIP",
NULL
);
} }
@@ -325,7 +401,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
break; break;
} }
unsigned offs = addr - es*16; unsigned offs = addr - es*16;
if (offs >= 3 && b[es*16 + offs-3] == 0x9a) if (offs >= 3 && b[es*16 + offs-3] == 0x9a && offs > di + 3)
{ {
for (t = di; t < offs-3; t++) for (t = di; t < offs-3; t++)
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high) if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
@@ -430,7 +506,10 @@ void PackExe::pack(OutputFile *fo)
// compress (max_match = 8192) // compress (max_match = 8192)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
cconf.conf_ucl.max_match = MAXMATCH; cconf.conf_ucl.max_match = MAXMATCH;
compressWithFilters(&ft, 32, 0, NULL, &cconf); cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 32, &cconf);
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
if (ph.max_run_found + ph.max_match_found > 0x8000) if (ph.max_run_found + ph.max_match_found > 0x8000)
throwCantPack("decompressor limit exceeded, send a bugreport"); throwCantPack("decompressor limit exceeded, send a bugreport");
@@ -498,15 +577,13 @@ void PackExe::pack(OutputFile *fo)
} }
extra_info[eisize++] = (unsigned char) flag; extra_info[eisize++] = (unsigned char) flag;
linker->defineSymbol("original_cs", ih.cs); if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
linker->defineSymbol("original_ip", ih.ip);
linker->defineSymbol("original_sp", ih.sp);
linker->defineSymbol("original_ss", ih.ss);
linker->defineSymbol("reloc_size",
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
>= relocsize ? 0 : MAXRELOCS) - relocsize);
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1)); linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
linker->defineSymbol("decompressor_entry", (packedsize & 15) + 1);
unsigned decompressor_entry = 1 + (packedsize & 15);
if (M_IS_LZMA(ph.method))
decompressor_entry = 0x10;
linker->defineSymbol("decompressor_entry", decompressor_entry);
// patch loader // patch loader
if (flag & USEJUMP) if (flag & USEJUMP)
@@ -542,8 +619,10 @@ void PackExe::pack(OutputFile *fo)
oh.m512 = outputlen & 511; oh.m512 = outputlen & 511;
oh.p512 = (outputlen + 511) >> 9; oh.p512 = (outputlen + 511) >> 9;
oh.ip = device_driver ? getLoaderSection("EXEENTRY") - 2 : 0; const char *exeentry = M_IS_LZMA(ph.method) ? "LZMAENTRY" : "EXEENTRY";
oh.ip = device_driver ? getLoaderSection(exeentry) - 2 : 0;
defineDecompressorSymbols();
relocateLoader(); relocateLoader();
memcpy(loader, getLoader(), lsize); memcpy(loader, getLoader(), lsize);
patchPackHeader(loader,e_len); patchPackHeader(loader,e_len);
@@ -592,7 +671,7 @@ int PackExe::canUnpack()
return false; return false;
const off_t off = ih.headsize16 * 16; const off_t off = ih.headsize16 * 16;
fi->seek(off, SEEK_SET); fi->seek(off, SEEK_SET);
bool b = readPackHeader(256); bool b = readPackHeader(4096);
return b && (off + (off_t) ph.c_len <= file_size); return b && (off + (off_t) ph.c_len <= file_size);
} }
@@ -727,6 +806,69 @@ Linker* PackExe::newLinker() const
return new ElfLinkerX86(); return new ElfLinkerX86();
} }
/*
memory layout at decompression time
===================================
normal exe
----------
a, at load time
(e - copying code, C - compressed data, d - decompressor+relocator,
x - not specified, U - uncompressed code+data, R uncompressed relocation)
eeCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCdddd
^ CS:0 ^ SS:0
b, after copying
xxxxxxxxxxxxxxxCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCdddd
^ES:DI=0 ^ DS:SI=0 ^ CS=SS, IP in range 0..0xf
c, after uncompression
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUURRdddd
^ ES:DI
device driver
-------------
the file has 2 entry points, CS:0 in device driver mode, and
CS:exe_as_device_entry in normal mode. the code in section DEVICEENTRY
sets up the same environment for section EXEENTRY, as it would see in normal
execution mode.
lzma uncompression for normal exes
----------------------------------
(n - nrv2b uncompressor, l - nrv2b compressed lzma + relocator code)
a, at load time
nneelllCCCCCCCCCCCCCCCCCCCCCCCCC
^ CS:0 ^ SS:0
b, after nrv2b
nneelllCCCCCCCCCCCCCCCCCCCCCCCCC dddd
^ CS:0 ^ SS:0x10
after this, normal ee code runs
lzma + device driver
--------------------
(D - device driver adapter)
a, at load time
DDnneelllCCCCCCCCCCCCCCCCCCCCCCCCC
*/
/* /*
vi:ts=4:et vi:ts=4:et
+7 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_DOS_EXE; } virtual int getFormat() const { return UPX_F_DOS_EXE; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
@@ -70,6 +71,7 @@ protected:
virtual int fillExeHeader(struct exe_header_t *) const; virtual int fillExeHeader(struct exe_header_t *) const;
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
void addLoaderEpilogue(int flag);
struct exe_header_t struct exe_header_t
{ {
@@ -109,6 +111,9 @@ protected:
MINMEM = 16, MINMEM = 16,
MAXMEM = 32 MAXMEM = 32
}; };
unsigned stack_for_lzma; // stack size required for lzma
bool use_clear_dirty_stack;
}; };
+19 -19
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -249,8 +249,8 @@ int const *
PackLinuxElf32ppc::getFilters() const PackLinuxElf32ppc::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0xd0, -1 0xd0,
}; FT_END };
return filters; return filters;
} }
@@ -258,8 +258,8 @@ int const *
PackLinuxElf64amd::getFilters() const PackLinuxElf64amd::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x49, -1 0x49,
}; FT_END };
return filters; return filters;
} }
@@ -464,7 +464,7 @@ PackLinuxElf32::buildLinuxLoader(
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc) if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
throwInternalError("loader compression failed"); throwInternalError("loader compression failed");
#if 0 //{ debugging only #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 ucl_uint tmp_len = h.sz_unc; // LZMA uses this as EOF
unsigned char *tmp = new unsigned char[tmp_len]; unsigned char *tmp = new unsigned char[tmp_len];
memset(tmp, 0, tmp_len); memset(tmp, 0, tmp_len);
@@ -776,12 +776,12 @@ bool PackLinuxElf32::canPack()
// additional requirements for linux/elf386 // additional requirements for linux/elf386
if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) { 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; return false;
} }
unsigned const e_phoff = get_native32(&ehdr->e_phoff); unsigned const e_phoff = get_native32(&ehdr->e_phoff);
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr 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; return false;
} }
@@ -794,7 +794,7 @@ bool PackLinuxElf32::canPack()
return false; return false;
if (1!=exetype && phdr->PT_LOAD32 == get_native32(&phdr->p_type)) { if (1!=exetype && phdr->PT_LOAD32 == get_native32(&phdr->p_type)) {
if (phdr->p_offset != 0) { if (phdr->p_offset != 0) {
throwCantPack("invalid Phdr p_offset; try `--force-execve'"); throwCantPack("invalid Phdr p_offset; try '--force-execve'");
return false; return false;
} }
exetype = 1; exetype = 1;
@@ -863,7 +863,7 @@ bool PackLinuxElf32::canPack()
// elf_lookup() returns 0 if any required table is missing. // elf_lookup() returns 0 if any required table is missing.
Elf32_Sym const *const lsm = elf_lookup(run_start[j]); Elf32_Sym const *const lsm = elf_lookup(run_start[j]);
if (lsm && get_native16(&lsm->st_shndx)==Elf32_Sym::SHN_UNDEF 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 ) { && get_native16(&lsm->st_other)==Elf32_Sym::STV_DEFAULT ) {
break; break;
} }
@@ -901,25 +901,25 @@ PackLinuxElf64amd::canPack()
// additional requirements for linux/elf386 // additional requirements for linux/elf386
if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) { 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; return false;
} }
acc_uint64l_t const e_phoff = get_native64(&ehdr->e_phoff); acc_uint64l_t const e_phoff = get_native64(&ehdr->e_phoff);
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr 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; return false;
} }
// The first PT_LOAD64 must cover the beginning of the file (0==p_offset). // The first PT_LOAD64 must cover the beginning of the file (0==p_offset).
unsigned const e_phnum = get_native16(&ehdr->e_phnum); 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) { for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
if (j >= 14) if (j >= 14)
return false; return false;
if (phdr->PT_LOAD64 == get_native32(&phdr->p_type)) { if (phdr->PT_LOAD64 == get_native32(&phdr->p_type)) {
// Just avoid the "rewind" when unpacking? // Just avoid the "rewind" when unpacking?
//if (phdr->p_offset != 0) { //if (phdr->p_offset != 0) {
// throwCantPack("invalid Phdr p_offset; try `--force-execve'"); // throwCantPack("invalid Phdr p_offset; try '--force-execve'");
// return false; // return false;
//} //}
exetype = 1; exetype = 1;
@@ -1424,8 +1424,8 @@ using namespace N_BELE_CTP;
static const int * static const int *
ARM_getFilters(bool const isBE) ARM_getFilters(bool const isBE)
{ {
static const int f50[] = { 0x50, -1 }; static const int f50[] = { 0x50, FT_END };
static const int f51[] = { 0x51, -1 }; static const int f51[] = { 0x51, FT_END };
if (isBE) if (isBE)
return f51; return f51;
return f50; return f50;
@@ -1857,7 +1857,7 @@ PackLinuxElf32x86::getFilters() const
0x82, 0x85, 0x82, 0x85,
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12, 0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
#endif #endif
-1 }; FT_END };
return filters; return filters;
} }
+29 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -161,6 +161,15 @@ protected:
char text[0x18 - 4*4]; // "OpenBSD" char text[0x18 - 4*4]; // "OpenBSD"
unsigned end; // 0 unsigned end; // 0
} elfnote; } 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)
}
}; };
@@ -225,6 +234,15 @@ protected:
__attribute_packed; __attribute_packed;
cprElfHdr3 elfout; 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 class PackLinuxElf32Be : public PackLinuxElf32
@@ -281,6 +299,7 @@ public:
virtual ~PackLinuxElf64amd(); virtual ~PackLinuxElf64amd();
virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; } virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; }
virtual const char *getName() const { return "linux/ElfAMD"; } 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 const int *getFilters() const;
virtual bool canPack(); virtual bool canPack();
protected: protected:
@@ -303,6 +322,7 @@ public:
virtual ~PackLinuxElf32ppc(); virtual ~PackLinuxElf32ppc();
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; } virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
virtual const char *getName() const { return "linux/ElfPPC"; } 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; virtual const int *getFilters() const;
protected: protected:
virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack1(OutputFile *, Filter &); // generate executable header
@@ -322,6 +342,7 @@ public:
virtual ~PackLinuxElf32x86(); virtual ~PackLinuxElf32x86();
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; } virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
virtual const char *getName() const { return "linux/elf386"; } 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 const int *getFilters() const;
virtual void unpack(OutputFile *fo); virtual void unpack(OutputFile *fo);
@@ -356,6 +377,7 @@ class PackFreeBSDElf32x86 : public PackBSDElf32x86
public: public:
PackFreeBSDElf32x86(InputFile *f); PackFreeBSDElf32x86(InputFile *f);
virtual ~PackFreeBSDElf32x86(); virtual ~PackFreeBSDElf32x86();
virtual const char *getFullName(const options_t *) const { return "i386-freebsd.elf"; }
}; };
class PackNetBSDElf32x86 : public PackBSDElf32x86 class PackNetBSDElf32x86 : public PackBSDElf32x86
@@ -364,6 +386,7 @@ class PackNetBSDElf32x86 : public PackBSDElf32x86
public: public:
PackNetBSDElf32x86(InputFile *f); PackNetBSDElf32x86(InputFile *f);
virtual ~PackNetBSDElf32x86(); virtual ~PackNetBSDElf32x86();
virtual const char *getFullName(const options_t *) const { return "i386-netbsd.elf"; }
}; };
class PackOpenBSDElf32x86 : public PackBSDElf32x86 class PackOpenBSDElf32x86 : public PackBSDElf32x86
@@ -372,6 +395,7 @@ class PackOpenBSDElf32x86 : public PackBSDElf32x86
public: public:
PackOpenBSDElf32x86(InputFile *f); PackOpenBSDElf32x86(InputFile *f);
virtual ~PackOpenBSDElf32x86(); virtual ~PackOpenBSDElf32x86();
virtual const char *getFullName(const options_t *) const { return "i386-openbsd.elf"; }
protected: protected:
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
@@ -394,6 +418,7 @@ public:
virtual ~PackLinuxElf32armLe(); virtual ~PackLinuxElf32armLe();
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; } virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
virtual const char *getName() const { return "linux/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; virtual const int *getFilters() const;
protected: protected:
@@ -413,6 +438,7 @@ public:
virtual ~PackLinuxElf32armBe(); virtual ~PackLinuxElf32armBe();
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; } virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; }
virtual const char *getName() const { return "linux/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; virtual const int *getFilters() const;
protected: protected:
+6 -6
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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) 2001-2006 John F. Reiser Copyright (C) 2001-2007 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -100,7 +100,7 @@ const int *PackLinuxI386::getFilters() const
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85, 0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12, 0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
#endif #endif
-1 }; FT_END };
return filters; return filters;
} }
@@ -204,7 +204,7 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ; ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
unsigned nw = fo->getBytesWritten(); unsigned nw = fo->getBytesWritten();
elfout.phdr[0].p_filesz = nw; 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 super::pack4(fo, ft); // write PackHeader and overlay_offset
set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr); set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);
@@ -373,7 +373,7 @@ PackLinuxI386::buildLinuxLoader(
addLoader("IDENTSTR", NULL); addLoader("IDENTSTR", NULL);
addLoader("LEXEC020", NULL); addLoader("LEXEC020", NULL);
addLoader("FOLDEXEC", NULL); addLoader("FOLDEXEC", NULL);
if (ph.method == M_LZMA) { if (M_IS_LZMA(ph.method)) {
const lzma_compress_result_t *res = &ph.compress_result.result_lzma; const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
acc_uint32e_t properties = // lc, lp, pb, dummy acc_uint32e_t properties = // lc, lp, pb, dummy
(res->lit_context_bits << 0) | (res->lit_context_bits << 0) |
+13 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -49,6 +49,7 @@ public:
); );
virtual int getFormat() const { return UPX_F_LINUX_i386; } virtual int getFormat() const { return UPX_F_LINUX_i386; }
virtual const char *getName() const { return "linux/386"; } 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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
virtual void buildLoader(const Filter *); virtual void buildLoader(const Filter *);
@@ -119,6 +120,15 @@ protected:
unsigned char ei_osabi; unsigned char ei_osabi;
char const *osabi_note; 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,6 +139,7 @@ public:
PackBSDI386(InputFile *f); PackBSDI386(InputFile *f);
virtual int getFormat() const { return UPX_F_BSD_i386; } virtual int getFormat() const { return UPX_F_BSD_i386; }
virtual const char *getName() const { return "*BSD/386"; } virtual const char *getName() const { return "*BSD/386"; }
virtual const char *getFullName(const options_t *) const { return "i386-bsd.elf.execve"; }
protected: protected:
virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack1(OutputFile *, Filter &); // generate executable header
+6 -6
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -164,9 +164,9 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL); ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL);
addLoader("LXPTI090", NULL); addLoader("LXPTI090", NULL);
addLoader("LXPTI043", NULL); //addLoader("LXPTI043", NULL);
ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL); //ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
addLoader("LXPTI090", NULL); //addLoader("LXPTI090", NULL);
addLoader("LXPTI091", NULL); addLoader("LXPTI091", NULL);
+4 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; } virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
virtual const char *getName() const { return "linux/elfi386"; } 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 bool canPack();
virtual void unpack(OutputFile *fo); virtual void unpack(OutputFile *fo);
+4 -4
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -85,7 +85,7 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
// get fresh filter // get fresh filter
Filter fold_ft = *ft; Filter fold_ft = *ft;
fold_ft.init(ft->id, ft->addvalue); 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; fold_ft.preferred_ctos = preferred_ctos;
// filter // filter
+4 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_LINUX_SH_i386; } virtual int getFormat() const { return UPX_F_LINUX_SH_i386; }
virtual const char *getName() const { return "linux/sh386"; } 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 const int *getFilters() const { return NULL; }
virtual void buildLoader(const Filter *); virtual void buildLoader(const Filter *);
+420 -55
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 2004-2006 John Reiser Copyright (C) 2004-2007 John Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -39,28 +39,46 @@ static const
static const static const
#include "stub/powerpc-darwin.macho-fold.h" #include "stub/powerpc-darwin.macho-fold.h"
PackMachPPC32::PackMachPPC32(InputFile *f) : static const
super(f), n_segment(0), rawmseg(0), msegcmd(0) #include "stub/i386-darwin.macho-entry.h"
static const
#include "stub/i386-darwin.macho-fold.h"
template <class T>
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned flavor,
unsigned count, unsigned size) :
super(f), my_cputype(cputype), my_thread_flavor(flavor),
my_thread_state_word_count(count), my_thread_command_size(size),
n_segment(0), rawmseg(NULL), msegcmd(NULL)
{ {
MachClass::compileTimeAssertions();
bele = N_BELE_CTP::getRTP<BeLePolicy>();
} }
PackMachPPC32::~PackMachPPC32() template <class T>
PackMachBase<T>::~PackMachBase()
{ {
delete [] msegcmd;
delete [] rawmseg; delete [] rawmseg;
delete [] msegcmd;
} }
const int *PackMachPPC32::getCompressionMethods(int /*method*/, int /*level*/) const template <class T>
const int *PackMachBase<T>::getCompressionMethods(int method, int level) const
{ {
// There really is no LE bias in M_NRV2E_LE32. // There really is no LE bias.
static const int m_nrv2e[] = { M_NRV2E_LE32, -1 }; return Packer::getDefaultCompressionMethods_le32(method, level);
return m_nrv2e;
} }
const int *PackMachPPC32::getFilters() const const int *PackMachPPC32::getFilters() const
{ {
static const int filters[] = { 0xd0, -1 }; static const int filters[] = { 0xd0, FT_END };
return filters;
}
int const *PackMachI386::getFilters() const
{
static const int filters[] = { 0x49, FT_END };
return filters; return filters;
} }
@@ -69,8 +87,14 @@ Linker *PackMachPPC32::newLinker() const
return new ElfLinkerPpc32; return new ElfLinkerPpc32;
} }
Linker *PackMachI386::newLinker() const
{
return new ElfLinkerX86;
}
template <class T>
void void
PackMachPPC32::addStubEntrySections(Filter const *) PackMachBase<T>::addStubEntrySections(Filter const *)
{ {
addLoader("MACOS000", NULL); addLoader("MACOS000", NULL);
//addLoader(getDecompressorSections(), NULL); //addLoader(getDecompressorSections(), NULL);
@@ -83,15 +107,79 @@ PackMachPPC32::addStubEntrySections(Filter const *)
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL); addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
} }
void PackMachI386::addStubEntrySections(Filter const *ft)
{
int const n_mru = ft->n_mru; // FIXME: belongs to filter? packerf?
void PackMachPPC32::defineSymbols(Filter const *) // entry to stub
addLoader("LEXEC000", NULL);
if (ft->id) {
{ // decompr, unfilter are separate
addLoader("LXUNF000", NULL);
addLoader("LXUNF002", NULL);
if (0x80==(ft->id & 0xF0)) {
if (256==n_mru) {
addLoader("MRUBYTE0", NULL);
}
else if (n_mru) {
addLoader("LXMRU005", NULL);
}
if (n_mru) {
addLoader("LXMRU006", NULL);
}
else {
addLoader("LXMRU007", NULL);
}
}
else if (0x40==(ft->id & 0xF0)) {
addLoader("LXUNF008", NULL);
}
addLoader("LXUNF010", NULL);
}
if (n_mru) {
addLoader("LEXEC009", NULL);
}
}
addLoader("LEXEC010", NULL);
addLoader(getDecompressorSections(), NULL);
addLoader("LEXEC015", NULL);
if (ft->id) {
{ // decompr, unfilter are separate
if (0x80!=(ft->id & 0xF0)) {
addLoader("LXUNF042", NULL);
}
}
addFilter32(ft->id);
{ // decompr, unfilter are separate
if (0x80==(ft->id & 0xF0)) {
if (0==n_mru) {
addLoader("LXMRU058", NULL);
}
}
addLoader("LXUNF035", NULL);
}
}
else {
addLoader("LEXEC017", NULL);
}
addLoader("IDENTSTR", NULL);
addLoader("LEXEC020", NULL);
addLoader("FOLDEXEC", NULL);
}
template <class T>
void PackMachBase<T>::defineSymbols(Filter const *)
{ {
// empty // empty
} }
template <class T>
void void
PackMachPPC32::buildMachLoader( PackMachBase<T>::buildMachLoader(
upx_byte const *const proto, upx_byte const *const proto,
unsigned const szproto, unsigned const szproto,
upx_byte const *const fold, upx_byte const *const fold,
@@ -142,11 +230,23 @@ PackMachPPC32::buildLoader(const Filter *ft)
stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry), stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry),
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft ); stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
} }
void PackMachPPC32::patchLoader() { }
void PackMachPPC32::updateLoader(OutputFile *) {}
void void
PackMachPPC32::patchLoaderChecksum() PackMachI386::buildLoader(const Filter *ft)
{
buildMachLoader(
stub_i386_darwin_macho_entry, sizeof(stub_i386_darwin_macho_entry),
stub_i386_darwin_macho_fold, sizeof(stub_i386_darwin_macho_fold), ft );
}
template <class T>
void PackMachBase<T>::patchLoader() { }
template <class T>
void PackMachBase<T>::updateLoader(OutputFile *) {}
template <class T>
void PackMachBase<T>::patchLoaderChecksum()
{ {
unsigned char *const ptr = getLoader(); unsigned char *const ptr = getLoader();
l_info *const lp = &linfo; l_info *const lp = &linfo;
@@ -160,8 +260,9 @@ PackMachPPC32::patchLoaderChecksum()
lp->l_checksum = upx_adler32(ptr, lsize); lp->l_checksum = upx_adler32(ptr, lsize);
} }
static int __acc_cdecl_qsort template <class T>
compare_segment_command(void const *const aa, void const *const bb) int __acc_cdecl_qsort
PackMachBase<T>::compare_segment_command(void const *const aa, void const *const bb)
{ {
Mach_segment_command const *const a = (Mach_segment_command const *)aa; Mach_segment_command const *const a = (Mach_segment_command const *)aa;
Mach_segment_command const *const b = (Mach_segment_command const *)bb; Mach_segment_command const *const b = (Mach_segment_command const *)bb;
@@ -174,8 +275,7 @@ compare_segment_command(void const *const aa, void const *const bb)
return 0; return 0;
} }
void void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{ {
// offset of p_info in compressed file // offset of p_info in compressed file
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo); overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
@@ -184,31 +284,59 @@ PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
segcmdo.filesize = fo->getBytesWritten(); segcmdo.filesize = fo->getBytesWritten();
segcmdo.vmsize += segcmdo.filesize; segcmdo.vmsize += segcmdo.filesize;
fo->seek(sizeof(mhdro), SEEK_SET); fo->seek(sizeof(mhdro), SEEK_SET);
fo->write(&segcmdo, sizeof(segcmdo)); fo->rewrite(&segcmdo, sizeof(segcmdo));
fo->write(&threado, sizeof(threado)); fo->rewrite(&threado, sizeof(threado));
fo->write(&linfo, sizeof(linfo)); fo->rewrite(&linfo, sizeof(linfo));
} }
void void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader {
// offset of p_info in compressed file
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
super::pack4(fo, ft);
segcmdo.filesize = fo->getBytesWritten();
segcmdo.vmsize += segcmdo.filesize;
fo->seek(sizeof(mhdro), SEEK_SET);
fo->rewrite(&segcmdo, sizeof(segcmdo));
fo->rewrite(&threado, sizeof(threado));
fo->rewrite(&linfo, sizeof(linfo));
}
void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
BE32 disp; BE32 disp;
unsigned const zero = 0; unsigned const zero = 0;
unsigned len = fo->getBytesWritten(); unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& -len); fo->write(&zero, 3& (0u-len));
len += (3& -len) + sizeof(disp); len += (3& (0u-len)) + sizeof(disp);
set_be32(&disp, 4+ len - sz_mach_headers); // 4: sizeof(instruction) disp = 4+ len - sz_mach_headers; // 4: sizeof(instruction)
fo->write(&disp, sizeof(disp)); fo->write(&disp, sizeof(disp));
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */ threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
super::pack3(fo, ft); super::pack3(fo, ft);
} }
void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
{
LE32 disp;
unsigned const zero = 0;
unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len));
len += (3& (0u-len));
disp = len - sz_mach_headers;
fo->write(&disp, sizeof(disp));
threado.state.eip = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
super::pack3(fo, ft);
}
// Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD // Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD
// which follows in the file (or end-of-file). Optimize for common case // which follows in the file (or end-of-file). Optimize for common case
// where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap. // where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap.
unsigned PackMachPPC32::find_SEGMENT_gap( template <class T>
unsigned PackMachBase<T>::find_SEGMENT_gap(
unsigned const k unsigned const k
) )
{ {
@@ -216,8 +344,7 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
|| 0==msegcmd[k].filesize ) { || 0==msegcmd[k].filesize ) {
return 0; return 0;
} }
unsigned const hi = get_native32(&msegcmd[k].fileoff) + unsigned const hi = msegcmd[k].fileoff + msegcmd[k].filesize;
get_native32(&msegcmd[k].filesize);
unsigned lo = ph.u_file_size; unsigned lo = ph.u_file_size;
unsigned j = k; unsigned j = k;
for (;;) { // circular search, optimize for adjacent ascending for (;;) { // circular search, optimize for adjacent ascending
@@ -230,7 +357,7 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
} }
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd
&& 0!=msegcmd[j].filesize ) { && 0!=msegcmd[j].filesize ) {
unsigned const t = get_native32(&msegcmd[j].fileoff); unsigned const t = msegcmd[j].fileoff;
if ((t - hi) < (lo - hi)) { if ((t - hi) < (lo - hi)) {
lo = t; lo = t;
if (hi==lo) { if (hi==lo) {
@@ -242,8 +369,20 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
return lo - hi; return lo - hi;
} }
void template <class T>
PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft)
{
PackUnix::pack4(fo, ft); // FIXME super() does not work?
}
template <class T>
void PackMachBase<T>::pack3(OutputFile *fo, Filter &ft)
{
PackUnix::pack3(fo, ft); // FIXME super() does not work?
}
template <class T>
void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed body
{ {
Extent x; Extent x;
unsigned k; unsigned k;
@@ -269,6 +408,17 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
uip->ui_pass = 0; uip->ui_pass = 0;
ft.addvalue = 0; ft.addvalue = 0;
// Packer::compressWithFilters chooses a filter for us, and the stubs
// can handle only one filter, and most filters are for executable
// instructions. So filter only the largest executable segment.
unsigned exe_filesize_max = 0;
for (k = 0; k < n_segment; ++k)
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
&& exe_filesize_max < msegcmd[k].filesize) {
exe_filesize_max = msegcmd[k].filesize;
}
int nx = 0; int nx = 0;
for (k = 0; k < n_segment; ++k) for (k = 0; k < n_segment; ++k)
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
@@ -280,17 +430,20 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
x.offset += delta; x.offset += delta;
x.size -= delta; x.size -= delta;
} }
bool const do_filter = (msegcmd[k].filesize==exe_filesize_max)
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot);
packExtent(x, total_in, total_out, packExtent(x, total_in, total_out,
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot) (do_filter ? &ft : 0 ), fo, hdr_u_len );
? &ft : 0 ), fo, hdr_u_len ); if (do_filter) {
exe_filesize_max = 0;
}
hdr_u_len = 0; hdr_u_len = 0;
++nx; ++nx;
} }
for (k = 0; k < n_segment; ++k) { for (k = 0; k < n_segment; ++k) {
x.size = find_SEGMENT_gap(k); x.size = find_SEGMENT_gap(k);
if (x.size) { if (x.size) {
x.offset = get_native32(&msegcmd[k].fileoff) + x.offset = msegcmd[k].fileoff +msegcmd[k].filesize;
get_native32(&msegcmd[k].filesize);
packExtent(x, total_in, total_out, 0, fo); packExtent(x, total_in, total_out, 0, fo);
} }
} }
@@ -304,12 +457,33 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
#undef PAGE_SIZE #undef PAGE_SIZE
#define PAGE_MASK (~0u<<12) #define PAGE_MASK (~0u<<12)
#define PAGE_SIZE -PAGE_MASK #define PAGE_SIZE -PAGE_MASK
void
PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable header void PackMachPPC32::pack1_setup_threado(OutputFile *const fo)
{
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
threado.cmdsize = sizeof(threado);
threado.flavor = my_thread_flavor;
threado.count = my_thread_state_word_count;
memset(&threado.state, 0, sizeof(threado.state));
fo->write(&threado, sizeof(threado));
}
void PackMachI386::pack1_setup_threado(OutputFile *const fo)
{
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
threado.cmdsize = sizeof(threado);
threado.flavor = my_thread_flavor;
threado.count = my_thread_state_word_count;
memset(&threado.state, 0, sizeof(threado.state));
fo->write(&threado, sizeof(threado));
}
template <class T>
void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header
{ {
mhdro = mhdri; mhdro = mhdri;
mhdro.ncmds = 2; mhdro.ncmds = 2;
mhdro.sizeofcmds = sizeof(segcmdo) + sizeof(threado); mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;
mhdro.flags = Mach_header::MH_NOUNDEFS; mhdro.flags = Mach_header::MH_NOUNDEFS;
fo->write(&mhdro, sizeof(mhdro)); fo->write(&mhdro, sizeof(mhdro));
@@ -329,12 +503,7 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
segcmdo.flags = 0; segcmdo.flags = 0;
fo->write(&segcmdo, sizeof(segcmdo)); fo->write(&segcmdo, sizeof(segcmdo));
threado.cmd = Mach_segment_command::LC_UNIXTHREAD; pack1_setup_threado(fo);
threado.cmdsize = sizeof(threado);
threado.flavor = Mach_thread_command::PPC_THREAD_STATE;
threado.count = Mach_thread_command::PPC_THREAD_STATE_COUNT;
memset(&threado.state, 0, sizeof(threado.state));
fo->write(&threado, sizeof(threado));
sz_mach_headers = fo->getBytesWritten(); sz_mach_headers = fo->getBytesWritten();
memset((char *)&linfo, 0, sizeof(linfo)); memset((char *)&linfo, 0, sizeof(linfo));
@@ -343,9 +512,11 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
return; return;
} }
void template <class T>
PackMachPPC32::unpack(OutputFile *fo) void PackMachBase<T>::unpack(OutputFile *fo)
{ {
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) +
my_thread_command_size + sizeof(linfo);
fi->seek(overlay_offset, SEEK_SET); fi->seek(overlay_offset, SEEK_SET);
p_info hbuf; p_info hbuf;
fi->readx(&hbuf, sizeof(hbuf)); fi->readx(&hbuf, sizeof(hbuf));
@@ -359,6 +530,8 @@ PackMachPPC32::unpack(OutputFile *fo)
fi->readx(&bhdr, sizeof(bhdr)); fi->readx(&bhdr, sizeof(bhdr));
ph.u_len = get_native32(&bhdr.sz_unc); ph.u_len = get_native32(&bhdr.sz_unc);
ph.c_len = get_native32(&bhdr.sz_cpr); ph.c_len = get_native32(&bhdr.sz_cpr);
ph.method = bhdr.b_method;
ph.filter = bhdr.b_ftid;
ph.filter_cto = bhdr.b_cto8; ph.filter_cto = bhdr.b_cto8;
// Uncompress Macho headers // Uncompress Macho headers
@@ -396,15 +569,14 @@ PackMachPPC32::unpack(OutputFile *fo)
) { ) {
if (Mach_segment_command::LC_SEGMENT==sc->cmd if (Mach_segment_command::LC_SEGMENT==sc->cmd
&& 0!=sc->filesize ) { && 0!=sc->filesize ) {
unsigned filesize = get_be32(&sc->filesize); unsigned filesize = sc->filesize;
unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr)); unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));
} }
} }
for (unsigned j = 0; j < ncmds; ++j) { for (unsigned j = 0; j < ncmds; ++j) {
unsigned const size = find_SEGMENT_gap(j); unsigned const size = find_SEGMENT_gap(j);
if (size) { if (size) {
unsigned const where = get_native32(&msegcmd[k].fileoff) + unsigned const where = msegcmd[k].fileoff +msegcmd[k].filesize;
get_native32(&msegcmd[k].filesize);
if (fo) if (fo)
fo->seek(where, SEEK_SET); fo->seek(where, SEEK_SET);
unpackExtent(size, fo, total_in, total_out, unpackExtent(size, fo, total_in, total_out,
@@ -414,14 +586,14 @@ PackMachPPC32::unpack(OutputFile *fo)
} }
bool template <class T>
PackMachPPC32::canPack() bool PackMachBase<T>::canPack()
{ {
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(&mhdri, sizeof(mhdri)); fi->readx(&mhdri, sizeof(mhdri));
if (Mach_header::MH_MAGIC !=mhdri.magic if (Mach_header::MH_MAGIC !=mhdri.magic
|| Mach_header::CPU_TYPE_POWERPC !=mhdri.cputype || my_cputype !=mhdri.cputype
|| Mach_header::MH_EXECUTE !=mhdri.filetype || Mach_header::MH_EXECUTE !=mhdri.filetype
) )
return false; return false;
@@ -457,11 +629,204 @@ PackMachPPC32::canPack()
sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff; sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;
} }
} }
// info: currently the header is 36 (32+4) bytes before EOF
unsigned char buf[256];
fi->seek(-(off_t)sizeof(buf), SEEK_END);
fi->readx(buf, sizeof(buf));
checkAlreadyPacked(buf, sizeof(buf));
// set options // set options
opt->o_unix.blocksize = file_size; opt->o_unix.blocksize = file_size;
return 0 < n_segment; return 0 < n_segment;
} }
template class PackMachBase<MachClass_BE32>;
template class PackMachBase<MachClass_LE32>;
PackMachFat::PackMachFat(InputFile *f) : super(f)
{
bele = &N_BELE_RTP::le_policy; // sham
}
PackMachFat::~PackMachFat()
{
}
const int *PackMachFat::getCompressionMethods(int /*method*/, int /*level*/) const
{
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
return m_nrv2e; // sham
}
const int *PackMachFat::getFilters() const
{
static const int filters[] = { 0x49, FT_END };
return filters; // sham
}
void PackMachFat::pack(OutputFile *fo)
{
unsigned const in_size = this->file_size;
fo->write(&fat_head, sizeof(fat_head.fat) +
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
unsigned length = 0;
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
unsigned base = fo->unset_extent(); // actual length
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
fo->seek(base, SEEK_SET);
fo->set_extent(base, ~0u);
ph.u_file_size = fat_head.arch[j].size;
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (fat_head.arch[j].cputype) {
case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi);
packer.initPackHeader();
packer.canPack();
packer.updatePackHeader();
packer.pack(fo);
} break;
case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi);
packer.initPackHeader();
packer.canPack();
packer.updatePackHeader();
packer.pack(fo);
} break;
} // switch cputype
fat_head.arch[j].offset = base;
length = fo->unset_extent();
fat_head.arch[j].size = length - base;
}
ph.u_file_size = in_size;
fi->set_extent(0, in_size);
fo->seek(0, SEEK_SET);
fo->rewrite(&fat_head, sizeof(fat_head.fat) +
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
fo->set_extent(0, length);
}
void PackMachFat::unpack(OutputFile *fo)
{
fo->seek(0, SEEK_SET);
fo->write(&fat_head, sizeof(fat_head.fat) +
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
unsigned length;
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
unsigned base = fo->unset_extent(); // actual length
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
fo->seek(base, SEEK_SET);
fo->set_extent(base, ~0u);
ph.u_file_size = fat_head.arch[j].size;
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (fat_head.arch[j].cputype) {
case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi);
packer.initPackHeader();
packer.canUnpack();
packer.unpack(fo);
} break;
case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi);
packer.initPackHeader();
packer.canUnpack();
packer.unpack(fo);
} break;
} // switch cputype
fat_head.arch[j].offset = base;
length = fo->unset_extent();
fat_head.arch[j].size = length - base;
}
fo->unset_extent();
fo->seek(0, SEEK_SET);
fo->rewrite(&fat_head, sizeof(fat_head.fat) +
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
}
bool PackMachFat::canPack()
{
struct Mach_fat_arch *arch = &fat_head.arch[0];
fi->readx(&fat_head, sizeof(fat_head));
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
return false;
}
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (arch[j].cputype) {
default: return false;
case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi);
if (!packer.canPack())
return false;
} break;
case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi);
if (!packer.canPack())
return false;
} break;
} // switch cputype
}
// info: currently the header is 36 (32+4) bytes before EOF
unsigned char buf[256];
fi->seek(-(off_t)sizeof(buf), SEEK_END);
fi->readx(buf, sizeof(buf));
checkAlreadyPacked(buf, sizeof(buf));
return true;
}
int PackMachFat::canUnpack()
{
struct Mach_fat_arch *arch = &fat_head.arch[0];
fi->readx(&fat_head, sizeof(fat_head));
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
return false;
}
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (arch[j].cputype) {
default: return false;
case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi);
if (!packer.canUnpack())
return 0;
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
} break;
case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi);
if (!packer.canUnpack())
return 0;
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
} break;
} // switch cputype
}
return 1;
}
void PackMachFat::buildLoader(const Filter */*ft*/)
{
assert(false);
}
Linker* PackMachFat::newLinker() const
{
return new ElfLinkerX86; // sham
}
void PackMachFat::list()
{
assert(false);
}
/* /*
vi:ts=4:et vi:ts=4:et
*/ */
+465 -128
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -29,159 +29,328 @@
#ifndef __UPX_P_MACHO_H #ifndef __UPX_P_MACHO_H
#define __UPX_P_MACHO_H #define __UPX_P_MACHO_H
struct Mach_fat_header {
BE32 magic;
enum { // note conflict with java bytecode PackLinuxI386
FAT_MAGIC = 0xcafebabe,
FAT_MAGIC_SWAB = 0xbebafeca
};
BE32 nfat_arch; // Number of Mach_fat_arch which follow.
}
__attribute_packed;
struct Mach_fat_arch {
BE32 cputype;
BE32 cpusubtype;
BE32 offset;
BE32 size;
BE32 align; /* shift count; log base 2 */
}
__attribute_packed;
/************************************************************************* /*************************************************************************
// Mach Mach Object executable // Mach Mach Object executable; all structures are target-endian
// 'otool' is the Mach analog of 'readelf' (convert executable file to ASCII).
**************************************************************************/ **************************************************************************/
struct Mach_header { namespace N_Mach {
BE32 magic;
enum {
MH_MAGIC = 0xfeedface
};
BE32 cputype;
enum {
CPU_TYPE_POWERPC = 18
};
BE32 cpysubtype;
BE32 filetype;
enum {
MH_EXECUTE = 2
};
BE32 ncmds;
BE32 sizeofcmds;
BE32 flags;
enum {
MH_NOUNDEFS = 1
};
}
__attribute_packed;
struct Mach_segment_command { // integral types
BE32 cmd; template <class TWord, class TXword, class TAddr, class TOff>
enum { struct MachITypes
LC_SEGMENT = 0x1, {
LC_THREAD = 0x4, typedef TWord Word;
LC_UNIXTHREAD = 0x5, typedef TXword Xword;
LC_LOAD_DYLINKER = 0xe typedef TAddr Addr;
}; typedef TOff Off;
BE32 cmdsize;
char segname[16];
BE32 vmaddr;
BE32 vmsize;
BE32 fileoff;
BE32 filesize;
BE32 maxprot;
enum {
VM_PROT_READ = 1,
VM_PROT_WRITE = 2,
VM_PROT_EXECUTE = 4
};
BE32 initprot;
BE32 nsects;
BE32 flags;
}
__attribute_packed;
struct Mach_section {
char sectname[16];
char segname[16];
BE32 addr; /* memory address */
BE32 size; /* size in bytes */
BE32 offset; /* file offset */
BE32 align; /* power of 2 */
BE32 reloff; /* file offset of relocation entries */
BE32 nreloc; /* number of relocation entries */
BE32 flags; /* section type and attributes */
enum {
S_REGULAR = 0,
S_ZEROFILL,
S_CSTRING_LITERALS,
S_4BYTE_LITERALS,
S_8BYTE_LITERALS,
S_LITERAL_POINTERS,
S_NON_LAZY_SYMBOL_POINTERS,
S_LAZY_SYMBOL_POINTERS,
S_SYMBOL_STUBS,
S_MOD_INIT_FUNC_POINTERS,
S_MOD_TERM_FNC_POINTERS,
S_COALESCED
};
enum {
S_ATTR_PURE_INSTRUCTIONS = 0x80000000,
S_ATTR_NO_TOC = 0x40000000,
S_ATTR_STRIP_STATIC_SYMS = 0x20000000,
S_ATTR_SOME_INSTRUCTIONS = 0x00000400,
S_ATTR_EXT_RELOC = 0x00000200,
S_ATTR_LOC_RELOC = 0x00000100
};
BE32 reserved1;
BE32 reserved2;
}
__attribute_packed;
struct Mach_ppc_thread_state {
BE32 srr0; /* Instruction address register (PC; entry addr) */
BE32 srr1; /* Machine state register (supervisor) */
BE32 r0, r1, r2, r3, r4, r5, r6, r7;
BE32 r8, r9,r10,r11,r12,r13,r14,r15;
BE32 r16,r17,r18,r19,r20,r21,r22,r23;
BE32 r24,r25,r26,r27,r28,r29,r30,r31;
BE32 cr; /* Condition register */
BE32 xer; /* User's integer exception register */
BE32 lr; /* Link register */
BE32 ctr; /* Count register */
BE32 mq; /* MQ register (601 only) */
BE32 vrsave; /* Vector Save Register */
}; };
struct Mach_thread_command { template <class TMachITypes>
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */ struct Mach_header
BE32 cmdsize; /* total size of this command */ {
BE32 flavor; typedef typename TMachITypes::Word Word;
enum {
PPC_THREAD_STATE = 1 Word magic;
}; Word cputype;
BE32 count; /* sizeof(following_thread_state)/4 */ Word cpysubtype;
enum { Word filetype;
PPC_THREAD_STATE_COUNT = sizeof(struct Mach_ppc_thread_state)/4 Word ncmds;
}; Word sizeofcmds;
struct Mach_ppc_thread_state state; Word flags;
#define WANT_MACH_HEADER_ENUM 1
#include "p_mach_enum.h"
} }
__attribute_packed; __attribute_packed;
template <class TMachITypes>
struct Mach_header64
{ // only difference is padding to 0 mod 8
typedef typename TMachITypes::Word Word;
Word magic;
Word cputype;
Word cpysubtype;
Word filetype;
Word ncmds;
Word sizeofcmds;
Word flags;
Word reserved; // pad to 0 mod 8
#define WANT_MACH_HEADER_ENUM 1
#include "p_mach_enum.h"
}
__attribute_packed;
template <class TMachITypes>
struct Mach_segment_command
{
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off;
Word cmd;
Word cmdsize;
char segname[16];
Addr vmaddr;
Addr vmsize;
Off fileoff;
Off filesize;
Word maxprot;
Word initprot;
Word nsects;
Word flags;
#define WANT_MACH_SEGMENT_ENUM 1
#include "p_mach_enum.h"
}
__attribute_packed;
template <class TMachITypes>
struct Mach_section_command
{
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off;
char sectname[16];
char segname[16];
Addr addr; /* memory address */
Addr size; /* size in bytes */
Word offset; /* file offset */ // FIXME: 64 bit?
Word align; /* power of 2 */
Word reloff; /* file offset of relocation entries */
Word nreloc; /* number of relocation entries */
Word flags; /* section type and attributes */
Word reserved1;
Word reserved2;
#define WANT_MACH_SECTION_ENUM 1
#include "p_mach_enum.h"
}
__attribute_packed;
template <class TMachITypes>
struct Mach_ppc_thread_state
{
typedef typename TMachITypes::Addr Addr;
Addr srr0; /* Instruction address register (PC; entry addr) */
Addr srr1; /* Machine state register (supervisor) */
Addr r0, r1, r2, r3, r4, r5, r6, r7;
Addr r8, r9,r10,r11,r12,r13,r14,r15;
Addr r16,r17,r18,r19,r20,r21,r22,r23;
Addr r24,r25,r26,r27,r28,r29,r30,r31;
Addr cr; /* Condition register */ // FIXME: Word?
Addr xer; /* User's integer exception register */
Addr lr; /* Link register */
Addr ctr; /* Count register */
Addr mq; /* MQ register (601 only) */
Addr vrsave; /* Vector Save Register */
}
__attribute_packed;
template <class TMachITypes>
struct Mach_i386_thread_state
{
typedef typename TMachITypes::Word Word;
Word eax, ebx, ecx, edx;
Word edi, esi, ebp;
Word esp, ss;
Word eflags;
Word eip, cs;
Word ds, es, fs, gs;
}
__attribute_packed;
template <class TMachITypes>
struct Mach_i386_new_thread_state
{
typedef typename TMachITypes::Word Word;
Word gs, fs, es, ds;
Word edi, esi, ebp, esp;
Word ebx, edx, ecx, eax;
Word eip, cs, efl;
Word uesp, ss;
}
__attribute_packed;
} // namespace N_Mach
namespace N_Mach32 {
} // namespace N_Mach32
namespace N_Mach64 {
template <class TMachITypes>
struct Mach_ppc_thread_state64
{
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Xword Xword;
Xword srr0; /* Instruction address register (PC; entry addr) */
Xword srr1; /* Machine state register (supervisor) */
Xword r0, r1, r2, r3, r4, r5, r6, r7;
Xword r8, r9,r10,r11,r12,r13,r14,r15;
Xword r16,r17,r18,r19,r20,r21,r22,r23;
Xword r24,r25,r26,r27,r28,r29,r30,r31;
Word cr; /* Condition register */ // FIXME: Xword?
Xword xer; /* User's integer exception register */
Xword lr; /* Link register */
Xword ctr; /* Count register */
Word vrsave; /* Vector Save Register */
}
__attribute_packed;
} // namespace N_Mach64
namespace N_Mach {
template <class TP>
struct MachClass_32
{
typedef TP BeLePolicy;
// integral types
typedef typename TP::U16 U16;
typedef typename TP::U32 U32;
typedef typename TP::U64 U64;
typedef N_Mach::MachITypes<U32, U64, U32, U32> MachITypes;
#if (ACC_CC_BORLANDC)
typedef U32 Addr;
#else
typedef typename MachITypes::Addr Addr;
#endif
// Mach types
typedef N_Mach::Mach_header<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state;
static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions();
COMPILE_TIME_ASSERT(sizeof(Addr) == 4)
}
};
template <class TP>
struct MachClass_64
{
typedef TP BeLePolicy;
// integral types
typedef typename TP::U16 U16;
typedef typename TP::U32 U32;
typedef typename TP::U64 U64;
typedef N_Mach::MachITypes<U32, U64, U64, U64> MachITypes;
// Mach types
typedef N_Mach::Mach_header64<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions();
}
};
} // namespace N_Mach
typedef N_Mach::MachClass_32<N_BELE_CTP::HostPolicy> MachClass_Host32;
typedef N_Mach::MachClass_64<N_BELE_CTP::HostPolicy> MachClass_Host64;
typedef N_Mach::MachClass_32<N_BELE_CTP::BEPolicy> MachClass_BE32;
typedef N_Mach::MachClass_64<N_BELE_CTP::BEPolicy> MachClass_BE64;
typedef N_Mach::MachClass_32<N_BELE_CTP::LEPolicy> MachClass_LE32;
typedef N_Mach::MachClass_64<N_BELE_CTP::LEPolicy> MachClass_LE64;
// shortcuts
typedef MachClass_Host32::Mach_segment_command Mach32_segment_command;
typedef MachClass_Host32::Mach_section_command Mach32_section_command;
typedef MachClass_Host64::Mach_segment_command Mach64_segment_command;
typedef MachClass_Host64::Mach_section_command Mach64_section_command;
typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command;
typedef MachClass_BE32::Mach_section_command MachBE32_section_command;
typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command;
typedef MachClass_BE64::Mach_section_command MachBE64_section_command;
typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command;
typedef MachClass_LE32::Mach_section_command MachLE32_section_command;
typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command;
typedef MachClass_LE64::Mach_section_command MachLE64_section_command;
typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state;
typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state;
#include "p_unix.h" #include "p_unix.h"
class PackMachPPC32 : public PackUnixBe32 template <class TMachClass>
class PackMachBase : public PackUnix
{ {
typedef PackUnixBe32 super; typedef PackUnix super;
protected:
typedef TMachClass MachClass;
typedef typename MachClass::BeLePolicy BeLePolicy;
typedef typename MachClass::MachITypes MachITypes;
// integral types
typedef typename MachClass::U16 U16;
typedef typename MachClass::U32 U32;
typedef typename MachClass::U64 U64;
typedef typename MachClass::Addr Addr;
// Mach types
typedef typename MachClass::Mach_header Mach_header;
typedef typename MachClass::Mach_segment_command Mach_segment_command;
typedef typename MachClass::Mach_section_command Mach_section_command;
public: public:
PackMachPPC32(InputFile *f); PackMachBase(InputFile *, unsigned cpuid, unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size);
virtual ~PackMachPPC32(); virtual ~PackMachBase();
virtual int getVersion() const { return 13; } 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 int *getCompressionMethods(int method, int level) const; virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
// called by the generic pack() // called by the generic pack()
virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual void pack2(OutputFile *, Filter &); // append compressed data virtual void pack2(OutputFile *, Filter &); // append compressed data
virtual void pack3(OutputFile *, Filter &); // append loader virtual void pack3(OutputFile *, Filter &) = 0; // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader
virtual void pack1_setup_threado(OutputFile *const fo) = 0;
virtual void unpack(OutputFile *fo); virtual void unpack(OutputFile *fo);
virtual bool canPack(); virtual bool canPack();
virtual unsigned find_SEGMENT_gap(unsigned const k); virtual unsigned find_SEGMENT_gap(unsigned const k);
protected: protected:
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
virtual void patchLoader(); virtual void patchLoader();
virtual void patchLoaderChecksum(); virtual void patchLoaderChecksum();
virtual void updateLoader(OutputFile *); virtual void updateLoader(OutputFile *);
@@ -194,6 +363,13 @@ protected:
virtual void defineSymbols(Filter const *); virtual void defineSymbols(Filter const *);
virtual void addStubEntrySections(Filter const *); virtual void addStubEntrySections(Filter const *);
static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb);
unsigned my_cputype;
unsigned my_thread_flavor;
unsigned my_thread_state_word_count;
unsigned my_thread_command_size;
unsigned n_segment; unsigned n_segment;
unsigned sz_segment; unsigned sz_segment;
unsigned sz_mach_headers; unsigned sz_mach_headers;
@@ -203,11 +379,172 @@ protected:
Mach_header mhdro; Mach_header mhdro;
Mach_segment_command segcmdo; Mach_segment_command segcmdo;
Mach_thread_command threado;
struct b_info { // 12-byte header before each compressed block
U32 sz_unc; // uncompressed_size
U32 sz_cpr; // compressed_size
unsigned char b_method; // compression algorithm
unsigned char b_ftid; // filter id
unsigned char b_cto8; // filter parameter
unsigned char b_unused;
}
__attribute_packed;
struct l_info { // 12-byte trailer in header for loader
U32 l_checksum;
LE32 l_magic;
U16 l_lsize;
unsigned char l_version;
unsigned char l_format;
}
__attribute_packed;
struct p_info { // 12-byte packed program header
U32 p_progid;
U32 p_filesize;
U32 p_blocksize;
}
__attribute_packed;
struct l_info linfo; struct l_info linfo;
}; };
class PackMachPPC32 : public PackMachBase<MachClass_BE32>
{
typedef PackMachBase<MachClass_BE32> super;
public:
PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC,
Mach_thread_command::PPC_THREAD_STATE,
sizeof(Mach_ppc_thread_state)>>2, sizeof(threado)) { }
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 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); }
virtual void set_native64(void *b, acc_uint64l_t v) const { set_be64(b, v); }
virtual void set_native32(void *b, unsigned v) const { set_be32(b, v); }
virtual void set_native16(void *b, unsigned v) const { set_be16(b, v); }
protected:
virtual const int *getFilters() const;
virtual void pack1_setup_threado(OutputFile *const fo);
virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader
virtual Linker* newLinker() const;
virtual void buildLoader(const Filter *ft);
struct Mach_thread_command
{
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
BE32 cmdsize; /* total size of this command */
BE32 flavor;
BE32 count; /* sizeof(following_thread_state)/4 */
Mach_ppc_thread_state state;
#define WANT_MACH_THREAD_ENUM
#include "p_mach_enum.h"
}
__attribute_packed;
Mach_thread_command threado;
};
class PackMachI386 : public PackMachBase<MachClass_LE32>
{
typedef PackMachBase<MachClass_LE32> super;
public:
PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386,
(unsigned)Mach_thread_command::i386_THREAD_STATE,
sizeof(Mach_i386_thread_state)>>2, sizeof(threado)) { }
virtual int getFormat() const { return UPX_F_MACH_i386; }
virtual const char *getName() const { return "Mach/i386"; }
virtual const char *getFullName(const options_t *) const { return "i386-darwin.macho"; }
protected:
virtual const int *getFilters() const;
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); }
virtual void set_native64(void *b, acc_uint64l_t v) const { set_le64(b, v); }
virtual void set_native32(void *b, unsigned v) const { set_le32(b, v); }
virtual void set_native16(void *b, unsigned v) const { set_le16(b, v); }
virtual void pack1_setup_threado(OutputFile *const fo);
virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader
virtual Linker* newLinker() const;
virtual void buildLoader(const Filter *ft);
virtual void addStubEntrySections(Filter const *);
struct Mach_thread_command
{
LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
LE32 cmdsize; /* total size of this command */
LE32 flavor;
LE32 count; /* sizeof(following_thread_state)/4 */
Mach_i386_thread_state state;
#define WANT_MACH_THREAD_ENUM
#include "p_mach_enum.h"
}
__attribute_packed;
Mach_thread_command threado;
};
class PackMachFat : public Packer
{
typedef Packer super;
public:
PackMachFat(InputFile *f);
virtual ~PackMachFat();
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_MACH_FAT; }
virtual const char *getName() const { return "Mach/fat"; }
virtual const char *getFullName(const options_t *) const { return "fat-darwin.macho"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
protected:
// implementation
virtual void pack(OutputFile *fo);
virtual void unpack(OutputFile *fo);
virtual void list();
public:
virtual bool canPack();
virtual int canUnpack();
protected:
// loader core
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
#if (ACC_CC_BORLANDC)
public:
#endif
enum { N_FAT_ARCH = 5 };
protected:
struct Fat_head {
struct Mach_fat_header fat;
struct Mach_fat_arch arch[N_FAT_ARCH];
}
__attribute_packed;
Fat_head fat_head;
// UI handler
UiPacker *uip;
// linker
Linker *linker;
#define WANT_MACH_HEADER_ENUM
#include "p_mach_enum.h"
};
#endif /* already included */ #endif /* already included */
+108
View File
@@ -0,0 +1,108 @@
/* p_mach_enum.h --
This file is part of the UPX executable compressor.
Copyright (C) 2007 John F. Reiser
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.
John F. Reiser
<jreiser@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 usual C++ way
// of "importing" enums) does not yield a POD any more
// - that older compilers do not correctly perform EBCO
**************************************************************************/
#ifdef WANT_MACH_HEADER_ENUM /*{*/
#undef WANT_MACH_HEADER_ENUM
enum { // magic
MH_MAGIC = 0xfeedface
};
enum { // cputype
CPU_TYPE_I386 = 7,
CPU_TYPE_POWERPC = 0x00000012,
CPU_TYPE_POWERPC64 = 0x01000012
};
enum { // filetype
MH_EXECUTE = 2
};
enum { // flags
MH_NOUNDEFS = 1
};
#endif /*}*/
#ifdef WANT_MACH_SEGMENT_ENUM /*{*/
#undef WANT_MACH_SEGMENT_ENUM
enum { // cmd
LC_SEGMENT = 0x1,
LC_THREAD = 0x4,
LC_UNIXTHREAD = 0x5,
LC_LOAD_DYLINKER = 0xe,
LC_SEGMENT_64 = 0x19
};
enum { // maxprot
VM_PROT_READ = 1,
VM_PROT_WRITE = 2,
VM_PROT_EXECUTE = 4
};
#endif /*}*/
#ifdef WANT_MACH_SECTION_ENUM /*{*/
#undef WANT_MACH_SECTION_ENUM
enum { // section flags
S_REGULAR = 0,
S_ZEROFILL,
S_CSTRING_LITERALS,
S_4BYTE_LITERALS,
S_8BYTE_LITERALS,
S_LITERAL_POINTERS,
S_NON_LAZY_SYMBOL_POINTERS,
S_LAZY_SYMBOL_POINTERS,
S_SYMBOL_STUBS,
S_MOD_INIT_FUNC_POINTERS,
S_MOD_TERM_FNC_POINTERS,
S_COALESCED
};
enum {
S_ATTR_PURE_INSTRUCTIONS = 0x80000000,
S_ATTR_NO_TOC = 0x40000000,
S_ATTR_STRIP_STATIC_SYMS = 0x20000000,
S_ATTR_SOME_INSTRUCTIONS = 0x00000400,
S_ATTR_EXT_RELOC = 0x00000200,
S_ATTR_LOC_RELOC = 0x00000100
};
#endif /*}*/
#ifdef WANT_MACH_THREAD_ENUM /*{*/
#undef WANT_MACH_THREAD_ENUM
enum { // thread flavor
PPC_THREAD_STATE = 1,
i386_THREAD_STATE = 1,
i386_OLD_THREAD_STATE = -1
};
#endif /*}*/
/*
vi:ts=4:et
*/
+40 -39
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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) 2002-2006 Jens Medoch Copyright (C) 2002-2007 Jens Medoch
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -53,7 +53,7 @@ static const
#define K0_BS (0x80000000) #define K0_BS (0x80000000)
#define K1_BS (0xa0000000) #define K1_BS (0xa0000000)
#define EXE_BS (ih.epc & K0_BS) #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 // lui / addiu
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15)) #define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
@@ -83,16 +83,17 @@ PackPs1::PackPs1(InputFile *f) :
pad_code(0), bss_start(0), bss_end(0) pad_code(0), bss_start(0), bss_end(0)
{ {
bele = &N_BELE_RTP::le_policy; 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(PS_HDR_SIZE > sizeof(ps1_exe_t)); COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136)
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40); COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44)
#if 0 // 1 || defined(WITH_NRV) COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5)
COMPILE_TIME_ASSERT(sizeof(nrv_loader) == 14812); COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_t)
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0); COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_hb_t)
#endif 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)
fdata_size = file_size - PS_HDR_SIZE; fdata_size = file_size - PS_HDR_SIZE;
ram_size = !opt->ps1_exe.do_8mb ? 0x200000 : 0x800000; ram_size = !opt->ps1_exe.do_8mb ? 0x200000 : 0x800000;
} }
@@ -151,7 +152,7 @@ bool PackPs1::readBkupHeader()
} }
#define INIT_BH_BKUP(p, l) {(p)->id = '1'; (p)->len = l;} #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) void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len)
{ {
@@ -169,7 +170,7 @@ void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsign
if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP) if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP)
throwInternalError("header compression failed"); throwInternalError("header compression failed");
INIT_BH_BKUP(p, sz_cbh); 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)); p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
memcpy(dst, cpr_bh, SZ_IH_BKUP); memcpy(dst, cpr_bh, SZ_IH_BKUP);
delete [] cpr_bh; delete [] cpr_bh;
@@ -300,7 +301,7 @@ void PackPs1::buildLoader(const Filter *)
else if (ph.method == M_NRV2E_LE32) else if (ph.method == M_NRV2E_LE32)
method = isCon ? "nrv2e.small,32bit.sub,nrv.done" : method = isCon ? "nrv2e.small,32bit.sub,nrv.done" :
"nrv2e.32bit,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"; method = "nrv2b.small,8bit.sub,nrv.done,lzma.prep";
else else
throwInternalError("unknown compression method"); throwInternalError("unknown compression method");
@@ -314,12 +315,12 @@ void PackPs1::buildLoader(const Filter *)
throwCantPack("packed data overlap (try --force)"); throwCantPack("packed data overlap (try --force)");
} }
else 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(); foundBss = findBssSection();
if (ph.method == M_LZMA && !buildPart2) if (M_IS_LZMA(ph.method) && !buildPart2)
{ {
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1)); initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
addLoader("decompressor.start", addLoader("decompressor.start",
@@ -329,7 +330,7 @@ void PackPs1::buildLoader(const Filter *)
} }
else else
{ {
if (ph.method == M_LZMA && buildPart2) if (M_IS_LZMA(ph.method) && buildPart2)
{ {
sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc); sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc);
unsigned char *cprLoader = new unsigned char[sz_lcpr]; unsigned char *cprLoader = new unsigned char[sz_lcpr];
@@ -338,21 +339,21 @@ void PackPs1::buildLoader(const Filter *)
if (r != UPX_E_OK || sz_lcpr >= sz_lunc) if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
throwInternalError("loader compression failed"); throwInternalError("loader compression failed");
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1), initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1),
(ph.method != M_LZMA || isCon) ? 0 : 1); isCon || !M_IS_LZMA(ph.method) ? 0 : 1);
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0); linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
delete [] cprLoader; delete [] cprLoader;
} }
else else
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1)); initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4); pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4u);
assert(pad_code < 4); assert(pad_code < 4);
static const unsigned char pad_buffer[4] = { 0, 0, 0, 0 }; static const unsigned char pad_buffer[4] = { 0, 0, 0, 0 };
linker->addSection("pad.code", pad_buffer, pad_code, 0); linker->addSection("pad.code", pad_buffer, pad_code, 0);
if (isCon) if (isCon)
{ {
if (ph.method == M_LZMA) if (M_IS_LZMA(ph.method))
addLoader(!foundBss ? "con.start" : "bss.con.start", addLoader(!foundBss ? "con.start" : "bss.con.start",
method, method,
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi", ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
@@ -368,7 +369,7 @@ void PackPs1::buildLoader(const Filter *)
} }
else 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", addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi", ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"lzma.exec", NULL); "lzma.exec", NULL);
@@ -389,7 +390,7 @@ void PackPs1::buildLoader(const Filter *)
#define REG1(x) (((x) >> 5) & 0x1f) #define REG1(x) (((x) >> 5) & 0x1f)
#define REG2(x) ((x) & 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 // Type
#define REGIMM 1 #define REGIMM 1
@@ -439,12 +440,12 @@ bool PackPs1::findBssSection()
bss_start = MIPS_IMM(p->hi1, p->lo1); bss_start = MIPS_IMM(p->hi1, p->lo1);
bss_end = MIPS_IMM(p->hi2, p->lo2); 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; unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
if (bss_end > (end_offs + wkmem_sz)) if (bss_end > (end_offs + wkmem_sz))
return (isCon || (!isCon && (ph.method == M_LZMA))); return isCon || (!isCon && M_IS_LZMA(ph.method));
else else
return false; return false;
} }
@@ -478,9 +479,9 @@ void PackPs1::pack(OutputFile *fo)
while (!(*--p_scan)) { if (sa_cnt++ > (0x10000 << 5) || sa_cnt >= fdata_size - 1024) break; } while (!(*--p_scan)) { if (sa_cnt++ > (0x10000 << 5) || sa_cnt >= fdata_size - 1024) break; }
if (sa_cnt > (0x10000 << 2)) if (sa_cnt > (0x10000 << 2))
sa_cnt = ALIGN_DOWN(sa_cnt,32); sa_cnt = ALIGN_DOWN(sa_cnt, 32u);
else else
sa_cnt = ALIGN_DOWN(sa_cnt,4); sa_cnt = ALIGN_DOWN(sa_cnt, 4u);
// prepare packheader // prepare packheader
ph.u_len = (fdata_size - sa_cnt); ph.u_len = (fdata_size - sa_cnt);
@@ -491,7 +492,7 @@ void PackPs1::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
cconf.conf_ucl.max_match = 65535; cconf.conf_ucl.max_match = 65535;
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack 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) if (overlap)
{ {
@@ -507,7 +508,7 @@ void PackPs1::pack(OutputFile *fo)
unsigned lzma_init = 0; unsigned lzma_init = 0;
if (ph.method == M_LZMA) if (M_IS_LZMA(ph.method))
{ {
sz_lunc = getLoaderSize(); sz_lunc = getLoaderSize();
@@ -553,7 +554,7 @@ void PackPs1::pack(OutputFile *fo)
} }
else 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; e_len = (lsize - d_len) - h_len;
} }
@@ -561,10 +562,10 @@ void PackPs1::pack(OutputFile *fo)
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ? linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
sa_cnt >> 5 : sa_cnt >> 2)); sa_cnt >> 5 : sa_cnt >> 2));
linker->defineSymbol("DECO", decomp_data_start); 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 (foundBss)
if (ph.method == M_LZMA) if (M_IS_LZMA(ph.method))
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize() linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
- (sz_lunc + 16)); - (sz_lunc + 16));
else else
@@ -588,7 +589,7 @@ void PackPs1::pack(OutputFile *fo)
ibuf.clear(0,fdata_size); ibuf.clear(0,fdata_size);
upx_bytep paddata = ibuf; upx_bytep paddata = ibuf;
if (ph.method == M_LZMA) if (M_IS_LZMA(ph.method))
{ {
linker->defineSymbol("lzma_init_off", lzma_init); linker->defineSymbol("lzma_init_off", lzma_init);
linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e")); linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));
@@ -600,7 +601,7 @@ void PackPs1::pack(OutputFile *fo)
if (isCon) if (isCon)
{ {
linker->defineSymbol("PAD", pad_code); linker->defineSymbol("PAD", pad_code);
if (ph.method == M_LZMA) if (M_IS_LZMA(ph.method))
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec"))); linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
else else
linker->defineSymbol("DCRT", (entry + (e_len - d_len))); linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
@@ -609,7 +610,7 @@ void PackPs1::pack(OutputFile *fo)
{ {
linker->defineSymbol("PSVR", FIX_PSVR); linker->defineSymbol("PSVR", FIX_PSVR);
linker->defineSymbol("CPDO", comp_data_start); linker->defineSymbol("CPDO", comp_data_start);
if (ph.method == M_LZMA) if (M_IS_LZMA(ph.method))
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec") linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
- getLoaderSectionStart("cdb.entry.lzma")); - getLoaderSectionStart("cdb.entry.lzma"));
} }
@@ -621,7 +622,7 @@ void PackPs1::pack(OutputFile *fo)
memcpy(loader, getLoader(), lsize); memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, 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"); throwInternalError("lzma --boot-only loader > 2048");
// ps1_exe_t structure // ps1_exe_t structure
@@ -655,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); printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
unsigned char i = 0; unsigned char i = 0;
if (isCon) { if (foundBss) i = 1; } 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" }; 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); 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]); printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
+5 -4
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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) 2002-2006 Jens Medoch Copyright (C) 2002-2007 Jens Medoch
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_PS1_EXE; } virtual int getFormat() const { return UPX_F_PS1_EXE; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
@@ -111,7 +112,7 @@ protected:
} }
__attribute_packed; __attribute_packed;
typedef struct bss_nfo struct bss_nfo
{ {
LE16 hi1, op1, lo1, op2; LE16 hi1, op1, lo1, op2;
LE16 hi2, op3, lo2, op4; LE16 hi2, op3, lo2, op4;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_DOS_SYS; } virtual int getFormat() const { return UPX_F_DOS_SYS; }
virtual const char *getName() const { return "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(); virtual bool canPack();
+14 -21
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -59,8 +59,9 @@ const int *PackTmt::getCompressionMethods(int method, int level) const
const int *PackTmt::getFilters() const const int *PackTmt::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x12, 0x15, 0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
-1 }; FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters; return filters;
} }
@@ -87,6 +88,8 @@ void PackTmt::buildLoader(const Filter *ft)
// prepare loader // prepare loader
initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt)); initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt));
addLoader("IDENTSTR,TMTMAIN1", addLoader("IDENTSTR,TMTMAIN1",
ph.first_offset_found == 1 ? "TMTMAIN1A" : "",
"TMTMAIN1B",
ft->id ? "TMTCALT1" : "", ft->id ? "TMTCALT1" : "",
"TMTMAIN2,UPX1HEAD,TMTCUTPO", "TMTMAIN2,UPX1HEAD,TMTCUTPO",
NULL); NULL);
@@ -168,7 +171,7 @@ int PackTmt::readFileHeader()
fi->seek(adam_offset,SEEK_SET); fi->seek(adam_offset,SEEK_SET);
fi->readx(&ih,sizeof(ih)); 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; return UPX_F_TMT_ADAM;
#undef H4 #undef H4
@@ -184,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;
}
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -249,7 +239,10 @@ void PackTmt::pack(OutputFile *fo)
Filter ft(ph.level); Filter ft(ph.level);
ft.buf_len = usize; ft.buf_len = usize;
// compress // 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 lsize = getLoaderSize();
const unsigned s_point = getLoaderSection("TMTMAIN1"); const unsigned s_point = getLoaderSection("TMTMAIN1");
@@ -259,11 +252,11 @@ void PackTmt::pack(OutputFile *fo)
// patch loader // patch loader
linker->defineSymbol("original_entry", ih.entry); linker->defineSymbol("original_entry", ih.entry);
defineFilterSymbols(linker, &ft);
defineDecompressorSymbols(); defineDecompressorSymbols();
defineFilterSymbols(&ft);
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len); 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); 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", //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); // e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_TMT_ADAM; } virtual int getFormat() const { return UPX_F_TMT_ADAM; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
+6 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -307,19 +307,19 @@ bool PackTos::checkFileHeader()
if ((f & F_PROTMODE) != F_PROT_P) if ((f & F_PROTMODE) != F_PROT_P)
{ {
if (opt->force < 1) 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 (f & F_SHTEXT)
{ {
if (opt->force < 1) 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 #if 0
// fh_reserved seems to be unused // fh_reserved seems to be unused
if (ih.fh_reserved != 0) if (ih.fh_reserved != 0)
{ {
if (opt->force < 1) 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 #endif
return true; return true;
@@ -508,7 +508,7 @@ void PackTos::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
cconf.conf_ucl.max_match = 65535; cconf.conf_ucl.max_match = 65535;
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 512, 0, NULL, &cconf); compressWithFilters(&ft, 512, &cconf);
// //
// multipass buildLoader() // multipass buildLoader()
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_ATARI_TOS; } virtual int getFormat() const { return UPX_F_ATARI_TOS; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
+12 -13
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -62,7 +62,7 @@ bool PackUnix::canPack()
#if defined(__unix__) #if defined(__unix__)
// must be executable by owner // must be executable by owner
if ((fi->st.st_mode & S_IXUSR) == 0) if ((fi->st.st_mode & S_IXUSR) == 0)
throwCantPack("file not executable; try `chmod +x'"); throwCantPack("file not executable; try 'chmod +x'");
#endif #endif
if (file_size < 4096) if (file_size < 4096)
throwCantPack("file is too small"); throwCantPack("file is too small");
@@ -125,8 +125,8 @@ int PackUnix::getStrategy(Filter &/*ft*/)
// Called just before reading and compressing each block. // Called just before reading and compressing each block.
// Might want to adjust blocksize, etc. // Might want to adjust blocksize, etc.
// If user specified the filter, then use it (-2==strategy). // If user specified the filter, then use it (-2==filter_strategy).
// Else try the first two filters, and pick the better (2==strategy). // Else try the first two filters, and pick the better (2==filter_strategy).
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2)); 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]. // which assumes it has free choice on each call [block].
// And if the choices aren't the same on each block, // And if the choices aren't the same on each block,
// then un-filtering will give incorrect results. // then un-filtering will give incorrect results.
int strategy = getStrategy(ft); int filter_strategy = getStrategy(ft);
if (file_size > (off_t)blocksize) if (file_size > (off_t)blocksize)
strategy = -3; // no filters filter_strategy = -3; // no filters
int l = fi->readx(ibuf, UPX_MIN(blocksize, remaining)); int l = fi->readx(ibuf, UPX_MIN(blocksize, remaining));
remaining -= l; remaining -= l;
@@ -170,7 +170,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
// that is, AFTER filtering. We want BEFORE filtering, // that is, AFTER filtering. We want BEFORE filtering,
// so that decompression checks the end-to-end checksum. // so that decompression checks the end-to-end checksum.
unsigned const end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler); 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) { if (ph.c_len < ph.u_len) {
ph.overlap_overhead = OVERHEAD; ph.overlap_overhead = OVERHEAD;
@@ -318,7 +318,7 @@ void PackUnix::packExtent(
} }
fi->seek(x.offset, SEEK_SET); fi->seek(x.offset, SEEK_SET);
for (off_t rest = x.size; 0 != rest; ) { 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)); int l = fi->readx(ibuf, UPX_MIN(rest, (off_t)blocksize));
if (l == 0) { if (l == 0) {
break; break;
@@ -345,12 +345,11 @@ void PackUnix::packExtent(
ft->id = 0; ft->id = 0;
ft->cto = 0; ft->cto = 0;
compressWithFilters(ft, OVERHEAD, strategy, compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy,
NULL, NULL, 0, 0, // those 4 args are the defaults 0, 0, 0, hdr_ibuf, hdr_u_len);
hdr_ibuf, hdr_u_len);
} }
else { 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) { if (ph.c_len < ph.u_len) {
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -235,7 +235,7 @@ public:
virtual bool canPack(); virtual bool canPack();
protected: protected:
virtual const upx_byte *getLoader() const; virtual upx_byte *getLoader() const;
virtual int getLoaderSize() const; virtual int getLoaderSize() const;
virtual void patchLoader(); virtual void patchLoader();
+742 -389
View File
File diff suppressed because it is too large Load Diff
+123 -27
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -31,45 +31,141 @@
#include "p_elf.h" #include "p_elf.h"
/************************************************************************* /*************************************************************************
// vmlinx/i386 (bare binary Linux kernel image) // vmlinx/i386 (bare binary Linux kernel image)
**************************************************************************/ **************************************************************************/
class PackVmlinuxI386 : public Packer template <class TElfClass>
class PackVmlinuxBase : public Packer
{ {
typedef Packer super; 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: public:
PackVmlinuxI386(InputFile *f); PackVmlinuxBase(InputFile *, unsigned, unsigned, unsigned, char const *);
virtual ~PackVmlinuxI386(); virtual ~PackVmlinuxBase();
virtual int getVersion() const { return 13; } 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 int getStrategy(Filter &);
virtual void pack(OutputFile *fo);
virtual void unpack(OutputFile *fo);
virtual bool canPack();
virtual int canUnpack();
protected: protected:
virtual Elf_LE32_Shdr const *getElfSections(); unsigned int const my_e_machine;
virtual void buildLoader(const Filter *ft); unsigned char const my_elfclass;
virtual Linker* newLinker() const; unsigned char const my_elfdata;
// virtual const upx_byte *getLoader() const; char const *const my_boot_label;
// virtual int getLoaderSize() const;
int n_ptload; int n_ptload;
unsigned sz_ptload; unsigned sz_ptload;
Elf_LE32_Phdr *phdri; // from input file unsigned paddr_min;
Elf_LE32_Shdr *shdri; // from input file Phdr *phdri; // from input file
Shdr *shdri; // from input file
char *shstrtab; // from input file char *shstrtab; // from input file
Elf_LE32_Shdr *p_text; Shdr *p_text;
Elf_LE32_Shdr *p_note0; Shdr *p_note0;
Elf_LE32_Shdr *p_note1; Shdr *p_note1;
Elf_LE32_Ehdr ehdri; // from input file 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
);
}; };
+23 -37
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -67,9 +67,9 @@ const int *PackVmlinuzI386::getCompressionMethods(int method, int level) const
const int *PackVmlinuzI386::getFilters() const const int *PackVmlinuzI386::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x49, 0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12, FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
-1 }; FT_END };
return filters; return filters;
} }
@@ -100,7 +100,7 @@ int PackVmlinuzI386::readFileHeader()
return 0; return 0;
int format = UPX_F_VMLINUZ_i386; 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; const unsigned char *p = (const unsigned char *) &h + 0x1e3;
@@ -137,13 +137,13 @@ int PackVmlinuzI386::decompressKernel()
// See startup_32: in linux/arch/i386/boot/compressed/head.S // See startup_32: in linux/arch/i386/boot/compressed/head.S
char const *p = (char const *)&obuf[setup_size]; char const *p = (char const *)&obuf[setup_size];
for (int j= 0; j < 0x200; ++j, ++p) for (int j= 0; j < 0x200; ++j, ++p)
if (0==strncmp("\xEA\x00\x00", p, 3) && 0==(0xf & p[3]) && 0==p[4]) { if (0==memcmp("\xEA\x00\x00", p, 3) && 0==(0xf & p[3]) && 0==p[4]) {
/* whole megabyte < 16MB */ /* whole megabyte < 16MB */
physical_start = get_le32(1+ p); physical_start = get_le32(1+ p);
break; break;
} }
checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, 1024)); checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024));
for (int gzoff = setup_size; gzoff < file_size; gzoff++) for (int gzoff = setup_size; gzoff < file_size; gzoff++)
{ {
@@ -208,7 +208,7 @@ int PackVmlinuzI386::decompressKernel()
if (fd_pos != file_size) if (fd_pos != file_size)
{ {
//printf("fd_pos: %ld, file_size: %ld\n", (long)fd_pos, (long)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");
} }
@@ -227,7 +227,7 @@ int PackVmlinuzI386::decompressKernel()
&& 0x0F==ibuf[19] && 0xA2==ibuf[20] // cpuid && 0x0F==ibuf[19] && 0xA2==ibuf[20] // cpuid
) goto head_ok; ) 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: head_ok:
// FIXME: more checks for special magic bytes in ibuf ??? // FIXME: more checks for special magic bytes in ibuf ???
@@ -275,6 +275,7 @@ void PackVmlinuzI386::buildLoader(const Filter *ft)
// prepare loader // prepare loader
initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz)); initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz));
addLoader("LINUZ000", addLoader("LINUZ000",
ph.first_offset_found == 1 ? "LINUZ001" : "",
ft->id ? "LZCALLT1" : "", ft->id ? "LZCALLT1" : "",
"LZIMAGE0", "LZIMAGE0",
getDecompressorSections(), getDecompressorSections(),
@@ -290,19 +291,6 @@ void PackVmlinuzI386::buildLoader(const Filter *ft)
} }
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) void PackVmlinuzI386::pack(OutputFile *fo)
{ {
readKernel(); readKernel();
@@ -316,12 +304,12 @@ void PackVmlinuzI386::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression // limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack 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(); const unsigned lsize = getLoaderSize();
defineFilterSymbols(linker, &ft);
defineDecompressorSymbols(); defineDecompressorSymbols();
defineFilterSymbols(&ft);
linker->defineSymbol("src_for_decompressor", zimage_offset + lsize); linker->defineSymbol("src_for_decompressor", zimage_offset + lsize);
linker->defineSymbol("original_entry", physical_start); linker->defineSymbol("original_entry", physical_start);
linker->defineSymbol("stack_offset", stack_offset_during_uncompression); linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
@@ -332,7 +320,7 @@ void PackVmlinuzI386::pack(OutputFile *fo)
patchPackHeader(loader, lsize); patchPackHeader(loader, lsize);
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf); 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(setup_buf, setup_buf.getSize());
fo->write(loader, lsize); fo->write(loader, lsize);
@@ -361,6 +349,7 @@ void PackBvmlinuzI386::buildLoader(const Filter *ft)
// prepare loader // prepare loader
initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz)); initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz));
addLoader("LINUZ000", addLoader("LINUZ000",
ph.first_offset_found == 1 ? "LINUZ001" : "",
(0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""), (0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""),
"LBZIMAGE,IDENTSTR", "LBZIMAGE,IDENTSTR",
"+40", // align the stuff to 4 byte boundary "+40", // align the stuff to 4 byte boundary
@@ -401,16 +390,16 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression // limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack 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 // align everything to dword boundary - it is easier to handle
unsigned c_len = ph.c_len; unsigned c_len = ph.c_len;
memset(obuf + c_len, 0, 4); memset(obuf + c_len, 0, 4);
c_len = ALIGN_UP(c_len, 4); c_len = ALIGN_UP(c_len, 4u);
const unsigned lsize = getLoaderSize(); 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; const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
acc_uint32e_t properties = // lc, lp, pb, dummy acc_uint32e_t properties = // lc, lp, pb, dummy
(res->lit_context_bits << 0) | (res->lit_context_bits << 0) |
@@ -429,11 +418,11 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
const int e_len = getLoaderSectionStart("LZCUTPOI"); const int e_len = getLoaderSectionStart("LZCUTPOI");
assert(e_len > 0); assert(e_len > 0);
const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4); const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4u);
const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16); const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16u);
const unsigned copy_size = c_len + d_len4; const unsigned copy_size = c_len + d_len4;
const unsigned edi = decompr_pos + d_len4 - 4; // copy to 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 - bzimage_offset + physical_start); linker->defineSymbol("decompressor", decompr_pos - bzimage_offset + physical_start);
linker->defineSymbol("src_for_decompressor", physical_start + decompr_pos - c_len); linker->defineSymbol("src_for_decompressor", physical_start + decompr_pos - c_len);
@@ -441,10 +430,7 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
linker->defineSymbol("copy_dest", physical_start + edi); linker->defineSymbol("copy_dest", physical_start + edi);
linker->defineSymbol("copy_source", bzimage_offset + esi); linker->defineSymbol("copy_source", bzimage_offset + esi);
defineFilterSymbols(linker, &ft); defineFilterSymbols(&ft);
if (0x40==(0xf0 & ft.id)) {
linker->defineSymbol("filter_length", ph.u_len); // redefine
}
defineDecompressorSymbols(); defineDecompressorSymbols();
linker->defineSymbol("original_entry", physical_start); linker->defineSymbol("original_entry", physical_start);
linker->defineSymbol("stack_offset", stack_offset_during_uncompression); linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
@@ -455,7 +441,7 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
patchPackHeader(loader, lsize); patchPackHeader(loader, lsize);
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf); 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(setup_buf, setup_buf.getSize());
fo->write(loader, e_len); fo->write(loader, e_len);
+6 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_VMLINUZ_i386; } virtual int getFormat() const { return UPX_F_VMLINUZ_i386; }
virtual const char *getName() const { return "vmlinuz/386"; } 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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
@@ -59,7 +60,7 @@ protected:
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
// virtual const upx_byte *getLoader() const; // virtual upx_byte *getLoader() const;
// virtual int getLoaderSize() const; // virtual int getLoaderSize() const;
struct boot_sect_t struct boot_sect_t
@@ -101,6 +102,7 @@ public:
PackBvmlinuzI386(InputFile *f) : super(f) { } PackBvmlinuzI386(InputFile *f) : super(f) { }
virtual int getFormat() const { return UPX_F_BVMLINUZ_i386; } virtual int getFormat() const { return UPX_F_BVMLINUZ_i386; }
virtual const char *getName() const { return "bvmlinuz/386"; } 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); virtual void pack(OutputFile *fo);
@@ -120,6 +122,7 @@ public:
PackElks8086(InputFile *f) : super(f) { } PackElks8086(InputFile *f) : super(f) { }
virtual int getFormat() const { return UPX_F_ELKS_8086; } virtual int getFormat() const { return UPX_F_ELKS_8086; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -59,7 +59,7 @@ protected:
virtual void encodeFixups(); virtual void encodeFixups();
virtual void decodeFixups(); virtual void decodeFixups();
virtual void encodeImage(const Filter *ft); virtual void encodeImage(Filter *ft);
virtual void decodeImage(); virtual void decodeImage();
}; };
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them 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 getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_WIN16_NE; } virtual int getFormat() const { return UPX_F_WIN16_NE; }
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
+35 -42
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
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
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -142,8 +142,9 @@ const int *PackW32Pe::getCompressionMethods(int method, int level) const
const int *PackW32Pe::getFilters() const const int *PackW32Pe::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x26, 0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12, 0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
-1 }; FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters; return filters;
} }
@@ -168,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 // import handling
**************************************************************************/ **************************************************************************/
@@ -530,7 +517,7 @@ void PackW32Pe::processLoadConf(Reloc *rel, const Interval *iv,
bool PackW32Pe::canPack() bool PackW32Pe::canPack()
{ {
if (!readFileHeader()) if (!readFileHeader() || ih.cpu < 0x14c || ih.cpu > 0x150)
return false; return false;
return true; return true;
} }
@@ -552,6 +539,7 @@ void PackW32Pe::buildLoader(const Filter *ft)
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "", icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
tmp_tlsindex ? "PETLSHAK" : "", tmp_tlsindex ? "PETLSHAK" : "",
"PEMAIN02", "PEMAIN02",
ph.first_offset_found == 1 ? "PEMAIN03" : "",
getDecompressorSections(), getDecompressorSections(),
/*multipass ? "PEMULTIP" : */ "", /*multipass ? "PEMULTIP" : */ "",
"PEMAIN10", "PEMAIN10",
@@ -649,7 +637,7 @@ void PackW32Pe::pack(OutputFile *fo)
if (ih.entry && ih.entry < rvamin) if (ih.entry && ih.entry < rvamin)
throwCantPack("run a virus scanner on this file!"); throwCantPack("run a virus scanner on this file!");
if (!opt->force && ih.subsystem == 1) 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) if (ih.filealign < 0x200)
throwCantPack("filealign < 0x200 is not yet supported"); throwCantPack("filealign < 0x200 is not yet supported");
@@ -722,14 +710,14 @@ void PackW32Pe::pack(OutputFile *fo)
const unsigned dllstrings = processImports(); const unsigned dllstrings = processImports();
processTls(&tlsiv); // call before processRelocs!! processTls(&tlsiv); // call before processRelocs!!
processLoadConf(&loadconfiv);
processResources(&res); processResources(&res);
processExports(&xport); processExports(&xport);
processLoadConf(&loadconfiv);
processRelocs(); processRelocs();
//OutputFile::dump("x1", ibuf, usize); //OutputFile::dump("x1", ibuf, usize);
// some checks for broken linkers - disable filter if neccessary // some checks for broken linkers - disable filter if necessary
bool allow_filter = true; bool allow_filter = true;
if (ih.codebase == ih.database if (ih.codebase == ih.database
|| ih.codebase + ih.codesize > ih.imagesize || ih.codebase + ih.codesize > ih.imagesize
@@ -794,17 +782,17 @@ void PackW32Pe::pack(OutputFile *fo)
ft.buf_len = ih.codesize; ft.buf_len = ih.codesize;
ft.addvalue = ih.codebase - rvamin; ft.addvalue = ih.codebase - rvamin;
// compress // compress
int strategy = allow_filter ? 0 : -3; int filter_strategy = allow_filter ? 0 : -3;
// disable filters for files with broken headers // disable filters for files with broken headers
if (ih.codebase + ih.codesize > ph.u_len) if (ih.codebase + ih.codesize > ph.u_len)
{ {
ft.buf_len = 1; ft.buf_len = 1;
strategy = -3; filter_strategy = -3;
} }
compressWithFilters(&ft, 2048, strategy, compressWithFilters(&ft, 2048, NULL_cconf, filter_strategy,
NULL, NULL, ih.codebase, rvamin); ih.codebase, rvamin, 0, NULL, 0);
// info: see buildLoader() // info: see buildLoader()
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1; newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4) if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
@@ -818,12 +806,14 @@ void PackW32Pe::pack(OutputFile *fo)
pe_section_t osection[3]; pe_section_t osection[3];
// section 0 : bss // section 0 : bss
// 1 : [ident + header] + packed_data + unpacker + tls // 1 : [ident + header] + packed_data + unpacker + tls + loadconf
// 2 : not compressed data // 2 : not compressed data
// section 2 should start with the resource data, because lots of lame // section 2 should start with the resource data, because lots of lame
// windoze codes assume that resources starts on the beginning of a section // 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 // identsplit - number of ident + (upx header) bytes to put into the PE header
int identsplit = pe_offset + sizeof(osection) + sizeof(oh); int identsplit = pe_offset + sizeof(osection) + sizeof(oh);
if ((identsplit & 0x1ff) == 0) if ((identsplit & 0x1ff) == 0)
@@ -837,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); 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); 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 s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1;
const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1; const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1;
@@ -888,9 +878,9 @@ void PackW32Pe::pack(OutputFile *fo)
linker->defineSymbol("VirtualFree", myimport + get_le32(oimpdlls + 16) + 16); linker->defineSymbol("VirtualFree", myimport + get_le32(oimpdlls + 16) + 16);
#endif #endif
defineFilterSymbols(linker, &ft);
linker->defineSymbol("filter_buffer_start", ih.codebase - rvamin);
defineDecompressorSymbols(); defineDecompressorSymbols();
defineFilterSymbols(&ft);
linker->defineSymbol("filter_buffer_start", ih.codebase - rvamin);
// in case of overlapping decompression, this hack is needed, // in case of overlapping decompression, this hack is needed,
// because windoze zeroes the word pointed by tlsindex before // because windoze zeroes the word pointed by tlsindex before
@@ -907,6 +897,7 @@ void PackW32Pe::pack(OutputFile *fo)
linker->defineSymbol("start_of_compressed", esi0 + ih.imagebase); linker->defineSymbol("start_of_compressed", esi0 + ih.imagebase);
linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection); linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);
//linker->dumpSymbols();
relocateLoader(); relocateLoader();
const unsigned lsize = getLoaderSize(); const unsigned lsize = getLoaderSize();
@@ -934,14 +925,19 @@ void PackW32Pe::pack(OutputFile *fo)
ODADDR(PEDIR_BOUNDIM) = 0; ODADDR(PEDIR_BOUNDIM) = 0;
ODSIZE(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); processTls(&rel,&tlsiv,ic);
ODADDR(PEDIR_TLS) = sotls ? ic : 0; ODADDR(PEDIR_TLS) = sotls ? ic : 0;
ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0; ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0;
ic += sotls; ic += sotls;
processLoadConf(&rel, &loadconfiv, ic);
ODADDR(PEDIR_LOADCONF) = soloadconf ? ic : 0;
ODSIZE(PEDIR_LOADCONF) = soloadconf;
ic += soloadconf;
// these are put into section 2 // these are put into section 2
ic = ncsection; ic = ncsection;
@@ -966,19 +962,13 @@ void PackW32Pe::pack(OutputFile *fo)
} }
ic += soexport; ic += soexport;
processLoadConf(&rel, &loadconfiv, ic);
ODADDR(PEDIR_LOADCONF) = soloadconf ? ic : 0;
ODSIZE(PEDIR_LOADCONF) = soloadconf;
ic += soloadconf;
processRelocs(&rel); processRelocs(&rel);
ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0; ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0;
ODSIZE(PEDIR_RELOC) = soxrelocs; ODSIZE(PEDIR_RELOC) = soxrelocs;
ic += soxrelocs; ic += soxrelocs;
// this is computed here, because soxrelocs changes some lines above // this is computed here, because soxrelocs changes some lines above
const unsigned ncsize = soresources + soimpdlls + soexport + soloadconf const unsigned ncsize = soresources + soimpdlls + soexport + soxrelocs;
+ soxrelocs;
ic = oh.filealign - 1; ic = oh.filealign - 1;
// this one is tricky: it seems windoze touches 4 bytes after // this one is tricky: it seems windoze touches 4 bytes after
@@ -1060,12 +1050,12 @@ void PackW32Pe::pack(OutputFile *fo)
if ((ic = fo->getBytesWritten() & 3) != 0) if ((ic = fo->getBytesWritten() & 3) != 0)
fo->write(ibuf,4 - ic); fo->write(ibuf,4 - ic);
fo->write(otls,sotls); fo->write(otls,sotls);
fo->write(oloadconf, soloadconf);
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0) if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
fo->write(ibuf,oh.filealign - ic); fo->write(ibuf,oh.filealign - ic);
fo->write(oresources,soresources); fo->write(oresources,soresources);
fo->write(oimpdlls,soimpdlls); fo->write(oimpdlls,soimpdlls);
fo->write(oexport,soexport); fo->write(oexport,soexport);
fo->write(oloadconf, soloadconf);
fo->write(oxrelocs,soxrelocs); fo->write(oxrelocs,soxrelocs);
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0) if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
@@ -1165,7 +1155,8 @@ int PackW32Pe::canUnpack()
void PackW32Pe::rebuildImports(upx_byte *& extrainfo) void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
{ {
if (ODADDR(PEDIR_IMPORT) == 0) if (ODADDR(PEDIR_IMPORT) == 0
|| ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
return; return;
// const upx_byte * const idata = obuf + get_le32(extrainfo); // const upx_byte * const idata = obuf + get_le32(extrainfo);
@@ -1183,6 +1174,7 @@ void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
for (p = idata; get_le32(p) != 0; ++p) for (p = idata; get_le32(p) != 0; ++p)
{ {
const upx_byte *dname = get_le32(p) + import; const upx_byte *dname = get_le32(p) + import;
ICHECK(dname, 1);
const unsigned dlen = strlen(dname); const unsigned dlen = strlen(dname);
ICHECK(dname, dlen + 1); ICHECK(dname, dlen + 1);
@@ -1195,7 +1187,7 @@ void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
else else
p += 5; p += 5;
} }
sdllnames = ALIGN_UP(sdllnames,2); sdllnames = ALIGN_UP(sdllnames, 2u);
upx_byte * const Obuf = obuf - rvamin; upx_byte * const Obuf = obuf - rvamin;
import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT)); import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
@@ -1208,6 +1200,7 @@ void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
{ {
// restore the name of the dll // restore the name of the dll
const upx_byte *dname = get_le32(p) + import; const upx_byte *dname = get_le32(p) + import;
ICHECK(dname, 1);
const unsigned dlen = strlen(dname); const unsigned dlen = strlen(dname);
ICHECK(dname, dlen + 1); ICHECK(dname, dlen + 1);

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