Compare commits
296 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f37a7811f9 | |||
| 9173c10239 | |||
| 318b31550d | |||
| c18ebc63a6 | |||
| d704694272 | |||
| 1cfec3bdf7 | |||
| fe6ea6bc10 | |||
| d29c8df45e | |||
| 71f996af95 | |||
| d9722ad6b3 | |||
| 398fd8028c | |||
| 1345a3cfd3 | |||
| 7eb0b195b8 | |||
| 009caee82d | |||
| 3bdc805a22 | |||
| ac457792b4 | |||
| 1377b54b9e | |||
| 66418ffc8c | |||
| b4c4b1fb70 | |||
| ffe4a4b047 | |||
| 753ce45310 | |||
| fece0d73e7 | |||
| edce076e68 | |||
| 675d0a009a | |||
| 5d41b5a4db | |||
| fe53b135eb | |||
| 5b1c154ee2 | |||
| 816d882611 | |||
| 12bcb09051 | |||
| c59c69a85f | |||
| bdd0daaf6f | |||
| cfad7c8356 | |||
| b2b8a128d0 | |||
| 1cfad80ca2 | |||
| a5a80e41b8 | |||
| 152f8e92bf | |||
| 0323560b49 | |||
| d3bc84a2f7 | |||
| 8a82c259bd | |||
| 46009c7658 | |||
| 6f760308bd | |||
| c346f8f17d | |||
| af1d059fff | |||
| 5562b21a20 | |||
| 8f68f31877 | |||
| ce7e94030c | |||
| ccf5a1b972 | |||
| 0d5ae77efc | |||
| 1695096d18 | |||
| 6db0b7cf18 | |||
| 575b43b0d4 | |||
| 7b39b05894 | |||
| 8bea9e0a5e | |||
| 2255b32e45 | |||
| b62573ae8f | |||
| 44ed84f5cf | |||
| d008c834be | |||
| 2d3a914aee | |||
| 7324f4c3d1 | |||
| 50c8860a50 | |||
| 6456de7188 | |||
| 23c629f2aa | |||
| 2bf154f74f | |||
| b598ad1bc0 | |||
| ace24ad68e | |||
| 750c1a0f27 | |||
| 52d89bd66b | |||
| 8cfb9d35e9 | |||
| 2f529158a0 | |||
| 6e68ab6d9e | |||
| 7a3c55af35 | |||
| fb39d6304a | |||
| 4cb57d9059 | |||
| 42d69bd0e5 | |||
| f27b399f81 | |||
| a545a3938f | |||
| d1e352c9ee | |||
| 99be1e798b | |||
| 2132a28a17 | |||
| 8b1cc28783 | |||
| 78364ac830 | |||
| 6e5f5732b5 | |||
| 87844254d1 | |||
| 08ef9f69fb | |||
| 5fbd1b78e7 | |||
| 39f5eb753f | |||
| f4cbe3f300 | |||
| 70632e5541 | |||
| 0bba700105 | |||
| b71aaccff3 | |||
| 7271ae9611 | |||
| 6e32dff2ad | |||
| 8f7c898c08 | |||
| f4a9815f48 | |||
| 0f8d5c7e98 | |||
| 5e83596a1b | |||
| 6361213e07 | |||
| 9c59a5d9b6 | |||
| bb04844bd5 | |||
| 0b988176fa | |||
| a354f18a2d | |||
| a7ca0fec88 | |||
| 06eec508df | |||
| 10dc580a3a | |||
| 2f6ae3ef01 | |||
| 392e803905 | |||
| 83a5fb585b | |||
| c6205ffbe0 | |||
| c04737ce20 | |||
| 11b92172fe | |||
| 3a6c574376 | |||
| b21ce925fb | |||
| de9dcc4ed6 | |||
| 9e77dbfe20 | |||
| 4cee0676a4 | |||
| 8ad9d21db3 | |||
| 8ba8317eea | |||
| d221187f24 | |||
| db54ec294f | |||
| 1d39796e3f | |||
| cd6a318903 | |||
| 73090b98ab | |||
| 745de1abab | |||
| 961031efc1 | |||
| 2487595778 | |||
| 5c4863d504 | |||
| 5e3a658932 | |||
| cb4704c821 | |||
| cc0b7d1492 | |||
| f8ebbf8b08 | |||
| 8795f60bf1 | |||
| f00c0a9436 | |||
| 767bc71870 | |||
| 4c068e3e00 | |||
| 277d862172 | |||
| dbed6a47bb | |||
| 94f3749784 | |||
| 728e6d851e | |||
| 11e863545f | |||
| dde49f0bb4 | |||
| a37a75aecc | |||
| e43e3aeb1c | |||
| a8fe529814 | |||
| d9f5e2bb08 | |||
| dfa83b0ac8 | |||
| bd5cef1411 | |||
| cd70b48831 | |||
| 50ebf8088a | |||
| c5cfb7eb40 | |||
| bccaafda6d | |||
| bf0086d7b5 | |||
| 7e65938ca6 | |||
| 112eff2509 | |||
| d7837d9179 | |||
| 6cdd057f80 | |||
| 5a03b213fb | |||
| f270213246 | |||
| 2e1795c5ba | |||
| 732d6710d3 | |||
| edf384d2ee | |||
| c307640826 | |||
| a77b598f82 | |||
| 217420cfa5 | |||
| f2b9dff596 | |||
| ae945ed315 | |||
| 770c153c76 | |||
| 29c4a7e606 | |||
| 8875470b37 | |||
| 6e52364bcb | |||
| 7015d616b4 | |||
| 92e6da3260 | |||
| 9220b6f1d5 | |||
| 1d0d538d0c | |||
| 83052eafae | |||
| fa95c3c4a2 | |||
| 665dcf221b | |||
| 8f73dbd253 | |||
| 826312cbad | |||
| 72a18f2b3f | |||
| a6b5e3d0ae | |||
| 1b321f4fa3 | |||
| fbde0b9f35 | |||
| 0e5f5e54cc | |||
| cbb5902066 | |||
| 92ec1b0598 | |||
| a62fc3abff | |||
| 08f8e55446 | |||
| 68f54a3247 | |||
| 29c099fe56 | |||
| 76b81c7b35 | |||
| d6b33ffd6b | |||
| 16b9873fa8 | |||
| ba4a686d1c | |||
| 4be3d79e12 | |||
| 2569b09dbe | |||
| 5d71e69941 | |||
| 16163bf20b | |||
| f1a97fecbd | |||
| a050f82f0e | |||
| ef7beea334 | |||
| 3f4acb33f9 | |||
| 14822e6395 | |||
| e82db4ed38 | |||
| 87b7ea9cf3 | |||
| 787b1fceff | |||
| 140d6ad839 | |||
| 46e8e22236 | |||
| c386db2b33 | |||
| 8dad091c6b | |||
| 3365ccbb9c | |||
| 2ced230965 | |||
| 989d10a3e1 | |||
| 62d8c69774 | |||
| cf704257b0 | |||
| a6cb6f57d3 | |||
| 141c703ed5 | |||
| 796d58867b | |||
| 2f483ec8e8 | |||
| e338918773 | |||
| d9effc58cf | |||
| 05d03f97fc | |||
| 03e891c0e8 | |||
| 4dfe9d52e9 | |||
| 9e65692b69 | |||
| 0687c9a57a | |||
| ffe1287016 | |||
| 75b7e7260f | |||
| d631e081bc | |||
| db5843d904 | |||
| 5ec16153f7 | |||
| 8c873ccdc8 | |||
| c95088f8d5 | |||
| 519fa55df7 | |||
| b8dda033ed | |||
| 0359e9c5c7 | |||
| d822b4a62a | |||
| d9e8c953b1 | |||
| 9eca502026 | |||
| cd0efe3edb | |||
| 8146e9cbcd | |||
| 5d95275024 | |||
| 49a97eea4b | |||
| 36e9c27e9c | |||
| 6e5153cd07 | |||
| c73da864c8 | |||
| 071bb75700 | |||
| 99374de340 | |||
| db7ae4ed5d | |||
| e61f481881 | |||
| 396a3ad2fc | |||
| be235ddc38 | |||
| 9e72ecd93d | |||
| 8e0bd936eb | |||
| 9d0270dcd6 | |||
| 713415c354 | |||
| 786550572e | |||
| 46caeddc81 | |||
| 71bfde2bfe | |||
| 76771b845a | |||
| a74e239e28 | |||
| 6e763b0b42 | |||
| 2f41ece017 | |||
| 01cd5fe0d5 | |||
| ed12ff7bb3 | |||
| f1386bb60d | |||
| 417bd06e76 | |||
| 91e46e3cf8 | |||
| deb5139c4d | |||
| 862ac5d014 | |||
| 028235d421 | |||
| 143d399849 | |||
| 375f171e47 | |||
| 387edcf4b2 | |||
| 011cd37cfb | |||
| 0d4254f319 | |||
| 4c407c2850 | |||
| 829e2d6c5d | |||
| a31c4bd474 | |||
| 17f24dc377 | |||
| de3e9f2809 | |||
| 4442a282e1 | |||
| 261010f23d | |||
| ede44ca6ee | |||
| 452a953234 | |||
| 2b122562ad | |||
| 6891bc3da3 | |||
| b31b8cd7f0 | |||
| e1379ac5ce | |||
| 0ef3f75d7a | |||
| 407a9e5be0 | |||
| 892bb9bf30 | |||
| 47ac871a12 | |||
| a38c3e7f6d | |||
| 08818355d1 | |||
| 0a68afef00 | |||
| 2c0783e327 |
@@ -2,11 +2,14 @@ syntax: regexp
|
||||
|
||||
^\.bzr
|
||||
^ChangeLog
|
||||
^Makevars.global
|
||||
^build
|
||||
^maint
|
||||
|
||||
syntax: glob
|
||||
|
||||
Makevars.local
|
||||
|
||||
*.a
|
||||
*.dll
|
||||
*.lib
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
|
||||
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
||||
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
||||
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
|
||||
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
||||
a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292
|
||||
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
|
||||
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
||||
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
||||
b82ef51896199484afe5b0553af7d1e59b7ce428 BRANCHPOINT_FOR_upx2.hg
|
||||
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
||||
d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290
|
||||
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
|
||||
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
@@ -8,6 +8,7 @@ export SHELL = /bin/sh
|
||||
|
||||
srcdir = .
|
||||
top_srcdir = .
|
||||
-include $(top_srcdir)/Makevars.global ./Makevars.local
|
||||
|
||||
|
||||
# info: src/stub needs GNU make 3.81 and special build tools
|
||||
@@ -33,15 +34,14 @@ endif
|
||||
$(MAKE) -C src $@
|
||||
$(MAKE) -C doc $@
|
||||
|
||||
# automatically generate ChangeLog from Mercurial repo
|
||||
ChangeLog:
|
||||
|
||||
ifneq ($(wildcard .hg/data/.),)
|
||||
# automatically generate ChangeLog from local Mercurial repo
|
||||
ChangeLog:
|
||||
hg log --style=changelog > $@
|
||||
else
|
||||
@echo "UPX info: no hg repo found"
|
||||
.PHONY: ChangeLog
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
||||
.PHONY: ChangeLog
|
||||
|
||||
|
||||
@@ -2,22 +2,48 @@
|
||||
User visible changes for UPX
|
||||
==================================================================
|
||||
|
||||
Changes in 2.90 (08 Oct 2006):
|
||||
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):
|
||||
* assorted bug fixes
|
||||
* arm/pe: fix "missing" icon & version info resource problem for wince 5
|
||||
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
|
||||
|
||||
Changes in 2.90 beta (08 Oct 2006):
|
||||
* LZMA algorithm support for most of the 32-bit and 64-bit file formats;
|
||||
use new option '--lzma' to enable
|
||||
* new format: BSD/elf386 supporting FreeBSD, NetBSD and OpenBSD
|
||||
via auto-detection of PT_NOTE or EI_OSABI
|
||||
* arm/pe: all the NRV compression methods are now supported
|
||||
(only NRV2D is missing in thumb mode)
|
||||
* linux/elf386, linux/ElfAMD remember /proc/self/exe in environment
|
||||
* vmlinuz/386: fixed zlib uncompression problem on dos
|
||||
* major source code change: the runtime decompression stubs are now
|
||||
* linux/elf386, linux/ElfAMD: remember /proc/self/exe in environment
|
||||
* major source code changes: the runtime decompression stubs are now
|
||||
built from internal ELF objects
|
||||
|
||||
==================================================================
|
||||
|
||||
Changes in 2.03 (07 Nov 2006):
|
||||
* bvmlinuz/386: fix for kernels not at 0x100000; also allow x86_64
|
||||
* linux/elf386: work around Linux kernel bug (0-length .bss needs PF_W)
|
||||
|
||||
Changes in 2.02 (13 Aug 2006):
|
||||
* linux/386: work around Linux kernel bug (".bss" requires PF_W)
|
||||
* linux/ppc32, mach/ppc32: compressed programs now work on a 405 CPU
|
||||
* vmlinuz/386: fixed zlib uncompression problem on dos
|
||||
* vmlinuz/386: fixed zlib uncompression problem on DOS
|
||||
|
||||
Changes in 2.01 (06 Jun 2006):
|
||||
* arm/pe: better DLL support
|
||||
@@ -286,8 +312,8 @@ Changes in 0.80 (03 Aug 1999)
|
||||
* win32/pe: even better TLS support
|
||||
* win32/pe: versioninfo works on NT
|
||||
* win32/pe: import by ordinal from kernel32.dll works
|
||||
* win32/pe: other import improvements: importing a nonexistant DLL
|
||||
results in a usual Windows message, importing a nonexistant function
|
||||
* win32/pe: other import improvements: importing a nonexistent DLL
|
||||
results in a usual Windows message, importing a nonexistent function
|
||||
results in program exit (instead of crash ;-)
|
||||
* win32/pe: new option: '--compress-resources=0'
|
||||
* win32/pe: reduced memory requirement during uncompression, some
|
||||
@@ -339,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 a problem with empty resource data
|
||||
* 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 an address optimization problem for some not Watcom LE files
|
||||
* fixed a bug which could make UPX hang when an exe header contained
|
||||
@@ -380,3 +406,5 @@ Changes in 0.20 (05 Jul 1998)
|
||||
Changes in 0.05 (26 May 1998)
|
||||
* first public beta release
|
||||
|
||||
|
||||
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ THE FUTURE
|
||||
- We will *NOT* add any sort of protection and/or encryption.
|
||||
This only gives people a false feeling of security because
|
||||
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"...
|
||||
|
||||
- Fix all remaining bugs - keep your reports coming ;-)
|
||||
@@ -108,9 +108,9 @@ THE FUTURE
|
||||
COPYRIGHT
|
||||
=========
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
|
||||
This program may be used freely, and you are welcome to
|
||||
redistribute it under certain conditions.
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
|
||||
+8
-3
@@ -75,13 +75,18 @@ Tools needed to build/modify the UPX sources
|
||||
To compile the packer sources
|
||||
-----------------------------
|
||||
|
||||
set the environment variable UPX_UCLDIR to point to your
|
||||
UCL installation, e.g.
|
||||
Set the environment variable UPX_UCLDIR to point to your
|
||||
UCL build directory, e.g.
|
||||
|
||||
set UPX_UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
||||
export UPX_UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
||||
|
||||
then type
|
||||
Set the environment variable UPX_LZMADIR to point to your
|
||||
to your unpacked lzma443.tar.bz2 source directory, e.g.
|
||||
|
||||
export UPX_LZMADIR=$HOME/local/src/lzma-4.43 (Unix)
|
||||
|
||||
Finally type
|
||||
|
||||
make
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
UPX TODO list. Last updated 2006-03-11.
|
||||
UPX TODO list. Last updated 2006-12-08.
|
||||
|
||||
|
||||
IMPORTANT PROBLEMS THAT SHOULD BE FIXED SOON:
|
||||
@@ -41,8 +41,6 @@ ALL FORMATS
|
||||
- implement `--cpu=486' option to use bswap on the 32-bit formats
|
||||
(if cpu >= 486)
|
||||
|
||||
- consider removing "or ebp,-1" when not needed
|
||||
|
||||
|
||||
FORMAT DJGPP2/COFF
|
||||
==================
|
||||
@@ -86,10 +84,6 @@ FORMAT WATCOM/LE
|
||||
|
||||
- handle holes in the file
|
||||
|
||||
- implement compressWithFilters()
|
||||
|
||||
- add a call to verifyOverlappingDecompression()
|
||||
|
||||
|
||||
FORMAT WIN16/NE
|
||||
===============
|
||||
|
||||
+2
-1
@@ -25,7 +25,7 @@ endif
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
||||
top_srcdir = ..
|
||||
top_srcdir ?= ..
|
||||
|
||||
PACKAGE = upx
|
||||
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||
@@ -81,4 +81,5 @@ mostlyclean clean distclean maintainer-clean:
|
||||
###
|
||||
|
||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
Decompressing ELF Directly to Memory on Linux/x86
|
||||
Copyright (C) 2000-2006 John F. Reiser jreiser@BitWagon.com
|
||||
Copyright (C) 2000-2007 John F. Reiser jreiser@BitWagon.com
|
||||
|
||||
References:
|
||||
<elf.h> definitions for the ELF file format
|
||||
@@ -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
|
||||
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,
|
||||
clear the free portion of the stack (to compensate for ld-linux.so.2
|
||||
assuming that its automatic stack variables are initialized to zero),
|
||||
|
||||
+1
-1
@@ -45,6 +45,6 @@ These symbols can be defined later in C++ using
|
||||
|
||||
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++
|
||||
module (src/linker.cpp) can interpret and work with.
|
||||
|
||||
+31
-52
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
|
||||
=head1 ABSTRACT
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
@@ -138,6 +138,9 @@ B<--help>: prints the help
|
||||
|
||||
B<--version>: print the version of B<UPX>
|
||||
|
||||
B<--exact>: when compressing, require to be able to get a byte-identical file
|
||||
after decompression with option B<-d>
|
||||
|
||||
[ ...to be written... - type `B<upx --help>' for now ]
|
||||
|
||||
|
||||
@@ -172,38 +175,13 @@ Note that compression level B<--best> can be somewhat slow for large
|
||||
files, but you definitely should use it when releasing a final version
|
||||
of your program.
|
||||
|
||||
Quick start for achieving the best compression ratio:
|
||||
|
||||
=over 4
|
||||
|
||||
Try B<upx --brute myfile.exe>.
|
||||
|
||||
=back
|
||||
|
||||
Details for achieving the best compression ratio:
|
||||
Quick info for achieving the best compression ratio:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Use the compression level B<--best>.
|
||||
|
||||
=item *
|
||||
|
||||
Try one or both of the options B<--all-methods> and B<--all-filters>.
|
||||
|
||||
=item *
|
||||
|
||||
Try the option B<--crp-ms=NUMBER>. This uses more memory during compression
|
||||
to achieve a (slightly) better compression ratio.
|
||||
|
||||
NUMBER must be a decimal value from 10000 to 999999, inclusive.
|
||||
The default value is 10000 (ten thousand).
|
||||
|
||||
=item *
|
||||
|
||||
Info: the option B<--brute> is an abbrevation for the options
|
||||
B<S<--best> S<--all-methods> S<--all-filters> S<--crp-ms=999999>>.
|
||||
Try B<upx --brute myfile.exe> or even B<upx --ultra-brute myfile.exe>.
|
||||
|
||||
=item *
|
||||
|
||||
@@ -219,7 +197,7 @@ For win32/pe programs there's B<--strip-relocs=0>. See notes below.
|
||||
|
||||
=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
|
||||
(this is a common practice to avoid an extra data file, though
|
||||
it would be better to use resource sections).
|
||||
@@ -367,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
|
||||
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
|
||||
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
|
||||
automatically stubify your COFF files. Use the option B<--coff> to
|
||||
@@ -402,7 +380,7 @@ Extra options available for this executable format:
|
||||
Introduction
|
||||
|
||||
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
|
||||
("linux/386").
|
||||
|
||||
@@ -430,14 +408,14 @@ General user's overview
|
||||
or network I/O.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
savings is less. Big programs tend not to benefit proportionally
|
||||
because each invocation may use only a small fraction of the program,
|
||||
@@ -446,7 +424,7 @@ General user's overview
|
||||
then compression may win anyway.
|
||||
|
||||
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
|
||||
process, then using the compressed version will require more RAM and/or
|
||||
swap space. So, shell programs (bash, csh, etc.) and ``make''
|
||||
@@ -535,7 +513,7 @@ The linux/elf386 format decompresses directly into RAM,
|
||||
uses only one exec, does not use space in /tmp,
|
||||
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.
|
||||
|
||||
@@ -624,7 +602,7 @@ Extra options available for this executable format:
|
||||
Please read the general Linux description first.
|
||||
|
||||
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.
|
||||
|
||||
Linux/386 is only selected if the specialized linux/elf386
|
||||
@@ -636,11 +614,11 @@ How it works:
|
||||
|
||||
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
|
||||
temporary file in the filesystem. Interestingly -
|
||||
temporary file in the file system. Interestingly -
|
||||
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
|
||||
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
|
||||
which contains the original program in a compressed form.
|
||||
@@ -666,7 +644,7 @@ Specific drawbacks:
|
||||
decompression, but you still need it for the full execution time
|
||||
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
|
||||
cannot compress programs that are used during the boot sequence
|
||||
before /proc is mounted.
|
||||
@@ -678,7 +656,7 @@ Specific drawbacks:
|
||||
|
||||
- Because of temporary decompression to disk the decompression speed
|
||||
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 :-).
|
||||
|
||||
Extra options available for this executable format:
|
||||
@@ -705,7 +683,7 @@ Notes:
|
||||
|
||||
- UPX creates as default a suitable executable for CD-Mastering
|
||||
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
|
||||
versions, so they will not override other memory areas while unpacking.
|
||||
@@ -781,7 +759,7 @@ Benefits:
|
||||
- Better compression (but note that the kernel was already compressed,
|
||||
so the improvement is not as large as with other formats).
|
||||
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:
|
||||
1589708 vmlinux
|
||||
@@ -828,13 +806,13 @@ Extra options available for this executable format:
|
||||
=head2 NOTES FOR WIN32/PE
|
||||
|
||||
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
|
||||
can see increased memory usage of your compressed files because the whole
|
||||
program is loaded into memory at startup.
|
||||
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.
|
||||
On the other hand if you're compressing only smaller programs, or
|
||||
running only one instance of larger programs, then this penalty is
|
||||
@@ -852,7 +830,7 @@ Screensavers are supported, with the restriction that the filename
|
||||
must end with ".scr" (as screensavers are handled slightly different
|
||||
than normal exe files).
|
||||
|
||||
UPX compressed PE files has some minor memory overhead (usually in the
|
||||
UPX compressed PE files have some minor memory overhead (usually in the
|
||||
10 - 30 kbytes range) which can be seen by specifying the "-i" command
|
||||
line switch during compression.
|
||||
|
||||
@@ -872,6 +850,7 @@ Extra options available for this executable format:
|
||||
--compress-icons=1 Compress all but the first icon.
|
||||
--compress-icons=2 Compress all icons which are not in the
|
||||
first icon directory. [DEFAULT]
|
||||
--compress-icons=3 Compress all icons.
|
||||
|
||||
--compress-resources=0 Don't compress any resources at all.
|
||||
|
||||
@@ -947,13 +926,13 @@ Please report all bugs immediately to the authors.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
|
||||
Copyright (C) 2002-2006 Jens Medoch
|
||||
Copyright (C) 2002-2007 Jens Medoch
|
||||
|
||||
This program may be used freely, and you are welcome to
|
||||
redistribute it under certain conditions.
|
||||
|
||||
+11
-27
@@ -7,9 +7,15 @@ MAKEFLAGS += -rR
|
||||
export SHELL = /bin/sh
|
||||
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
|
||||
|
||||
srcdir ?= $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
||||
ifneq ($(srcdir),./)
|
||||
ifndef srcdir
|
||||
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
||||
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))
|
||||
VPATH := . $(srcdir)
|
||||
endif
|
||||
@@ -17,7 +23,7 @@ endif
|
||||
ifeq ($(CXX),)
|
||||
CXX = g++
|
||||
endif
|
||||
ifeq ($(firstword $(CXX)),g++)
|
||||
ifneq ($(findstring $(firstword $(CXX)),g++),)
|
||||
USE_GNUC ?= 1
|
||||
endif
|
||||
ifeq ($(USE_GNUC),1)
|
||||
@@ -48,25 +54,13 @@ endif
|
||||
LIBS += -lucl -lz
|
||||
# you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2
|
||||
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||
DEFS += -DWITH_LZMA
|
||||
DEFS += -DWITH_LZMA=1
|
||||
INCLUDES += -I$(UPX_LZMADIR)
|
||||
endif
|
||||
# you should set envvar UPX_LUADIR to point to your unpacked lua-5.1.1.tar.gz
|
||||
# [disabled for now]
|
||||
ifneq ($(wildcard $(UPX_LUADIR)/src/lua.h),)
|
||||
##DEFS += -DWITH_LUA
|
||||
##upx_SOURCES_LUA := $(wildcard $(UPX_LUADIR)/src/*.c)
|
||||
##upx_SOURCES_LUA := $(filter-out %lua.c, $(upx_SOURCES_LUA))
|
||||
##upx_SOURCES_LUA := $(filter-out %luac.c, $(upx_SOURCES_LUA))
|
||||
##upx_OBJECTS_LUA := $(notdir $(upx_SOURCES_LUA:.c=$(objext)))
|
||||
##upx_OBJECTS_LUA := $(addprefix lua_,$(upx_OBJECTS_LUA))
|
||||
##upx_OBJECTS += $(upx_OBJECTS_LUA)
|
||||
else
|
||||
##$(error please set UPX_LUADIR)
|
||||
endif
|
||||
|
||||
|
||||
all: upx$(exeext)
|
||||
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS)
|
||||
|
||||
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
||||
$($(notdir $@).PRE_LINK_STEP)
|
||||
@@ -86,16 +80,6 @@ compress_lzma$(objext) : CXXFLAGS += -Wno-unused
|
||||
##compress_lzma$(objext) : CXXFLAGS += -Wno-error
|
||||
endif
|
||||
|
||||
ifneq ($(strip $(upx_OBJECTS_LUA)),)
|
||||
$(upx_OBJECTS_LUA) : lua_%.o : $(UPX_LUADIR)/src/%.c
|
||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||
ifeq ($(USE_GNUC),1)
|
||||
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-cast-align
|
||||
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-cast-qual
|
||||
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-error
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
mostlyclean clean distclean maintainer-clean:
|
||||
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
|
||||
|
||||
+147
-16
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -183,81 +183,143 @@ inline void set_le64(void *p, acc_uint64l_t v)
|
||||
// get signed values, i.e. sign-extend
|
||||
**************************************************************************/
|
||||
|
||||
inline int sign_extend(int v, int bits)
|
||||
inline int sign_extend(unsigned v, unsigned bits)
|
||||
{
|
||||
const unsigned sign_bit = 1u << (bits - 1);
|
||||
v |= 0u - (v & sign_bit);
|
||||
return v;
|
||||
v &= sign_bit | (sign_bit - 1);
|
||||
//v = (v ^ sign_bit) - sign_bit;
|
||||
v |= 0 - (v & sign_bit);
|
||||
return (int) v;
|
||||
}
|
||||
|
||||
inline acc_int64l_t sign_extend(acc_int64l_t v, int bits)
|
||||
inline acc_int64l_t sign_extend(acc_uint64l_t v, unsigned bits)
|
||||
{
|
||||
const acc_uint64l_t sign_bit = ACC_UINT64_C(1) << (bits - 1);
|
||||
v |= ACC_UINT64_C(0) - (v & sign_bit);
|
||||
return v;
|
||||
v &= sign_bit | (sign_bit - 1);
|
||||
//v = (v ^ sign_bit) - sign_bit;
|
||||
v |= 0 - (v & sign_bit);
|
||||
return (acc_int64l_t) v;
|
||||
}
|
||||
|
||||
inline int get_be16_signed(const void *p)
|
||||
{
|
||||
int v = get_be16(p);
|
||||
unsigned v = get_be16(p);
|
||||
return sign_extend(v, 16);
|
||||
}
|
||||
|
||||
inline int get_be24_signed(const void *p)
|
||||
{
|
||||
int v = get_be24(p);
|
||||
unsigned v = get_be24(p);
|
||||
return sign_extend(v, 24);
|
||||
}
|
||||
|
||||
inline int get_be32_signed(const void *p)
|
||||
{
|
||||
int v = get_be32(p);
|
||||
unsigned v = get_be32(p);
|
||||
return sign_extend(v, 32);
|
||||
}
|
||||
|
||||
inline acc_int64l_t get_be64_signed(const void *p)
|
||||
{
|
||||
acc_int64l_t v = get_be64(p);
|
||||
acc_uint64l_t v = get_be64(p);
|
||||
return sign_extend(v, 64);
|
||||
}
|
||||
|
||||
inline int get_le16_signed(const void *p)
|
||||
{
|
||||
int v = get_le16(p);
|
||||
unsigned v = get_le16(p);
|
||||
return sign_extend(v, 16);
|
||||
}
|
||||
|
||||
inline int get_le24_signed(const void *p)
|
||||
{
|
||||
int v = get_le24(p);
|
||||
unsigned v = get_le24(p);
|
||||
return sign_extend(v, 24);
|
||||
}
|
||||
|
||||
inline int get_le32_signed(const void *p)
|
||||
{
|
||||
int v = get_le32(p);
|
||||
unsigned v = get_le32(p);
|
||||
return sign_extend(v, 32);
|
||||
}
|
||||
|
||||
inline acc_int64l_t get_le64_signed(const void *p)
|
||||
{
|
||||
acc_int64l_t v = get_le64(p);
|
||||
acc_uint64l_t v = get_le64(p);
|
||||
return sign_extend(v, 64);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// swab (bswap)
|
||||
**************************************************************************/
|
||||
|
||||
inline unsigned acc_swab16(unsigned v)
|
||||
{
|
||||
return ((v & 0x00ff) << 8) |
|
||||
((v & 0xff00) >> 8);
|
||||
}
|
||||
|
||||
inline unsigned acc_swab32(unsigned v)
|
||||
{
|
||||
return ((v & 0x000000ff) << 24) |
|
||||
((v & 0x0000ff00) << 8) |
|
||||
((v & 0x00ff0000) >> 8) |
|
||||
((v & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned acc_swab16p(const acc_uint16e_t *p)
|
||||
{
|
||||
return acc_swab16(*p);
|
||||
}
|
||||
|
||||
inline unsigned acc_swap32p(const acc_uint32e_t *p)
|
||||
{
|
||||
return acc_swab32(*p);
|
||||
}
|
||||
|
||||
|
||||
inline void acc_swab16s(acc_uint16e_t *p)
|
||||
{
|
||||
*p = acc_swab16(*p);
|
||||
}
|
||||
|
||||
inline void acc_swab32s(acc_uint32e_t *p)
|
||||
{
|
||||
*p = acc_swab32(*p);
|
||||
}
|
||||
|
||||
|
||||
inline void acc_ua_swab16s(void *p)
|
||||
{
|
||||
set_be16(p, get_le16(p));
|
||||
}
|
||||
|
||||
inline void acc_ua_swab32s(void *p)
|
||||
{
|
||||
set_be32(p, get_le32(p));
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// classes for portable unaligned access
|
||||
//
|
||||
// Important: these classes must be PODs (Plain Old Data), i.e. no
|
||||
// constructor, no destructor, no virtual functions and no default
|
||||
// assignment operator, and all fields must be public(!).
|
||||
//
|
||||
// [Actually we _can_ use a safe non-POD subset, but for this we need
|
||||
// to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
|
||||
**************************************************************************/
|
||||
|
||||
struct BE16
|
||||
{
|
||||
unsigned char d[2];
|
||||
|
||||
//inline BE16() { }
|
||||
//BE16(unsigned v) { set_be16(d, v); }
|
||||
|
||||
BE16& operator = (unsigned v) { set_be16(d, v); return *this; }
|
||||
BE16& operator += (unsigned v) { set_be16(d, get_be16(d) + v); return *this; }
|
||||
BE16& operator -= (unsigned v) { set_be16(d, get_be16(d) - v); return *this; }
|
||||
@@ -278,6 +340,9 @@ struct BE32
|
||||
{
|
||||
unsigned char d[4];
|
||||
|
||||
//inline BE32() { }
|
||||
//BE32(unsigned v) { set_be32(d, v); }
|
||||
|
||||
BE32& operator = (unsigned v) { set_be32(d, v); return *this; }
|
||||
BE32& operator += (unsigned v) { set_be32(d, get_be32(d) + v); return *this; }
|
||||
BE32& operator -= (unsigned v) { set_be32(d, get_be32(d) - v); return *this; }
|
||||
@@ -298,6 +363,9 @@ struct BE64
|
||||
{
|
||||
unsigned char d[8];
|
||||
|
||||
//inline BE64() { }
|
||||
//BE64(acc_uint64l_t v) { set_be64(d, v); }
|
||||
|
||||
BE64& operator = (acc_uint64l_t v) { set_be64(d, v); return *this; }
|
||||
BE64& operator += (acc_uint64l_t v) { set_be64(d, get_be64(d) + v); return *this; }
|
||||
BE64& operator -= (acc_uint64l_t v) { set_be64(d, get_be64(d) - v); return *this; }
|
||||
@@ -318,6 +386,9 @@ struct LE16
|
||||
{
|
||||
unsigned char d[2];
|
||||
|
||||
//inline LE16() { }
|
||||
//LE16(unsigned v) { set_le16(d, v); }
|
||||
|
||||
LE16& operator = (unsigned v) { set_le16(d, v); return *this; }
|
||||
LE16& operator += (unsigned v) { set_le16(d, get_le16(d) + v); return *this; }
|
||||
LE16& operator -= (unsigned v) { set_le16(d, get_le16(d) - v); return *this; }
|
||||
@@ -338,6 +409,9 @@ struct LE32
|
||||
{
|
||||
unsigned char d[4];
|
||||
|
||||
//inline LE32() { }
|
||||
//LE32(unsigned v) { set_le32(d, v); }
|
||||
|
||||
LE32& operator = (unsigned v) { set_le32(d, v); return *this; }
|
||||
LE32& operator += (unsigned v) { set_le32(d, get_le32(d) + v); return *this; }
|
||||
LE32& operator -= (unsigned v) { set_le32(d, get_le32(d) - v); return *this; }
|
||||
@@ -358,6 +432,9 @@ struct LE64
|
||||
{
|
||||
unsigned char d[8];
|
||||
|
||||
//inline LE64() { }
|
||||
//LE64(acc_uint64l_t v) { set_le64(d, v); }
|
||||
|
||||
LE64& operator = (acc_uint64l_t v) { set_le64(d, v); return *this; }
|
||||
LE64& operator += (acc_uint64l_t v) { set_le64(d, get_le64(d) + v); return *this; }
|
||||
LE64& operator -= (acc_uint64l_t v) { set_le64(d, get_le64(d) - v); return *this; }
|
||||
@@ -417,11 +494,47 @@ template <class T> T* operator + (const LE64& v, T* ptr);
|
||||
template <class T> T* operator - (T* ptr, const LE64& v);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// global overloads
|
||||
**************************************************************************/
|
||||
|
||||
#if 1 && !defined(ALIGN_DOWN)
|
||||
inline unsigned ALIGN_DOWN(unsigned a, const LE32& b) { return ALIGN_DOWN(a, (unsigned) b); }
|
||||
inline unsigned ALIGN_DOWN(const LE32& a, unsigned b) { return ALIGN_DOWN((unsigned) a, b); }
|
||||
inline unsigned ALIGN_UP (unsigned a, const LE32& b) { return ALIGN_UP (a, (unsigned) b); }
|
||||
inline unsigned ALIGN_UP (const LE32& a, unsigned b) { return ALIGN_UP ((unsigned) a, b); }
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(UPX_MAX)
|
||||
inline unsigned UPX_MAX(unsigned a, const BE16& b) { return UPX_MAX(a, (unsigned) b); }
|
||||
inline unsigned UPX_MAX(const BE16& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
|
||||
inline unsigned UPX_MIN(unsigned a, const BE16& b) { return UPX_MIN(a, (unsigned) b); }
|
||||
inline unsigned UPX_MIN(const BE16& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
|
||||
|
||||
inline unsigned UPX_MAX(unsigned a, const BE32& b) { return UPX_MAX(a, (unsigned) b); }
|
||||
inline unsigned UPX_MAX(const BE32& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
|
||||
inline unsigned UPX_MIN(unsigned a, const BE32& b) { return UPX_MIN(a, (unsigned) b); }
|
||||
inline unsigned UPX_MIN(const BE32& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
|
||||
|
||||
inline unsigned UPX_MAX(unsigned a, const LE16& b) { return UPX_MAX(a, (unsigned) b); }
|
||||
inline unsigned UPX_MAX(const LE16& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
|
||||
inline unsigned UPX_MIN(unsigned a, const LE16& b) { return UPX_MIN(a, (unsigned) b); }
|
||||
inline unsigned UPX_MIN(const LE16& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
|
||||
|
||||
inline unsigned UPX_MAX(unsigned a, const LE32& b) { return UPX_MAX(a, (unsigned) b); }
|
||||
inline unsigned UPX_MAX(const LE32& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
|
||||
inline unsigned UPX_MIN(unsigned a, const LE32& b) { return UPX_MIN(a, (unsigned) b); }
|
||||
inline unsigned UPX_MIN(const LE32& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
// for use with qsort()
|
||||
extern "C" {
|
||||
int __acc_cdecl_qsort be16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare(const void *, const void *);
|
||||
@@ -438,6 +551,7 @@ int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
||||
} // extern "C"
|
||||
|
||||
|
||||
// just for testing...
|
||||
@@ -486,10 +600,14 @@ int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
||||
// forward declarations
|
||||
namespace N_BELE_CTP {
|
||||
class BEPolicy; class LEPolicy;
|
||||
extern const BEPolicy be_policy;
|
||||
extern const LEPolicy le_policy;
|
||||
}
|
||||
namespace N_BELE_RTP {
|
||||
class AbstractPolicy;
|
||||
class BEPolicy; class LEPolicy;
|
||||
extern const BEPolicy be_policy;
|
||||
extern const LEPolicy le_policy;
|
||||
}
|
||||
|
||||
namespace N_BELE_CTP {
|
||||
@@ -504,6 +622,19 @@ namespace N_BELE_RTP {
|
||||
#undef BELE_RTP
|
||||
}
|
||||
|
||||
namespace N_BELE_CTP {
|
||||
|
||||
template <class T>
|
||||
inline const N_BELE_RTP::AbstractPolicy* getRTP();
|
||||
template <>
|
||||
inline const N_BELE_RTP::AbstractPolicy* getRTP<BEPolicy>()
|
||||
{ return &N_BELE_RTP::be_policy; }
|
||||
template <>
|
||||
inline const N_BELE_RTP::AbstractPolicy* getRTP<LEPolicy>()
|
||||
{ return &N_BELE_RTP::le_policy; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
+25
-15
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -53,7 +53,8 @@
|
||||
#if defined(BELE_RTP)
|
||||
struct AbstractPolicy
|
||||
{
|
||||
virtual inline ~AbstractPolicy() {}
|
||||
inline AbstractPolicy() { }
|
||||
virtual inline ~AbstractPolicy() { }
|
||||
V bool isBE() C = 0;
|
||||
V bool isLE() C = 0;
|
||||
|
||||
@@ -81,6 +82,9 @@ struct AbstractPolicy
|
||||
S u24_compare_signed(const void *a, const void *b) C = 0;
|
||||
S u32_compare_signed(const void *a, const void *b) C = 0;
|
||||
S u64_compare_signed(const void *a, const void *b) C = 0;
|
||||
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -90,14 +94,14 @@ struct BEPolicy
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
inline BEPolicy() { }
|
||||
#if defined(BELE_CTP)
|
||||
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
||||
enum { isBE = 1, isLE = 0 };
|
||||
#elif defined(BELE_RTP)
|
||||
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
||||
V bool isBE() C { return CTP_Policy::isBE; }
|
||||
V bool isLE() C { return CTP_Policy::isLE; }
|
||||
#endif
|
||||
V bool isBE() C { return true; }
|
||||
V bool isLE() C { return false; }
|
||||
|
||||
typedef BE16 U16;
|
||||
typedef BE32 U32;
|
||||
@@ -152,10 +156,13 @@ struct BEPolicy
|
||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U16)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U32)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||
}
|
||||
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
};
|
||||
|
||||
|
||||
@@ -164,14 +171,14 @@ struct LEPolicy
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
inline LEPolicy() { }
|
||||
#if defined(BELE_CTP)
|
||||
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
||||
enum { isBE = 0, isLE = 1 };
|
||||
#elif defined(BELE_RTP)
|
||||
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
||||
V bool isBE() C { return CTP_Policy::isBE; }
|
||||
V bool isLE() C { return CTP_Policy::isLE; }
|
||||
#endif
|
||||
V bool isBE() C { return false; }
|
||||
V bool isLE() C { return true; }
|
||||
|
||||
typedef LE16 U16;
|
||||
typedef LE32 U32;
|
||||
@@ -226,10 +233,13 @@ struct LEPolicy
|
||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U16)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U32)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||
}
|
||||
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
};
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+9
-5
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -106,7 +106,7 @@ int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||
cresult->c_len = 0;
|
||||
#endif
|
||||
|
||||
if (method < 0) {
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
@@ -152,7 +152,7 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||
if (cresult && cresult->method == 0)
|
||||
cresult = NULL;
|
||||
|
||||
if (method < 0) {
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
@@ -165,6 +165,10 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||
#if defined(WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_ZLIB)
|
||||
else if (M_IS_DEFLATE(method))
|
||||
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
@@ -193,7 +197,7 @@ int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||
assert((int)overlap_overhead > 0);
|
||||
|
||||
if (method < 0) {
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
|
||||
+23
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -35,6 +35,7 @@
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(WITH_LZMA)
|
||||
const char *upx_lzma_version_string(void);
|
||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
@@ -53,6 +54,7 @@ int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
|
||||
|
||||
#if defined(WITH_NRV)
|
||||
const char *upx_nrv_version_string(void);
|
||||
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
@@ -71,6 +73,7 @@ int upx_nrv_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
|
||||
|
||||
#if defined(WITH_UCL)
|
||||
const char *upx_ucl_version_string(void);
|
||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
@@ -87,6 +90,24 @@ int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
#if defined(WITH_ZLIB)
|
||||
const char *upx_zlib_version_string(void);
|
||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
+146
-69
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -28,6 +28,24 @@
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
|
||||
|
||||
void lzma_compress_config_t::reset()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
|
||||
pos_bits.reset();
|
||||
lit_pos_bits.reset();
|
||||
lit_context_bits.reset();
|
||||
dict_size.reset();
|
||||
fast_mode = 2;
|
||||
num_fast_bytes.reset();
|
||||
match_finder_cycles = 0;
|
||||
|
||||
max_num_probs = 0;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(WITH_LZMA)
|
||||
extern int compress_lzma_dummy;
|
||||
int compress_lzma_dummy = 0;
|
||||
@@ -89,49 +107,49 @@ int compress_lzma_dummy = 0;
|
||||
|
||||
namespace MyLzma {
|
||||
|
||||
struct InStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||
struct InStream: public ISequentialInStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
const Byte *Data; size_t Size; size_t Pos;
|
||||
const Byte *b_buf; size_t b_size; size_t b_pos;
|
||||
void Init(const Byte *data, size_t size) {
|
||||
Data = data; Size = size; Pos = 0;
|
||||
b_buf = data; b_size = size; b_pos = 0;
|
||||
}
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP InStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 remain = Size - Pos;
|
||||
if (size > remain) size = remain;
|
||||
memmove(data, Data + Pos, size);
|
||||
Pos += size;
|
||||
size_t remain = b_size - b_pos;
|
||||
if (size > remain) size = (UInt32) remain;
|
||||
memcpy(data, b_buf + b_pos, size);
|
||||
b_pos += size;
|
||||
if (processedSize != NULL) *processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct OutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||
struct OutStream : public ISequentialOutStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
Byte *Data; size_t Size; size_t Pos; bool Overflow;
|
||||
Byte *b_buf; size_t b_size; size_t b_pos; bool overflow;
|
||||
void Init(Byte *data, size_t size) {
|
||||
Data = data; Size = size; Pos = 0; Overflow = false;
|
||||
b_buf = data; b_size = size; b_pos = 0; overflow = false;
|
||||
}
|
||||
HRESULT WriteByte(Byte b) {
|
||||
if (Pos >= Size) { Overflow = true; return E_FAIL; }
|
||||
Data[Pos++] = b;
|
||||
HRESULT WriteByte(Byte c) {
|
||||
if (b_pos >= b_size) { overflow = true; return E_FAIL; }
|
||||
b_buf[b_pos++] = c;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP OutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < size && Pos < Size; i++)
|
||||
Data[Pos++] = ((const Byte *)data)[i];
|
||||
if (processedSize != NULL) *processedSize = i;
|
||||
if (i != size) { Overflow = true; return E_FAIL; }
|
||||
return S_OK;
|
||||
size_t remain = b_size - b_pos;
|
||||
if (size > remain) size = (UInt32) remain, overflow = true;
|
||||
memcpy(b_buf + b_pos, data, size);
|
||||
b_pos += size;
|
||||
if (processedSize != NULL) *processedSize = size;
|
||||
return overflow ? E_FAIL : S_OK;
|
||||
}
|
||||
|
||||
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
||||
@@ -151,6 +169,23 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
|
||||
} // namespace
|
||||
|
||||
|
||||
#if (ACC_CC_INTELC) && defined(__linux__)
|
||||
# pragma warning(disable: 424) // #424: extra ";" ignored
|
||||
#endif
|
||||
|
||||
#include "C/Common/Alloc.cpp"
|
||||
#include "C/Common/CRC.cpp"
|
||||
//#include "C/7zip/Common/InBuffer.cpp"
|
||||
#include "C/7zip/Common/OutBuffer.cpp"
|
||||
#include "C/7zip/Common/StreamUtils.cpp"
|
||||
#include "C/7zip/Compress/LZ/LZInWindow.cpp"
|
||||
//#include "C/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||
//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||
#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||
#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||
#undef RC_NORMALIZE
|
||||
|
||||
|
||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
@@ -158,15 +193,16 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
const upx_compress_config_t *cconf_parm,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_LZMA);
|
||||
assert(M_IS_LZMA(method));
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
|
||||
int r = UPX_E_ERROR;
|
||||
HRESULT rh;
|
||||
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL;
|
||||
lzma_compress_result_t *res = &cresult->result_lzma;
|
||||
|
||||
MyLzma::InStreamRam is; is.AddRef();
|
||||
MyLzma::OutStreamRam os; os.AddRef();
|
||||
MyLzma::InStream is; is.AddRef();
|
||||
MyLzma::OutStream os; os.AddRef();
|
||||
is.Init(src, src_len);
|
||||
os.Init(dst, *dst_len);
|
||||
|
||||
@@ -174,27 +210,47 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
progress.cb = cb;
|
||||
|
||||
NCompress::NLZMA::CEncoder enc;
|
||||
const PROPID propIDs[7] = {
|
||||
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||
NCoderPropID::kDictionarySize, // 3
|
||||
NCoderPropID::kAlgorithm, // 4 _fastmode
|
||||
NCoderPropID::kNumFastBytes, // 5
|
||||
NCoderPropID::kMatchFinderCycles // 6
|
||||
const PROPID propIDs[8] = {
|
||||
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||
NCoderPropID::kDictionarySize, // 3 ds
|
||||
NCoderPropID::kAlgorithm, // 4 fm _fastmode
|
||||
NCoderPropID::kNumFastBytes, // 5 fb
|
||||
NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue
|
||||
NCoderPropID::kMatchFinder // 7 mf
|
||||
};
|
||||
PROPVARIANT pr[7];
|
||||
PROPVARIANT pr[8];
|
||||
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
|
||||
pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
|
||||
pr[7].vt = VT_BSTR;
|
||||
|
||||
// setup defaults
|
||||
pr[0].uintVal = 2; // 0..4
|
||||
pr[1].uintVal = 0; // 0..4
|
||||
pr[2].uintVal = 3; // 0..8
|
||||
pr[3].uintVal = 1024 * 1024;
|
||||
pr[0].uintVal = 2; // 0 .. 4
|
||||
pr[1].uintVal = 0; // 0 .. 4
|
||||
pr[2].uintVal = 3; // 0 .. 8
|
||||
pr[3].uintVal = 4 * 1024 * 1024; // 1 .. 2**30
|
||||
pr[4].uintVal = 2;
|
||||
pr[5].uintVal = 64; // 5..
|
||||
pr[5].uintVal = 64; // 5 .. 273
|
||||
pr[6].uintVal = 0;
|
||||
#ifdef COMPRESS_MF_BT4
|
||||
static wchar_t matchfinder[] = L"BT4";
|
||||
#endif
|
||||
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
||||
pr[7].bstrVal = matchfinder;
|
||||
#if 1
|
||||
pr[0].uintVal = lzma_compress_config_t::pos_bits_t::default_value_c;
|
||||
pr[1].uintVal = lzma_compress_config_t::lit_pos_bits_t::default_value_c;
|
||||
pr[2].uintVal = lzma_compress_config_t::lit_context_bits_t::default_value_c;
|
||||
pr[3].uintVal = lzma_compress_config_t::dict_size_t::default_value_c;
|
||||
pr[5].uintVal = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
|
||||
#endif
|
||||
// method overrides
|
||||
if (method >= 0x100) {
|
||||
pr[0].uintVal = (method >> 16) & 15;
|
||||
pr[1].uintVal = (method >> 12) & 15;
|
||||
pr[2].uintVal = (method >> 8) & 15;
|
||||
}
|
||||
#if 0
|
||||
// DEBUG - set sizes so that we use a maxmimum amount of stack.
|
||||
// These settings cause res->num_probs == 3147574, i.e. we will
|
||||
@@ -209,8 +265,11 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
case 1:
|
||||
pr[3].uintVal = 256 * 1024;
|
||||
pr[4].uintVal = 0;
|
||||
pr[5].uintVal = 8;
|
||||
break;
|
||||
case 2:
|
||||
pr[3].uintVal = 256 * 1024;
|
||||
pr[4].uintVal = 0;
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
@@ -234,17 +293,27 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
goto error;
|
||||
}
|
||||
|
||||
// cconf overrides
|
||||
if (lcconf)
|
||||
{
|
||||
oassign(pr[0].uintVal, lcconf->pos_bits);
|
||||
oassign(pr[1].uintVal, lcconf->lit_pos_bits);
|
||||
oassign(pr[2].uintVal, lcconf->lit_context_bits);
|
||||
oassign(pr[3].uintVal, lcconf->dict_size);
|
||||
oassign(pr[5].uintVal, lcconf->num_fast_bytes);
|
||||
}
|
||||
|
||||
// limit dictionary size
|
||||
if (pr[3].uintVal > src_len)
|
||||
pr[3].uintVal = src_len;
|
||||
|
||||
// limit num_probs
|
||||
if (cconf_parm && cconf_parm->conf_lzma.max_num_probs)
|
||||
if (lcconf && lcconf->max_num_probs)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
unsigned n = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
|
||||
if (n <= cconf_parm->conf_lzma.max_num_probs)
|
||||
if (n <= lcconf->max_num_probs)
|
||||
break;
|
||||
if (pr[1].uintVal > pr[2].uintVal)
|
||||
{
|
||||
@@ -265,9 +334,13 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
res->lit_pos_bits = pr[1].uintVal;
|
||||
res->lit_context_bits = pr[2].uintVal;
|
||||
res->dict_size = pr[3].uintVal;
|
||||
res->fast_mode = pr[4].uintVal;
|
||||
res->num_fast_bytes = pr[5].uintVal;
|
||||
res->match_finder_cycles = pr[6].uintVal;
|
||||
//res->num_probs = LzmaGetNumProbs(&s.Properties));
|
||||
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
||||
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
|
||||
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
try {
|
||||
@@ -275,20 +348,20 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
# error
|
||||
#endif
|
||||
|
||||
if (enc.SetCoderProperties(propIDs, pr, 7) != S_OK)
|
||||
if (enc.SetCoderProperties(propIDs, pr, 8) != S_OK)
|
||||
goto error;
|
||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||
goto error;
|
||||
if (os.Overflow) {
|
||||
if (os.overflow) {
|
||||
//r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
goto error;
|
||||
}
|
||||
assert(os.Pos == 5);
|
||||
assert(os.b_pos == 5);
|
||||
#if defined(USE_LZMA_PROPERTIES)
|
||||
os.Pos = 1;
|
||||
os.b_pos = 1;
|
||||
#else
|
||||
os.Pos = 0;
|
||||
os.b_pos = 0;
|
||||
// extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||
os.WriteByte((t << 3) | res->pos_bits);
|
||||
@@ -298,44 +371,33 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
rh = enc.Code(&is, &os, NULL, NULL, &progress);
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
} catch(...) { return UPX_E_OUT_OF_MEMORY; }
|
||||
} catch (...) { rh = E_OUTOFMEMORY; }
|
||||
#endif
|
||||
|
||||
assert(is.Pos <= src_len);
|
||||
assert(os.Pos <= *dst_len);
|
||||
assert(is.b_pos <= src_len);
|
||||
assert(os.b_pos <= *dst_len);
|
||||
if (rh == E_OUTOFMEMORY)
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
else if (os.Overflow)
|
||||
else if (os.overflow)
|
||||
{
|
||||
assert(os.Pos == *dst_len);
|
||||
assert(os.b_pos == *dst_len);
|
||||
//r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
}
|
||||
else if (rh == S_OK)
|
||||
{
|
||||
assert(is.Pos == src_len);
|
||||
assert(is.b_pos == src_len);
|
||||
r = UPX_E_OK;
|
||||
}
|
||||
|
||||
error:
|
||||
*dst_len = os.Pos;
|
||||
*dst_len = os.b_pos;
|
||||
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
|
||||
//printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
#include "C/Common/Alloc.cpp"
|
||||
#include "C/Common/CRC.cpp"
|
||||
//#include "C/7zip/Common/InBuffer.cpp"
|
||||
#include "C/7zip/Common/OutBuffer.cpp"
|
||||
#include "C/7zip/Common/StreamUtils.cpp"
|
||||
#include "C/7zip/Compress/LZ/LZInWindow.cpp"
|
||||
//#include "C/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||
//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||
#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||
#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||
#undef RC_NORMALIZE
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// decompress
|
||||
**************************************************************************/
|
||||
@@ -352,7 +414,7 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_LZMA);
|
||||
assert(M_IS_LZMA(method));
|
||||
// see res->num_probs above
|
||||
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||
@@ -391,6 +453,9 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
||||
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||
const lzma_compress_result_t *res = &cresult->result_lzma;
|
||||
UNUSED(res);
|
||||
//printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
||||
}
|
||||
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||
if (!s.Probs)
|
||||
@@ -426,7 +491,7 @@ int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_LZMA);
|
||||
assert(M_IS_LZMA(method));
|
||||
|
||||
// FIXME - implement this
|
||||
// Note that Packer::verifyOverlappingDecompression() will
|
||||
@@ -443,6 +508,18 @@ int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_lzma_version_string(void)
|
||||
{
|
||||
// FIXME
|
||||
// return NULL;
|
||||
return "4.43";
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_LZMA */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
|
||||
+22
-6
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -84,13 +84,14 @@ static int convert_errno_from_ucl(int r)
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
||||
{
|
||||
if (state != -1 && state != 3) return;
|
||||
upx_callback_p cb = (upx_callback_p) user;
|
||||
if (cb && cb->nprogress)
|
||||
cb->nprogress(cb, a, b);
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -107,6 +108,8 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
int r;
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||
|
||||
ucl_progress_callback_t cb;
|
||||
cb.callback = 0;
|
||||
cb.user = NULL;
|
||||
@@ -115,8 +118,7 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
cb.user = cb_parm;
|
||||
}
|
||||
|
||||
ucl_compress_config_t cconf;
|
||||
memset(&cconf, 0xff, sizeof(cconf));
|
||||
ucl_compress_config_t cconf; cconf.reset();
|
||||
if (cconf_parm)
|
||||
cconf = cconf_parm->conf_ucl; // struct copy
|
||||
|
||||
@@ -134,7 +136,7 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
// prepare bit-buffer settings
|
||||
cconf.bb_endian = 0;
|
||||
cconf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16)
|
||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
||||
{
|
||||
static const unsigned char sizes[3] = {32, 8, 16};
|
||||
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||
@@ -164,6 +166,10 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
// make sure first_offset_found is set
|
||||
if (res[6] == 0)
|
||||
res[6] = 1;
|
||||
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
@@ -268,6 +274,16 @@ int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_ucl_version_string(void)
|
||||
{
|
||||
return ucl_version_string();
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_UCL */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
/* compress_zlib.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
|
||||
|
||||
void zlib_compress_config_t::reset()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
|
||||
mem_level.reset();
|
||||
window_bits.reset();
|
||||
strategy.reset();
|
||||
}
|
||||
|
||||
|
||||
#if !defined(WITH_ZLIB)
|
||||
extern int compress_zlib_dummy;
|
||||
int compress_zlib_dummy = 0;
|
||||
#else
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
static int convert_errno_from_zlib(int zr)
|
||||
{
|
||||
switch (zr)
|
||||
{
|
||||
case Z_OK: return UPX_E_OK;
|
||||
case Z_DATA_ERROR: return UPX_E_ERROR;
|
||||
case Z_NEED_DICT: return UPX_E_ERROR;
|
||||
}
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb_parm,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf_parm,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_DEFLATE);
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
UNUSED(cb_parm);
|
||||
int r = UPX_E_ERROR;
|
||||
int zr;
|
||||
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : NULL;
|
||||
zlib_compress_result_t *res = &cresult->result_zlib;
|
||||
|
||||
if (level == 10)
|
||||
level = 9;
|
||||
|
||||
zlib_compress_config_t::mem_level_t mem_level;
|
||||
zlib_compress_config_t::window_bits_t window_bits;
|
||||
zlib_compress_config_t::strategy_t strategy;
|
||||
// cconf overrides
|
||||
if (lcconf)
|
||||
{
|
||||
oassign(mem_level, lcconf->mem_level);
|
||||
oassign(window_bits, lcconf->window_bits);
|
||||
oassign(strategy, lcconf->strategy);
|
||||
}
|
||||
|
||||
res->dummy = 0;
|
||||
|
||||
z_stream s;
|
||||
s.zalloc = (alloc_func) 0;
|
||||
s.zfree = (free_func) 0;
|
||||
s.next_in = const_cast<upx_bytep>(src); // UNCONST
|
||||
s.avail_in = src_len;
|
||||
s.next_out = dst;
|
||||
s.avail_out = *dst_len;
|
||||
s.total_in = s.total_out = 0;
|
||||
|
||||
zr = deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
|
||||
mem_level, strategy);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
zr = deflate(&s, Z_FINISH);
|
||||
if (zr != Z_STREAM_END)
|
||||
goto error;
|
||||
zr = deflateEnd(&s);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
r = UPX_E_OK;
|
||||
goto done;
|
||||
error:
|
||||
(void) deflateEnd(&s);
|
||||
r = convert_errno_from_zlib(zr);
|
||||
if (r == UPX_E_OK)
|
||||
r = UPX_E_ERROR;
|
||||
done:
|
||||
if (r == UPX_E_OK)
|
||||
{
|
||||
if (s.avail_in != 0 || s.total_in != src_len)
|
||||
r = UPX_E_ERROR;
|
||||
}
|
||||
assert(s.total_in <= src_len);
|
||||
assert(s.total_out <= *dst_len);
|
||||
*dst_len = s.total_out;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_DEFLATE);
|
||||
UNUSED(method);
|
||||
UNUSED(cresult);
|
||||
int r = UPX_E_ERROR;
|
||||
int zr;
|
||||
|
||||
z_stream s;
|
||||
s.zalloc = (alloc_func) 0;
|
||||
s.zfree = (free_func) 0;
|
||||
s.next_in = const_cast<upx_bytep>(src); // UNCONST
|
||||
s.avail_in = src_len;
|
||||
s.next_out = dst;
|
||||
s.avail_out = *dst_len;
|
||||
s.total_in = s.total_out = 0;
|
||||
|
||||
zr = inflateInit2(&s, -15);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
zr = inflate(&s, Z_FINISH);
|
||||
if (zr != Z_STREAM_END)
|
||||
goto error;
|
||||
zr = inflateEnd(&s);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
r = UPX_E_OK;
|
||||
goto done;
|
||||
error:
|
||||
(void) inflateEnd(&s);
|
||||
r = convert_errno_from_zlib(zr);
|
||||
if (r == UPX_E_OK)
|
||||
r = UPX_E_ERROR;
|
||||
done:
|
||||
if (r == UPX_E_OK)
|
||||
{
|
||||
if (s.avail_in != 0 || s.total_in != src_len)
|
||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||
}
|
||||
assert(s.total_in <= src_len);
|
||||
assert(s.total_out <= *dst_len);
|
||||
*dst_len = s.total_out;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// test_overlap
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_DEFLATE);
|
||||
|
||||
// FIXME - implement this
|
||||
// Note that Packer::verifyOverlappingDecompression() will
|
||||
// verify the final result in any case.
|
||||
UNUSED(buf);
|
||||
|
||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||
//printf("upx_zlib_test_overlap: %d\n", overlap_overhead);
|
||||
if ((int)overlap_overhead >= 256)
|
||||
return UPX_E_OK;
|
||||
|
||||
UNUSED(cresult);
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_zlib_version_string(void)
|
||||
{
|
||||
return zlibVersion();
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_ZLIB */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+308
-182
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -40,8 +40,16 @@
|
||||
#if ((ACC_OS_WIN32 || ACC_OS_WIN64) && ACC_CC_MWERKS) && defined(__MSL__)
|
||||
# undef HAVE_UTIME_H /* this pulls in <windows.h> */
|
||||
#endif
|
||||
// FIXME - quick hack for arm-wince-gcc-3.4 (Debian pocketpc-*.deb packages)
|
||||
#if 1 && (ACC_ARCH_ARM) && defined(__pe__) && !defined(_WIN32)
|
||||
# undef HAVE_CHMOD
|
||||
# undef HAVE_CHOWN
|
||||
# undef HAVE_LSTAT
|
||||
# undef HAVE_UTIME
|
||||
#endif
|
||||
|
||||
|
||||
// pragmas
|
||||
#if (ACC_CC_BORLANDC)
|
||||
# if (__BORLANDC__ < 0x0500)
|
||||
# error "need Borland C++ 5.0 or newer"
|
||||
@@ -96,6 +104,8 @@
|
||||
# if (_MSC_VER >= 1400)
|
||||
# pragma warning(disable: 4996) // W1: 'function': was declared deprecated
|
||||
# endif
|
||||
#elif (ACC_CC_SUNPROC)
|
||||
//# pragma error_messages(off,"badargtype2w") // FIXME
|
||||
#elif (ACC_CC_WATCOMC)
|
||||
# if (__WATCOMC__ < 1100)
|
||||
# error "need Watcom C++ 11.0c or newer"
|
||||
@@ -159,11 +169,14 @@
|
||||
# include <nrv/nrvconf.h>
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
# define ucl_compress_config_t REAL_ucl_compress_config_t
|
||||
# include <ucl/uclconf.h>
|
||||
# include <ucl/ucl.h>
|
||||
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010300L)
|
||||
# error "please upgrade your UCL installation"
|
||||
# endif
|
||||
# undef ucl_compress_config_t
|
||||
# undef ucl_compress_config_p
|
||||
#endif
|
||||
#if !defined(__UPX_CHECKER)
|
||||
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
|
||||
@@ -176,91 +189,6 @@
|
||||
|
||||
#define upx_byte unsigned char
|
||||
#define upx_bytep upx_byte *
|
||||
#define UPX_E_OK (0)
|
||||
#define UPX_E_ERROR (-1)
|
||||
#define UPX_E_OUT_OF_MEMORY (-2)
|
||||
#define UPX_E_NOT_COMPRESSIBLE (-3)
|
||||
#define UPX_E_INPUT_OVERRUN (-4)
|
||||
#define UPX_E_OUTPUT_OVERRUN (-5)
|
||||
#define UPX_E_LOOKBEHIND_OVERRUN (-6)
|
||||
#define UPX_E_EOF_NOT_FOUND (-7)
|
||||
#define UPX_E_INPUT_NOT_CONSUMED (-8)
|
||||
#define UPX_E_NOT_YET_IMPLEMENTED (-9)
|
||||
#define UPX_E_INVALID_ARGUMENT (-10)
|
||||
|
||||
struct upx_callback_t;
|
||||
#define upx_callback_p upx_callback_t *
|
||||
typedef void* (__acc_cdecl *upx_alloc_func_t)
|
||||
(upx_callback_p self, unsigned items, unsigned size);
|
||||
typedef void (__acc_cdecl *upx_free_func_t)
|
||||
(upx_callback_p self, void* ptr);
|
||||
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||
(upx_callback_p, unsigned, unsigned);
|
||||
|
||||
struct upx_callback_t
|
||||
{
|
||||
#if 0
|
||||
upx_alloc_func_t nalloc;
|
||||
upx_free_func_t nfree;
|
||||
#endif
|
||||
upx_progress_func_t nprogress;
|
||||
void * user1;
|
||||
#if 0
|
||||
unsigned user2;
|
||||
unsigned user3;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct lzma_compress_config_t
|
||||
{
|
||||
unsigned max_num_probs;
|
||||
#if 0
|
||||
unsigned pos_bits; // pb
|
||||
unsigned lit_pos_bits; // lp
|
||||
unsigned lit_context_bits; // lc
|
||||
unsigned dict_size;
|
||||
unsigned mf_passes;
|
||||
#endif
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
#define upx_compress_config_p upx_compress_config_t *
|
||||
struct upx_compress_config_t
|
||||
{
|
||||
lzma_compress_config_t conf_lzma;
|
||||
ucl_compress_config_t conf_ucl;
|
||||
void reset() {
|
||||
conf_lzma.reset();
|
||||
memset(&conf_ucl, 0xff, sizeof(conf_ucl));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct lzma_compress_result_t
|
||||
{
|
||||
unsigned pos_bits; // pb
|
||||
unsigned lit_pos_bits; // lp
|
||||
unsigned lit_context_bits; // lc
|
||||
unsigned dict_size;
|
||||
unsigned num_probs;
|
||||
};
|
||||
|
||||
struct ucl_compress_result_t
|
||||
{
|
||||
ucl_uint result[16];
|
||||
};
|
||||
|
||||
struct upx_compress_result_t
|
||||
{
|
||||
#if 1
|
||||
// debug
|
||||
int method, level;
|
||||
unsigned u_len, c_len;
|
||||
#endif
|
||||
lzma_compress_result_t result_lzma;
|
||||
ucl_compress_result_t result_ucl;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -270,18 +198,6 @@ struct upx_compress_result_t
|
||||
// malloc debuggers
|
||||
#if defined(WITH_VALGRIND)
|
||||
# include <valgrind/memcheck.h>
|
||||
#elif defined(WITH_DMALLOC)
|
||||
# define DMALLOC_FUNC_CHECK
|
||||
# include <dmalloc.h>
|
||||
#elif defined(WITH_GC)
|
||||
# define GC_DEBUG
|
||||
# include <gc/gc.h>
|
||||
# undef malloc
|
||||
# undef realloc
|
||||
# undef free
|
||||
# define malloc GC_MALLOC
|
||||
# define realloc GC_REALLOC
|
||||
# define free GC_FREE
|
||||
#endif
|
||||
|
||||
#if !defined(VALGRIND_MAKE_WRITABLE)
|
||||
@@ -299,6 +215,7 @@ struct upx_compress_result_t
|
||||
#endif
|
||||
|
||||
|
||||
// unconditionally turn on assertions
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
@@ -375,18 +292,6 @@ struct upx_compress_result_t
|
||||
#undef PAGE_MASK
|
||||
#undef PAGE_SIZE
|
||||
|
||||
|
||||
#undef __attribute_packed
|
||||
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
|
||||
# if (1 && (ACC_ARCH_I386))
|
||||
# define __attribute_packed
|
||||
# else
|
||||
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
|
||||
# endif
|
||||
#else
|
||||
# define __attribute_packed
|
||||
#endif
|
||||
|
||||
#if !defined(O_BINARY)
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
@@ -396,6 +301,19 @@ struct upx_compress_result_t
|
||||
#endif
|
||||
|
||||
|
||||
#undef __attribute_packed
|
||||
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
|
||||
# if (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
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
@@ -403,68 +321,52 @@ struct upx_compress_result_t
|
||||
#define UNUSED(var) ACC_UNUSED(var)
|
||||
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
||||
|
||||
#if 1
|
||||
# define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
|
||||
#define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
|
||||
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
||||
struct acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z[7]; } __attribute_packed; \
|
||||
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 8*sizeof(b)+sizeof(a)) \
|
||||
struct acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; } __attribute_packed; \
|
||||
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \
|
||||
}
|
||||
#else
|
||||
# define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
|
||||
struct acc_tmp_t { b x; a y; b z[7]; } __attribute_packed; \
|
||||
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 8*sizeof(b)+sizeof(a)) \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__acc_alignof)
|
||||
# define COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) \
|
||||
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b))
|
||||
#else
|
||||
# define COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b)
|
||||
#endif
|
||||
#define COMPILE_TIME_ASSERT_ALIGNED1(a) __COMPILE_TIME_ASSERT_ALIGNOF(a,char)
|
||||
|
||||
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0])))
|
||||
|
||||
|
||||
#if 0
|
||||
#define ALIGN_DOWN(a,b) (((a) / (b)) * (b))
|
||||
#define ALIGN_UP(a,b) ALIGN_DOWN((a) + ((b) - 1), b)
|
||||
#define ALIGN_GAP(a,b) (ALIGN_UP(a,b) - (a))
|
||||
#elif 1
|
||||
template <class T>
|
||||
inline T ALIGN_DOWN(const T& a, const T& b) { T r; r = (a / b) * b; return r; }
|
||||
template <class T>
|
||||
inline T ALIGN_UP (const T& a, const T& b) { T r; r = ((a + b - 1) / b) * b; return r; }
|
||||
template <class T>
|
||||
inline T ALIGN_GAP (const T& a, const T& b) { T r; r = ALIGN_UP(a, b) - a; return r; }
|
||||
#else
|
||||
inline unsigned ALIGN_DOWN(unsigned a, unsigned b) { return (a / b) * b; }
|
||||
inline unsigned ALIGN_UP (unsigned a, unsigned b) { return ((a + b - 1) / b) * b; }
|
||||
inline unsigned ALIGN_GAP (unsigned a, unsigned b) { return ALIGN_UP(a, b) - a; }
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define UPX_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
||||
#define UPX_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||
#define UPX_MAX3(a,b,c) ((a) >= (b) ? UPX_MAX(a,c) : UPX_MAX(b,c))
|
||||
#define UPX_MIN3(a,b,c) ((a) <= (b) ? UPX_MIN(a,c) : UPX_MIN(b,c))
|
||||
|
||||
|
||||
#if 0 && defined(__cplusplus) && !defined(new) && !defined(delete)
|
||||
// global operators - debug
|
||||
inline void *operator new(size_t l)
|
||||
{
|
||||
void *p = malloc(l);
|
||||
printf("new %6ld %p\n",(long)l,p);
|
||||
fflush(stdout);
|
||||
return p;
|
||||
}
|
||||
inline void *operator new[](size_t l)
|
||||
{
|
||||
void *p = malloc(l);
|
||||
printf("new[] %6ld %p\n",(long)l,p);
|
||||
fflush(stdout);
|
||||
return p;
|
||||
}
|
||||
inline void operator delete(void *p)
|
||||
{
|
||||
printf("delete %p\n",p);
|
||||
fflush(stdout);
|
||||
if (p) free(p);
|
||||
}
|
||||
inline void operator delete[](void *p)
|
||||
{
|
||||
printf("delete[] %p\n",p);
|
||||
fflush(stdout);
|
||||
if (p) free(p);
|
||||
}
|
||||
#elif 1
|
||||
template <class T>
|
||||
inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a; }
|
||||
template <class T>
|
||||
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
|
||||
#else
|
||||
inline unsigned UPX_MAX(unsigned a, unsigned b) { return a < b ? b : a; }
|
||||
inline unsigned UPX_MIN(unsigned a, unsigned b) { return a < b ? a : b; }
|
||||
#endif
|
||||
|
||||
|
||||
@@ -477,6 +379,14 @@ inline void operator delete[](void *p)
|
||||
|
||||
#define ByteArray(var, size) Array(unsigned char, var, size)
|
||||
|
||||
struct nocopy
|
||||
{
|
||||
inline nocopy() {}
|
||||
private:
|
||||
nocopy(const nocopy &); // undefined
|
||||
nocopy& operator=(const nocopy &); // undefined
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// constants
|
||||
@@ -496,28 +406,23 @@ inline void operator delete[](void *p)
|
||||
#define EXIT_INTERNAL 1
|
||||
|
||||
|
||||
// compression methods - DO NOT CHANGE
|
||||
#define M_SKIP (-2)
|
||||
#define M_END (-1)
|
||||
#define M_NRV2B_LE32 2
|
||||
#define M_NRV2B_8 3
|
||||
#define M_NRV2B_LE16 4
|
||||
#define M_NRV2D_LE32 5
|
||||
#define M_NRV2D_8 6
|
||||
#define M_NRV2D_LE16 7
|
||||
#define M_NRV2E_LE32 8
|
||||
#define M_NRV2E_8 9
|
||||
#define M_NRV2E_LE16 10
|
||||
#define M_CL1B_LE32 11
|
||||
#define M_CL1B_8 12
|
||||
#define M_CL1B_LE16 13
|
||||
#define M_LZMA 14
|
||||
// magic constants for patching
|
||||
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
||||
#define UPX_MAGIC2_LE32 0xD5D0D8A1
|
||||
|
||||
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
||||
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
||||
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
|
||||
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
||||
#define M_IS_LZMA(x) ((x) == M_LZMA)
|
||||
|
||||
// upx_compress() error codes
|
||||
#define UPX_E_OK (0)
|
||||
#define UPX_E_ERROR (-1)
|
||||
#define UPX_E_OUT_OF_MEMORY (-2)
|
||||
#define UPX_E_NOT_COMPRESSIBLE (-3)
|
||||
#define UPX_E_INPUT_OVERRUN (-4)
|
||||
#define UPX_E_OUTPUT_OVERRUN (-5)
|
||||
#define UPX_E_LOOKBEHIND_OVERRUN (-6)
|
||||
#define UPX_E_EOF_NOT_FOUND (-7)
|
||||
#define UPX_E_INPUT_NOT_CONSUMED (-8)
|
||||
#define UPX_E_NOT_YET_IMPLEMENTED (-9)
|
||||
#define UPX_E_INVALID_ARGUMENT (-10)
|
||||
|
||||
|
||||
// Executable formats. Note: big endian types are >= 128.
|
||||
@@ -544,11 +449,14 @@ inline void operator delete[](void *p)
|
||||
#define UPX_F_WINCE_ARM_PE 21
|
||||
#define UPX_F_LINUX_ELF64_AMD 22
|
||||
#define UPX_F_LINUX_ELF32_ARMLE 23
|
||||
|
||||
#define UPX_F_BSD_i386 24
|
||||
#define UPX_F_BSD_ELF_i386 25
|
||||
#define UPX_F_BSD_SH_i386 26
|
||||
|
||||
#define UPX_F_VMLINUX_AMD64 27
|
||||
#define UPX_F_VMLINUX_ARM 28
|
||||
#define UPX_F_MACH_i386 29
|
||||
|
||||
#define UPX_F_PLAIN_TEXT 127
|
||||
|
||||
#define UPX_F_ATARI_TOS 129
|
||||
@@ -556,10 +464,229 @@ inline void operator delete[](void *p)
|
||||
#define UPX_F_MACH_PPC32 131
|
||||
#define UPX_F_LINUX_ELFPPC32 132
|
||||
#define UPX_F_LINUX_ELF32_ARMBE 133
|
||||
#define UPX_F_MACH_FAT 134
|
||||
|
||||
|
||||
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
||||
#define UPX_MAGIC2_LE32 0xD5D0D8A1
|
||||
// compression methods
|
||||
#define M_ALL (-1)
|
||||
#define M_END (-2)
|
||||
#define M_NONE (-3)
|
||||
#define M_SKIP (-4)
|
||||
#define M_ULTRA_BRUTE (-5)
|
||||
// compression methods - DO NOT CHANGE
|
||||
#define M_NRV2B_LE32 2
|
||||
#define M_NRV2B_8 3
|
||||
#define M_NRV2B_LE16 4
|
||||
#define M_NRV2D_LE32 5
|
||||
#define M_NRV2D_8 6
|
||||
#define M_NRV2D_LE16 7
|
||||
#define M_NRV2E_LE32 8
|
||||
#define M_NRV2E_8 9
|
||||
#define M_NRV2E_LE16 10
|
||||
//#define M_CL1B_LE32 11
|
||||
//#define M_CL1B_8 12
|
||||
//#define M_CL1B_LE16 13
|
||||
#define M_LZMA 14
|
||||
#define M_DEFLATE 15 /* zlib */
|
||||
|
||||
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
||||
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
||||
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
|
||||
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
||||
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
|
||||
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
||||
|
||||
|
||||
// filters
|
||||
#define FT_END (-1)
|
||||
#define FT_NONE (-2)
|
||||
#define FT_SKIP (-3)
|
||||
#define FT_ULTRA_BRUTE (-4)
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// compression - callback_t
|
||||
**************************************************************************/
|
||||
|
||||
struct upx_callback_t;
|
||||
#define upx_callback_p upx_callback_t *
|
||||
#if 0
|
||||
typedef void* (__acc_cdecl *upx_alloc_func_t)
|
||||
(upx_callback_p self, unsigned items, unsigned size);
|
||||
typedef void (__acc_cdecl *upx_free_func_t)
|
||||
(upx_callback_p self, void* ptr);
|
||||
#endif
|
||||
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||
(upx_callback_p, unsigned, unsigned);
|
||||
|
||||
struct upx_callback_t
|
||||
{
|
||||
upx_progress_func_t nprogress;
|
||||
void *user;
|
||||
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// compression - config_t
|
||||
**************************************************************************/
|
||||
|
||||
template <class T, T default_value, T min_value, T max_value>
|
||||
struct OptVar
|
||||
{
|
||||
typedef T Type;
|
||||
static const T default_value_c = default_value;
|
||||
static const T min_value_c = min_value;
|
||||
static const T max_value_c = max_value;
|
||||
|
||||
void assertValue() {
|
||||
// FIXME: this generates annoying warnings "unsigned >= 0 is always true"
|
||||
//assert((v >= min_value) && (v <= max_value));
|
||||
}
|
||||
|
||||
OptVar() : v(default_value), is_set(0) { }
|
||||
OptVar& operator= (const T other) {
|
||||
v = other; is_set += 1;
|
||||
assertValue();
|
||||
return *this;
|
||||
}
|
||||
#if 0
|
||||
#error
|
||||
// there is too much implicit magic in this copy operator;
|
||||
// better introduce an explicit "oassign" function.
|
||||
OptVar& operator= (const OptVar& other) {
|
||||
if (other.is_set) { v = other.v; is_set += 1; }
|
||||
assertValue(); return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
void reset() { v = default_value; is_set = 0; }
|
||||
operator T () const { return v; }
|
||||
|
||||
T v;
|
||||
unsigned is_set;
|
||||
};
|
||||
|
||||
|
||||
// optional assignments
|
||||
template <class T> inline void oassign(T& self, const T& other) {
|
||||
if (other.is_set) { self.v = other.v; self.is_set += 1; }
|
||||
}
|
||||
#if 0
|
||||
template <class V, class T> inline void oassign(V& v, const T& other) {
|
||||
if (other.is_set) { v = other.v; }
|
||||
}
|
||||
#else
|
||||
template <class T> inline void oassign(unsigned& v, const T& other) {
|
||||
if (other.is_set) { v = other.v; }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct lzma_compress_config_t
|
||||
{
|
||||
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
|
||||
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lb
|
||||
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
|
||||
typedef OptVar<unsigned, (1u<<22), 1u, (1u<<30) > dict_size_t;
|
||||
typedef OptVar<unsigned, 64u, 5u, 273u> num_fast_bytes_t;
|
||||
|
||||
pos_bits_t pos_bits; // pb
|
||||
lit_pos_bits_t lit_pos_bits; // lp
|
||||
lit_context_bits_t lit_context_bits; // lc
|
||||
dict_size_t dict_size;
|
||||
unsigned fast_mode;
|
||||
num_fast_bytes_t num_fast_bytes;
|
||||
unsigned match_finder_cycles;
|
||||
|
||||
unsigned max_num_probs;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
|
||||
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
|
||||
{
|
||||
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct zlib_compress_config_t
|
||||
{
|
||||
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
||||
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
|
||||
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
|
||||
|
||||
mem_level_t mem_level; // ml
|
||||
window_bits_t window_bits; // wb
|
||||
strategy_t strategy; // st
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
|
||||
struct upx_compress_config_t
|
||||
{
|
||||
lzma_compress_config_t conf_lzma;
|
||||
ucl_compress_config_t conf_ucl;
|
||||
zlib_compress_config_t conf_zlib;
|
||||
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); }
|
||||
};
|
||||
|
||||
#define NULL_cconf ((upx_compress_config_t *) NULL)
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// compression - result_t
|
||||
**************************************************************************/
|
||||
|
||||
struct lzma_compress_result_t
|
||||
{
|
||||
unsigned pos_bits; // pb
|
||||
unsigned lit_pos_bits; // lp
|
||||
unsigned lit_context_bits; // lc
|
||||
unsigned dict_size;
|
||||
unsigned fast_mode;
|
||||
unsigned num_fast_bytes;
|
||||
unsigned match_finder_cycles;
|
||||
unsigned num_probs; // (computed result)
|
||||
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct ucl_compress_result_t
|
||||
{
|
||||
ucl_uint result[16];
|
||||
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct zlib_compress_result_t
|
||||
{
|
||||
unsigned dummy;
|
||||
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct upx_compress_result_t
|
||||
{
|
||||
// debug
|
||||
int method, level;
|
||||
unsigned u_len, c_len;
|
||||
|
||||
lzma_compress_result_t result_lzma;
|
||||
ucl_compress_result_t result_ucl;
|
||||
zlib_compress_result_t result_zlib;
|
||||
|
||||
void reset() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
result_lzma.reset(); result_ucl.reset(); result_zlib.reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -585,7 +712,6 @@ typedef ElfLinker Linker;
|
||||
|
||||
// main.cpp
|
||||
extern const char *progname;
|
||||
void init_options(struct options_t *o);
|
||||
bool set_ec(int ec);
|
||||
#if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||
void e_exit(int ec) __attribute__((__noreturn__));
|
||||
@@ -632,7 +758,7 @@ void do_files(int i, int argc, char *argv[]);
|
||||
|
||||
// help.cpp
|
||||
void show_head(void);
|
||||
void show_help(int x = 0);
|
||||
void show_help(int verbose=0);
|
||||
void show_license(void);
|
||||
void show_usage(void);
|
||||
void show_version(int);
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+7
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -85,6 +85,11 @@ void throwCantPack(const char *msg)
|
||||
throw CantUnpackException(msg);
|
||||
}
|
||||
|
||||
void throwCantPackExact()
|
||||
{
|
||||
throwCantPack("option '--exact' does not work with this file");
|
||||
}
|
||||
|
||||
void throwFilterException()
|
||||
{
|
||||
throwCantPack("filter problem");
|
||||
|
||||
+3
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -208,6 +208,7 @@ public:
|
||||
#endif
|
||||
|
||||
void throwCantPack(const char *msg) NORET;
|
||||
void throwCantPackExact() NORET;
|
||||
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
||||
void throwNotCompressible(const char *msg = NULL) NORET;
|
||||
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
||||
|
||||
+79
-8
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -69,7 +69,7 @@ void File::unlink(const char *name)
|
||||
**************************************************************************/
|
||||
|
||||
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));
|
||||
}
|
||||
@@ -104,6 +104,10 @@ void FileBase::sopen()
|
||||
assert(0);
|
||||
#endif
|
||||
}
|
||||
if (!(_fd < 0)) {
|
||||
::fstat(_fd, &st);
|
||||
_length = st.st_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +121,8 @@ bool FileBase::close()
|
||||
_flags = 0;
|
||||
_mode = 0;
|
||||
_name = NULL;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -164,10 +170,17 @@ void FileBase::seek(off_t off, int whence)
|
||||
{
|
||||
if (!isOpen())
|
||||
throwIOException("bad seek 1");
|
||||
if (whence == SEEK_SET && off < 0)
|
||||
throwIOException("bad seek 2");
|
||||
if (whence == SEEK_END && off > 0)
|
||||
throwIOException("bad seek 3");
|
||||
if (whence == SEEK_SET) {
|
||||
if (off < 0)
|
||||
throwIOException("bad seek 2");
|
||||
off += _offset;
|
||||
}
|
||||
if (whence == SEEK_END) {
|
||||
if (off > 0)
|
||||
throwIOException("bad seek 3");
|
||||
off += _offset + _length;
|
||||
whence = SEEK_SET;
|
||||
}
|
||||
if (::lseek(_fd,off,whence) < 0)
|
||||
throwIOException("seek error",errno);
|
||||
}
|
||||
@@ -180,7 +193,19 @@ off_t FileBase::tell() const
|
||||
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
||||
if (l < 0)
|
||||
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;
|
||||
_shflags = shflags;
|
||||
_mode = 0;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
FileBase::sopen();
|
||||
if (!isOpen())
|
||||
{
|
||||
@@ -289,6 +316,8 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
||||
_flags = flags;
|
||||
_shflags = shflags;
|
||||
_mode = mode;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
FileBase::sopen();
|
||||
if (!isOpen())
|
||||
{
|
||||
@@ -316,6 +345,8 @@ bool OutputFile::openStdout(int flags, bool force)
|
||||
_flags = flags;
|
||||
_shflags = -1;
|
||||
_mode = 0;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
if (flags && acc_set_binmode(fd, 1) == -1)
|
||||
throwIOException(_name, errno);
|
||||
_fd = fd;
|
||||
@@ -329,6 +360,16 @@ void OutputFile::write(const void *buf, int 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)
|
||||
{
|
||||
@@ -343,6 +384,36 @@ void OutputFile::write(const MemBuffer &buf, int 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)
|
||||
{
|
||||
|
||||
+12
-14
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -59,6 +59,8 @@ public:
|
||||
virtual bool isOpen() const { return _fd >= 0; }
|
||||
int getFd() const { return _fd; }
|
||||
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:
|
||||
void sopen();
|
||||
@@ -73,6 +75,8 @@ protected:
|
||||
int _shflags;
|
||||
int _mode;
|
||||
const char *_name;
|
||||
off_t _offset;
|
||||
off_t _length;
|
||||
public:
|
||||
struct stat st;
|
||||
};
|
||||
@@ -128,21 +132,15 @@ public:
|
||||
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 set_extent(off_t offset, off_t length);
|
||||
virtual off_t unset_extent(); // returns actual length
|
||||
|
||||
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
|
||||
virtual void seek(off_t off, int whence)
|
||||
{
|
||||
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
|
||||
}
|
||||
// FIXME - these won't work when using the '--stdout' option
|
||||
virtual void seek(off_t off, int whence);
|
||||
virtual void rewrite(const void *buf, int len);
|
||||
|
||||
// util
|
||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
||||
|
||||
+20
-6
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -61,10 +61,10 @@ const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
||||
memset(filter_map, 0xff, sizeof(filter_map));
|
||||
for (int i = 0; i < n_filters; i++)
|
||||
{
|
||||
int fid = filters[i].id;
|
||||
assert(fid >= 0 && fid <= 255);
|
||||
assert(filter_map[fid] == 0xff);
|
||||
filter_map[fid] = (unsigned char) i;
|
||||
int filter_id = filters[i].id;
|
||||
assert(filter_id >= 0 && filter_id <= 255);
|
||||
assert(filter_map[filter_id] == 0xff);
|
||||
filter_map[filter_id] = (unsigned char) i;
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
@@ -85,6 +85,20 @@ bool Filter::isValidFilter(int filter_id)
|
||||
return fe != NULL;
|
||||
}
|
||||
|
||||
bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
|
||||
{
|
||||
if (!isValidFilter(filter_id))
|
||||
return false;
|
||||
if (filter_id == 0)
|
||||
return true;
|
||||
if (allowed_filters == NULL)
|
||||
return false;
|
||||
while (*allowed_filters != FT_END)
|
||||
if (*allowed_filters++ == filter_id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// high level API
|
||||
|
||||
+3
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
bool scan(const upx_byte *buf, unsigned buf_len);
|
||||
|
||||
static bool isValidFilter(int filter_id);
|
||||
static bool isValidFilter(int filter_id, const int *allowed_filters);
|
||||
|
||||
public:
|
||||
// Will be set by each call to filter()/unfilter().
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+13
-6
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -58,10 +58,18 @@ static int F(Filter *f)
|
||||
// must not conflict with the mark.
|
||||
// Note that unsigned comparison checks both edges of buffer.
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
if (COND(b,ic) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
{
|
||||
if (!COND(b,ic))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
return -1;
|
||||
@@ -79,8 +87,7 @@ static int F(Filter *f)
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
|
||||
return 1; // fail - buffer not restored
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
#endif
|
||||
|
||||
+14
-7
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -57,10 +57,18 @@ static int F(Filter *f)
|
||||
memset(buf,0,256);
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
if (COND(b,ic,lastcall) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
{
|
||||
if (!COND(b,ic,lastcall))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
return -1;
|
||||
@@ -78,8 +86,7 @@ static int F(Filter *f)
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
|
||||
return 1; // fail - buffer not restored
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+14
-7
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -58,10 +58,18 @@ static int F(Filter *f)
|
||||
memset(buf,0,256);
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
if (COND(b,ic,lastcall,id) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
{
|
||||
if (!COND(b,ic,lastcall,id))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
return -1;
|
||||
@@ -79,8 +87,7 @@ static int F(Filter *f)
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
|
||||
return 1; // fail - buffer not restored
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+4
-4
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2004-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2004-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -58,7 +58,7 @@ static int F(Filter *f)
|
||||
{
|
||||
unsigned char buf[256];
|
||||
unsigned short wbuf[256];
|
||||
const size_t WW = (size_t)0 - (~(size_t)0) << W_CTO; // ???
|
||||
const size_t WW = (size_t)0 - ((~(size_t)0) << W_CTO); // ???
|
||||
memset(wbuf, 0, sizeof(wbuf));
|
||||
memset(buf , 0, WW);
|
||||
memset(buf + WW, 1, 256 - WW);
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -109,7 +109,7 @@ umin(unsigned const a, unsigned const b)
|
||||
|
||||
#define COND1(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||
#define COND2(b,x,lc) (lc!=(x) && 0xf==b[(x)-1] && 0x80<=b[x] && b[x]<=0x8f)
|
||||
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
||||
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
||||
#define F f_ctok32_e8e9_bswap_le
|
||||
#define U u_ctok32_e8e9_bswap_le
|
||||
#include "filter/ctok.h"
|
||||
|
||||
+137
-60
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#include "packmast.h"
|
||||
#include "packer.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -48,7 +51,7 @@ void show_head(void)
|
||||
fg = con_fg(f,FG_GREEN);
|
||||
con_fprintf(f,
|
||||
" Ultimate Packer for eXecutables\n"
|
||||
" Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006\n"
|
||||
" Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007\n"
|
||||
"UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n",
|
||||
#if (ACC_OS_DOS16 || ACC_OS_DOS32)
|
||||
V("d"),
|
||||
@@ -88,7 +91,77 @@ void show_usage(void)
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void show_help(int x)
|
||||
struct PackerNames
|
||||
{
|
||||
struct Entry {
|
||||
const char* fname;
|
||||
const char* sname;
|
||||
};
|
||||
Entry names[32];
|
||||
size_t names_count;
|
||||
const options_t *o;
|
||||
PackerNames() : names_count(0), o(NULL) { }
|
||||
void add(const Packer *p)
|
||||
{
|
||||
p->assertPacker();
|
||||
assert(names_count < 32);
|
||||
names[names_count].fname = p->getFullName(o);
|
||||
names[names_count].sname = p->getName();
|
||||
names_count++;
|
||||
}
|
||||
static Packer* visit(Packer *p, void *user)
|
||||
{
|
||||
PackerNames *self = (PackerNames *) user;
|
||||
self->add(p);
|
||||
return NULL;
|
||||
}
|
||||
static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) {
|
||||
return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname);
|
||||
}
|
||||
static int __acc_cdecl_qsort cmp_sname(const void *a, const void *b) {
|
||||
return strcmp(((const Entry *) a)->sname, ((const Entry *) b)->sname);
|
||||
}
|
||||
};
|
||||
|
||||
static void show_all_packers(FILE *f, int verbose)
|
||||
{
|
||||
options_t o; o.reset();
|
||||
PackerNames pn; pn.o = &o;
|
||||
PackMaster::visitAllPackers(pn.visit, NULL, &o, &pn);
|
||||
qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), pn.cmp_fname);
|
||||
size_t pos = 0;
|
||||
for (size_t i = 0; i < pn.names_count; ++i)
|
||||
{
|
||||
const char *fn = pn.names[i].fname;
|
||||
const char *sn = pn.names[i].sname;
|
||||
if (verbose)
|
||||
{
|
||||
con_fprintf(f, " %-32s %s\n", fn, sn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos == 0) {
|
||||
con_fprintf(f, " %s", fn);
|
||||
pos = 2 + strlen(fn);
|
||||
} else if (pos + 1 + strlen(fn) > 80) {
|
||||
con_fprintf(f, "\n %s", fn);
|
||||
pos = 2 + strlen(fn);
|
||||
} else {
|
||||
con_fprintf(f, " %s", fn);
|
||||
pos += 1 + strlen(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!verbose && pn.names_count)
|
||||
con_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void show_help(int verbose)
|
||||
{
|
||||
FILE *f = con_term;
|
||||
int fg;
|
||||
@@ -105,8 +178,8 @@ void show_help(int x)
|
||||
" -d decompress -l list compressed file\n"
|
||||
" -t test compressed file -V display version number\n"
|
||||
" -h give %s help -L display software license\n%s",
|
||||
x == 0 ? "" : " --best compress best (can be slow for big files)\n",
|
||||
x == 0 ? "more" : "this", x == 0 ? "" : "\n");
|
||||
verbose == 0 ? "" : " --best compress best (can be slow for big files)\n",
|
||||
verbose == 0 ? "more" : "this", verbose == 0 ? "" : "\n");
|
||||
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options:\n");
|
||||
@@ -114,22 +187,29 @@ void show_help(int x)
|
||||
|
||||
con_fprintf(f,
|
||||
" -q be quiet -v be verbose\n"
|
||||
" -oFILE write output to `FILE'\n"
|
||||
" -oFILE write output to 'FILE'\n"
|
||||
//" -f force overwrite of output files and compression of suspicious files\n"
|
||||
" -f force compression of suspicious files\n"
|
||||
"%s%s"
|
||||
, (x == 0) ? " -k keep backup files\n" : ""
|
||||
, (verbose == 0) ? " -k keep backup files\n" : ""
|
||||
#if 1
|
||||
, (x > 0) ? " --no-color, --mono, --color, --no-progress change look\n" : ""
|
||||
, (verbose > 0) ? " --no-color, --mono, --color, --no-progress change look\n" : ""
|
||||
#else
|
||||
, ""
|
||||
#endif
|
||||
);
|
||||
|
||||
if (x > 0)
|
||||
if (verbose > 0)
|
||||
{
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"\nBackup options:\n");
|
||||
con_fprintf(f,"\nCompression tuning options:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" --brute try all available compression methods & filters\n"
|
||||
" --ultra-brute try even more compression variants\n"
|
||||
"\n");
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Backup options:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" -k, --backup keep backup files\n"
|
||||
@@ -221,7 +301,7 @@ void show_help(int x)
|
||||
" --le produce LE output [default: EXE]\n"
|
||||
"\n");
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options for win32/pe & rtm32/pe:\n");
|
||||
con_fprintf(f,"Options for win32/pe, rtm32/pe & arm/pe:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" --compress-exports=0 do not compress the export section\n"
|
||||
@@ -229,6 +309,7 @@ void show_help(int x)
|
||||
" --compress-icons=0 do not compress any icons\n"
|
||||
" --compress-icons=1 compress all but the first icon\n"
|
||||
" --compress-icons=2 compress all but the first icon directory [default]\n"
|
||||
" --compress-icons=3 compress all icons\n"
|
||||
" --compress-resources=0 do not compress any resources at all\n"
|
||||
" --keep-resource=list do not compress resources specified by list\n"
|
||||
" --strip-relocs=0 do not strip relocations\n"
|
||||
@@ -238,43 +319,23 @@ void show_help(int x)
|
||||
"\n");
|
||||
}
|
||||
|
||||
con_fprintf(f,
|
||||
"file.. executables to (de)compress\n"
|
||||
"\n");
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"This version supports:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f," "
|
||||
// TODO:
|
||||
// support for mach/ppc32
|
||||
// support for linux elf/ppc32
|
||||
// support for linux elf/amd64
|
||||
" arm/pe,"
|
||||
" atari/tos,"
|
||||
" bvmlinuz/386,"
|
||||
" djgpp2/coff,"
|
||||
" dos/com,"
|
||||
" dos/exe,"
|
||||
" dos/sys,"
|
||||
"\n "
|
||||
//" elks/8086,"
|
||||
" linux/amd64,"
|
||||
" linux/i386,"
|
||||
" linux/ppc32,"
|
||||
" mach/ppc32,"
|
||||
" ps1/exe,"
|
||||
" rtm32/pe,"
|
||||
"\n "
|
||||
" tmt/adam,"
|
||||
" vmlinux/386,"
|
||||
" vmlinuz/386,"
|
||||
" watcom/le,"
|
||||
//" win16/ne,"
|
||||
" win32/pe"
|
||||
"\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n"
|
||||
// "\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details type `upx -L'.\n"
|
||||
"");
|
||||
con_fprintf(f, "file.. executables to (de)compress\n");
|
||||
|
||||
if (verbose > 0)
|
||||
{
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"\nThis version supports:\n");
|
||||
fg = con_fg(f,fg);
|
||||
show_all_packers(f, verbose);
|
||||
}
|
||||
else
|
||||
{
|
||||
con_fprintf(f,"\nType '%s --help' for more detailed help.\n", progname);
|
||||
}
|
||||
|
||||
con_fprintf(f,"\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n"
|
||||
// "\nUPX comes with ABSOLUTELY NO WARRANTY; for details type 'upx -L'.\n"
|
||||
"");
|
||||
|
||||
#if defined(DEBUG) || defined(TESTING)
|
||||
fg = con_fg(f,FG_RED);
|
||||
@@ -340,27 +401,43 @@ void show_license(void)
|
||||
|
||||
void show_version(int x)
|
||||
{
|
||||
FILE *f = stdout;
|
||||
FILE *fp = stdout;
|
||||
const char *v;
|
||||
UNUSED(x);
|
||||
UNUSED(v);
|
||||
|
||||
fprintf(f,"upx %s\n", UPX_VERSION_STRING);
|
||||
fprintf(fp, "upx %s\n", UPX_VERSION_STRING);
|
||||
#if defined(WITH_NRV)
|
||||
fprintf(f,"NRV data compression library %s\n", nrv_version_string());
|
||||
v = upx_nrv_version_string();
|
||||
if (v != NULL && v[0])
|
||||
fprintf(fp, "NRV data compression library %s\n", v);
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
fprintf(f,"UCL data compression library %s\n", ucl_version_string());
|
||||
v = upx_ucl_version_string();
|
||||
if (v != NULL && v[0])
|
||||
fprintf(fp, "UCL data compression library %s\n", v);
|
||||
#endif
|
||||
#if 0 && defined(WITH_LZMA)
|
||||
fprintf(f,"LZMA SDK version ???\n");
|
||||
#if defined(WITH_ZLIB)
|
||||
v = upx_zlib_version_string();
|
||||
if (v != NULL && v[0])
|
||||
fprintf(fp, "zlib data compression library %s\n", v);
|
||||
#endif
|
||||
fprintf(f,"Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n");
|
||||
fprintf(f,"Copyright (C) 1996-2006 Laszlo Molnar\n");
|
||||
fprintf(f,"Copyright (C) 2000-2006 John F. Reiser\n");
|
||||
fprintf(f,"Copyright (C) 2002-2006 Jens Medoch\n");
|
||||
#if defined(WITH_LZMA)
|
||||
fprintf(f,"Copyright (C) 1999-2006 Igor Pavlov\n");
|
||||
v = upx_lzma_version_string();
|
||||
if (v != NULL && v[0])
|
||||
fprintf(fp, "LZMA SDK version %s\n", v);
|
||||
#endif
|
||||
fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
|
||||
fprintf(fp, "Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer\n");
|
||||
fprintf(fp, "Copyright (C) 1996-2007 Laszlo Molnar\n");
|
||||
fprintf(fp, "Copyright (C) 2000-2007 John F. Reiser\n");
|
||||
fprintf(fp, "Copyright (C) 2002-2007 Jens Medoch\n");
|
||||
#if defined(WITH_ZLIB)
|
||||
fprintf(fp, "Copyright (C) 1995" "-2005 Jean-loup Gailly and Mark Adler\n");
|
||||
#endif
|
||||
#if defined(WITH_LZMA)
|
||||
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
|
||||
#endif
|
||||
fprintf(fp, "UPX comes with ABSOLUTELY NO WARRANTY; for details type '%s -L'.\n", progname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+343
-155
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "conf.h"
|
||||
#include "linker.h"
|
||||
|
||||
static int hex(unsigned char c)
|
||||
static unsigned hex(unsigned char c)
|
||||
{
|
||||
return (c & 0xf) + (c > '9' ? 9 : 0);
|
||||
}
|
||||
@@ -45,17 +45,20 @@ static bool update_capacity(unsigned size, unsigned *capacity)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// Section
|
||||
**************************************************************************/
|
||||
|
||||
ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a) :
|
||||
name(strdup(n)), output(NULL), size(s), offset(0), align(a), next(NULL)
|
||||
name(NULL), output(NULL), size(s), offset(0), p2align(a), next(NULL)
|
||||
{
|
||||
assert(name);
|
||||
name = strdup(n);
|
||||
assert(name != NULL);
|
||||
input = malloc(s + 1);
|
||||
assert(input);
|
||||
assert(input != NULL);
|
||||
memcpy(input, i, s);
|
||||
((char *)input)[s] = 0;
|
||||
}
|
||||
|
||||
ElfLinker::Section::~Section()
|
||||
@@ -64,10 +67,17 @@ ElfLinker::Section::~Section()
|
||||
free(input);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// Symbol
|
||||
**************************************************************************/
|
||||
|
||||
ElfLinker::Symbol::Symbol(const char *n, Section *s, unsigned o) :
|
||||
name(strdup(n)), section(s), offset(o)
|
||||
name(NULL), section(s), offset(o)
|
||||
{
|
||||
assert(name);
|
||||
name = strdup(n);
|
||||
assert(name != NULL);
|
||||
assert(section != NULL);
|
||||
}
|
||||
|
||||
ElfLinker::Symbol::~Symbol()
|
||||
@@ -75,13 +85,111 @@ ElfLinker::Symbol::~Symbol()
|
||||
free(name);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// Relocation
|
||||
**************************************************************************/
|
||||
|
||||
ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t,
|
||||
const Symbol *v, unsigned a) :
|
||||
section(s), offset(o), type(t), value(v), add(a)
|
||||
{}
|
||||
{
|
||||
assert(section != NULL);
|
||||
}
|
||||
|
||||
|
||||
void ElfLinker::preprocessSections(char *start, const char *end)
|
||||
/*************************************************************************
|
||||
// ElfLinker
|
||||
**************************************************************************/
|
||||
|
||||
ElfLinker::ElfLinker() :
|
||||
bele(&N_BELE_RTP::le_policy),
|
||||
input(NULL), output(NULL), head(NULL), tail(NULL),
|
||||
sections(NULL), symbols(NULL), relocations(NULL),
|
||||
nsections(0), nsections_capacity(0),
|
||||
nsymbols(0), nsymbols_capacity(0),
|
||||
nrelocations(0), nrelocations_capacity(0),
|
||||
reloc_done(false)
|
||||
{
|
||||
}
|
||||
|
||||
ElfLinker::~ElfLinker()
|
||||
{
|
||||
delete [] input;
|
||||
delete [] output;
|
||||
|
||||
unsigned ic;
|
||||
for (ic = 0; ic < nsections; ic++)
|
||||
delete sections[ic];
|
||||
free(sections);
|
||||
for (ic = 0; ic < nsymbols; ic++)
|
||||
delete symbols[ic];
|
||||
free(symbols);
|
||||
for (ic = 0; ic < nrelocations; ic++)
|
||||
delete relocations[ic];
|
||||
free(relocations);
|
||||
}
|
||||
|
||||
void ElfLinker::init(const void *pdata_v, int plen)
|
||||
{
|
||||
const upx_byte *pdata = (const upx_byte *) pdata_v;
|
||||
if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0)
|
||||
{
|
||||
// decompress pre-compressed stub-loader
|
||||
int method;
|
||||
unsigned u_len, c_len;
|
||||
if (pdata[4])
|
||||
{
|
||||
method = pdata[4];
|
||||
u_len = get_le16(pdata + 5);
|
||||
c_len = get_le16(pdata + 7);
|
||||
pdata += 9;
|
||||
assert(9 + c_len == (unsigned) plen);
|
||||
}
|
||||
else
|
||||
{
|
||||
method = pdata[5];
|
||||
u_len = get_le32(pdata + 6);
|
||||
c_len = get_le32(pdata + 10);
|
||||
pdata += 14;
|
||||
assert(14 + c_len == (unsigned) plen);
|
||||
}
|
||||
assert((unsigned) plen < u_len);
|
||||
inputlen = u_len;
|
||||
input = new upx_byte[inputlen + 1];
|
||||
unsigned new_len = u_len;
|
||||
int r = upx_decompress(pdata, c_len, input, &new_len, method, NULL);
|
||||
if (r != 0 || new_len != u_len)
|
||||
throwBadLoader();
|
||||
}
|
||||
else
|
||||
{
|
||||
inputlen = plen;
|
||||
input = new upx_byte[inputlen + 1];
|
||||
memcpy(input, pdata, inputlen);
|
||||
}
|
||||
input[inputlen] = 0; // NUL terminate
|
||||
|
||||
output = new upx_byte[inputlen];
|
||||
outputlen = 0;
|
||||
|
||||
int pos = find(input, inputlen, "Sections:\n", 10);
|
||||
assert(pos != -1);
|
||||
char *psections = (char *) input + pos;
|
||||
|
||||
char *psymbols = strstr(psections, "SYMBOL TABLE:\n");
|
||||
assert(psymbols != NULL);
|
||||
|
||||
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR ");
|
||||
assert(prelocs != NULL);
|
||||
|
||||
preprocessSections(psections, psymbols);
|
||||
preprocessSymbols(psymbols, prelocs);
|
||||
preprocessRelocations(prelocs, (char*) input + inputlen);
|
||||
addLoader("*UND*");
|
||||
}
|
||||
|
||||
void ElfLinker::preprocessSections(char *start, char *end)
|
||||
{
|
||||
nsections = 0;
|
||||
while (start < end)
|
||||
@@ -107,36 +215,42 @@ void ElfLinker::preprocessSections(char *start, const char *end)
|
||||
addSection("*UND*", NULL, 0, 0);
|
||||
}
|
||||
|
||||
void ElfLinker::preprocessSymbols(char *start, const char *end)
|
||||
void ElfLinker::preprocessSymbols(char *start, char *end)
|
||||
{
|
||||
nsymbols = 0;
|
||||
while (start < end)
|
||||
{
|
||||
char section[1024];
|
||||
char symbol[1024];
|
||||
unsigned offset;
|
||||
unsigned value, offset;
|
||||
|
||||
char *nextl = strchr(start, '\n');
|
||||
assert(nextl != NULL);
|
||||
|
||||
if (sscanf(start, "%x%*8c %1024s %*x %1023s",
|
||||
if (sscanf(start, "%x g *ABS* %x %1023s",
|
||||
&value, &offset, symbol) == 3)
|
||||
{
|
||||
char *s = strstr(start, symbol);
|
||||
s[strlen(symbol)] = 0;
|
||||
addSymbol(s, "*ABS*", value);
|
||||
assert(offset == 0);
|
||||
}
|
||||
else if (sscanf(start, "%x%*8c %1023s %*x %1023s",
|
||||
&offset, section, symbol) == 3)
|
||||
{
|
||||
char *s = strstr(start, symbol);
|
||||
s[strlen(symbol)] = 0;
|
||||
|
||||
if (strcmp(section, "*UND*") == 0)
|
||||
offset = 0xdeaddead;
|
||||
assert(strcmp(section, "*ABS*") != 0);
|
||||
addSymbol(s, section, offset);
|
||||
|
||||
//printf("symbol %s preprocessed o=%x\n", s, offset);
|
||||
}
|
||||
|
||||
start = nextl + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ElfLinker::preprocessRelocations(char *start, const char *end)
|
||||
void ElfLinker::preprocessRelocations(char *start, char *end)
|
||||
{
|
||||
char sect[1024];
|
||||
Section *section = NULL;
|
||||
@@ -163,60 +277,80 @@ void ElfLinker::preprocessRelocations(char *start, const char *end)
|
||||
unsigned add = 0;
|
||||
if (char *p = strstr(symbol, "+0x"))
|
||||
{
|
||||
// Beware: sscanf("0xfffffffffffffffc", "%x", &add) ==> -1 == add
|
||||
// because conversion stops after 32 bits for a non-long.
|
||||
// Also, glibc-2.3.5 has a bug: even using "%lx" still gives -1 instead of -4.
|
||||
long addend;
|
||||
*p = 0; // terminate the symbol name
|
||||
p+=3;
|
||||
if ('f'==p[0] && 0==strncmp(p, "ffffffff", 8)) {
|
||||
p+=8; // workaround a bug in glibc-2.3.5
|
||||
p += 3;
|
||||
|
||||
if (strlen(p) == 16) {
|
||||
// skip 8 leading chars if sign of char 9 matches
|
||||
if (memcmp(p, "000000000", 9))
|
||||
p += 8;
|
||||
else if (memcmp(p, "fffffffff", 9))
|
||||
p += 8;
|
||||
}
|
||||
sscanf(p, "%lx", &addend);
|
||||
add = (unsigned)addend;
|
||||
assert(strlen(p) == 8);
|
||||
char *endptr = NULL;
|
||||
unsigned long ul = strtoul(p, &endptr, 16);
|
||||
add = (unsigned) ul;
|
||||
assert(add == ul);
|
||||
assert(endptr && *endptr == '\0');
|
||||
}
|
||||
|
||||
addRelocation(section->name, offset, t, symbol, add);
|
||||
|
||||
//printf("relocation %s %x preprocessed\n", section->name, offset);
|
||||
//printf("relocation %s %s %x %d preprocessed\n", section->name, symbol, offset, add);
|
||||
}
|
||||
|
||||
start = nextl + 1;
|
||||
}
|
||||
}
|
||||
|
||||
ElfLinker::Section *ElfLinker::findSection(const char *name) const
|
||||
ElfLinker::Section *ElfLinker::findSection(const char *name, bool fatal) const
|
||||
{
|
||||
for (unsigned ic = 0; ic < nsections; ic++)
|
||||
if (strcmp(sections[ic]->name, name) == 0)
|
||||
return sections[ic];
|
||||
|
||||
printf("unknown section %s\n", name);
|
||||
abort();
|
||||
if (fatal)
|
||||
{
|
||||
printf("unknown section %s\n", name);
|
||||
abort();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name) /*const*/
|
||||
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name, bool fatal) const
|
||||
{
|
||||
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||
if (strcmp(symbols[ic]->name, name) == 0)
|
||||
return symbols[ic];
|
||||
|
||||
// FIXME: this should be a const method !
|
||||
if ('*' == name[0]) // *ABS*
|
||||
return addSymbol(name, name, 0);
|
||||
|
||||
printf("unknown symbol %s\n", name);
|
||||
abort();
|
||||
if (fatal)
|
||||
{
|
||||
printf("unknown symbol %s\n", name);
|
||||
abort();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
|
||||
unsigned offset)
|
||||
ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen, unsigned p2align)
|
||||
{
|
||||
//printf("addSection: %s len=%d align=%d\n", sname, slen, p2align);
|
||||
if (update_capacity(nsections, &nsections_capacity))
|
||||
sections = static_cast<Section **>(realloc(sections, nsections_capacity * sizeof(Section *)));
|
||||
assert(sections);
|
||||
assert(sname); assert(sname[0]); assert(sname[strlen(sname)-1] != ':');
|
||||
assert(findSection(sname, false) == NULL);
|
||||
Section *sec = new Section(sname, sdata, slen, p2align);
|
||||
sections[nsections++] = sec;
|
||||
return sec;
|
||||
}
|
||||
|
||||
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
|
||||
unsigned offset)
|
||||
{
|
||||
//printf("addSymbol: %s %s 0x%x\n", name, section, offset);
|
||||
if (update_capacity(nsymbols, &nsymbols_capacity))
|
||||
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
|
||||
assert(symbols != NULL);
|
||||
assert(name); assert(name[0]); assert(name[strlen(name)-1] != ':');
|
||||
assert(findSymbol(name, false) == NULL);
|
||||
Symbol *sym = new Symbol(name, findSection(section), offset);
|
||||
symbols[nsymbols++] = sym;
|
||||
return sym;
|
||||
@@ -235,69 +369,18 @@ ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned of
|
||||
return rel;
|
||||
}
|
||||
|
||||
ElfLinker::ElfLinker() :
|
||||
frozen(false), input(NULL), output(NULL), head(NULL), tail(NULL),
|
||||
sections(NULL), symbols(NULL), relocations(NULL),
|
||||
nsections(0), nsections_capacity(0),
|
||||
nsymbols(0), nsymbols_capacity(0),
|
||||
nrelocations(0), nrelocations_capacity(0)
|
||||
{
|
||||
}
|
||||
|
||||
ElfLinker::~ElfLinker()
|
||||
{
|
||||
delete [] input;
|
||||
delete [] output;
|
||||
|
||||
unsigned ic;
|
||||
for (ic = 0; ic < nsections; ic++)
|
||||
delete sections[ic];
|
||||
free(sections);
|
||||
for (ic = 0; ic < nsymbols; ic++)
|
||||
delete symbols[ic];
|
||||
free(symbols);
|
||||
for (ic = 0; ic < nrelocations; ic++)
|
||||
delete relocations[ic];
|
||||
free(relocations);
|
||||
}
|
||||
|
||||
void ElfLinker::init(const void *pdata, int plen)
|
||||
{
|
||||
upx_byte *i = new upx_byte[plen + 1];
|
||||
memcpy(i, pdata, plen);
|
||||
input = i;
|
||||
inputlen = plen;
|
||||
|
||||
output = new upx_byte[plen];
|
||||
outputlen = 0;
|
||||
|
||||
int pos = find(input, plen, "Sections:", 9);
|
||||
assert(pos != -1);
|
||||
char *psections = pos + (char *) input;
|
||||
|
||||
char *psymbols = strstr(psections, "SYMBOL TABLE:");
|
||||
assert(psymbols != NULL);
|
||||
|
||||
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR");
|
||||
assert(prelocs != NULL);
|
||||
input[plen] = 0;
|
||||
|
||||
preprocessSections(psections, psymbols);
|
||||
preprocessSymbols(psymbols, prelocs);
|
||||
preprocessRelocations(prelocs, (char*) input + inputlen);
|
||||
addLoader("*UND*");
|
||||
}
|
||||
|
||||
#if 0
|
||||
void ElfLinker::setLoaderAlignOffset(int phase)
|
||||
{
|
||||
//assert(phase & 0);
|
||||
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ElfLinker::addLoader(const char *sname)
|
||||
{
|
||||
assert(!frozen);
|
||||
if (sname[0] == 0)
|
||||
assert(sname != NULL);
|
||||
if (!sname[0])
|
||||
return outputlen;
|
||||
|
||||
char *begin = strdup(sname);
|
||||
@@ -311,33 +394,35 @@ int ElfLinker::addLoader(const char *sname)
|
||||
break;
|
||||
}
|
||||
|
||||
if (*sect == '+') // alignment
|
||||
if (sect[0] == '+') // alignment
|
||||
{
|
||||
assert(tail);
|
||||
if (unsigned l = (hex(sect[2]) - tail->offset - tail->size)
|
||||
% hex(sect[1]))
|
||||
unsigned l = (hex(sect[2]) - tail->offset - tail->size) % hex(sect[1]);
|
||||
if (l)
|
||||
{
|
||||
alignCode(l);
|
||||
if (sect[3] == 'D')
|
||||
alignData(l);
|
||||
else
|
||||
alignCode(l);
|
||||
tail->size += l;
|
||||
outputlen += l;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Section *section = findSection(sect);
|
||||
if (section->align) {
|
||||
unsigned const v = ~0u << section->align;
|
||||
if (section->p2align) {
|
||||
assert(tail);
|
||||
if (unsigned const l = ~v & -(tail->offset + tail->size)) {
|
||||
assert(tail != section);
|
||||
unsigned const v = ~0u << section->p2align;
|
||||
if (unsigned const l = ~v & (0u-(tail->offset + tail->size))) {
|
||||
alignCode(l);
|
||||
tail->size += l;
|
||||
outputlen += l;
|
||||
}
|
||||
}
|
||||
memcpy(output + outputlen, section->input, section->size);
|
||||
section->output = output + outputlen;
|
||||
//printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name);
|
||||
outputlen += section->size;
|
||||
//printf("section added: %s\n", sect);
|
||||
|
||||
if (head)
|
||||
{
|
||||
@@ -354,38 +439,39 @@ int ElfLinker::addLoader(const char *sname)
|
||||
return outputlen;
|
||||
}
|
||||
|
||||
void ElfLinker::addSection(const char *sname, const void *sdata, int slen, int align)
|
||||
void ElfLinker::addLoader(const char *s, va_list ap)
|
||||
{
|
||||
assert(!frozen);
|
||||
if (update_capacity(nsections, &nsections_capacity))
|
||||
sections = static_cast<Section **>(realloc(sections, nsections_capacity * sizeof(Section *)));
|
||||
assert(sections);
|
||||
Section *sec = new Section(sname, sdata, slen, align);
|
||||
sections[nsections++] = sec;
|
||||
//return sec;
|
||||
while (s != NULL)
|
||||
{
|
||||
addLoader(s);
|
||||
s = va_arg(ap, const char *);
|
||||
}
|
||||
}
|
||||
|
||||
void ElfLinker::freeze()
|
||||
void __acc_cdecl_va ElfLinker::addLoaderVA(const char *s, ...)
|
||||
{
|
||||
if (frozen)
|
||||
return;
|
||||
|
||||
frozen = true;
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
addLoader(s, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
int ElfLinker::getSection(const char *sname, int *slen)
|
||||
int ElfLinker::getSection(const char *sname, int *slen) const
|
||||
{
|
||||
assert(frozen);
|
||||
Section *section = findSection(sname);
|
||||
const Section *section = findSection(sname);
|
||||
if (slen)
|
||||
*slen = section->size;
|
||||
return section->output - output;
|
||||
}
|
||||
|
||||
upx_byte *ElfLinker::getLoader(int *llen)
|
||||
int ElfLinker::getSectionSize(const char *sname) const
|
||||
{
|
||||
assert(frozen);
|
||||
const Section *section = findSection(sname);
|
||||
return section->size;
|
||||
}
|
||||
|
||||
upx_byte *ElfLinker::getLoader(int *llen) const
|
||||
{
|
||||
if (llen)
|
||||
*llen = outputlen;
|
||||
return output;
|
||||
@@ -393,31 +479,40 @@ upx_byte *ElfLinker::getLoader(int *llen)
|
||||
|
||||
void ElfLinker::relocate()
|
||||
{
|
||||
assert(frozen);
|
||||
|
||||
assert(!reloc_done);
|
||||
reloc_done = true;
|
||||
for (unsigned ic = 0; ic < nrelocations; ic++)
|
||||
{
|
||||
Relocation *rel = relocations[ic];
|
||||
const Relocation *rel = relocations[ic];
|
||||
unsigned value;
|
||||
|
||||
if (rel->section->output == NULL)
|
||||
continue;
|
||||
if (rel->value->section->output == NULL)
|
||||
if (strcmp(rel->value->section->name, "*ABS*") == 0)
|
||||
{
|
||||
value = rel->value->offset;
|
||||
}
|
||||
else if (strcmp(rel->value->section->name, "*UND*") == 0 &&
|
||||
rel->value->offset == 0xdeaddead)
|
||||
{
|
||||
printf("undefined symbol '%s' referenced\n", rel->value->name);
|
||||
abort();
|
||||
}
|
||||
else if (rel->value->section->output == NULL)
|
||||
{
|
||||
printf("can not apply reloc '%s:%x' without section '%s'\n",
|
||||
rel->section->name, rel->offset,
|
||||
rel->value->section->name);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (strcmp(rel->value->section->name, "*UND*") == 0 &&
|
||||
rel->value->offset == 0xdeaddead)
|
||||
else
|
||||
{
|
||||
printf("undefined symbol '%s' referenced\n", rel->value->name);
|
||||
abort();
|
||||
value = rel->value->section->offset +
|
||||
rel->value->offset + rel->add;
|
||||
}
|
||||
unsigned value = rel->value->section->offset +
|
||||
rel->value->offset + rel->add;
|
||||
upx_byte *location = rel->section->output + rel->offset;
|
||||
|
||||
//printf("%-28s %-28s %-10s 0x%08x 0x%08x\n", rel->section->name, rel->value->name, rel->type, value, value - rel->section->offset - rel->offset);
|
||||
//printf(" %d %d %d %d %d : %d\n", value, rel->value->section->offset, rel->value->offset, rel->offset, rel->add, *location);
|
||||
relocate1(rel, location, value, rel->type);
|
||||
}
|
||||
}
|
||||
@@ -425,7 +520,12 @@ void ElfLinker::relocate()
|
||||
void ElfLinker::defineSymbol(const char *name, unsigned value)
|
||||
{
|
||||
Symbol *symbol = findSymbol(name);
|
||||
if (strcmp(symbol->section->name, "*UND*") == 0) // for undefined symbols
|
||||
if (strcmp(symbol->section->name, "*ABS*") == 0)
|
||||
{
|
||||
printf("defineSymbol: symbol '%s' is *ABS*\n", name);
|
||||
abort();
|
||||
}
|
||||
else if (strcmp(symbol->section->name, "*UND*") == 0) // for undefined symbols
|
||||
symbol->offset = value;
|
||||
else if (strcmp(symbol->section->name, name) == 0) // for sections
|
||||
{
|
||||
@@ -438,36 +538,57 @@ void ElfLinker::defineSymbol(const char *name, unsigned value)
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("symbol '%s' already defined\n", name);
|
||||
printf("defineSymbol: symbol '%s' already defined\n", name);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// debugging support
|
||||
void ElfLinker::dumpSymbols(FILE *fp) const
|
||||
void ElfLinker::dumpSymbol(const Symbol *symbol, unsigned flags, FILE *fp) const
|
||||
{
|
||||
if ((flags & 1) && symbol->section->output == NULL)
|
||||
return;
|
||||
fprintf(fp, "%-28s 0x%08x | %-28s 0x%08x\n",
|
||||
symbol->name, symbol->offset, symbol->section->name, symbol->section->offset);
|
||||
}
|
||||
void ElfLinker::dumpSymbols(unsigned flags, FILE *fp) const
|
||||
{
|
||||
if (fp == NULL)
|
||||
fp = stdout;
|
||||
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||
if ((flags & 2) == 0)
|
||||
{
|
||||
Symbol *symbol = symbols[ic];
|
||||
fprintf(fp, "%-20s 0x%08x | %-20s 0x%08x\n",
|
||||
symbol->name, symbol->offset, symbol->section->name, symbol->section->offset);
|
||||
// default: dump symbols in used section order
|
||||
for (const Section *section = head; section; section = section->next)
|
||||
{
|
||||
fprintf(fp, "%-42s%-28s 0x%08x\n", "", section->name, section->offset);
|
||||
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||
{
|
||||
const Symbol *symbol = symbols[ic];
|
||||
if (symbol->section == section && strcmp(symbol->name, section->name) != 0)
|
||||
dumpSymbol(symbol, flags, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// dump all symbols
|
||||
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||
dumpSymbol(symbols[ic], flags, fp);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ElfLinker::getSymbolOffset(const char *name) const
|
||||
{
|
||||
assert(frozen);
|
||||
Symbol *symbol = const_cast<ElfLinker *>(this)->findSymbol(name);
|
||||
const Symbol *symbol = findSymbol(name);
|
||||
if (symbol->section->output == NULL)
|
||||
return 0xdeaddead;
|
||||
return symbol->section->offset + symbol->offset;
|
||||
}
|
||||
|
||||
void ElfLinker::alignWithByte(unsigned len, upx_byte b)
|
||||
void ElfLinker::alignWithByte(unsigned len, unsigned char b)
|
||||
{
|
||||
memset(output + outputlen, b, len);
|
||||
outputlen += len;
|
||||
}
|
||||
|
||||
void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
|
||||
@@ -481,8 +602,26 @@ void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
|
||||
/*************************************************************************
|
||||
// ElfLinker arch subclasses
|
||||
// FIXME: add more displacment overflow checks
|
||||
// FIXME: add support for our special "ignore_reloc_overflow" section
|
||||
**************************************************************************/
|
||||
|
||||
#if 0 // FIXME
|
||||
static void check8(const Relocation *rel, const upx_byte *location, int v, int d)
|
||||
{
|
||||
if (v < -128 || v > 127) {
|
||||
printf("value out of range (%d) in reloc %s:%x\n",
|
||||
v, rel->section->name, rel->offset);
|
||||
abort();
|
||||
}
|
||||
if (d < -128 || d > 127) {
|
||||
printf("displacement target out of range (%d) in reloc %s:%x\n",
|
||||
v, rel->section->name, rel->offset);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
@@ -498,7 +637,11 @@ void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
|
||||
|
||||
if (strcmp(type, "8") == 0)
|
||||
{
|
||||
#if (ACC_CC_PGI)
|
||||
int displ = * (signed char *) location + (int) value; // CBUG
|
||||
#else
|
||||
int displ = (signed char) *location + (int) value;
|
||||
#endif
|
||||
if (displ < -128 || displ > 127)
|
||||
{
|
||||
printf("target out of range (%d) in reloc %s:%x\n",
|
||||
@@ -540,6 +683,9 @@ void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location,
|
||||
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||
//set_be32(location, get_be32(location) + value / 4);
|
||||
}
|
||||
else if (0==strcmp("R_ARM_ABS8", type)) {
|
||||
*location += value;
|
||||
}
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
@@ -569,6 +715,9 @@ void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location,
|
||||
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||
//set_le32(location, get_le32(location) + value / 4);
|
||||
}
|
||||
else if (0==strcmp("R_ARM_ABS8", type)) {
|
||||
*location += value;
|
||||
}
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
@@ -580,6 +729,7 @@ void ElfLinkerM68k::alignCode(unsigned len)
|
||||
assert((outputlen & 1) == 0);
|
||||
for (unsigned i = 0; i < len; i += 2)
|
||||
set_be16(output + outputlen + i, 0x4e71); // "nop"
|
||||
outputlen += len;
|
||||
}
|
||||
|
||||
void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location,
|
||||
@@ -594,17 +744,51 @@ void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location,
|
||||
value -= rel->section->offset + rel->offset;
|
||||
type += 2;
|
||||
}
|
||||
if (strcmp(type, "8") == 0)
|
||||
if (strcmp(type, "8") == 0) {
|
||||
*location += value;
|
||||
else if (strcmp(type, "16") == 0)
|
||||
}
|
||||
else if (strcmp(type, "16") == 0) {
|
||||
set_be16(location, get_be16(location) + value);
|
||||
else if (strcmp(type, "32") == 0)
|
||||
}
|
||||
else if (strcmp(type, "32") == 0) {
|
||||
set_be32(location, get_be32(location) + value);
|
||||
}
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||
#define MIPS_LO(a) ((a) & 0xffff)
|
||||
#define MIPS_PC16(a) ((a) >> 2)
|
||||
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||
|
||||
if (strcmp(type, "R_MIPS_HI16") == 0)
|
||||
set_le16(location, get_le16(location) + MIPS_HI(value));
|
||||
else if (strcmp(type, "R_MIPS_LO16") == 0)
|
||||
set_le16(location, get_le16(location) + MIPS_LO(value));
|
||||
else if (strcmp(type, "R_MIPS_PC16") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
set_le16(location, get_le16(location) + MIPS_PC16(value));
|
||||
}
|
||||
else if (strcmp(type, "R_MIPS_26") == 0)
|
||||
set_le32(location, get_le32(location) + MIPS_PC26(value));
|
||||
else if (strcmp(type, "R_MIPS_32") == 0)
|
||||
set_le32(location, get_le32(location) + value);
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
|
||||
#undef MIPS_HI
|
||||
#undef MIPS_LO
|
||||
#undef MIPS_PC16
|
||||
#undef MIPS_PC26
|
||||
}
|
||||
|
||||
|
||||
void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
@@ -651,20 +835,24 @@ void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location,
|
||||
return super::relocate1(rel, location, value, type);
|
||||
type += 6;
|
||||
|
||||
int range_check = 0;
|
||||
bool range_check = false;
|
||||
if (strncmp(type, "PC", 2) == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
type += 2;
|
||||
range_check = 1;
|
||||
range_check = true;
|
||||
}
|
||||
|
||||
if (strcmp(type, "8") == 0)
|
||||
{
|
||||
#if (ACC_CC_PGI)
|
||||
int displ = * (signed char *) location + (int) value; // CBUG
|
||||
#else
|
||||
int displ = (signed char) *location + (int) value;
|
||||
#endif
|
||||
if (range_check && (displ < -128 || displ > 127)) {
|
||||
printf("target out of range (%d) in reloc %s:%x\n",
|
||||
displ, rel->section->name, rel->offset);
|
||||
printf("target out of range (%d,%d,%d) in reloc %s:%x\n",
|
||||
displ, *location, value, rel->section->name, rel->offset);
|
||||
abort();
|
||||
}
|
||||
*location += value;
|
||||
|
||||
+46
-18
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -36,13 +36,14 @@
|
||||
|
||||
class ElfLinker : private nocopy
|
||||
{
|
||||
friend class Packer;
|
||||
public:
|
||||
const N_BELE_RTP::AbstractPolicy *bele;
|
||||
protected:
|
||||
struct Section;
|
||||
struct Symbol;
|
||||
struct Relocation;
|
||||
|
||||
bool frozen; // FIXME: can we remove this ?
|
||||
|
||||
upx_byte *input;
|
||||
int inputlen;
|
||||
upx_byte *output;
|
||||
@@ -62,11 +63,14 @@ protected:
|
||||
unsigned nrelocations;
|
||||
unsigned nrelocations_capacity;
|
||||
|
||||
void preprocessSections(char *start, const char *end);
|
||||
void preprocessSymbols(char *start, const char *end);
|
||||
void preprocessRelocations(char *start, const char *end);
|
||||
Section *findSection(const char *name) const;
|
||||
Symbol *findSymbol(const char *name) /*const*/;
|
||||
bool reloc_done;
|
||||
|
||||
protected:
|
||||
void preprocessSections(char *start, char *end);
|
||||
void preprocessSymbols(char *start, char *end);
|
||||
void preprocessRelocations(char *start, char *end);
|
||||
Section *findSection(const char *name, bool fatal=true) const;
|
||||
Symbol *findSymbol(const char *name, bool fatal=true) const;
|
||||
|
||||
Symbol *addSymbol(const char *name, const char *section, unsigned offset);
|
||||
Relocation *addRelocation(const char *section, unsigned off, const char *type,
|
||||
@@ -77,21 +81,30 @@ public:
|
||||
virtual ~ElfLinker();
|
||||
|
||||
virtual void init(const void *pdata, int plen);
|
||||
virtual void setLoaderAlignOffset(int phase);
|
||||
//virtual void setLoaderAlignOffset(int phase);
|
||||
virtual int addLoader(const char *sname);
|
||||
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
|
||||
virtual void freeze();
|
||||
virtual int getSection(const char *sname, int *slen=NULL);
|
||||
virtual upx_byte *getLoader(int *llen=NULL);
|
||||
virtual void relocate();
|
||||
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 int getSection(const char *sname, int *slen=NULL) const;
|
||||
virtual int getSectionSize(const char *sname) const;
|
||||
virtual upx_byte *getLoader(int *llen=NULL) const;
|
||||
virtual void defineSymbol(const char *name, unsigned value);
|
||||
virtual unsigned getSymbolOffset(const char *) const;
|
||||
virtual void dumpSymbols(FILE *fp=NULL) const;
|
||||
|
||||
void alignWithByte(unsigned len, upx_byte b);
|
||||
virtual void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const;
|
||||
virtual void dumpSymbols(unsigned flags=0, FILE *fp=NULL) const;
|
||||
|
||||
void alignWithByte(unsigned len, unsigned char b);
|
||||
virtual void alignCode(unsigned len) { alignWithByte(len, 0); }
|
||||
virtual void alignData(unsigned len) { alignWithByte(len, 0); }
|
||||
|
||||
protected:
|
||||
virtual void relocate();
|
||||
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||
unsigned value, const char *type);
|
||||
};
|
||||
@@ -104,7 +117,7 @@ struct ElfLinker::Section : private nocopy
|
||||
upx_byte *output;
|
||||
unsigned size;
|
||||
unsigned offset;
|
||||
unsigned char align; // log2
|
||||
unsigned p2align; // log2
|
||||
Section *next;
|
||||
|
||||
Section(const char *n, const void *i, unsigned s, unsigned a=0);
|
||||
@@ -153,6 +166,8 @@ protected:
|
||||
class ElfLinkerArmBE : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
public:
|
||||
ElfLinkerArmBE() { bele = &N_BELE_RTP::be_policy; }
|
||||
protected:
|
||||
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||
unsigned value, const char *type);
|
||||
@@ -171,6 +186,8 @@ protected:
|
||||
class ElfLinkerM68k : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
public:
|
||||
ElfLinkerM68k() { bele = &N_BELE_RTP::be_policy; }
|
||||
protected:
|
||||
virtual void alignCode(unsigned len);
|
||||
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||
@@ -178,9 +195,20 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
class ElfLinkerMipsLE : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
protected:
|
||||
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||
unsigned value, const char *type);
|
||||
};
|
||||
|
||||
|
||||
class ElfLinkerPpc32 : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
public:
|
||||
ElfLinkerPpc32() { bele = &N_BELE_RTP::be_policy; }
|
||||
protected:
|
||||
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||
unsigned value, const char *type);
|
||||
|
||||
+260
-124
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -43,15 +43,16 @@ int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
|
||||
// options
|
||||
**************************************************************************/
|
||||
|
||||
void init_options(struct options_t *o)
|
||||
void options_t::reset()
|
||||
{
|
||||
options_t *o = this;
|
||||
memset(o, 0, sizeof(*o));
|
||||
o->crp.reset();
|
||||
|
||||
o->cmd = CMD_NONE;
|
||||
o->method = -1;
|
||||
o->method = M_NONE;
|
||||
o->level = -1;
|
||||
o->filter = -1;
|
||||
o->filter = FT_NONE;
|
||||
|
||||
o->backup = -1;
|
||||
o->overlay = -1;
|
||||
@@ -76,8 +77,8 @@ void init_options(struct options_t *o)
|
||||
o->win32_pe.keep_resource = "";
|
||||
}
|
||||
|
||||
static struct options_t global_options;
|
||||
struct options_t *opt = &global_options;
|
||||
static options_t global_options;
|
||||
options_t *opt = &global_options;
|
||||
|
||||
static int done_output_name = 0;
|
||||
static int done_script_name = 0;
|
||||
@@ -182,7 +183,7 @@ static void e_method(int m, int l)
|
||||
static void e_optarg(const char *n)
|
||||
{
|
||||
fflush(con_term);
|
||||
fprintf(stderr,"%s: invalid argument in option `%s'\n", argv0, n);
|
||||
fprintf(stderr,"%s: invalid argument in option '%s'\n", argv0, n);
|
||||
e_exit(EXIT_USAGE);
|
||||
}
|
||||
|
||||
@@ -190,7 +191,7 @@ static void e_optarg(const char *n)
|
||||
static void e_optval(const char *n)
|
||||
{
|
||||
fflush(con_term);
|
||||
fprintf(stderr,"%s: invalid value for option `%s'\n", argv0, n);
|
||||
fprintf(stderr,"%s: invalid value for option '%s'\n", argv0, n);
|
||||
e_exit(EXIT_USAGE);
|
||||
}
|
||||
|
||||
@@ -200,10 +201,10 @@ void e_envopt(const char *n)
|
||||
{
|
||||
fflush(con_term);
|
||||
if (n)
|
||||
fprintf(stderr,"%s: invalid string `%s' in environment variable `%s'\n",
|
||||
fprintf(stderr,"%s: invalid string '%s' in environment variable '%s'\n",
|
||||
argv0, n, OPTIONS_VAR);
|
||||
else
|
||||
fprintf(stderr,"%s: illegal option in environment variable `%s'\n",
|
||||
fprintf(stderr,"%s: illegal option in environment variable '%s'\n",
|
||||
argv0, OPTIONS_VAR);
|
||||
e_exit(EXIT_USAGE);
|
||||
}
|
||||
@@ -226,7 +227,7 @@ void check_not_both(bool e1, bool e2, const char *c1, const char *c2)
|
||||
if (e1 && e2)
|
||||
{
|
||||
fprintf(stderr,"%s: ",argv0);
|
||||
fprintf(stderr,"cannot use both `%s' and `%s'\n", c1, c2);
|
||||
fprintf(stderr,"cannot use both '%s' and '%s'\n", c1, c2);
|
||||
e_usage();
|
||||
}
|
||||
}
|
||||
@@ -236,12 +237,24 @@ void check_options(int i, int argc)
|
||||
{
|
||||
assert(i <= argc);
|
||||
|
||||
if (opt->cmd != CMD_COMPRESS)
|
||||
{
|
||||
// invalidate compression options
|
||||
opt->method = 0;
|
||||
opt->level = 0;
|
||||
opt->exact = 0;
|
||||
opt->small = 0;
|
||||
opt->crp.reset();
|
||||
}
|
||||
|
||||
// set default overlay action
|
||||
if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))
|
||||
opt->overlay = opt->COPY_OVERLAY;
|
||||
else if (opt->overlay < 0)
|
||||
opt->overlay = opt->COPY_OVERLAY;
|
||||
|
||||
check_not_both(opt->exact, opt->overlay == opt->STRIP_OVERLAY, "--exact", "--overlay=strip");
|
||||
|
||||
// set default backup option
|
||||
if (opt->backup < 0)
|
||||
opt->backup = 0;
|
||||
@@ -251,14 +264,14 @@ void check_options(int i, int argc)
|
||||
check_not_both(opt->to_stdout, opt->output_name != NULL, "--stdout", "-o");
|
||||
if (opt->to_stdout && opt->cmd == CMD_COMPRESS)
|
||||
{
|
||||
fprintf(stderr,"%s: cannot use `--stdout' when compressing\n", argv0);
|
||||
fprintf(stderr,"%s: cannot use '--stdout' when compressing\n", argv0);
|
||||
e_usage();
|
||||
}
|
||||
if (opt->to_stdout || opt->output_name)
|
||||
{
|
||||
if (i + 1 != argc)
|
||||
{
|
||||
fprintf(stderr,"%s: need exactly one argument when using `%s'\n",
|
||||
fprintf(stderr,"%s: need exactly one argument when using '%s'\n",
|
||||
argv0, opt->to_stdout ? "--stdout" : "-o");
|
||||
e_usage();
|
||||
}
|
||||
@@ -299,8 +312,14 @@ static bool set_method(int m, int l)
|
||||
{
|
||||
if (!Packer::isValidCompressionMethod(m))
|
||||
return false;
|
||||
opt->method = m;
|
||||
opt->all_methods = false;
|
||||
#if 1
|
||||
// something like "--brute --lzma" should not disable "--brute"
|
||||
if (!opt->all_methods)
|
||||
#endif
|
||||
{
|
||||
opt->method = m;
|
||||
opt->all_methods = false;
|
||||
}
|
||||
}
|
||||
if (l > 0)
|
||||
opt->level = l;
|
||||
@@ -314,7 +333,7 @@ static void set_output_name(const char *n, bool allow_m)
|
||||
#if 1
|
||||
if (done_output_name > 0)
|
||||
{
|
||||
fprintf(stderr,"%s: option `-o' more than once given\n",argv0);
|
||||
fprintf(stderr,"%s: option '-o' more than once given\n",argv0);
|
||||
e_usage();
|
||||
}
|
||||
#endif
|
||||
@@ -337,7 +356,7 @@ static void set_script_name(const char *n, bool allow_m)
|
||||
#if 1
|
||||
if (done_script_name > 0)
|
||||
{
|
||||
fprintf(stderr,"%s: option `--script' more than once given\n",argv0);
|
||||
fprintf(stderr,"%s: option '--script' more than once given\n",argv0);
|
||||
e_usage();
|
||||
}
|
||||
#endif
|
||||
@@ -405,28 +424,58 @@ char* prepare_shortopts(char *buf, const char *n,
|
||||
|
||||
|
||||
template <class T>
|
||||
int getoptvar(T *var, const T minval, const T maxval)
|
||||
int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal)
|
||||
{
|
||||
const char *p = mfx_optarg;
|
||||
char *endptr;
|
||||
int r = 0;
|
||||
long n;
|
||||
T v;
|
||||
|
||||
if (!p || !p[0])
|
||||
return -1;
|
||||
{ r = -1; goto error; }
|
||||
// avoid interpretation as octal value
|
||||
while (p[0] == '0' && isdigit(p[1]))
|
||||
p++;
|
||||
long n = strtol(p, &endptr, 0);
|
||||
n = strtol(p, &endptr, 0);
|
||||
if (*endptr != '\0')
|
||||
return -2;
|
||||
T v = (T) n;
|
||||
if (v < minval)
|
||||
return -3;
|
||||
if (v > maxval)
|
||||
return -4;
|
||||
{ r = -2; goto error; }
|
||||
v = (T) n;
|
||||
if (v < min_value)
|
||||
{ r = -3; goto error; }
|
||||
if (v > max_value)
|
||||
{ r = -4; goto error; }
|
||||
*var = v;
|
||||
return 0;
|
||||
goto done;
|
||||
error:
|
||||
if (arg_fatal != NULL)
|
||||
e_optval(arg_fatal);
|
||||
done:
|
||||
return r;
|
||||
}
|
||||
|
||||
#if 1 && (ACC_CC_GNUC >= 0x030300)
|
||||
template <class T, T default_value, T min_value, T max_value>
|
||||
int getoptvar(OptVar<T,default_value,min_value,max_value> *var, const char *arg_fatal)
|
||||
{
|
||||
T v = default_value;
|
||||
int r = getoptvar(&v, min_value, max_value, arg_fatal);
|
||||
if (r == 0)
|
||||
*var = v;
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
template <class T>
|
||||
int getoptvar(T *var, const char *arg_fatal)
|
||||
{
|
||||
typename T::Type v = T::default_value_c;
|
||||
int r = getoptvar(&v, T::min_value_c, T::max_value_c, arg_fatal);
|
||||
if (r == 0)
|
||||
*var = v;
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int do_option(int optc, const char *arg)
|
||||
{
|
||||
@@ -450,7 +499,7 @@ static int do_option(int optc, const char *arg)
|
||||
case 'f':
|
||||
opt->force++;
|
||||
break;
|
||||
case 902:
|
||||
case 909:
|
||||
set_cmd(CMD_FILEINFO);
|
||||
break;
|
||||
case 'h':
|
||||
@@ -459,10 +508,13 @@ static int do_option(int optc, const char *arg)
|
||||
set_cmd(CMD_HELP);
|
||||
break;
|
||||
case 'h'+256:
|
||||
#if 0
|
||||
/* according to GNU standards */
|
||||
set_term(stdout);
|
||||
opt->console = CON_FILE;
|
||||
#if 1
|
||||
if (!acc_isatty(STDOUT_FILENO))
|
||||
{
|
||||
/* according to GNU standards */
|
||||
set_term(stdout);
|
||||
opt->console = CON_FILE;
|
||||
}
|
||||
#endif
|
||||
show_help(1);
|
||||
e_exit(EXIT_OK);
|
||||
@@ -501,22 +553,32 @@ static int do_option(int optc, const char *arg)
|
||||
|
||||
// method
|
||||
case 702:
|
||||
opt->method_nrv2b_seen = true;
|
||||
if (!set_method(M_NRV2B_LE32, -1))
|
||||
e_method(M_NRV2B_LE32, opt->level);
|
||||
break;
|
||||
case 704:
|
||||
opt->method_nrv2d_seen = true;
|
||||
if (!set_method(M_NRV2D_LE32, -1))
|
||||
e_method(M_NRV2D_LE32, opt->level);
|
||||
break;
|
||||
case 705:
|
||||
opt->method_nrv2e_seen = true;
|
||||
if (!set_method(M_NRV2E_LE32, -1))
|
||||
e_method(M_NRV2E_LE32, opt->level);
|
||||
break;
|
||||
case 721:
|
||||
opt->method_lzma_seen = true;
|
||||
opt->all_methods_use_lzma = true;
|
||||
if (!set_method(M_LZMA, -1))
|
||||
e_method(M_LZMA, opt->level);
|
||||
break;
|
||||
case 722:
|
||||
opt->method_lzma_seen = false;
|
||||
opt->all_methods_use_lzma = false;
|
||||
if (M_IS_LZMA(opt->method))
|
||||
opt->method = -1;
|
||||
break;
|
||||
|
||||
// compression level
|
||||
case '1':
|
||||
@@ -532,6 +594,9 @@ static int do_option(int optc, const char *arg)
|
||||
e_method(opt->method, optc);
|
||||
break;
|
||||
|
||||
case 902: // --ultra-brute
|
||||
opt->ultra_brute = true;
|
||||
/* fallthrough */
|
||||
case 901: // --brute
|
||||
opt->all_methods = true;
|
||||
opt->all_methods_use_lzma = true;
|
||||
@@ -561,6 +626,9 @@ static int do_option(int optc, const char *arg)
|
||||
e_optarg(arg);
|
||||
opt->debug.dump_stub_loader = mfx_optarg;
|
||||
break;
|
||||
case 545:
|
||||
opt->debug.disable_random_id = true;
|
||||
break;
|
||||
|
||||
// misc
|
||||
case 512:
|
||||
@@ -585,7 +653,7 @@ static int do_option(int optc, const char *arg)
|
||||
opt->small++;
|
||||
break;
|
||||
case 521: // --filter=
|
||||
getoptvar(&opt->filter, 0, 255);
|
||||
getoptvar(&opt->filter, 0, 255, arg);
|
||||
opt->all_filters = false;
|
||||
break;
|
||||
case 522: // --no-filter
|
||||
@@ -599,37 +667,64 @@ static int do_option(int optc, const char *arg)
|
||||
break;
|
||||
case 524: // --all-methods
|
||||
opt->all_methods = true;
|
||||
opt->all_methods_use_lzma = true;
|
||||
opt->method = -1;
|
||||
break;
|
||||
case 525: // --exact
|
||||
opt->exact = true;
|
||||
break;
|
||||
// compression runtime parameters
|
||||
case 531:
|
||||
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3);
|
||||
case 801:
|
||||
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
|
||||
break;
|
||||
case 532:
|
||||
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2);
|
||||
case 802:
|
||||
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2, arg);
|
||||
break;
|
||||
case 533:
|
||||
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1);
|
||||
case 803:
|
||||
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1, arg);
|
||||
break;
|
||||
case 534:
|
||||
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7);
|
||||
case 804:
|
||||
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7, arg);
|
||||
break;
|
||||
case 535:
|
||||
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u);
|
||||
case 805:
|
||||
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u, arg);
|
||||
break;
|
||||
case 536:
|
||||
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u);
|
||||
case 806:
|
||||
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u, arg);
|
||||
break;
|
||||
case 537:
|
||||
if (getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u) != 0)
|
||||
e_optval("--crp-ms=");
|
||||
case 807:
|
||||
getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg);
|
||||
break;
|
||||
case 811:
|
||||
getoptvar(&opt->crp.crp_lzma.pos_bits, arg);
|
||||
break;
|
||||
case 812:
|
||||
getoptvar(&opt->crp.crp_lzma.lit_pos_bits, arg);
|
||||
break;
|
||||
case 813:
|
||||
getoptvar(&opt->crp.crp_lzma.lit_context_bits, arg);
|
||||
break;
|
||||
case 814:
|
||||
getoptvar(&opt->crp.crp_lzma.dict_size, arg);
|
||||
break;
|
||||
case 816:
|
||||
getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg);
|
||||
break;
|
||||
case 821:
|
||||
getoptvar(&opt->crp.crp_zlib.mem_level, arg);
|
||||
break;
|
||||
case 822:
|
||||
getoptvar(&opt->crp.crp_zlib.window_bits, arg);
|
||||
break;
|
||||
case 823:
|
||||
getoptvar(&opt->crp.crp_zlib.strategy, arg);
|
||||
break;
|
||||
// backup
|
||||
case 'k':
|
||||
opt->backup = 1;
|
||||
break;
|
||||
case 541:
|
||||
if (opt->backup != 1) // do not overide `--backup'
|
||||
if (opt->backup != 1) // do not overide '--backup'
|
||||
opt->backup = 0;
|
||||
break;
|
||||
// overlay
|
||||
@@ -687,18 +782,20 @@ static int do_option(int optc, const char *arg)
|
||||
break;
|
||||
case 630:
|
||||
opt->win32_pe.compress_exports = 1;
|
||||
getoptvar(&opt->win32_pe.compress_exports, 0, 1);
|
||||
if (mfx_optarg && mfx_optarg[0])
|
||||
getoptvar(&opt->win32_pe.compress_exports, 0, 1, arg);
|
||||
//printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
|
||||
break;
|
||||
case 631:
|
||||
opt->win32_pe.compress_icons = 1;
|
||||
getoptvar(&opt->win32_pe.compress_icons, 0, 2);
|
||||
if (mfx_optarg && mfx_optarg[0])
|
||||
getoptvar(&opt->win32_pe.compress_icons, 0, 3, arg);
|
||||
//printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
|
||||
break;
|
||||
case 632:
|
||||
opt->win32_pe.compress_resources = true;
|
||||
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
|
||||
opt->win32_pe.compress_resources = false;
|
||||
opt->win32_pe.compress_resources = 1;
|
||||
if (mfx_optarg && mfx_optarg[0])
|
||||
getoptvar(&opt->win32_pe.compress_resources, 0, 1, arg);
|
||||
//printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
|
||||
break;
|
||||
case 633:
|
||||
@@ -706,8 +803,8 @@ static int do_option(int optc, const char *arg)
|
||||
break;
|
||||
case 634:
|
||||
opt->win32_pe.strip_relocs = 1;
|
||||
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
|
||||
opt->win32_pe.strip_relocs = 0;
|
||||
if (mfx_optarg && mfx_optarg[0])
|
||||
getoptvar(&opt->win32_pe.strip_relocs, 0, 1, arg);
|
||||
//printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
|
||||
break;
|
||||
case 635:
|
||||
@@ -719,7 +816,7 @@ static int do_option(int optc, const char *arg)
|
||||
opt->atari_tos.split_segments = true;
|
||||
break;
|
||||
case 660:
|
||||
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u);
|
||||
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u, arg);
|
||||
break;
|
||||
case 661:
|
||||
opt->o_unix.force_execve = true;
|
||||
@@ -727,7 +824,7 @@ static int do_option(int optc, const char *arg)
|
||||
case 662:
|
||||
opt->o_unix.script_name = "/usr/local/lib/upx/upxX";
|
||||
if (mfx_optarg && mfx_optarg[0])
|
||||
set_script_name(mfx_optarg,1);
|
||||
set_script_name(mfx_optarg, 1);
|
||||
break;
|
||||
case 663:
|
||||
opt->o_unix.is_ptinterp = true;
|
||||
@@ -769,7 +866,7 @@ static int do_option(int optc, const char *arg)
|
||||
case ':':
|
||||
return -2;
|
||||
default:
|
||||
fprintf(stderr,"%s: internal error in getopt (%d)\n",argv0,optc);
|
||||
fprintf(stderr,"%s: internal error in getopt (%d)\n", argv0, optc);
|
||||
return -3;
|
||||
}
|
||||
|
||||
@@ -786,10 +883,11 @@ static const struct mfx_option longopts[] =
|
||||
// commands
|
||||
{"best", 0x10, 0, 900}, // compress best
|
||||
{"brute", 0x10, 0, 901}, // compress best, brute force
|
||||
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
|
||||
{"decompress", 0, 0, 'd'}, // decompress
|
||||
{"fast", 0x10, 0, '1'}, // compress faster
|
||||
{"fileinfo", 0x10, 0, 902}, // display info about file
|
||||
{"file-info", 0x10, 0, 902}, // display info about file
|
||||
{"fileinfo", 0x10, 0, 909}, // display info about file
|
||||
{"file-info", 0x10, 0, 909}, // display info about file
|
||||
{"help", 0, 0, 'h'+256}, // give help
|
||||
{"license", 0, 0, 'L'}, // display software license
|
||||
{"list", 0, 0, 'l'}, // list compressed exe
|
||||
@@ -818,18 +916,19 @@ static const struct mfx_option longopts[] =
|
||||
{"dump-stub-loader" ,0x31, 0, 544}, // for internal debugging
|
||||
{"fake-stub-version",0x31, 0, 542}, // for internal debugging
|
||||
{"fake-stub-year" ,0x31, 0, 543}, // for internal debugging
|
||||
{"disable-random-id",0x10, 0, 545}, // for internal debugging
|
||||
|
||||
// backup options
|
||||
{"backup", 0, 0, 'k'},
|
||||
{"keep", 0, 0, 'k'},
|
||||
{"no-backup", 0, 0, 541},
|
||||
{"backup", 0x10, 0, 'k'},
|
||||
{"keep", 0x10, 0, 'k'},
|
||||
{"no-backup", 0x10, 0, 541},
|
||||
|
||||
// overlay options
|
||||
{"overlay", 0x31, 0, 551}, // --overlay=
|
||||
{"skip-overlay", 0, 0, 552},
|
||||
{"no-overlay", 0, 0, 552}, // old name
|
||||
{"copy-overlay", 0, 0, 553},
|
||||
{"strip-overlay", 0, 0, 554},
|
||||
{"skip-overlay", 0x10, 0, 552},
|
||||
{"no-overlay", 0x10, 0, 552}, // old name
|
||||
{"copy-overlay", 0x10, 0, 553},
|
||||
{"strip-overlay", 0x10, 0, 554},
|
||||
|
||||
// CPU options
|
||||
{"cpu", 0x31, 0, 560}, // --cpu=
|
||||
@@ -838,34 +937,53 @@ static const struct mfx_option longopts[] =
|
||||
{"486", 0x10, 0, 564},
|
||||
|
||||
// color options
|
||||
{"no-color", 0, 0, 512},
|
||||
{"mono", 0, 0, 513},
|
||||
{"color", 0, 0, 514},
|
||||
{"no-color", 0x10, 0, 512},
|
||||
{"mono", 0x10, 0, 513},
|
||||
{"color", 0x10, 0, 514},
|
||||
|
||||
// compression method
|
||||
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
||||
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
||||
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
||||
{"lzma", 0x10, 0, 721}, // --lzma
|
||||
{"no-lzma", 0x10, 0, 722}, // (disable all_methods_use_lzma)
|
||||
// compression settings
|
||||
{"all-filters", 0x10, 0, 523},
|
||||
{"all-methods", 0x10, 0, 524},
|
||||
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
|
||||
{"filter", 0x31, 0, 521}, // --filter=
|
||||
{"no-filter", 0x10, 0, 522},
|
||||
{"small", 0x10, 0, 520},
|
||||
// compression runtime parameters
|
||||
{"crp-cf", 0x31, 0, 531},
|
||||
{"crp-sl", 0x31, 0, 532},
|
||||
{"crp-hl", 0x31, 0, 533},
|
||||
{"crp-pl", 0x31, 0, 534},
|
||||
{"crp-mo", 0x31, 0, 535},
|
||||
{"crp-mm", 0x31, 0, 536},
|
||||
{"crp-ms", 0x31, 0, 537},
|
||||
{"crp-nrv-cf", 0x31, 0, 801},
|
||||
{"crp-nrv-sl", 0x31, 0, 802},
|
||||
{"crp-nrv-hl", 0x31, 0, 803},
|
||||
{"crp-nrv-pl", 0x31, 0, 804},
|
||||
{"crp-nrv-mo", 0x31, 0, 805},
|
||||
{"crp-nrv-mm", 0x31, 0, 806},
|
||||
{"crp-nrv-ms", 0x31, 0, 807},
|
||||
{"crp-ucl-cf", 0x31, 0, 801},
|
||||
{"crp-ucl-sl", 0x31, 0, 802},
|
||||
{"crp-ucl-hl", 0x31, 0, 803},
|
||||
{"crp-ucl-pl", 0x31, 0, 804},
|
||||
{"crp-ucl-mo", 0x31, 0, 805},
|
||||
{"crp-ucl-mm", 0x31, 0, 806},
|
||||
{"crp-ucl-ms", 0x31, 0, 807},
|
||||
{"crp-lzma-pb", 0x31, 0, 811},
|
||||
{"crp-lzma-lp", 0x31, 0, 812},
|
||||
{"crp-lzma-lc", 0x31, 0, 813},
|
||||
{"crp-lzma-ds", 0x31, 0, 814},
|
||||
{"crp-lzma-fb", 0x31, 0, 816},
|
||||
{"crp-zlib-ml", 0x31, 0, 821},
|
||||
{"crp-zlib-wb", 0x31, 0, 822},
|
||||
{"crp-zlib-st", 0x31, 0, 823},
|
||||
// [deprecated - only for compatibility with UPX 2.0x]
|
||||
{"crp-ms", 0x31, 0, 807},
|
||||
|
||||
// atari/tos
|
||||
{"split-segments", 0x10, 0, 650},
|
||||
// djgpp2/coff
|
||||
{"coff", 0, 0, 610}, // produce COFF output
|
||||
{"coff", 0x10, 0, 610}, // produce COFF output
|
||||
// dos/com
|
||||
// dos/exe
|
||||
//{"force-stub", 0x10, 0, 600},
|
||||
@@ -877,15 +995,19 @@ static const struct mfx_option longopts[] =
|
||||
#if 0
|
||||
{"script", 0x31, 0, 662}, // --script=
|
||||
#endif
|
||||
{"is_ptinterp", 0, 0, 663}, // linux/elf386 PT_INTERP program
|
||||
{"use_ptinterp", 0, 0, 664}, // linux/elf386 PT_INTERP program
|
||||
{"make_ptinterp", 0, 0, 665}, // linux/elf386 PT_INTERP program
|
||||
{"Linux", 0, 0, 666},
|
||||
{"FreeBSD", 0, 0, 667},
|
||||
{"NetBSD", 0, 0, 668},
|
||||
{"OpenBSD", 0, 0, 669},
|
||||
{"is_ptinterp", 0x10, 0, 663}, // linux/elf386 PT_INTERP program
|
||||
{"use_ptinterp", 0x10, 0, 664}, // linux/elf386 PT_INTERP program
|
||||
{"make_ptinterp", 0x10, 0, 665}, // linux/elf386 PT_INTERP program
|
||||
{"Linux", 0x10, 0, 666},
|
||||
{"linux", 0x10, 0, 666},
|
||||
{"FreeBSD", 0x10, 0, 667},
|
||||
{"freebsd", 0x10, 0, 667},
|
||||
{"NetBSD", 0x10, 0, 668},
|
||||
{"netbsd", 0x10, 0, 668},
|
||||
{"OpenBSD", 0x10, 0, 669},
|
||||
{"openbsd", 0x10, 0, 669},
|
||||
// watcom/le
|
||||
{"le", 0, 0, 620}, // produce LE output
|
||||
{"le", 0x10, 0, 620}, // produce LE output
|
||||
// win32/pe
|
||||
{"compress-exports", 2, 0, 630},
|
||||
{"compress-icons", 2, 0, 631},
|
||||
@@ -930,6 +1052,7 @@ static const struct mfx_option longopts[] =
|
||||
// commands
|
||||
{"best", 0x10, 0, 900}, // compress best
|
||||
{"brute", 0x10, 0, 901}, // compress best, brute force
|
||||
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
|
||||
{"fast", 0x10, 0, '1'}, // compress faster
|
||||
|
||||
// options
|
||||
@@ -939,17 +1062,20 @@ static const struct mfx_option longopts[] =
|
||||
{"silent", 0, 0, 'q'}, // quiet mode
|
||||
{"verbose", 0, 0, 'v'}, // verbose mode
|
||||
|
||||
// debug options
|
||||
{"disable-random-id",0x10, 0, 545}, // for internal debugging
|
||||
|
||||
// backup options
|
||||
{"backup", 0, 0, 'k'},
|
||||
{"keep", 0, 0, 'k'},
|
||||
{"backup", 0x10, 0, 'k'},
|
||||
{"keep", 0x10, 0, 'k'},
|
||||
{"no-backup", 0x10, 0, 541},
|
||||
|
||||
// overlay options
|
||||
{"overlay", 0x31, 0, 551}, // --overlay=
|
||||
{"skip-overlay", 0, 0, 552},
|
||||
{"no-overlay", 0, 0, 552}, // old name
|
||||
{"copy-overlay", 0, 0, 553},
|
||||
{"strip-overlay", 0, 0, 554},
|
||||
{"skip-overlay", 0x10, 0, 552},
|
||||
{"no-overlay", 0x10, 0, 552}, // old name
|
||||
{"copy-overlay", 0x10, 0, 553},
|
||||
{"strip-overlay", 0x10, 0, 554},
|
||||
|
||||
// CPU options
|
||||
{"cpu", 0x31, 0, 560}, // --cpu=
|
||||
@@ -958,18 +1084,14 @@ static const struct mfx_option longopts[] =
|
||||
{"486", 0x10, 0, 564},
|
||||
|
||||
// color options
|
||||
{"no-color", 0, 0, 512},
|
||||
{"mono", 0, 0, 513},
|
||||
{"color", 0, 0, 514},
|
||||
{"no-color", 0x10, 0, 512},
|
||||
{"mono", 0x10, 0, 513},
|
||||
{"color", 0x10, 0, 514},
|
||||
|
||||
// compression settings
|
||||
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
|
||||
|
||||
// compression runtime parameters
|
||||
{"crp-cf", 0x31, 0, 531},
|
||||
{"crp-sl", 0x31, 0, 532},
|
||||
{"crp-hl", 0x31, 0, 533},
|
||||
{"crp-pl", 0x31, 0, 534},
|
||||
{"crp-mo", 0x31, 0, 535},
|
||||
{"crp-mm", 0x31, 0, 536},
|
||||
{"crp-ms", 0x31, 0, 537},
|
||||
|
||||
// win32/pe
|
||||
{"compress-exports", 2, 0, 630},
|
||||
@@ -1093,9 +1215,25 @@ static void first_options(int argc, char **argv)
|
||||
**************************************************************************/
|
||||
|
||||
template <class T> struct TestBELE {
|
||||
static int test(void)
|
||||
static bool test(void)
|
||||
{
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
||||
struct test1_t { char a; T b; } __attribute_packed;
|
||||
struct test2_t { char a; T b[3]; } __attribute_packed;
|
||||
test1_t t1[7]; UNUSED(t1); test2_t t2[7]; UNUSED(t2);
|
||||
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
|
||||
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7*sizeof(T))
|
||||
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3*sizeof(T))
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
|
||||
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21*sizeof(T))
|
||||
#if defined(__acc_alignof)
|
||||
COMPILE_TIME_ASSERT(__acc_alignof(t1) == 1)
|
||||
COMPILE_TIME_ASSERT(__acc_alignof(t2) == 1)
|
||||
#endif
|
||||
#if 1 && !defined(xUPX_OFFICIAL_BUILD)
|
||||
T allbits; allbits = 0; allbits -= 1;
|
||||
//++allbits; allbits++; --allbits; allbits--;
|
||||
T v1; v1 = 1; v1 *= 2; v1 -= 1;
|
||||
T v2; v2 = 1;
|
||||
assert( (v1 == v2)); assert(!(v1 != v2));
|
||||
@@ -1109,7 +1247,9 @@ static int test(void)
|
||||
assert(v1 == 1); assert(v2 == 0);
|
||||
v1 <<= 1; v1 |= v2; v1 >>= 1; v2 &= v1; v2 /= v1; v2 *= v1;
|
||||
assert(v1 == 1); assert(v2 == 0);
|
||||
return (v1 ^ v2) == 1;
|
||||
if ((v1 ^ v2) != 1) return false;
|
||||
#endif
|
||||
return true;
|
||||
}};
|
||||
|
||||
|
||||
@@ -1141,12 +1281,12 @@ void upx_sanity_check(void)
|
||||
COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
|
||||
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(BE16, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(BE32, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(BE64, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(LE16, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(LE32, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(LE64, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(BE16)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(BE32)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(BE64)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(LE16)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(LE32)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(LE64)
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
|
||||
assert(strlen(UPX_VERSION_STRING4) == 4);
|
||||
@@ -1157,14 +1297,12 @@ void upx_sanity_check(void)
|
||||
assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0);
|
||||
|
||||
#if 1
|
||||
# if 1 && !defined(UPX_OFFICIAL_BUILD)
|
||||
assert(TestBELE<LE16>::test());
|
||||
assert(TestBELE<LE32>::test());
|
||||
assert(TestBELE<LE64>::test());
|
||||
assert(TestBELE<BE16>::test());
|
||||
assert(TestBELE<BE32>::test());
|
||||
assert(TestBELE<BE64>::test());
|
||||
# endif
|
||||
{
|
||||
static const unsigned char dd[32] = { 0, 0, 0, 0, 0, 0, 0,
|
||||
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
|
||||
@@ -1188,6 +1326,7 @@ void upx_sanity_check(void)
|
||||
assert(get_le24_signed(d) == -131329);
|
||||
assert(get_le32(d) == 0xfcfdfeff);
|
||||
assert(get_le32_signed(d) == -50462977);
|
||||
assert(get_le64_signed(d) == ACC_INT64_C(-506097522914230529));
|
||||
assert(find_be16(d, 2, 0xfffe) == 0);
|
||||
assert(find_le16(d, 2, 0xfeff) == 0);
|
||||
assert(find_be32(d, 4, 0xfffefdfc) == 0);
|
||||
@@ -1196,6 +1335,7 @@ void upx_sanity_check(void)
|
||||
assert(get_be16_signed(d) == 32638);
|
||||
assert(get_be24_signed(d) == 8355453);
|
||||
assert(get_be32_signed(d) == 2138996092);
|
||||
assert(get_be64_signed(d) == ACC_INT64_C(9186918263483431288));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1207,6 +1347,10 @@ void upx_sanity_check(void)
|
||||
|
||||
#if !defined(WITH_GUI)
|
||||
|
||||
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||
extern "C" { extern long _stksize; long _stksize = 256 * 1024L; }
|
||||
#endif
|
||||
|
||||
int __acc_cdecl_main main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
@@ -1220,7 +1364,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
||||
acc_wildargv(&argc, &argv);
|
||||
|
||||
upx_sanity_check();
|
||||
init_options(opt);
|
||||
opt->reset();
|
||||
|
||||
if (!argv[0] || !argv[0][0])
|
||||
argv[0] = default_argv0;
|
||||
@@ -1321,14 +1465,6 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
if (opt->cmd != CMD_COMPRESS)
|
||||
{
|
||||
// invalidate compression options
|
||||
opt->method = 0;
|
||||
opt->level = 0;
|
||||
memset(&opt->crp, 0xff, sizeof(opt->crp));
|
||||
}
|
||||
|
||||
/* check options */
|
||||
if (argc == 1)
|
||||
e_help();
|
||||
@@ -1347,7 +1483,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
||||
set_term(stdout);
|
||||
do_files(i,argc,argv);
|
||||
|
||||
#if 0 && (UPX_VERSION_HEX < 0x020000)
|
||||
#if 0 && (UPX_VERSION_HEX < 0x030000)
|
||||
{
|
||||
FILE *f = stdout;
|
||||
int fg = con_fg(f,FG_RED);
|
||||
|
||||
+4
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -209,6 +209,8 @@ void MemBuffer::alloc(unsigned size)
|
||||
}
|
||||
else
|
||||
b = p ;
|
||||
|
||||
//fill(0, b_size, (rand() & 0xff) | 1); // debug
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -38,7 +38,7 @@ class MemBuffer
|
||||
{
|
||||
public:
|
||||
MemBuffer();
|
||||
MemBuffer(unsigned size);
|
||||
explicit MemBuffer(unsigned size);
|
||||
~MemBuffer();
|
||||
|
||||
static unsigned getSizeForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
|
||||
+265
-26
@@ -2,6 +2,7 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
|
||||
@@ -37,7 +38,7 @@
|
||||
|
||||
#ifndef __ACC_H_INCLUDED
|
||||
#define __ACC_H_INCLUDED 1
|
||||
#define ACC_VERSION 20060823L
|
||||
#define ACC_VERSION 20070113L
|
||||
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
||||
# define __CYGWIN__ __CYGWIN32__
|
||||
#endif
|
||||
@@ -1169,7 +1170,7 @@ extern "C" {
|
||||
# define ACC_SIZEOF_LONG_LONG 8
|
||||
#elif (ACC_ARCH_I386 && (ACC_CC_INTELC && defined(__linux__)))
|
||||
# define ACC_SIZEOF_LONG_LONG 8
|
||||
#elif (ACC_ARCH_I386 && (ACC_CC_MWERKS || ACC_CC_PELLESC || ACC_CC_PGI))
|
||||
#elif (ACC_ARCH_I386 && (ACC_CC_MWERKS || ACC_CC_PELLESC || ACC_CC_PGI || ACC_CC_SUNPROC))
|
||||
# define ACC_SIZEOF_LONG_LONG 8
|
||||
#elif (ACC_ARCH_I386 && (ACC_CC_INTELC || ACC_CC_MSC))
|
||||
# define ACC_SIZEOF___INT64 8
|
||||
@@ -1301,7 +1302,7 @@ extern "C" {
|
||||
#elif !defined(ACC_ABI_BIG_ENDIAN) && !defined(ACC_ABI_LITTLE_ENDIAN)
|
||||
#if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
|
||||
# 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
|
||||
#elif (ACC_ARCH_M68K || ACC_ARCH_S390)
|
||||
# define ACC_ABI_BIG_ENDIAN 1
|
||||
@@ -1634,6 +1635,15 @@ extern "C" {
|
||||
# define ACC_UNUSED_LABEL(l) switch(0) case 1:goto l
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(ACC_DEFINE_UNINITIALIZED_VAR)
|
||||
# if 0
|
||||
# define ACC_DEFINE_UNINITIALIZED_VAR(type,var,init) type var
|
||||
# elif 0 && (ACC_CC_GNUC)
|
||||
# define ACC_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var
|
||||
# else
|
||||
# define ACC_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(ACC_COMPILE_TIME_ASSERT_HEADER)
|
||||
# if (ACC_CC_AZTECC || ACC_CC_ZORTECHC)
|
||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) extern int __acc_cta[1-!(e)];
|
||||
@@ -2745,6 +2755,9 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
||||
#if !defined(acc_signo_t)
|
||||
# define acc_signo_t int
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#if (ACC_BROKEN_CDECL_ALT_SYNTAX)
|
||||
typedef void __acc_cdecl_sighandler (*acc_sighandler_t)(acc_signo_t);
|
||||
#elif defined(RETSIGTYPE)
|
||||
@@ -2752,6 +2765,9 @@ typedef RETSIGTYPE (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
|
||||
#else
|
||||
typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
# if defined(ACC_CFG_NO_ACC_UA_H)
|
||||
# else
|
||||
#if (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020700ul))
|
||||
@@ -3164,6 +3180,9 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
||||
#if !defined(acc_signo_t)
|
||||
# define acc_signo_t int
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#if (ACC_BROKEN_CDECL_ALT_SYNTAX)
|
||||
typedef void __acc_cdecl_sighandler (*acc_sighandler_t)(acc_signo_t);
|
||||
#elif defined(RETSIGTYPE)
|
||||
@@ -3171,6 +3190,9 @@ typedef RETSIGTYPE (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
|
||||
#else
|
||||
typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
# if !defined(ACC_CFG_NO_ACC_UA_H)
|
||||
#if (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020700ul))
|
||||
#elif (ACC_CC_GNUC && (ACC_CC_GNUC < 0x020800ul)) && defined(__cplusplus)
|
||||
@@ -3968,32 +3990,42 @@ ACCLIB_EXTERN(void, acc_uclock_read) (acc_uclock_handle_p, acc_uclock_p);
|
||||
ACCLIB_EXTERN(double, acc_uclock_get_elapsed) (acc_uclock_handle_p, const acc_uclock_p, const acc_uclock_p);
|
||||
#endif
|
||||
ACCLIB_EXTERN(int, acc_uclock_flush_cpu_cache) (acc_uclock_handle_p, unsigned);
|
||||
typedef struct {
|
||||
struct acc_getopt_t;
|
||||
typedef struct acc_getopt_t acc_getopt_t;
|
||||
#ifndef acc_getopt_p
|
||||
#define acc_getopt_p acc_getopt_t *
|
||||
#endif
|
||||
struct acc_getopt_longopt_t;
|
||||
typedef struct acc_getopt_longopt_t acc_getopt_longopt_t;
|
||||
#ifndef acc_getopt_longopt_p
|
||||
#define acc_getopt_longopt_p acc_getopt_longopt_t *
|
||||
#endif
|
||||
struct acc_getopt_longopt_t {
|
||||
const char* name;
|
||||
int has_arg;
|
||||
int* flag;
|
||||
int val;
|
||||
} acc_getopt_longopt_t;
|
||||
#ifndef acc_getopt_longopt_p
|
||||
#define acc_getopt_longopt_p acc_getopt_longopt_t *
|
||||
#endif
|
||||
typedef struct {
|
||||
int go_argc;
|
||||
char** go_argv;
|
||||
const char* go_shortopts;
|
||||
const acc_getopt_longopt_p longopts;
|
||||
#if (ACC_BROKEN_CDECL_ALT_SYNTAX)
|
||||
int __acc_cdecl_va (*go_error)(const char *, ...);
|
||||
#else
|
||||
int (__acc_cdecl_va *go_error)(const char *, ...);
|
||||
#endif
|
||||
} acc_getopt_t;
|
||||
#ifndef acc_getopt_p
|
||||
#define acc_getopt_p acc_getopt_t *
|
||||
#endif
|
||||
ACCLIB_EXTERN(void, acc_getopt_init) (acc_getopt_p);
|
||||
ACCLIB_EXTERN(int, acc_getopt) (acc_getopt_p);
|
||||
ACCLIB_EXTERN(void, acc_getopt_close)(acc_getopt_p);
|
||||
};
|
||||
struct acc_getopt_t {
|
||||
void *user;
|
||||
char *optarg;
|
||||
void (*opterr)(acc_getopt_p, const char*, void *);
|
||||
int optind;
|
||||
int optopt;
|
||||
int errcount;
|
||||
const char* progname;
|
||||
int argc; char** argv;
|
||||
int eof; int shortpos;
|
||||
int pending_rotate_first, pending_rotate_middle;
|
||||
};
|
||||
enum { ACC_GETOPT_NO_ARG, ACC_GETOPT_REQUIRED_ARG, ACC_GETOPT_OPTIONAL_ARG, ACC_GETOPT_EXACT_ARG = 0x10 };
|
||||
enum { ACC_GETOPT_PERMUTE, ACC_GETOPT_RETURN_IN_ORDER, ACC_GETOPT_REQUIRE_ORDER };
|
||||
ACCLIB_EXTERN(void, acc_getopt_init) (acc_getopt_p g,
|
||||
int start_argc, int argc, char** argv);
|
||||
ACCLIB_EXTERN(int, acc_getopt) (acc_getopt_p g,
|
||||
const char* shortopts,
|
||||
const acc_getopt_longopt_p longopts,
|
||||
int* longind);
|
||||
typedef struct {
|
||||
acc_uint32l_t seed;
|
||||
} acc_rand31_t;
|
||||
@@ -5245,6 +5277,213 @@ ACCLIB_PUBLIC(int, acc_dos_free) (void __far* p)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#if defined(ACC_WANT_ACCLIB_GETOPT)
|
||||
# undef ACC_WANT_ACCLIB_GETOPT
|
||||
#define __ACCLIB_GETOPT_CH_INCLUDED 1
|
||||
#if !defined(ACCLIB_PUBLIC)
|
||||
# define ACCLIB_PUBLIC(r,f) r __ACCLIB_FUNCNAME(f)
|
||||
#endif
|
||||
ACCLIB_PUBLIC(void, acc_getopt_init) (acc_getopt_p g,
|
||||
int start_argc, int argc, char** argv)
|
||||
{
|
||||
memset(g, 0, sizeof(*g));
|
||||
g->argc = argc;
|
||||
g->argv = argv;
|
||||
g->pending_rotate_first = g->pending_rotate_middle = g->optind = start_argc;
|
||||
}
|
||||
static int __ACCLIB_FUNCNAME(acc_getopt_rotate) (char **p, int first, int middle, int last)
|
||||
{
|
||||
char** a; char** b;
|
||||
if (first >= middle || middle >= last) return 0;
|
||||
for (a = p + first, b = p + middle - 1; a < b; ++a, --b) {
|
||||
char* t = *a; *a = *b; *b = t;
|
||||
}
|
||||
for (a = p + middle, b = p + last - 1; a < b; ++a, --b) {
|
||||
char* t = *a; *a = *b; *b = t;
|
||||
}
|
||||
for (a = p + first, b = p + last - 1; a < b; ++a, --b) {
|
||||
char* t = *a; *a = *b; *b = t;
|
||||
}
|
||||
return middle - first;
|
||||
}
|
||||
static int __acc_getopt_x(acc_getopt_p g, int ret, int oo, int flags, const char *f, ...)
|
||||
{
|
||||
if (oo >= 0)
|
||||
g->optopt = oo;
|
||||
if (flags & 1)
|
||||
{
|
||||
if (g->shortpos == 0)
|
||||
g->optind++;
|
||||
else if (!g->argv[g->optind][++g->shortpos])
|
||||
g->optind++, g->shortpos = 0;
|
||||
}
|
||||
if (f == NULL)
|
||||
return ret;
|
||||
if (g->opterr)
|
||||
{
|
||||
#if !defined(HAVE_STDARG_H)
|
||||
g->opterr(g, f, NULL);
|
||||
#else
|
||||
va_list ap;
|
||||
va_start(ap, f);
|
||||
g->opterr(g, f, &ap);
|
||||
va_end(ap);
|
||||
#endif
|
||||
}
|
||||
g->errcount++;
|
||||
return ret;
|
||||
}
|
||||
ACCLIB_PUBLIC(int, acc_getopt) (acc_getopt_p g,
|
||||
const char* shortopts,
|
||||
const acc_getopt_longopt_p longopts,
|
||||
int* longind)
|
||||
{
|
||||
int ordering = ACC_GETOPT_PERMUTE;
|
||||
char *a;
|
||||
int has_arg = 0;
|
||||
char *arg;
|
||||
unsigned char sc;
|
||||
int i;
|
||||
if (shortopts && (*shortopts == '-' || *shortopts == '+'))
|
||||
ordering = *shortopts++ == '-' ? ACC_GETOPT_RETURN_IN_ORDER : ACC_GETOPT_REQUIRE_ORDER;
|
||||
g->optarg = NULL;
|
||||
g->optopt = '?';
|
||||
if (longind != NULL)
|
||||
*longind = -1;
|
||||
if (g->eof || g->optind >= g->argc || g->argv == NULL)
|
||||
goto acc_label_eof;
|
||||
if (g->shortpos)
|
||||
goto acc_label_next_shortopt;
|
||||
g->optind -= __ACCLIB_FUNCNAME(acc_getopt_rotate)(g->argv, g->pending_rotate_first, g->pending_rotate_middle, g->optind);
|
||||
g->pending_rotate_first = g->pending_rotate_middle = g->optind;
|
||||
if (ordering == ACC_GETOPT_PERMUTE)
|
||||
{
|
||||
while (g->optind < g->argc && !(g->argv[g->optind][0] == '-' && g->argv[g->optind][1]))
|
||||
g->optind++;
|
||||
g->pending_rotate_middle = g->optind;
|
||||
}
|
||||
if (g->optind >= g->argc)
|
||||
{
|
||||
g->optind = g->pending_rotate_first;
|
||||
acc_label_eof:
|
||||
g->optind -= __ACCLIB_FUNCNAME(acc_getopt_rotate)(g->argv, g->pending_rotate_first, g->pending_rotate_middle, g->optind);
|
||||
g->pending_rotate_first = g->pending_rotate_middle = g->optind;
|
||||
g->eof = 1;
|
||||
return -1;
|
||||
}
|
||||
a = g->argv[g->optind];
|
||||
if (strcmp(a, "--") == 0)
|
||||
{
|
||||
g->optind++;
|
||||
goto acc_label_eof;
|
||||
}
|
||||
if (!(a[0] == '-' && a[1]))
|
||||
{
|
||||
if (ordering == ACC_GETOPT_REQUIRE_ORDER)
|
||||
goto acc_label_eof;
|
||||
if (ordering == ACC_GETOPT_RETURN_IN_ORDER)
|
||||
{
|
||||
g->optarg = a;
|
||||
g->optind++;
|
||||
return 1;
|
||||
}
|
||||
__acc_getopt_x(g, -1, -1, 0, "invalid ordering %d", ordering);
|
||||
goto acc_label_eof;
|
||||
}
|
||||
if (a[1] == '-')
|
||||
{
|
||||
const acc_getopt_longopt_p lo = NULL;
|
||||
size_t match_chars;
|
||||
for (arg = a + 2; *arg && *arg != '=' && *arg != '#'; )
|
||||
++arg;
|
||||
match_chars = (size_t) (arg - (a + 2));
|
||||
for (i = 0; longopts && longopts[i].name; ++i)
|
||||
{
|
||||
size_t n = match_chars;
|
||||
size_t l = strlen(longopts[i].name);
|
||||
if (longopts[i].has_arg & ACC_GETOPT_EXACT_ARG) n = l;
|
||||
if (strncmp(a, longopts[i].name, n) != 0)
|
||||
continue;
|
||||
if (match_chars == l)
|
||||
{
|
||||
lo = &longopts[i];
|
||||
break;
|
||||
}
|
||||
else if (lo == NULL)
|
||||
lo = &longopts[i];
|
||||
else
|
||||
return __acc_getopt_x(g, '?', 0, 1, "option '%s' is ambiguous (could be '--%s' or '--%s')",
|
||||
a, lo->name, longopts[i].name);
|
||||
}
|
||||
if (lo == NULL)
|
||||
return __acc_getopt_x(g, '?', 0, 1, "unrecognized option '%s'", a);
|
||||
switch (lo->has_arg & 0x2f)
|
||||
{
|
||||
case ACC_GETOPT_OPTIONAL_ARG:
|
||||
break;
|
||||
case ACC_GETOPT_REQUIRED_ARG:
|
||||
if (*arg)
|
||||
g->optarg = arg + 1;
|
||||
else if (g->optind + 1 < g->argc)
|
||||
g->optarg = g->argv[++g->optind];
|
||||
else
|
||||
return __acc_getopt_x(g, '?', 0, 1, "option '%s' requires an argument", lo->name);
|
||||
g->optind++;
|
||||
break;
|
||||
case ACC_GETOPT_REQUIRED_ARG | 0x20:
|
||||
break;
|
||||
default:
|
||||
if (*arg)
|
||||
return __acc_getopt_x(g, '?', lo->val, 1, "option '%s' doesn't allow an argument", lo->name);
|
||||
g->optind++;
|
||||
break;
|
||||
}
|
||||
if (longind != NULL)
|
||||
*longind = (int) (lo - longopts);
|
||||
if (lo->flag != NULL)
|
||||
{
|
||||
*lo->flag = lo->val;
|
||||
return 0;
|
||||
}
|
||||
return lo->val;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *sp;
|
||||
g->shortpos = 1;
|
||||
acc_label_next_shortopt:
|
||||
a = g->argv[g->optind] + g->shortpos;
|
||||
sp = NULL; sc = (unsigned char) *a;
|
||||
if (shortopts)
|
||||
sp = strchr(shortopts, sc);
|
||||
if (!sp)
|
||||
return __acc_getopt_x(g, '?', sc, 1, "invalid option '-%c'", sc);
|
||||
if (sp[1] == ':') { has_arg++; if (sp[2] == ':') has_arg++; }
|
||||
arg = a + 1;
|
||||
switch (has_arg)
|
||||
{
|
||||
case ACC_GETOPT_OPTIONAL_ARG:
|
||||
if (*arg)
|
||||
g->optarg = arg + 1;
|
||||
g->optind++, g->shortpos = 0;
|
||||
break;
|
||||
case ACC_GETOPT_REQUIRED_ARG:
|
||||
if (*arg)
|
||||
g->optarg = arg + 1;
|
||||
else if (g->optind + 1 < g->argc)
|
||||
g->optarg = g->argv[++g->optind];
|
||||
else
|
||||
return __acc_getopt_x(g, '?', 0, 1, "option '-%c' requires an argument", sc);
|
||||
g->optind++, g->shortpos = 0;
|
||||
break;
|
||||
default:
|
||||
__acc_getopt_x(g, 0, -1, 1, NULL);
|
||||
break;
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(ACC_WANT_ACCLIB_HALLOC)
|
||||
# undef ACC_WANT_ACCLIB_HALLOC
|
||||
#define __ACCLIB_HALLOC_CH_INCLUDED 1
|
||||
@@ -6161,7 +6400,7 @@ ACCLIB_PUBLIC(acclib_handle_t, acc_get_osfhandle) (int fd)
|
||||
}
|
||||
ACCLIB_PUBLIC(int, acc_set_binmode) (int fd, int binary)
|
||||
{
|
||||
#if (ACC_ARCH_M68K && ACC_OS_TOS && defined(__MINT__))
|
||||
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||
FILE* fp; int old_binary;
|
||||
if (fd == STDIN_FILENO) fp = stdin;
|
||||
else if (fd == STDOUT_FILENO) fp = stdout;
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+16
-27
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -47,12 +47,18 @@ struct options_t {
|
||||
|
||||
// compression options
|
||||
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 filter; // preferred filter from Packer::getFilters()
|
||||
bool ultra_brute;
|
||||
bool all_methods; // try all available compression methods ?
|
||||
bool all_methods_use_lzma;
|
||||
bool all_filters; // try all available filters ?
|
||||
bool no_filter; // force no filter
|
||||
bool exact; // user requires byte-identical decompression
|
||||
|
||||
// other options
|
||||
int backup;
|
||||
@@ -70,6 +76,7 @@ struct options_t {
|
||||
// debug options
|
||||
struct {
|
||||
int debug_level;
|
||||
bool disable_random_id; // for Packer::getRandomId()
|
||||
const char *dump_stub_loader;
|
||||
char fake_stub_version[4+1]; // for internal debugging
|
||||
char fake_stub_year[4+1]; // for internal debugging
|
||||
@@ -83,32 +90,12 @@ struct options_t {
|
||||
};
|
||||
int overlay;
|
||||
|
||||
// compression runtime parameters - see struct ucl_compress_config_t
|
||||
struct crp_lzma_t {
|
||||
int dummy;
|
||||
#if 0
|
||||
unsigned pos_bits; // pb
|
||||
unsigned lit_pos_bits; // lp
|
||||
unsigned lit_context_bits; // lc
|
||||
unsigned dict_size;
|
||||
unsigned mf_passes;
|
||||
#endif
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
struct crp_ucl_t {
|
||||
unsigned max_offset;
|
||||
unsigned max_match;
|
||||
int s_level;
|
||||
int h_level;
|
||||
int p_level;
|
||||
int c_flags;
|
||||
unsigned m_size;
|
||||
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||
};
|
||||
// compression runtime parameters - see struct XXX_compress_config_t
|
||||
struct crp_t {
|
||||
crp_lzma_t crp_lzma;
|
||||
crp_ucl_t crp_ucl;
|
||||
void reset() { crp_lzma.reset(); crp_ucl.reset(); }
|
||||
lzma_compress_config_t crp_lzma;
|
||||
ucl_compress_config_t crp_ucl;
|
||||
zlib_compress_config_t crp_zlib;
|
||||
void reset() { crp_lzma.reset(); crp_ucl.reset(); crp_zlib.reset(); }
|
||||
};
|
||||
crp_t crp;
|
||||
|
||||
@@ -162,6 +149,8 @@ struct options_t {
|
||||
int strip_relocs;
|
||||
const char *keep_resource;
|
||||
} win32_pe;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
extern struct options_t *opt;
|
||||
|
||||
+62
-56
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -115,26 +115,25 @@ PackArmPe::~PackArmPe()
|
||||
|
||||
const int *PackArmPe::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
static const int m_nrv2b[] = { M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END };
|
||||
static const int m_nrv2e[] = { M_NRV2E_8, M_NRV2B_8, M_LZMA, M_END };
|
||||
static const int m_all[] = { M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END };
|
||||
static const int m_lzma[] = { M_LZMA, M_END };
|
||||
static const int m_nrv2b[] = { M_NRV2B_8, M_END };
|
||||
static const int m_nrv2e[] = { M_NRV2E_8, M_END };
|
||||
|
||||
if (!use_thumb_stub)
|
||||
return getDefaultCompressionMethods_8(method, level);
|
||||
|
||||
if (M_IS_NRV2B(method))
|
||||
return m_nrv2b;
|
||||
if (M_IS_NRV2E(method))
|
||||
return m_nrv2e;
|
||||
if (M_IS_LZMA(method))
|
||||
return m_lzma;
|
||||
if (method == M_ALL) return m_all;
|
||||
if (M_IS_LZMA(method)) return m_lzma;
|
||||
if (M_IS_NRV2B(method)) return m_nrv2b;
|
||||
if (M_IS_NRV2E(method)) return m_nrv2e;
|
||||
return m_nrv2e;
|
||||
}
|
||||
|
||||
|
||||
const int *PackArmPe::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0x50, -1 };
|
||||
static const int filters[] = { 0x50, FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -292,7 +291,7 @@ unsigned PackArmPe::processImports() // pass 1
|
||||
|
||||
unsigned k32namepos = ptr_diff(dllnames,oimpdlls);
|
||||
|
||||
memcpy(importednames, llgpa, ALIGN_UP(sizeof(llgpa), 2));
|
||||
memcpy(importednames, llgpa, ALIGN_UP((unsigned) sizeof(llgpa), 2u));
|
||||
strcpy(dllnames,kernel32dll);
|
||||
im->dllname = k32namepos;
|
||||
im->iat = ptr_diff(ordinals,oimpdlls);
|
||||
@@ -440,7 +439,7 @@ unsigned PackArmPe::processImports() // pass 1
|
||||
|
||||
void PackArmPe::processTls(Interval *) // pass 1
|
||||
{
|
||||
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4)) == 0)
|
||||
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4u)) == 0)
|
||||
return;
|
||||
|
||||
// never should happen on wince
|
||||
@@ -462,10 +461,10 @@ bool PackArmPe::canPack()
|
||||
}
|
||||
|
||||
|
||||
int PackArmPe::buildLoader(const Filter *ft)
|
||||
void PackArmPe::buildLoader(const Filter *ft)
|
||||
{
|
||||
const unsigned char *loader = use_thumb_stub ? nrv_loader_thumb : nrv_loader_arm;
|
||||
unsigned size = use_thumb_stub ? sizeof(nrv_loader_thumb) : sizeof(nrv_loader_arm);
|
||||
const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe;
|
||||
unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe);
|
||||
|
||||
// prepare loader
|
||||
initLoader(loader, size);
|
||||
@@ -503,8 +502,6 @@ int PackArmPe::buildLoader(const Filter *ft)
|
||||
addLoader("+40C,LZMA_DECODE,LZMA_DEC10", NULL);
|
||||
|
||||
addLoader("IDENTSTR,UPX1HEAD", NULL);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -557,7 +554,7 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
if (ih.entry && ih.entry < rvamin)
|
||||
throwCantPack("run a virus scanner on this file!");
|
||||
if (!opt->force && ih.subsystem == 1)
|
||||
throwCantPack("subsystem `native' is not supported (try --force)");
|
||||
throwCantPack("subsystem 'native' is not supported (try --force)");
|
||||
if (ih.filealign < 0x200)
|
||||
throwCantPack("filealign < 0x200 is not yet supported");
|
||||
|
||||
@@ -635,7 +632,7 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
|
||||
//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;
|
||||
if (ih.codebase == ih.database
|
||||
|| ih.codebase + ih.codesize > ih.imagesize
|
||||
@@ -700,20 +697,20 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
ft.buf_len = ih.codesize;
|
||||
ft.addvalue = ih.codebase - rvamin;
|
||||
// compress
|
||||
int strategy = allow_filter ? 0 : -3;
|
||||
int filter_strategy = allow_filter ? 0 : -3;
|
||||
|
||||
// disable filters for files with broken headers
|
||||
if (ih.codebase + ih.codesize > ph.u_len)
|
||||
{
|
||||
ft.buf_len = 1;
|
||||
strategy = -3;
|
||||
filter_strategy = -3;
|
||||
}
|
||||
|
||||
// limit stack size needed for runtime decompression
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 2048, strategy,
|
||||
NULL, &cconf, ih.codebase, rvamin);
|
||||
compressWithFilters(&ft, 2048, &cconf, filter_strategy,
|
||||
ih.codebase, rvamin, 0, NULL, 0);
|
||||
// info: see buildLoader()
|
||||
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
|
||||
/*
|
||||
@@ -729,13 +726,11 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
getLoaderSection("UPX1HEAD",(int*)&ic);
|
||||
identsize += ic;
|
||||
|
||||
pe_section_t osection[3];
|
||||
pe_section_t osection[4];
|
||||
// section 0 : bss
|
||||
// 1 : [ident + header] + packed_data + unpacker + tls
|
||||
// 2 : not compressed data
|
||||
|
||||
// section 2 should start with the resource data, because lots of lame
|
||||
// windoze codes assume that resources starts on the beginning of a section
|
||||
// 3 : resource data -- wince 5 needs a new section for this
|
||||
|
||||
// identsplit - number of ident + (upx header) bytes to put into the PE header
|
||||
int identsplit = pe_offset + sizeof(osection) + sizeof(oh);
|
||||
@@ -750,7 +745,7 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
const unsigned c_len = ((ph.c_len + ic) & 15) == 0 ? ph.c_len : ph.c_len + 16 - ((ph.c_len + ic) & 15);
|
||||
obuf.clear(ph.c_len, c_len - ph.c_len);
|
||||
|
||||
const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4) + sotls;
|
||||
const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4u) + sotls;
|
||||
const unsigned s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1;
|
||||
|
||||
const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1;
|
||||
@@ -773,7 +768,7 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
memset(osection,0,sizeof(osection));
|
||||
|
||||
oh.entry = upxsection;
|
||||
oh.objects = 3;
|
||||
oh.objects = 4;
|
||||
oh.chksum = 0;
|
||||
|
||||
// fill the data directory
|
||||
@@ -802,12 +797,6 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
ODSIZE(PEDIR_RELOC) = soxrelocs;
|
||||
ic += soxrelocs;
|
||||
|
||||
if (soresources)
|
||||
processResources(&res,ic);
|
||||
ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0;
|
||||
ODSIZE(PEDIR_RESOURCE) = soresources;
|
||||
ic += soresources;
|
||||
|
||||
processImports(ic, linker->getSymbolOffset("IATT") + upxsection);
|
||||
ODADDR(PEDIR_IMPORT) = ic;
|
||||
ODSIZE(PEDIR_IMPORT) = soimpdlls;
|
||||
@@ -823,7 +812,15 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
}
|
||||
ic += soexport;
|
||||
|
||||
const unsigned onam = ncsection + soxrelocs + soresources + ih.imagebase;
|
||||
ic = (ic + oam1) &~ oam1;
|
||||
const unsigned res_start = ic;
|
||||
if (soresources)
|
||||
processResources(&res,ic);
|
||||
ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0;
|
||||
ODSIZE(PEDIR_RESOURCE) = soresources;
|
||||
ic += soresources;
|
||||
|
||||
const unsigned onam = ncsection + soxrelocs + ih.imagebase;
|
||||
linker->defineSymbol("start_of_dll_names", onam);
|
||||
linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
|
||||
linker->defineSymbol("start_of_relocs", crelocs + rvamin + ih.imagebase);
|
||||
@@ -835,54 +832,52 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
linker->defineSymbol("compressed_length", ph.c_len);
|
||||
linker->defineSymbol("start_of_compressed", ih.imagebase + s1addr + identsize - identsplit);
|
||||
defineDecompressorSymbols();
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
// this is computed here, because soxrelocs changes some lines above
|
||||
const unsigned ncsize = soxrelocs + soresources + soimpdlls + soexport;
|
||||
const unsigned ncsize = soxrelocs + soimpdlls + soexport;
|
||||
const unsigned fam1 = oh.filealign - 1;
|
||||
|
||||
// fill the sections
|
||||
strcpy(osection[0].name,"UPX0");
|
||||
strcpy(osection[1].name,"UPX1");
|
||||
// after some windoze debugging I found that the name of the sections
|
||||
// DOES matter :( .rsrc is used by oleaut32.dll (TYPELIBS)
|
||||
// and because of this lame dll, the resource stuff must be the
|
||||
// first in the 3rd section - the author of this dll seems to be
|
||||
// too idiot to use the data directories... M$ suxx 4 ever!
|
||||
// ... even worse: exploder.exe in NiceTry also depends on this to
|
||||
// locate version info
|
||||
|
||||
strcpy(osection[2].name,soresources ? ".rsrc" : "UPX2");
|
||||
strcpy(osection[2].name, "UPX2");
|
||||
strcpy(osection[3].name, ".rsrc");
|
||||
|
||||
osection[0].vaddr = rvamin;
|
||||
osection[1].vaddr = s1addr;
|
||||
osection[2].vaddr = ncsection;
|
||||
osection[3].vaddr = res_start;
|
||||
|
||||
osection[0].size = 0;
|
||||
osection[1].size = (s1size + fam1) &~ fam1;
|
||||
osection[2].size = (ncsize + fam1) &~ fam1;
|
||||
osection[3].size = (soresources + fam1) &~ fam1;
|
||||
|
||||
osection[0].vsize = osection[1].vaddr - osection[0].vaddr;
|
||||
//osection[1].vsize = (osection[1].size + oam1) &~ oam1;
|
||||
//osection[2].vsize = (osection[2].size + oam1) &~ oam1;
|
||||
osection[1].vsize = osection[1].size;
|
||||
osection[2].vsize = osection[2].size;
|
||||
osection[3].vsize = osection[3].size;
|
||||
|
||||
osection[0].rawdataptr = 0;
|
||||
osection[1].rawdataptr = (pe_offset + sizeof(oh) + sizeof(osection) + fam1) &~ fam1;
|
||||
osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size;
|
||||
osection[3].rawdataptr = osection[2].rawdataptr + osection[2].size;
|
||||
|
||||
osection[0].flags = (unsigned) (PEFL_BSS|PEFL_EXEC|PEFL_WRITE|PEFL_READ);
|
||||
osection[1].flags = (unsigned) (PEFL_DATA|PEFL_EXEC|PEFL_WRITE|PEFL_READ);
|
||||
osection[2].flags = (unsigned) (PEFL_DATA|PEFL_READ);
|
||||
osection[3].flags = (unsigned) (PEFL_DATA|PEFL_READ);
|
||||
|
||||
oh.imagesize = (osection[2].vaddr + osection[2].vsize + oam1) &~ oam1;
|
||||
oh.imagesize = (osection[3].vaddr + osection[3].vsize + oam1) &~ oam1;
|
||||
oh.bsssize = osection[0].vsize;
|
||||
oh.datasize = osection[2].vsize;
|
||||
oh.datasize = osection[2].vsize + osection[3].vsize;
|
||||
oh.database = osection[2].vaddr;
|
||||
oh.codesize = osection[1].vsize;
|
||||
oh.codebase = osection[1].vaddr;
|
||||
@@ -900,6 +895,11 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
|
||||
infoHeader("[Writing compressed file]");
|
||||
|
||||
if (soresources == 0)
|
||||
{
|
||||
oh.objects = 3;
|
||||
memset(&osection[3], 0, sizeof(osection[3]));
|
||||
}
|
||||
// write loader + compressed file
|
||||
fo->write(&oh,sizeof(oh));
|
||||
fo->write(osection,sizeof(osection));
|
||||
@@ -920,14 +920,17 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
if ((ic = fo->getBytesWritten() & 3) != 0)
|
||||
fo->write(ibuf,4 - ic);
|
||||
fo->write(otls,sotls);
|
||||
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
|
||||
if ((ic = fo->getBytesWritten() & fam1) != 0)
|
||||
fo->write(ibuf,oh.filealign - ic);
|
||||
fo->write(oxrelocs,soxrelocs);
|
||||
fo->write(oresources,soresources);
|
||||
fo->write(oimpdlls,soimpdlls);
|
||||
fo->write(oexport,soexport);
|
||||
|
||||
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
|
||||
if ((ic = fo->getBytesWritten() & fam1) != 0)
|
||||
fo->write(ibuf,oh.filealign - ic);
|
||||
|
||||
fo->write(oresources,soresources);
|
||||
if ((ic = fo->getBytesWritten() & fam1) != 0)
|
||||
fo->write(ibuf,oh.filealign - ic);
|
||||
|
||||
#if 0
|
||||
@@ -970,7 +973,7 @@ int PackArmPe::canUnpack()
|
||||
fi->readx(isection,sizeof(pe_section_t)*objs);
|
||||
if (ih.objects < 3)
|
||||
return -1;
|
||||
bool is_packed = (ih.objects == 3 &&
|
||||
bool is_packed = ((ih.objects == 3 || ih.objects == 4) &&
|
||||
(IDSIZE(15) || ih.entry > isection[1].vaddr));
|
||||
bool found_ph = false;
|
||||
if (memcmp(isection[0].name,"UPX",3) == 0)
|
||||
@@ -1024,7 +1027,8 @@ int PackArmPe::canUnpack()
|
||||
|
||||
void PackArmPe::rebuildImports(upx_byte *& extrainfo)
|
||||
{
|
||||
if (ODADDR(PEDIR_IMPORT) == 0)
|
||||
if (ODADDR(PEDIR_IMPORT) == 0
|
||||
|| ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
|
||||
return;
|
||||
|
||||
// const upx_byte * const idata = obuf + get_le32(extrainfo);
|
||||
@@ -1042,6 +1046,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
|
||||
for (p = idata; get_le32(p) != 0; ++p)
|
||||
{
|
||||
const upx_byte *dname = get_le32(p) + import;
|
||||
ICHECK(dname, 1);
|
||||
const unsigned dlen = strlen(dname);
|
||||
ICHECK(dname, dlen + 1);
|
||||
|
||||
@@ -1054,7 +1059,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
|
||||
else
|
||||
p += 5;
|
||||
}
|
||||
sdllnames = ALIGN_UP(sdllnames,2);
|
||||
sdllnames = ALIGN_UP(sdllnames,2u);
|
||||
|
||||
upx_byte * const Obuf = obuf - rvamin;
|
||||
import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
|
||||
@@ -1067,6 +1072,7 @@ void PackArmPe::rebuildImports(upx_byte *& extrainfo)
|
||||
{
|
||||
// restore the name of the dll
|
||||
const upx_byte *dname = get_le32(p) + import;
|
||||
ICHECK(dname, 1);
|
||||
const unsigned dlen = strlen(dname);
|
||||
ICHECK(dname, dlen + 1);
|
||||
|
||||
|
||||
+5
-4
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -39,9 +39,10 @@ class PackArmPe : public PeFile
|
||||
|
||||
public:
|
||||
PackArmPe(InputFile *f);
|
||||
~PackArmPe();
|
||||
virtual ~PackArmPe();
|
||||
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
||||
virtual const char *getName() const { return "arm/pe"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "arm-wince.pe"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -51,7 +52,7 @@ public:
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
virtual unsigned processImports();
|
||||
|
||||
+13
-19
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -45,16 +45,11 @@ static const
|
||||
|
||||
const int *PackCom::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
static const int m_nrv2b[] = { M_NRV2B_LE16, -1 };
|
||||
if (M_IS_NRV2B(method))
|
||||
return m_nrv2b;
|
||||
static const int m_nrv2b[] = { M_NRV2B_LE16, M_END };
|
||||
#if 0
|
||||
// NOT IMPLEMENTED
|
||||
static const int m_nrv2d[] = { M_NRV2D_LE16, -1 };
|
||||
if (M_IS_NRV2D(method))
|
||||
return m_nrv2d;
|
||||
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
|
||||
#endif
|
||||
UNUSED(level);
|
||||
UNUSED(method); UNUSED(level);
|
||||
return m_nrv2b;
|
||||
}
|
||||
|
||||
@@ -63,7 +58,7 @@ const int *PackCom::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -101,7 +96,7 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
{
|
||||
const int e_len = getLoaderSectionStart("COMCUTPO");
|
||||
const int d_len = lsize - e_len;
|
||||
assert(e_len > 0 && e_len < 256);
|
||||
assert(e_len > 0 && e_len < 128);
|
||||
assert(d_len > 0 && d_len < 256);
|
||||
|
||||
const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100;
|
||||
@@ -116,9 +111,10 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
linker->defineSymbol("bytes_to_copy", ph.c_len + lsize);
|
||||
linker->defineSymbol("copy_source", ph.c_len + lsize + 0x100);
|
||||
linker->defineSymbol("copy_destination", upper_end);
|
||||
linker->defineSymbol("COMCUTPO", ph.u_len + ph.overlap_overhead);
|
||||
linker->defineSymbol("neg_e_len", 0 - e_len);
|
||||
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead);
|
||||
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
loader = getLoader();
|
||||
|
||||
// some day we could use the relocation stuff for patchPackHeader too
|
||||
@@ -135,9 +131,9 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
}
|
||||
|
||||
|
||||
int PackCom::buildLoader(const Filter *ft)
|
||||
void PackCom::buildLoader(const Filter *ft)
|
||||
{
|
||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
||||
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
|
||||
addLoader("COMMAIN1",
|
||||
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
||||
"COMPSHDI",
|
||||
@@ -154,8 +150,6 @@ int PackCom::buildLoader(const Filter *ft)
|
||||
assert(ft->calls > 0);
|
||||
addFilter16(ft->id);
|
||||
}
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +197,7 @@ void PackCom::pack(OutputFile *fo)
|
||||
ft.addvalue = getCallTrickOffset();
|
||||
// compress
|
||||
const unsigned overlap_range = ph.u_len < 0xFE00 - ft.addvalue ? 32 : 0;
|
||||
compressWithFilters(&ft, overlap_range);
|
||||
compressWithFilters(&ft, overlap_range, NULL_cconf);
|
||||
|
||||
const int lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
|
||||
+5
-4
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -38,10 +38,11 @@ class PackCom : public Packer
|
||||
{
|
||||
typedef Packer super;
|
||||
public:
|
||||
PackCom(InputFile *f) : super(f) { }
|
||||
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_DOS_COM; }
|
||||
virtual const char *getName() const { return "dos/com"; }
|
||||
virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.com" : "i286-dos16.com"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -56,7 +57,7 @@ protected:
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
||||
virtual void addFilter16(int filter_id);
|
||||
};
|
||||
|
||||
+24
-47
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -46,13 +46,14 @@ static const
|
||||
PackDjgpp2::PackDjgpp2(InputFile *f) :
|
||||
super(f), coff_offset(0)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40);
|
||||
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8);
|
||||
COMPILE_TIME_ASSERT(sizeof(stubify_stub) == 2048);
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(external_scnhdr_t, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(coff_header_t, char)
|
||||
COMPILE_TIME_ASSERT(STUBIFY_STUB_ADLER32 == 0xbf689ba8);
|
||||
COMPILE_TIME_ASSERT(STUBIFY_STUB_CRC32 == 0x2ae982b2);
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
|
||||
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(external_scnhdr_t)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(coff_header_t)
|
||||
COMPILE_TIME_ASSERT(sizeof(stub_i386_dos32_djgpp2_stubify) == 2048)
|
||||
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_ADLER32 == 0xbf689ba8)
|
||||
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
|
||||
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
|
||||
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||
}
|
||||
@@ -67,8 +68,9 @@ const int *PackDjgpp2::getCompressionMethods(int method, int level) const
|
||||
const int *PackDjgpp2::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||
-1 };
|
||||
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
||||
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -89,16 +91,16 @@ Linker* PackDjgpp2::newLinker() const
|
||||
}
|
||||
|
||||
|
||||
int PackDjgpp2::buildLoader(const Filter *ft)
|
||||
void PackDjgpp2::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
|
||||
addLoader("IDENTSTR,DJ2MAIN1",
|
||||
ft->id ? "DJCALLT1" : "",
|
||||
"DJ2MAIN2",
|
||||
ph.method == M_LZMA ? "LZMA_INIT_STACK" : "",
|
||||
ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
|
||||
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
|
||||
getDecompressorSections(),
|
||||
ph.method == M_LZMA ? "LZMA_DONE_STACK" : "",
|
||||
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
|
||||
"DJ2BSS00",
|
||||
NULL
|
||||
);
|
||||
@@ -109,8 +111,6 @@ int PackDjgpp2::buildLoader(const Filter *ft)
|
||||
addFilter32(ft->id);
|
||||
}
|
||||
addLoader("DJRETURN,+40C,UPX1HEAD", NULL);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -130,8 +130,8 @@ void PackDjgpp2::handleStub(OutputFile *fo)
|
||||
else
|
||||
{
|
||||
// "stubify" stub
|
||||
info("Adding stub: %ld bytes", (long)sizeof(stubify_stub));
|
||||
fo->write(stubify_stub, sizeof(stubify_stub));
|
||||
info("Adding stub: %ld bytes", (long)sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,29 +235,6 @@ void PackDjgpp2::stripDebug()
|
||||
}
|
||||
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
return false;
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
|
||||
#if 0
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
int const mru = ph.n_mru ? 1+ ph.n_mru : 0;
|
||||
if (mru && mru!=256) {
|
||||
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||
patch_le32(0x80 + (char *)loader, lsize - 0x80, "NMRU", mru - is_pwr2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
@@ -326,7 +303,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
// limit stack size needed for runtime decompression
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||
compressWithFilters(&ft, 512, &cconf);
|
||||
|
||||
// patch coff header #2
|
||||
const unsigned lsize = getLoaderSize();
|
||||
@@ -335,7 +312,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
data->size = ph.c_len; // new size of .data
|
||||
|
||||
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
|
||||
stack = ALIGN_UP(stack, 16);
|
||||
stack = ALIGN_UP(stack, 16u);
|
||||
if (bss->size < stack) // give it a .bss
|
||||
bss->size = stack;
|
||||
|
||||
@@ -351,7 +328,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
|
||||
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
|
||||
linker->defineSymbol("start_of_compressed", data->vaddr);
|
||||
defineFilterSymbols(linker, &ft);
|
||||
defineFilterSymbols(&ft);
|
||||
|
||||
// we should not overwrite our decompressor during unpacking
|
||||
// the original coff header (which is put just before the
|
||||
@@ -369,7 +346,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
data->size = ALIGN_UP(data->size, 4);
|
||||
|
||||
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
|
||||
// prepare loader
|
||||
MemBuffer loader(lsize);
|
||||
|
||||
+4
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
virtual int getVersion() const { return 14; }
|
||||
virtual int getFormat() const { return UPX_F_DJGPP2_COFF; }
|
||||
virtual const char *getName() const { return "djgpp2/coff"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-dos32.djgpp2"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -59,7 +60,7 @@ protected:
|
||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||
unsigned range = 0,
|
||||
unsigned upper_limit = ~0u) const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
long coff_offset;
|
||||
|
||||
+247
-241
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -31,15 +31,34 @@
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// Some ELF type definitinons
|
||||
// N_Elf
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_Elf {
|
||||
|
||||
// integral types
|
||||
template <class THalf, class TWord, class TXword, class TAddr, class TOff>
|
||||
struct ElfITypes
|
||||
{
|
||||
typedef THalf Half;
|
||||
typedef TWord Word;
|
||||
typedef TXword Xword;
|
||||
typedef TAddr Addr;
|
||||
typedef TOff Off;
|
||||
typedef THalf Section;
|
||||
typedef THalf Versym;
|
||||
};
|
||||
|
||||
|
||||
// The ELF file header. This appears at the start of every ELF file.
|
||||
template <class Word, class Addr, class Off, class Half>
|
||||
template <class TElfITypes>
|
||||
struct Ehdr
|
||||
{
|
||||
typedef typename TElfITypes::Half Half;
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
unsigned char e_ident[16]; /* Magic number and other info */
|
||||
Half e_type; /* Object file type */
|
||||
Half e_machine; /* Architecture */
|
||||
@@ -55,76 +74,57 @@ struct Ehdr
|
||||
Half e_shnum; /* Section header table entry count */
|
||||
Half e_shstrndx; /* Section header string table index */
|
||||
|
||||
enum { // e_ident[]
|
||||
EI_CLASS = 4,
|
||||
EI_DATA = 5, /* Data encoding */
|
||||
EI_VERSION = 6,
|
||||
EI_OSABI = 7,
|
||||
EI_ABIVERSION = 8,
|
||||
};
|
||||
enum { // e_ident[EI_CLASS]
|
||||
ELFCLASS32 = 1, /* 32-bit objects */
|
||||
ELFCLASS64 = 2, /* 64-bit objects */
|
||||
};
|
||||
enum { // e_ident[EI_DATA]
|
||||
ELFDATA2LSB = 1, /* 2's complement, little endian */
|
||||
ELFDATA2MSB = 2 /* 2's complement, big endian */
|
||||
};
|
||||
enum { // e_ident[EI_OSABI]
|
||||
ELFOSABI_NONE = 0,
|
||||
ELFOSABI_NETBSD = 2,
|
||||
ELFOSABI_LINUX = 3,
|
||||
ELFOSABI_FREEBSD = 9,
|
||||
ELFOSABI_OPENBSD = 12,
|
||||
ELFOSABI_ARM = 97
|
||||
};
|
||||
enum { // e_type
|
||||
ET_NONE = 0, /* No file type */
|
||||
ET_REL = 1, /* Relocatable file */
|
||||
ET_EXEC = 2, /* Executable file */
|
||||
ET_DYN = 3, /* Shared object file */
|
||||
ET_CORE = 4, /* Core file */
|
||||
};
|
||||
enum { // e_machine
|
||||
EM_386 = 3,
|
||||
EM_PPC = 20,
|
||||
EM_PPC64 = 21,
|
||||
EM_ARM = 40,
|
||||
EM_X86_64 = 62,
|
||||
};
|
||||
enum { // e_version
|
||||
EV_CURRENT = 1,
|
||||
};
|
||||
# define WANT_EHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
template <class Word, class Addr>
|
||||
template <class TElfITypes>
|
||||
struct Dyn
|
||||
{
|
||||
Word d_tag;
|
||||
typedef typename TElfITypes::Xword Xword;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
|
||||
Xword d_tag;
|
||||
Addr d_val;
|
||||
|
||||
enum { // d_tag
|
||||
DT_NULL = 0, /* End flag */
|
||||
DT_NEEDED = 1, /* Name of needed library */
|
||||
DT_HASH = 4, /* Hash table of symbol names */
|
||||
DT_STRTAB = 5, /* String table */
|
||||
DT_SYMTAB = 6, /* Symbol table */
|
||||
DT_STRSZ = 10, /* Sizeof string table */
|
||||
};
|
||||
# define WANT_DYN_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
template <class TElfITypes>
|
||||
struct External_Note
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
|
||||
Word xn_namesz; // includes terminating '\0'
|
||||
Word xn_datasz;
|
||||
Word xn_type;
|
||||
//char xn_name[N]; // terminate with '\0'
|
||||
//char xn_data[M]; // aligned to 0 mod 4
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
} // namespace N_Elf
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// N_Elf32
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_Elf32 {
|
||||
|
||||
// Program segment header.
|
||||
template <class Word, class Addr, class Off>
|
||||
template <class TElfITypes>
|
||||
struct Phdr
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
Word p_type; /* Segment type */
|
||||
Off p_offset; /* Segment file offset */
|
||||
Addr p_vaddr; /* Segment virtual address */
|
||||
@@ -134,25 +134,19 @@ struct Phdr
|
||||
Word p_flags; /* Segment flags */
|
||||
Word p_align; /* Segment alignment */
|
||||
|
||||
enum { // p_type
|
||||
PT_LOAD = 1, /* Loadable program segment */
|
||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||
PT_INTERP = 3, /* Name of program interpreter */
|
||||
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
|
||||
PT_PHDR = 6, /* Entry for header table itself */
|
||||
};
|
||||
|
||||
enum { // p_flags
|
||||
PF_X = 1, /* Segment is executable */
|
||||
PF_W = 2, /* Segment is writable */
|
||||
PF_R = 4, /* Segment is readable */
|
||||
};
|
||||
# define WANT_PHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
template <class Word, class Addr, class Off>
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Shdr
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
Word sh_name; /* Section name (string tbl index) */
|
||||
Word sh_type; /* Section type */
|
||||
Word sh_flags; /* Section flags */
|
||||
@@ -164,94 +158,53 @@ struct Shdr
|
||||
Word sh_addralign; /* Section alignment */
|
||||
Word sh_entsize; /* Entry size if section holds table */
|
||||
|
||||
enum { // sh_type
|
||||
SHT_NULL = 0, /* Section header table entry unused */
|
||||
SHT_PROGBITS = 1, /* Program data */
|
||||
SHT_SYMTAB = 2, /* Symbol table */
|
||||
SHT_STRTAB = 3, /* String table */
|
||||
SHT_RELA = 4, /* Relocation entries with addends */
|
||||
SHT_HASH = 5, /* Symbol hash table */
|
||||
SHT_DYNAMIC = 6, /* Dynamic linking information */
|
||||
SHT_NOTE = 7, /* Notes */
|
||||
SHT_NOBITS = 8, /* Program space with no data (bss) */
|
||||
SHT_REL = 9, /* Relocation entries, no addends */
|
||||
SHT_SHLIB = 10, /* Reserved */
|
||||
SHT_DYNSYM = 11, /* Dynamic linker symbol table */
|
||||
/* 12, 13 hole */
|
||||
SHT_INIT_ARRAY = 14, /* Array of constructors */
|
||||
SHT_FINI_ARRAY = 15, /* Array of destructors */
|
||||
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
|
||||
SHT_GROUP = 17, /* Section group */
|
||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
|
||||
};
|
||||
|
||||
enum { // sh_flags
|
||||
SHF_WRITE = (1 << 0), /* Writable */
|
||||
SHF_ALLOC = (1 << 1), /* Occupies memory during execution */
|
||||
SHF_EXECINSTR = (1 << 2), /* Executable */
|
||||
SHF_MERGE = (1 << 4), /* Might be merged */
|
||||
SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */
|
||||
SHF_INFO_LINK = (1 << 6), /* `sh_info' contains SHT index */
|
||||
SHF_LINK_ORDER = (1 << 7), /* Preserve order after combining */
|
||||
};
|
||||
# define WANT_SHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
template <class TT16, class TT32>
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Sym
|
||||
{
|
||||
TT32 st_name; /* symbol name (index into string table) */
|
||||
TT32 st_value; /* symbol value */
|
||||
TT32 st_size; /* symbol size */
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Section Section;
|
||||
|
||||
Word st_name; /* symbol name (index into string table) */
|
||||
Addr st_value; /* symbol value */
|
||||
Word st_size; /* symbol size */
|
||||
unsigned char st_info; /* symbol type and binding */
|
||||
unsigned char st_other; /* symbol visibility */
|
||||
TT16 st_shndx; /* section index */
|
||||
Section st_shndx; /* section index */
|
||||
|
||||
unsigned int st_bind(unsigned int x) const { return 0xf & (x>>4); }
|
||||
unsigned int st_type(unsigned int x) const { return 0xf & x ; }
|
||||
unsigned char St_info(unsigned bind, unsigned type) const { return (bind<<4) + (0xf & type); }
|
||||
# define WANT_SYM_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
|
||||
enum { // st_bind (high 4 bits of st_info)
|
||||
STB_LOCAL = 0, /* Local symbol */
|
||||
STB_GLOBAL = 1, /* Global symbol */
|
||||
STB_WEAK = 2, /* Weak symbol */
|
||||
};
|
||||
|
||||
enum { // st_type (low 4 bits of st_info)
|
||||
STT_NOTYPE = 0, /* Symbol type is unspecified */
|
||||
STT_OBJECT = 1, /* Symbol is a data object */
|
||||
STT_FUNC = 2, /* Symbol is a code object */
|
||||
STT_SECTION = 3, /* Symbol associated with a section */
|
||||
STT_FILE = 4, /* Symbol's name is file name */
|
||||
STT_COMMON = 5, /* Symbol is a common data object */
|
||||
STT_TLS = 6, /* Symbol is thread-local data object*/
|
||||
};
|
||||
|
||||
enum { // st_other (visibility)
|
||||
STV_DEFAULT = 0, /* Default symbol visibility rules */
|
||||
STV_INTERNAL = 1, /* Processor specific hidden class */
|
||||
STV_HIDDEN = 2, /* Sym unavailable in other modules */
|
||||
STV_PROTECTED= 3, /* Not preemptible, not exported */
|
||||
};
|
||||
|
||||
enum { // st_shndx
|
||||
SHN_UNDEF = 0, /* Undefined section */
|
||||
SHN_ABS = 0xfff1, /* Associated symbol is absolute */
|
||||
SHN_COMMON = 0xfff2, /* Associated symbol is common */
|
||||
};
|
||||
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
|
||||
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
|
||||
static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
} // namespace N_Elf32
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// N_Elf64
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_Elf64 {
|
||||
|
||||
// Program segment header.
|
||||
template <class Word, class Xword, class Addr, class Off>
|
||||
template <class TElfITypes>
|
||||
struct Phdr
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Xword Xword;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
Word p_type; /* Segment type */
|
||||
Word p_flags; /* Segment flags */
|
||||
Off p_offset; /* Segment file offset */
|
||||
@@ -261,24 +214,20 @@ struct Phdr
|
||||
Xword p_memsz; /* Segment size in memory */
|
||||
Xword p_align; /* Segment alignment */
|
||||
|
||||
enum { // p_type
|
||||
PT_LOAD = 1, /* Loadable program segment */
|
||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||
PT_INTERP = 3, /* Name of program interpreter */
|
||||
PT_PHDR = 6, /* Entry for header table itself */
|
||||
};
|
||||
|
||||
enum { // p_flags
|
||||
PF_X = 1, /* Segment is executable */
|
||||
PF_W = 2, /* Segment is writable */
|
||||
PF_R = 4, /* Segment is readable */
|
||||
};
|
||||
# define WANT_PHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
template <class Word, class Xword, class Addr, class Off>
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Shdr
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Xword Xword;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
Word sh_name; /* Section name (string tbl index) */
|
||||
Word sh_type; /* Section type */
|
||||
Xword sh_flags; /* Section flags */
|
||||
@@ -290,115 +239,172 @@ struct Shdr
|
||||
Xword sh_addralign; /* Section alignment */
|
||||
Xword sh_entsize; /* Entry size if section holds table */
|
||||
|
||||
enum { // sh_type
|
||||
SHT_NULL = 0, /* Section header table entry unused */
|
||||
SHT_PROGBITS = 1, /* Program data */
|
||||
SHT_SYMTAB = 2, /* Symbol table */
|
||||
SHT_STRTAB = 3, /* String table */
|
||||
SHT_RELA = 4, /* Relocation entries with addends */
|
||||
SHT_HASH = 5, /* Symbol hash table */
|
||||
SHT_DYNAMIC = 6, /* Dynamic linking information */
|
||||
SHT_NOTE = 7, /* Notes */
|
||||
SHT_NOBITS = 8, /* Program space with no data (bss) */
|
||||
SHT_REL = 9, /* Relocation entries, no addends */
|
||||
SHT_SHLIB = 10, /* Reserved */
|
||||
SHT_DYNSYM = 11, /* Dynamic linker symbol table */
|
||||
/* 12, 13 hole */
|
||||
SHT_INIT_ARRAY = 14, /* Array of constructors */
|
||||
SHT_FINI_ARRAY = 15, /* Array of destructors */
|
||||
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
|
||||
SHT_GROUP = 17, /* Section group */
|
||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
|
||||
};
|
||||
# define WANT_SHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Sym
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Xword Xword;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Section Section;
|
||||
|
||||
Word st_name; /* symbol name (index into string table) */
|
||||
unsigned char st_info; /* symbol type and binding */
|
||||
unsigned char st_other; /* symbol visibility */
|
||||
Section st_shndx; /* section index */
|
||||
Addr st_value; /* symbol value */
|
||||
Xword st_size; /* symbol size */
|
||||
|
||||
# define WANT_SYM_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
|
||||
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
|
||||
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
|
||||
static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
} // namespace N_Elf64
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// now for the actual types
|
||||
// aggregate types into an ElfClass
|
||||
**************************************************************************/
|
||||
|
||||
#define P N_BELE_CTP::HostPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf32_Ehdr;
|
||||
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf32_Phdr;
|
||||
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf32_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U32,P::U32> Elf32_Dyn;
|
||||
typedef N_Elf32::Sym <P::U16,P::U32> Elf32_Sym;
|
||||
#undef P
|
||||
namespace N_Elf {
|
||||
|
||||
#define P N_BELE_CTP::BEPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_BE32_Ehdr;
|
||||
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_BE32_Phdr;
|
||||
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_BE32_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_BE32_Dyn;
|
||||
typedef N_Elf32::Sym <P::U16,P::U32> Elf_BE32_Sym;
|
||||
#undef P
|
||||
template <class TP>
|
||||
struct ElfClass_32
|
||||
{
|
||||
typedef TP BeLePolicy;
|
||||
|
||||
#define P N_BELE_CTP::LEPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_LE32_Ehdr;
|
||||
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_LE32_Phdr;
|
||||
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_LE32_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_LE32_Dyn;
|
||||
typedef N_Elf32::Sym <P::U16,P::U32> Elf_LE32_Sym;
|
||||
#undef P
|
||||
// integral types
|
||||
typedef typename TP::U16 U16;
|
||||
typedef typename TP::U32 U32;
|
||||
typedef typename TP::U64 U64;
|
||||
typedef N_Elf::ElfITypes<U16, U32, U32, U32, U32> ElfITypes;
|
||||
|
||||
#define P N_BELE_CTP::HostPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf64_Ehdr;
|
||||
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf64_Phdr;
|
||||
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf64_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U64,P::U64> Elf64_Dyn;
|
||||
#undef P
|
||||
// ELF types
|
||||
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
|
||||
typedef N_Elf32::Phdr<ElfITypes> Phdr;
|
||||
typedef N_Elf32::Shdr<ElfITypes> Shdr;
|
||||
typedef N_Elf ::Dyn <ElfITypes> Dyn;
|
||||
typedef N_Elf32::Sym <ElfITypes> Sym;
|
||||
typedef N_Elf ::External_Note<ElfITypes> External_Note;
|
||||
|
||||
#define P N_BELE_CTP::BEPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_BE64_Ehdr;
|
||||
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Phdr;
|
||||
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_BE64_Dyn;
|
||||
#undef P
|
||||
|
||||
#define P N_BELE_CTP::LEPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_LE64_Ehdr;
|
||||
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Phdr;
|
||||
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_LE64_Dyn;
|
||||
#undef P
|
||||
static void compileTimeAssertions() {
|
||||
BeLePolicy::compileTimeAssertions();
|
||||
COMPILE_TIME_ASSERT(sizeof(Ehdr) == 52)
|
||||
COMPILE_TIME_ASSERT(sizeof(Phdr) == 32)
|
||||
COMPILE_TIME_ASSERT(sizeof(Shdr) == 40)
|
||||
COMPILE_TIME_ASSERT(sizeof(Dyn) == 8)
|
||||
COMPILE_TIME_ASSERT(sizeof(Sym) == 16)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
|
||||
template <class TP>
|
||||
struct ElfClass_64
|
||||
{
|
||||
typedef TP BeLePolicy;
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Shdr) == 40)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Dyn) == 8)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Sym) == 16)
|
||||
// integral types
|
||||
typedef typename TP::U16 U16;
|
||||
typedef typename TP::U32 U32;
|
||||
typedef typename TP::U64 U64;
|
||||
typedef N_Elf::ElfITypes<U16, U32, U64, U64, U64> ElfITypes;
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
|
||||
// ELF types
|
||||
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
|
||||
typedef N_Elf64::Phdr<ElfITypes> Phdr;
|
||||
typedef N_Elf64::Shdr<ElfITypes> Shdr;
|
||||
typedef N_Elf ::Dyn <ElfITypes> Dyn;
|
||||
typedef N_Elf64::Sym <ElfITypes> Sym;
|
||||
typedef N_Elf ::External_Note<ElfITypes> External_Note;
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Ehdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16)
|
||||
static void compileTimeAssertions() {
|
||||
BeLePolicy::compileTimeAssertions();
|
||||
COMPILE_TIME_ASSERT(sizeof(Ehdr) == 64)
|
||||
COMPILE_TIME_ASSERT(sizeof(Phdr) == 56)
|
||||
COMPILE_TIME_ASSERT(sizeof(Shdr) == 64)
|
||||
COMPILE_TIME_ASSERT(sizeof(Dyn) == 16)
|
||||
COMPILE_TIME_ASSERT(sizeof(Sym) == 24)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
|
||||
}
|
||||
};
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Ehdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Phdr) == 56)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Shdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Dyn) == 16)
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Ehdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Phdr) == 56)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Shdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Dyn) == 16)
|
||||
} // namespace N_Elf
|
||||
|
||||
|
||||
typedef N_Elf::ElfClass_32<N_BELE_CTP::HostPolicy> ElfClass_Host32;
|
||||
typedef N_Elf::ElfClass_64<N_BELE_CTP::HostPolicy> ElfClass_Host64;
|
||||
typedef N_Elf::ElfClass_32<N_BELE_CTP::BEPolicy> ElfClass_BE32;
|
||||
typedef N_Elf::ElfClass_64<N_BELE_CTP::BEPolicy> ElfClass_BE64;
|
||||
typedef N_Elf::ElfClass_32<N_BELE_CTP::LEPolicy> ElfClass_LE32;
|
||||
typedef N_Elf::ElfClass_64<N_BELE_CTP::LEPolicy> ElfClass_LE64;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// shortcuts
|
||||
**************************************************************************/
|
||||
|
||||
typedef ElfClass_Host32::Ehdr Elf32_Ehdr;
|
||||
typedef ElfClass_Host32::Phdr Elf32_Phdr;
|
||||
typedef ElfClass_Host32::Shdr Elf32_Shdr;
|
||||
typedef ElfClass_Host32::Dyn Elf32_Dyn;
|
||||
typedef ElfClass_Host32::Sym Elf32_Sym;
|
||||
typedef ElfClass_Host32::External_Note Elf32_External_Note;
|
||||
|
||||
typedef ElfClass_Host64::Ehdr Elf64_Ehdr;
|
||||
typedef ElfClass_Host64::Phdr Elf64_Phdr;
|
||||
typedef ElfClass_Host64::Shdr Elf64_Shdr;
|
||||
typedef ElfClass_Host64::Dyn Elf64_Dyn;
|
||||
typedef ElfClass_Host64::Sym Elf64_Sym;
|
||||
typedef ElfClass_Host64::External_Note Elf64_External_Note;
|
||||
|
||||
typedef ElfClass_BE32::Ehdr Elf_BE32_Ehdr;
|
||||
typedef ElfClass_BE32::Phdr Elf_BE32_Phdr;
|
||||
typedef ElfClass_BE32::Shdr Elf_BE32_Shdr;
|
||||
typedef ElfClass_BE32::Dyn Elf_BE32_Dyn;
|
||||
typedef ElfClass_BE32::Sym Elf_BE32_Sym;
|
||||
typedef ElfClass_BE32::External_Note Elf_BE32_External_Note;
|
||||
|
||||
typedef ElfClass_BE64::Ehdr Elf_BE64_Ehdr;
|
||||
typedef ElfClass_BE64::Phdr Elf_BE64_Phdr;
|
||||
typedef ElfClass_BE64::Shdr Elf_BE64_Shdr;
|
||||
typedef ElfClass_BE64::Dyn Elf_BE64_Dyn;
|
||||
typedef ElfClass_BE64::Sym Elf_BE64_Sym;
|
||||
typedef ElfClass_BE64::External_Note Elf_BE64_External_Note;
|
||||
|
||||
typedef ElfClass_LE32::Ehdr Elf_LE32_Ehdr;
|
||||
typedef ElfClass_LE32::Phdr Elf_LE32_Phdr;
|
||||
typedef ElfClass_LE32::Shdr Elf_LE32_Shdr;
|
||||
typedef ElfClass_LE32::Dyn Elf_LE32_Dyn;
|
||||
typedef ElfClass_LE32::Sym Elf_LE32_Sym;
|
||||
typedef ElfClass_LE32::External_Note Elf_LE32_External_Note;
|
||||
|
||||
typedef ElfClass_LE64::Ehdr Elf_LE64_Ehdr;
|
||||
typedef ElfClass_LE64::Phdr Elf_LE64_Phdr;
|
||||
typedef ElfClass_LE64::Shdr Elf_LE64_Shdr;
|
||||
typedef ElfClass_LE64::Dyn Elf_LE64_Dyn;
|
||||
typedef ElfClass_LE64::Sym Elf_LE64_Sym;
|
||||
typedef ElfClass_LE64::External_Note Elf_LE64_External_Note;
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
+8
-10
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -94,14 +94,12 @@ void PackElks8086::readKernel()
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackElks8086::buildLoader(const Filter *ft)
|
||||
void PackElks8086::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
// FIXME
|
||||
UNUSED(ft);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +112,7 @@ void PackElks8086::pack(OutputFile *fo)
|
||||
ft.buf_len = ph.u_len;
|
||||
ft.addvalue = kernel_entry;
|
||||
// compress
|
||||
compressWithFilters(&ft, overlap_range);
|
||||
compressWithFilters(&ft, overlap_range, NULL_cconf);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
@@ -123,11 +121,11 @@ void PackElks8086::pack(OutputFile *fo)
|
||||
patchPackHeader(loader, lsize);
|
||||
#if 0
|
||||
// FIXME
|
||||
defineFilterSymbols();
|
||||
defineFilterSymbols(&ft);
|
||||
defineDecompressorSymbols();
|
||||
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||
patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
||||
//patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||
//patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||
//patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
||||
#endif
|
||||
|
||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||
|
||||
+211
-55
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -50,8 +50,15 @@ static const
|
||||
PackExe::PackExe(InputFile *f) :
|
||||
super(f)
|
||||
{
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
|
||||
ih_exesize = ih_imagesize = ih_overlay = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +80,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
#define oh (*eh)
|
||||
// fill new exe header
|
||||
int flag = 0;
|
||||
if (!opt->dos_exe.no_reloc)
|
||||
if (!opt->dos_exe.no_reloc && !M_IS_LZMA(ph.method))
|
||||
flag |= USEJUMP;
|
||||
if (ih.relocs == 0)
|
||||
flag |= NORELOC;
|
||||
@@ -82,7 +89,16 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
oh.ident = 'M' + 'Z' * 256;
|
||||
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;
|
||||
oh.ss = ph.c_len/16 + destpara;
|
||||
@@ -94,27 +110,118 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
|
||||
if (oh.ss != ih.ss)
|
||||
flag |= SS;
|
||||
if (oh.sp != ih.sp)
|
||||
if (oh.sp != ih.sp || M_IS_LZMA(ph.method))
|
||||
flag |= SP;
|
||||
return flag;
|
||||
#undef oh
|
||||
}
|
||||
|
||||
|
||||
int PackExe::buildLoader(const Filter *)
|
||||
void PackExe::addLoaderEpilogue(int flag)
|
||||
{
|
||||
struct exe_header_t tmp_oh;
|
||||
int flag = fillExeHeader(&tmp_oh);
|
||||
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 *)
|
||||
{
|
||||
// get flag
|
||||
exe_header_t dummy_oh;
|
||||
int flag = fillExeHeader(&dummy_oh);
|
||||
|
||||
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)
|
||||
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);
|
||||
|
||||
// prepare loader
|
||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||
if (device_driver)
|
||||
addLoader("DEVICEENTRY", NULL);
|
||||
addLoader("EXEENTRY",
|
||||
device_driver ? "DEVICESUB" : "EXESUB",
|
||||
M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
|
||||
"JNCDOCOPY",
|
||||
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
|
||||
);
|
||||
if (ph.method == M_NRV2B_8)
|
||||
@@ -153,32 +260,12 @@ int PackExe::buildLoader(const Filter *)
|
||||
"NRV2EEX9",
|
||||
NULL
|
||||
);
|
||||
else if M_IS_LZMA(ph.method)
|
||||
return;
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
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
|
||||
);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
|
||||
addLoaderEpilogue(flag);
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +324,9 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
const upx_byte *relocs, const unsigned nrelocs,
|
||||
upx_byte *crel, bool *has_9a)
|
||||
{
|
||||
if (opt->exact)
|
||||
throwCantPackExact();
|
||||
|
||||
upx_byte * const crel_save = crel;
|
||||
unsigned i;
|
||||
unsigned seg_high = 0;
|
||||
@@ -311,7 +401,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
break;
|
||||
}
|
||||
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++)
|
||||
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
|
||||
@@ -416,9 +506,12 @@ void PackExe::pack(OutputFile *fo)
|
||||
// compress (max_match = 8192)
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_ucl.max_match = MAXMATCH;
|
||||
compressWithFilters(&ft, 32, 0, NULL, &cconf);
|
||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||
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)
|
||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||
|
||||
#ifdef TESTING
|
||||
if (opt->debug.debug_level)
|
||||
@@ -484,15 +577,13 @@ void PackExe::pack(OutputFile *fo)
|
||||
}
|
||||
extra_info[eisize++] = (unsigned char) flag;
|
||||
|
||||
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);
|
||||
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
|
||||
linker->defineSymbol("decompressor_entry", (packedsize & 15) + 1);
|
||||
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((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
|
||||
if (flag & USEJUMP)
|
||||
@@ -528,9 +619,11 @@ void PackExe::pack(OutputFile *fo)
|
||||
oh.m512 = outputlen & 511;
|
||||
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;
|
||||
|
||||
linker->relocate();
|
||||
defineDecompressorSymbols();
|
||||
relocateLoader();
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
@@ -578,7 +671,7 @@ int PackExe::canUnpack()
|
||||
return false;
|
||||
const off_t off = ih.headsize16 * 16;
|
||||
fi->seek(off, SEEK_SET);
|
||||
bool b = readPackHeader(256);
|
||||
bool b = readPackHeader(4096);
|
||||
return b && (off + (off_t) ph.c_len <= file_size);
|
||||
}
|
||||
|
||||
@@ -713,6 +806,69 @@ Linker* PackExe::newLinker() const
|
||||
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
|
||||
|
||||
+8
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_DOS_EXE; }
|
||||
virtual const char *getName() const { return "dos/exe"; }
|
||||
virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.exe" : "i286-dos16.exe"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -68,8 +69,9 @@ protected:
|
||||
virtual int readFileHeader(void);
|
||||
|
||||
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
void addLoaderEpilogue(int flag);
|
||||
|
||||
struct exe_header_t
|
||||
{
|
||||
@@ -109,6 +111,9 @@ protected:
|
||||
MINMEM = 16,
|
||||
MAXMEM = 32
|
||||
};
|
||||
|
||||
unsigned stack_for_lzma; // stack size required for lzma
|
||||
bool use_clear_dirty_stack;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+81
-209
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -249,8 +249,8 @@ int const *
|
||||
PackLinuxElf32ppc::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0xd0, -1
|
||||
};
|
||||
0xd0,
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -258,8 +258,8 @@ int const *
|
||||
PackLinuxElf64amd::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x49, -1
|
||||
};
|
||||
0x49,
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ void PackLinuxElf32x86::defineSymbols(Filter const *const ft)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxElf32::buildLinuxLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
@@ -464,7 +464,7 @@ PackLinuxElf32::buildLinuxLoader(
|
||||
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
|
||||
throwInternalError("loader compression failed");
|
||||
#if 0 //{ debugging only
|
||||
if (M_LZMA==ph.method) {
|
||||
if (M_IS_LZMA(ph.method)) {
|
||||
ucl_uint tmp_len = h.sz_unc; // LZMA uses this as EOF
|
||||
unsigned char *tmp = new unsigned char[tmp_len];
|
||||
memset(tmp, 0, tmp_len);
|
||||
@@ -488,13 +488,11 @@ PackLinuxElf32::buildLinuxLoader(
|
||||
|
||||
addStubEntrySections(ft);
|
||||
|
||||
freezeLoader();
|
||||
defineSymbols(ft);
|
||||
linker->relocate();
|
||||
return getLoaderSize();
|
||||
relocateLoader();
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxElf64::buildLinuxLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
@@ -538,10 +536,8 @@ PackLinuxElf64::buildLinuxLoader(
|
||||
|
||||
addStubEntrySections(ft);
|
||||
|
||||
freezeLoader();
|
||||
defineSymbols(ft);
|
||||
linker->relocate();
|
||||
return getLoaderSize();
|
||||
relocateLoader();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -567,7 +563,7 @@ PackLinuxElf64amd::defineSymbols(Filter const *)
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
#define PAGE_SIZE (-PAGE_MASK)
|
||||
lsize = /*getLoaderSize()*/ 64 * 1024; // upper bound; avoid circularity
|
||||
acc_uint64l_t lo_va_stub = elfout.phdr[0].p_vaddr;
|
||||
acc_uint64l_t lo_va_stub = get_native64(&elfout.phdr[0].p_vaddr);
|
||||
acc_uint64l_t adrc;
|
||||
acc_uint64l_t adrm;
|
||||
acc_uint64l_t adru;
|
||||
@@ -629,15 +625,15 @@ static const
|
||||
static const
|
||||
#include "stub/i386-linux.elf-fold.h"
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxElf32x86::buildLoader(const Filter *ft)
|
||||
{
|
||||
unsigned char tmp[sizeof(linux_i386elf_fold)];
|
||||
memcpy(tmp, linux_i386elf_fold, sizeof(linux_i386elf_fold));
|
||||
unsigned char tmp[sizeof(stub_i386_linux_elf_fold)];
|
||||
memcpy(tmp, stub_i386_linux_elf_fold, sizeof(stub_i386_linux_elf_fold));
|
||||
checkPatch(NULL, 0, 0, 0); // reset
|
||||
if (opt->o_unix.is_ptinterp) {
|
||||
unsigned j;
|
||||
for (j = 0; j < sizeof(linux_i386elf_fold)-1; ++j) {
|
||||
for (j = 0; j < sizeof(stub_i386_linux_elf_fold)-1; ++j) {
|
||||
if (0x60==tmp[ j]
|
||||
&& 0x47==tmp[1+j] ) {
|
||||
/* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
|
||||
@@ -647,9 +643,9 @@ PackLinuxElf32x86::buildLoader(const Filter *ft)
|
||||
}
|
||||
}
|
||||
}
|
||||
return buildLinuxLoader(
|
||||
linux_i386elf_loader, sizeof(linux_i386elf_loader),
|
||||
tmp, sizeof(linux_i386elf_fold), ft );
|
||||
buildLinuxLoader(
|
||||
stub_i386_linux_elf_entry, sizeof(stub_i386_linux_elf_entry),
|
||||
tmp, sizeof(stub_i386_linux_elf_fold), ft );
|
||||
}
|
||||
|
||||
static const
|
||||
@@ -657,15 +653,15 @@ static const
|
||||
static const
|
||||
#include "stub/i386-bsd.elf-fold.h"
|
||||
|
||||
int
|
||||
void
|
||||
PackBSDElf32x86::buildLoader(const Filter *ft)
|
||||
{
|
||||
unsigned char tmp[sizeof(bsd_i386elf_fold)];
|
||||
memcpy(tmp, bsd_i386elf_fold, sizeof(bsd_i386elf_fold));
|
||||
unsigned char tmp[sizeof(stub_i386_bsd_elf_fold)];
|
||||
memcpy(tmp, stub_i386_bsd_elf_fold, sizeof(stub_i386_bsd_elf_fold));
|
||||
checkPatch(NULL, 0, 0, 0); // reset
|
||||
if (opt->o_unix.is_ptinterp) {
|
||||
unsigned j;
|
||||
for (j = 0; j < sizeof(bsd_i386elf_fold)-1; ++j) {
|
||||
for (j = 0; j < sizeof(stub_i386_bsd_elf_fold)-1; ++j) {
|
||||
if (0x60==tmp[ j]
|
||||
&& 0x47==tmp[1+j] ) {
|
||||
/* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
|
||||
@@ -675,9 +671,9 @@ PackBSDElf32x86::buildLoader(const Filter *ft)
|
||||
}
|
||||
}
|
||||
}
|
||||
return buildLinuxLoader(
|
||||
bsd_i386elf_loader, sizeof(bsd_i386elf_loader),
|
||||
tmp, sizeof(bsd_i386elf_fold), ft );
|
||||
buildLinuxLoader(
|
||||
stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
|
||||
tmp, sizeof(stub_i386_bsd_elf_fold), ft);
|
||||
}
|
||||
|
||||
#if 0 //{ re-use for OpenBSD, too
|
||||
@@ -687,15 +683,15 @@ static const
|
||||
static const
|
||||
#include "stub/i386-openbsd.elf-fold.h"
|
||||
|
||||
int
|
||||
void
|
||||
PackOpenBSDElf32x86::buildLoader(const Filter *ft)
|
||||
{
|
||||
unsigned char tmp[sizeof(openbsd_i386elf_fold)];
|
||||
memcpy(tmp, openbsd_i386elf_fold, sizeof(openbsd_i386elf_fold));
|
||||
unsigned char tmp[sizeof(stub_i386_openbsd_elf_fold)];
|
||||
memcpy(tmp, stub_i386_openbsd_elf_fold, sizeof(stub_i386_openbsd_elf_fold));
|
||||
checkPatch(NULL, 0, 0, 0); // reset
|
||||
if (opt->o_unix.is_ptinterp) {
|
||||
unsigned j;
|
||||
for (j = 0; j < sizeof(openbsd_i386elf_fold)-1; ++j) {
|
||||
for (j = 0; j < sizeof(stub_i386_openbsd_elf_fold)-1; ++j) {
|
||||
if (0x60==tmp[ j]
|
||||
&& 0x47==tmp[1+j] ) {
|
||||
/* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */
|
||||
@@ -705,9 +701,9 @@ PackOpenBSDElf32x86::buildLoader(const Filter *ft)
|
||||
}
|
||||
}
|
||||
}
|
||||
return buildLinuxLoader(
|
||||
bsd_i386elf_loader, sizeof(bsd_i386elf_loader),
|
||||
tmp, sizeof(openbsd_i386elf_fold), ft );
|
||||
buildLinuxLoader(
|
||||
stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
|
||||
tmp, sizeof(stub_i386_openbsd_elf_fold), ft);
|
||||
}
|
||||
|
||||
static const
|
||||
@@ -715,78 +711,27 @@ static const
|
||||
static const
|
||||
#include "stub/arm-linux.elf-fold.h"
|
||||
|
||||
static const
|
||||
#include "stub/armeb-linux.elf-entry.h"
|
||||
static const
|
||||
#include "stub/armeb-linux.elf-fold.h"
|
||||
|
||||
#include "mem.h"
|
||||
|
||||
static void brev(
|
||||
unsigned char *const dst,
|
||||
unsigned char const *const src,
|
||||
unsigned len
|
||||
)
|
||||
{
|
||||
assert(0==(3 & len));
|
||||
// Detect overlap which over-writes src before it is used.
|
||||
assert(!((4+ src)<=dst && dst < (len + src)));
|
||||
for (unsigned j = 0; j < len; j += 4) {
|
||||
// Simple way (and somewhat slow) to allow in-place brev().
|
||||
unsigned char tmp[4];
|
||||
memcpy(tmp, j + src, 4);
|
||||
dst[0+ j] = tmp[3];
|
||||
dst[1+ j] = tmp[2];
|
||||
dst[2+ j] = tmp[1];
|
||||
dst[3+ j] = tmp[0];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ehdr_bele(Elf_BE32_Ehdr *const ehdr_be, Elf_LE32_Ehdr const *const ehdr_le)
|
||||
{
|
||||
memcpy(&ehdr_be->e_ident, &ehdr_le->e_ident, sizeof(ehdr_be->e_ident));
|
||||
ehdr_be->e_ident[Elf32_Ehdr::EI_DATA] = Elf32_Ehdr::ELFDATA2MSB;
|
||||
ehdr_be->e_type = ehdr_le->e_type;
|
||||
ehdr_be->e_machine = ehdr_le->e_machine;
|
||||
ehdr_be->e_version = ehdr_le->e_version;
|
||||
ehdr_be->e_entry = ehdr_le->e_entry;
|
||||
ehdr_be->e_phoff = ehdr_le->e_phoff;
|
||||
ehdr_be->e_shoff = ehdr_le->e_shoff;
|
||||
ehdr_be->e_flags = ehdr_le->e_flags;
|
||||
ehdr_be->e_ehsize = ehdr_le->e_ehsize;
|
||||
ehdr_be->e_phentsize = ehdr_le->e_phentsize;
|
||||
ehdr_be->e_phnum = ehdr_le->e_phnum;
|
||||
ehdr_be->e_shentsize = ehdr_le->e_shentsize;
|
||||
ehdr_be->e_shnum = ehdr_le->e_shnum;
|
||||
ehdr_be->e_shstrndx = ehdr_le->e_shstrndx;
|
||||
}
|
||||
|
||||
static void
|
||||
ehdr_lebe(Elf_LE32_Ehdr *const ehdr_le, Elf_BE32_Ehdr const *const ehdr_be)
|
||||
{
|
||||
memcpy(&ehdr_le->e_ident, &ehdr_be->e_ident, sizeof(ehdr_le->e_ident));
|
||||
ehdr_le->e_ident[Elf32_Ehdr::EI_DATA] = Elf32_Ehdr::ELFDATA2LSB;
|
||||
ehdr_le->e_type = ehdr_be->e_type;
|
||||
ehdr_le->e_machine = ehdr_be->e_machine;
|
||||
ehdr_le->e_version = ehdr_be->e_version;
|
||||
ehdr_le->e_entry = ehdr_be->e_entry;
|
||||
ehdr_le->e_phoff = ehdr_be->e_phoff;
|
||||
ehdr_le->e_shoff = ehdr_be->e_shoff;
|
||||
ehdr_le->e_flags = ehdr_be->e_flags;
|
||||
ehdr_le->e_ehsize = ehdr_be->e_ehsize;
|
||||
ehdr_le->e_phentsize = ehdr_be->e_phentsize;
|
||||
ehdr_le->e_phnum = ehdr_be->e_phnum;
|
||||
ehdr_le->e_shentsize = ehdr_be->e_shentsize;
|
||||
ehdr_le->e_shnum = ehdr_be->e_shnum;
|
||||
ehdr_le->e_shstrndx = ehdr_be->e_shstrndx;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxElf32armBe::buildLoader(Filter const *ft)
|
||||
{
|
||||
return ARM_buildLoader(ft, true);
|
||||
buildLinuxLoader(
|
||||
stub_armeb_linux_elf_entry, sizeof(stub_armeb_linux_elf_entry),
|
||||
stub_armeb_linux_elf_fold, sizeof(stub_armeb_linux_elf_fold), ft);
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxElf32armLe::buildLoader(Filter const *ft)
|
||||
{
|
||||
return ARM_buildLoader(ft, false);
|
||||
buildLinuxLoader(
|
||||
stub_arm_linux_elf_entry, sizeof(stub_arm_linux_elf_entry),
|
||||
stub_arm_linux_elf_fold, sizeof(stub_arm_linux_elf_fold), ft);
|
||||
}
|
||||
|
||||
static const
|
||||
@@ -794,12 +739,12 @@ static const
|
||||
static const
|
||||
#include "stub/powerpc-linux.elf-fold.h"
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxElf32ppc::buildLoader(const Filter *ft)
|
||||
{
|
||||
return buildLinuxLoader(
|
||||
linux_elfppc32_loader, sizeof(linux_elfppc32_loader),
|
||||
linux_elfppc32_fold, sizeof(linux_elfppc32_fold), ft );
|
||||
buildLinuxLoader(
|
||||
stub_powerpc_linux_elf_entry, sizeof(stub_powerpc_linux_elf_entry),
|
||||
stub_powerpc_linux_elf_fold, sizeof(stub_powerpc_linux_elf_fold), ft);
|
||||
}
|
||||
|
||||
static const
|
||||
@@ -807,12 +752,12 @@ static const
|
||||
static const
|
||||
#include "stub/amd64-linux.elf-fold.h"
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxElf64amd::buildLoader(const Filter *ft)
|
||||
{
|
||||
return buildLinuxLoader(
|
||||
linux_elf64amd_loader, sizeof(linux_elf64amd_loader),
|
||||
linux_elf64amd_fold, sizeof(linux_elf64amd_fold), ft );
|
||||
buildLinuxLoader(
|
||||
stub_amd64_linux_elf_entry, sizeof(stub_amd64_linux_elf_entry),
|
||||
stub_amd64_linux_elf_fold, sizeof(stub_amd64_linux_elf_fold), ft);
|
||||
}
|
||||
|
||||
bool PackLinuxElf32::canPack()
|
||||
@@ -831,12 +776,12 @@ bool PackLinuxElf32::canPack()
|
||||
|
||||
// additional requirements for linux/elf386
|
||||
if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) {
|
||||
throwCantPack("invalid Ehdr e_ehsize; try `--force-execve'");
|
||||
throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
|
||||
return false;
|
||||
}
|
||||
unsigned const e_phoff = get_native32(&ehdr->e_phoff);
|
||||
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
|
||||
throwCantPack("non-contiguous Ehdr/Phdr; try `--force-execve'");
|
||||
throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -849,7 +794,7 @@ bool PackLinuxElf32::canPack()
|
||||
return false;
|
||||
if (1!=exetype && phdr->PT_LOAD32 == get_native32(&phdr->p_type)) {
|
||||
if (phdr->p_offset != 0) {
|
||||
throwCantPack("invalid Phdr p_offset; try `--force-execve'");
|
||||
throwCantPack("invalid Phdr p_offset; try '--force-execve'");
|
||||
return false;
|
||||
}
|
||||
exetype = 1;
|
||||
@@ -918,7 +863,7 @@ bool PackLinuxElf32::canPack()
|
||||
// elf_lookup() returns 0 if any required table is missing.
|
||||
Elf32_Sym const *const lsm = elf_lookup(run_start[j]);
|
||||
if (lsm && get_native16(&lsm->st_shndx)==Elf32_Sym::SHN_UNDEF
|
||||
&& get_native16(&lsm->st_info)==lsm->Elf32_Sym::St_info(Elf32_Sym::STB_GLOBAL, Elf32_Sym::STT_FUNC)
|
||||
&& get_native16(&lsm->st_info)==lsm->Elf32_Sym::make_st_info(Elf32_Sym::STB_GLOBAL, Elf32_Sym::STT_FUNC)
|
||||
&& get_native16(&lsm->st_other)==Elf32_Sym::STV_DEFAULT ) {
|
||||
break;
|
||||
}
|
||||
@@ -956,25 +901,25 @@ PackLinuxElf64amd::canPack()
|
||||
|
||||
// additional requirements for linux/elf386
|
||||
if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) {
|
||||
throwCantPack("invalid Ehdr e_ehsize; try `--force-execve'");
|
||||
throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
|
||||
return false;
|
||||
}
|
||||
acc_uint64l_t const e_phoff = get_native64(&ehdr->e_phoff);
|
||||
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
|
||||
throwCantPack("non-contiguous Ehdr/Phdr; try `--force-execve'");
|
||||
throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
|
||||
return false;
|
||||
}
|
||||
|
||||
// The first PT_LOAD64 must cover the beginning of the file (0==p_offset).
|
||||
unsigned const e_phnum = get_native16(&ehdr->e_phnum);
|
||||
Elf64_Phdr const *phdr = (Elf64_Phdr const *)(buf + e_phoff);
|
||||
Elf64_Phdr const *phdr = (Elf64_Phdr const *)(buf + (unsigned) e_phoff);
|
||||
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||
if (j >= 14)
|
||||
return false;
|
||||
if (phdr->PT_LOAD64 == get_native32(&phdr->p_type)) {
|
||||
// Just avoid the "rewind" when unpacking?
|
||||
//if (phdr->p_offset != 0) {
|
||||
// throwCantPack("invalid Phdr p_offset; try `--force-execve'");
|
||||
// throwCantPack("invalid Phdr p_offset; try '--force-execve'");
|
||||
// return false;
|
||||
//}
|
||||
exetype = 1;
|
||||
@@ -1053,7 +998,7 @@ PackLinuxElf32::generateElfHdr(
|
||||
h2->ehdr.e_shoff = 0;
|
||||
assert(get_native16(&h2->ehdr.e_ehsize) == sizeof(Elf32_Ehdr));
|
||||
assert(get_native16(&h2->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
|
||||
h2->ehdr.e_shentsize = 0;
|
||||
set_native16(&h2->ehdr.e_shentsize, sizeof(Elf32_Shdr));
|
||||
h2->ehdr.e_shnum = 0;
|
||||
h2->ehdr.e_shstrndx = 0;
|
||||
|
||||
@@ -1103,7 +1048,7 @@ PackOpenBSDElf32x86::generateElfHdr(
|
||||
h3->ehdr.e_shoff = 0;
|
||||
assert(get_native16(&h3->ehdr.e_ehsize) == sizeof(Elf32_Ehdr));
|
||||
assert(get_native16(&h3->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
|
||||
h3->ehdr.e_shentsize = 0;
|
||||
set_native16(&h3->ehdr.e_shentsize, sizeof(Elf32_Shdr));
|
||||
h3->ehdr.e_shnum = 0;
|
||||
h3->ehdr.e_shstrndx = 0;
|
||||
|
||||
@@ -1165,7 +1110,7 @@ PackLinuxElf64::generateElfHdr(
|
||||
h2->ehdr.e_shoff = 0;
|
||||
assert(get_native16(&h2->ehdr.e_ehsize) == sizeof(Elf64_Ehdr));
|
||||
assert(get_native16(&h2->ehdr.e_phentsize) == sizeof(Elf64_Phdr));
|
||||
h2->ehdr.e_shentsize = 0;
|
||||
set_native16(&h2->ehdr.e_shentsize, sizeof(Elf64_Shdr));
|
||||
h2->ehdr.e_shnum = 0;
|
||||
h2->ehdr.e_shstrndx = 0;
|
||||
|
||||
@@ -1217,52 +1162,35 @@ void PackLinuxElf32::pack1(OutputFile */*fo*/, Filter &/*ft*/)
|
||||
void PackLinuxElf32x86::pack1(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
PackLinuxElf32::pack1(fo, ft);
|
||||
generateElfHdr(fo, linux_i386elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
generateElfHdr(fo, stub_i386_linux_elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
}
|
||||
|
||||
void PackBSDElf32x86::pack1(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
PackLinuxElf32::pack1(fo, ft);
|
||||
generateElfHdr(fo, bsd_i386elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
}
|
||||
|
||||
void PackLinuxElf32::ARM_pack1(OutputFile *fo, bool const isBE)
|
||||
{
|
||||
Elf32_Ehdr const *const fold = (Elf32_Ehdr const *)&linux_elf32arm_fold;
|
||||
cprElfHdr3 h3;
|
||||
// We need Elf32_Ehdr and Elf32_Phdr with byte gender of target.
|
||||
// The stub may have been compiled differently.
|
||||
if (this->ei_data==fold->e_ident[Elf32_Ehdr::EI_DATA]) {
|
||||
memcpy(&h3, (void const *)linux_elf32arm_fold,
|
||||
sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr) );
|
||||
}
|
||||
else {
|
||||
(isBE ? (void (*)(void *, void const *))ehdr_bele
|
||||
: (void (*)(void *, void const *))ehdr_lebe)
|
||||
((void *)&h3.ehdr, (void const *)linux_elf32arm_fold);
|
||||
brev((unsigned char *)&h3.phdr[0],
|
||||
sizeof(Elf32_Ehdr) + (unsigned char const *)&linux_elf32arm_fold,
|
||||
3*sizeof(Elf32_Phdr) );
|
||||
}
|
||||
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
generateElfHdr(fo, stub_i386_bsd_elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
}
|
||||
|
||||
void PackLinuxElf32armLe::pack1(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
super::pack1(fo, ft);
|
||||
ARM_pack1(fo, false);
|
||||
cprElfHdr3 h3;
|
||||
memcpy(&h3, stub_arm_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
|
||||
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
}
|
||||
|
||||
void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft) // FIXME
|
||||
void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
super::pack1(fo, ft);
|
||||
ARM_pack1(fo, true);
|
||||
cprElfHdr3 h3;
|
||||
memcpy(&h3, stub_armeb_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
|
||||
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
}
|
||||
|
||||
void PackLinuxElf32ppc::pack1(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
super::pack1(fo, ft);
|
||||
generateElfHdr(fo, linux_elfppc32_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
generateElfHdr(fo, stub_powerpc_linux_elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
}
|
||||
|
||||
void PackLinuxElf64::pack1(OutputFile */*fo*/, Filter &/*ft*/)
|
||||
@@ -1284,7 +1212,7 @@ void PackLinuxElf64::pack1(OutputFile */*fo*/, Filter &/*ft*/)
|
||||
void PackLinuxElf64amd::pack1(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
super::pack1(fo, ft);
|
||||
generateElfHdr(fo, linux_elf64amd_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
generateElfHdr(fo, stub_amd64_linux_elf_fold, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||
}
|
||||
|
||||
// Determine length of gap between PT_LOAD phdr[k] and closest PT_LOAD
|
||||
@@ -1496,9 +1424,9 @@ using namespace N_BELE_CTP;
|
||||
static const int *
|
||||
ARM_getFilters(bool const isBE)
|
||||
{
|
||||
static const int f50[] = { 0x50, -1 };
|
||||
static const int f51[] = { 0x51, -1 };
|
||||
if (HostPolicy::isBE ^ isBE)
|
||||
static const int f50[] = { 0x50, FT_END };
|
||||
static const int f51[] = { 0x51, FT_END };
|
||||
if (isBE)
|
||||
return f51;
|
||||
return f50;
|
||||
}
|
||||
@@ -1515,62 +1443,6 @@ PackLinuxElf32armLe::getFilters() const
|
||||
return ARM_getFilters(false);
|
||||
}
|
||||
|
||||
int
|
||||
PackLinuxElf32::ARM_buildLoader(const Filter *ft, bool const isBE)
|
||||
{
|
||||
unsigned const sz_loader = sizeof(linux_elf32arm_loader);
|
||||
unsigned const sz_fold = sizeof(linux_elf32arm_fold);
|
||||
|
||||
// Was ARM code assembled for same endianness as the target?
|
||||
bool const asm_brev = (this->ei_data
|
||||
!= ((Elf32_Ehdr const *)linux_elf32arm_fold)->e_ident[Elf32_Ehdr::EI_DATA] );
|
||||
|
||||
MemBuffer tmp_fold(sz_fold);
|
||||
memcpy(tmp_fold, linux_elf32arm_fold, sz_fold);
|
||||
|
||||
// 0xe3530050 is "cmp fid,#0x50" with fid .req r3
|
||||
if (HostPolicy::isBE ^ isBE) { // change filter 0x50 to filter 0x51
|
||||
if (HostPolicy::isBE ^ isBE ^ asm_brev) { // find 0xe3530050 big-endian
|
||||
checkPatch(NULL,0,0,0); // reset
|
||||
patch_be32(tmp_fold, sz_fold, "\xe3\x53\x00\x50", 0xe3530051);
|
||||
checkPatch(NULL,0,0,0); // reset
|
||||
}
|
||||
else { // find 0xe3530050 little-endian
|
||||
checkPatch(NULL,0,0,0); // reset
|
||||
patch_le32(tmp_fold, sz_fold, "\x50\x00\x53\xe3", 0xe3530051);
|
||||
checkPatch(NULL,0,0,0); // reset
|
||||
}
|
||||
}
|
||||
if (!asm_brev) { // was assembled to match target
|
||||
return buildLinuxLoader(linux_elf32arm_loader, sz_loader,
|
||||
tmp_fold, sz_fold, ft );
|
||||
}
|
||||
else { // was assembled brev() from target
|
||||
// linux_elf32arm_loader[] is all instructions, except for two strings
|
||||
// at the end: the copyright message, and the SELinux message.
|
||||
// The copyright message begins and ends with '\n', and the SELinux
|
||||
// message ends with '\n'. So copy back to the third '\n' from the end,
|
||||
// and apply brev() only before that point.
|
||||
MemBuffer brev_loader(sz_loader);
|
||||
int nl = 0;
|
||||
int j;
|
||||
for (j= sz_loader; --j>=0; ) {
|
||||
unsigned char const c = linux_elf32arm_loader[j];
|
||||
brev_loader[j] = c;
|
||||
if ('\n'==c) {
|
||||
if (3==++nl) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
brev(brev_loader, linux_elf32arm_loader, j);
|
||||
(isBE ? (void (*)(void *, void const *))ehdr_bele
|
||||
: (void (*)(void *, void const *))ehdr_lebe)
|
||||
(tmp_fold.getVoidPtr(), (void const *)linux_elf32arm_fold);
|
||||
return buildLinuxLoader(brev_loader, sz_loader, tmp_fold, sz_fold, ft);
|
||||
}
|
||||
}
|
||||
|
||||
void PackLinuxElf32::ARM_defineSymbols(Filter const * /*ft*/)
|
||||
{
|
||||
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
||||
@@ -1985,7 +1857,7 @@ PackLinuxElf32x86::getFilters() const
|
||||
0x82, 0x85,
|
||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||
#endif
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
+43
-19
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -40,7 +40,7 @@ class PackLinuxElf : public PackUnix
|
||||
public:
|
||||
PackLinuxElf(InputFile *f);
|
||||
virtual ~PackLinuxElf();
|
||||
/*virtual int buildLoader(const Filter *);*/
|
||||
/*virtual void buildLoader(const Filter *);*/
|
||||
virtual bool canUnpackVersion(int version) const { return (version >= 11); }
|
||||
|
||||
protected:
|
||||
@@ -90,10 +90,8 @@ protected:
|
||||
|
||||
// These ARM routines are essentially common to big/little endian,
|
||||
// but the class hierarchy splits after this class.
|
||||
virtual int ARM_buildLoader(Filter const *ft, bool isBE);
|
||||
virtual void ARM_defineSymbols(Filter const *ft);
|
||||
virtual void ARM_updateLoader(OutputFile *);
|
||||
virtual void ARM_pack1(OutputFile *, bool isBE);
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
@@ -106,7 +104,7 @@ protected:
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
);
|
||||
virtual int buildLinuxLoader(
|
||||
virtual void buildLinuxLoader(
|
||||
upx_byte const *const proto, // assembly-only sections
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold, // linked assembly + C section
|
||||
@@ -163,6 +161,15 @@ protected:
|
||||
char text[0x18 - 4*4]; // "OpenBSD"
|
||||
unsigned end; // 0
|
||||
} elfnote;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 52 + 1*32 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 52 + 2*32 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 52 + 3*32 + 12)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -172,7 +179,7 @@ class PackLinuxElf64 : public PackLinuxElf
|
||||
public:
|
||||
PackLinuxElf64(InputFile *f);
|
||||
virtual ~PackLinuxElf64();
|
||||
/*virtual int buildLoader(const Filter *);*/
|
||||
/*virtual void buildLoader(const Filter *);*/
|
||||
|
||||
protected:
|
||||
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||
@@ -188,7 +195,7 @@ protected:
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
);
|
||||
virtual int buildLinuxLoader(
|
||||
virtual void buildLinuxLoader(
|
||||
upx_byte const *const proto, // assembly-only sections
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold, // linked assembly + C section
|
||||
@@ -227,13 +234,22 @@ protected:
|
||||
__attribute_packed;
|
||||
|
||||
cprElfHdr3 elfout;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 64 + 1*56 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 64 + 2*56 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 64 + 3*56 + 12)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
|
||||
}
|
||||
};
|
||||
|
||||
class PackLinuxElf32Be : public PackLinuxElf32
|
||||
{
|
||||
typedef PackLinuxElf32 super;
|
||||
protected:
|
||||
PackLinuxElf32Be(InputFile *f) : super(f) { }
|
||||
PackLinuxElf32Be(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; }
|
||||
|
||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
||||
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
|
||||
@@ -247,7 +263,7 @@ class PackLinuxElf32Le : public PackLinuxElf32
|
||||
{
|
||||
typedef PackLinuxElf32 super;
|
||||
protected:
|
||||
PackLinuxElf32Le(InputFile *f) : super(f) { }
|
||||
PackLinuxElf32Le(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||
|
||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||
@@ -261,7 +277,7 @@ class PackLinuxElf64Le : public PackLinuxElf64
|
||||
{
|
||||
typedef PackLinuxElf64 super;
|
||||
protected:
|
||||
PackLinuxElf64Le(InputFile *f) : super(f) { }
|
||||
PackLinuxElf64Le(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||
|
||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||
@@ -283,12 +299,13 @@ public:
|
||||
virtual ~PackLinuxElf64amd();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; }
|
||||
virtual const char *getName() const { return "linux/ElfAMD"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "amd64-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
virtual bool canPack();
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void defineSymbols(Filter const *);
|
||||
};
|
||||
@@ -305,10 +322,11 @@ public:
|
||||
virtual ~PackLinuxElf32ppc();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
||||
virtual const char *getName() const { return "linux/ElfPPC"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "powerpc-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
virtual Linker* newLinker() const;
|
||||
};
|
||||
|
||||
@@ -324,6 +342,7 @@ public:
|
||||
virtual ~PackLinuxElf32x86();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
|
||||
virtual const char *getName() const { return "linux/elf386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
virtual void unpack(OutputFile *fo);
|
||||
@@ -331,7 +350,7 @@ public:
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
virtual void addStubEntrySections(Filter const *);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void defineSymbols(Filter const *);
|
||||
@@ -349,7 +368,7 @@ public:
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
};
|
||||
|
||||
class PackFreeBSDElf32x86 : public PackBSDElf32x86
|
||||
@@ -358,6 +377,7 @@ class PackFreeBSDElf32x86 : public PackBSDElf32x86
|
||||
public:
|
||||
PackFreeBSDElf32x86(InputFile *f);
|
||||
virtual ~PackFreeBSDElf32x86();
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-freebsd.elf"; }
|
||||
};
|
||||
|
||||
class PackNetBSDElf32x86 : public PackBSDElf32x86
|
||||
@@ -366,6 +386,7 @@ class PackNetBSDElf32x86 : public PackBSDElf32x86
|
||||
public:
|
||||
PackNetBSDElf32x86(InputFile *f);
|
||||
virtual ~PackNetBSDElf32x86();
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-netbsd.elf"; }
|
||||
};
|
||||
|
||||
class PackOpenBSDElf32x86 : public PackBSDElf32x86
|
||||
@@ -374,9 +395,10 @@ class PackOpenBSDElf32x86 : public PackBSDElf32x86
|
||||
public:
|
||||
PackOpenBSDElf32x86(InputFile *f);
|
||||
virtual ~PackOpenBSDElf32x86();
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-openbsd.elf"; }
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
@@ -396,13 +418,14 @@ public:
|
||||
virtual ~PackLinuxElf32armLe();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
|
||||
virtual const char *getName() const { return "linux/armLE"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
virtual void updateLoader(OutputFile *);
|
||||
virtual void defineSymbols(Filter const *);
|
||||
};
|
||||
@@ -415,13 +438,14 @@ public:
|
||||
virtual ~PackLinuxElf32armBe();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; }
|
||||
virtual const char *getName() const { return "linux/armBE"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
virtual void updateLoader(OutputFile *);
|
||||
virtual void defineSymbols(Filter const *);
|
||||
};
|
||||
|
||||
+26
-25
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2001-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2001-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -57,6 +57,7 @@
|
||||
PackLinuxI386::PackLinuxI386(InputFile *f) : super(f),
|
||||
ei_osabi(Elf32_Ehdr::ELFOSABI_LINUX), osabi_note(NULL)
|
||||
{
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
}
|
||||
|
||||
PackBSDI386::PackBSDI386(InputFile *f) : super(f)
|
||||
@@ -99,7 +100,7 @@ const int *PackLinuxI386::getFilters() const
|
||||
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||
#endif
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -182,7 +183,7 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
|
||||
// create a pseudo-unique program id for our paranoid stub
|
||||
progid = getRandomId();
|
||||
|
||||
generateElfHdr(fo, linux_i386exec_fold, 0);
|
||||
generateElfHdr(fo, stub_i386_linux_elf_execve_fold, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -191,7 +192,7 @@ PackBSDI386::pack1(OutputFile *fo, Filter &)
|
||||
// create a pseudo-unique program id for our paranoid stub
|
||||
progid = getRandomId();
|
||||
|
||||
generateElfHdr(fo, bsd_i386exec_fold, 0);
|
||||
generateElfHdr(fo, stub_i386_bsd_elf_execve_fold, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -203,7 +204,7 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
||||
unsigned nw = fo->getBytesWritten();
|
||||
elfout.phdr[0].p_filesz = nw;
|
||||
nw = -(-elfout.phdr[0].p_align & -nw); // ALIGN_UP
|
||||
nw = 0u-((0u-elfout.phdr[0].p_align) & (0u-nw)); // ALIGN_UP
|
||||
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
||||
set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);
|
||||
|
||||
@@ -292,7 +293,7 @@ Linker *PackLinuxI386::newLinker() const
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxI386::buildLinuxLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
@@ -372,13 +373,14 @@ PackLinuxI386::buildLinuxLoader(
|
||||
addLoader("IDENTSTR", NULL);
|
||||
addLoader("LEXEC020", NULL);
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
freezeLoader();
|
||||
if (ph.method == M_LZMA) {
|
||||
if (M_IS_LZMA(ph.method)) {
|
||||
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||
unsigned const properties = // lc, lp, pb, dummy
|
||||
acc_uint32e_t properties = // lc, lp, pb, dummy
|
||||
(res->lit_context_bits << 0) |
|
||||
(res->lit_pos_bits << 8) |
|
||||
(res->pos_bits << 16);
|
||||
if (linker->bele->isBE()) // big endian - bswap32
|
||||
acc_swab32s(&properties);
|
||||
linker->defineSymbol("lzma_properties", properties);
|
||||
// -2 for properties
|
||||
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
||||
@@ -393,16 +395,15 @@ PackLinuxI386::buildLinuxLoader(
|
||||
linker->defineSymbol("NMRU", mru - is_pwr2);
|
||||
}
|
||||
}
|
||||
linker->relocate();
|
||||
return getLoaderSize();
|
||||
relocateLoader();
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxI386::buildLoader(Filter const *ft)
|
||||
{
|
||||
unsigned const sz_fold = sizeof(linux_i386exec_fold);
|
||||
unsigned const sz_fold = sizeof(stub_i386_linux_elf_execve_fold);
|
||||
MemBuffer buf(sz_fold);
|
||||
memcpy(buf, linux_i386exec_fold, sz_fold);
|
||||
memcpy(buf, stub_i386_linux_elf_execve_fold, sz_fold);
|
||||
|
||||
// patch loader
|
||||
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||
@@ -412,17 +413,17 @@ PackLinuxI386::buildLoader(Filter const *ft)
|
||||
patch_le32(buf,sz_fold,"UPX3",progid);
|
||||
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
||||
|
||||
return buildLinuxLoader(
|
||||
linux_i386exec_loader, sizeof(linux_i386exec_loader),
|
||||
buildLinuxLoader(
|
||||
stub_i386_linux_elf_execve_entry, sizeof(stub_i386_linux_elf_execve_entry),
|
||||
buf, sz_fold, ft );
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
PackBSDI386::buildLoader(Filter const *ft)
|
||||
{
|
||||
unsigned const sz_fold = sizeof(bsd_i386exec_fold);
|
||||
unsigned const sz_fold = sizeof(stub_i386_bsd_elf_execve_fold);
|
||||
MemBuffer buf(sz_fold);
|
||||
memcpy(buf, bsd_i386exec_fold, sz_fold);
|
||||
memcpy(buf, stub_i386_bsd_elf_execve_fold, sz_fold);
|
||||
|
||||
// patch loader
|
||||
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||
@@ -432,8 +433,8 @@ PackBSDI386::buildLoader(Filter const *ft)
|
||||
patch_le32(buf,sz_fold,"UPX3",progid);
|
||||
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
||||
|
||||
return buildLinuxLoader(
|
||||
bsd_i386exec_loader, sizeof(bsd_i386exec_loader),
|
||||
buildLinuxLoader(
|
||||
stub_i386_bsd_elf_execve_entry, sizeof(stub_i386_bsd_elf_execve_entry),
|
||||
buf, sz_fold, ft );
|
||||
}
|
||||
|
||||
@@ -449,7 +450,7 @@ int PackLinuxI386::getLoaderPrefixSize() const
|
||||
**************************************************************************/
|
||||
|
||||
// basic check of an Linux ELF Ehdr
|
||||
int PackLinuxI386::checkEhdr(const Elf32_Ehdr *ehdr) const
|
||||
int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||
{
|
||||
const unsigned char * const buf = ehdr->e_ident;
|
||||
|
||||
@@ -499,7 +500,7 @@ bool PackLinuxI386::canPack()
|
||||
if (exetype != 0)
|
||||
return super::canPack();
|
||||
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
unsigned char *buf = ehdr.e_ident;
|
||||
|
||||
fi->seek(0, SEEK_SET);
|
||||
|
||||
+17
-6
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -49,9 +49,10 @@ public:
|
||||
);
|
||||
virtual int getFormat() const { return UPX_F_LINUX_i386; }
|
||||
virtual const char *getName() const { return "linux/386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.execve"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
|
||||
virtual bool canPack();
|
||||
|
||||
@@ -64,7 +65,7 @@ protected:
|
||||
// loader util
|
||||
virtual Linker* newLinker() const;
|
||||
virtual int getLoaderPrefixSize() const;
|
||||
virtual int buildLinuxLoader(
|
||||
virtual void buildLinuxLoader(
|
||||
upx_byte const *const proto, // assembly-only sections
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold, // linked assembly + C section
|
||||
@@ -78,7 +79,7 @@ protected:
|
||||
virtual void updateLoader(OutputFile *);
|
||||
|
||||
// ELF util
|
||||
virtual int checkEhdr(const Elf32_Ehdr *ehdr) const;
|
||||
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const;
|
||||
|
||||
enum {
|
||||
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
||||
@@ -119,6 +120,15 @@ protected:
|
||||
|
||||
unsigned char ei_osabi;
|
||||
char const *osabi_note;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 52 + 1*32 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 52 + 2*32 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 52 + 3*32 + 12)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -129,11 +139,12 @@ public:
|
||||
PackBSDI386(InputFile *f);
|
||||
virtual int getFormat() const { return UPX_F_BSD_i386; }
|
||||
virtual const char *getName() const { return "*BSD/386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-bsd.elf.execve"; }
|
||||
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
};
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
+8
-9
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -147,8 +147,8 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||
}
|
||||
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
initLoader(linux_i386pti_loader, sizeof(linux_i386pti_loader));
|
||||
linker->addSection("FOLDEXEC", linux_i386pti_fold, sizeof(linux_i386pti_fold), 0);
|
||||
initLoader(stub_i386_linux_elf_interp_entry, sizeof(stub_i386_linux_elf_interp_entry));
|
||||
linker->addSection("FOLDEXEC", stub_i386_linux_elf_interp_fold, sizeof(stub_i386_linux_elf_interp_fold), 0);
|
||||
|
||||
addLoader("LXPTI000", NULL);
|
||||
|
||||
@@ -164,9 +164,9 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||
ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI043", NULL);
|
||||
ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
//addLoader("LXPTI043", NULL);
|
||||
//ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
//addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI091", NULL);
|
||||
|
||||
@@ -182,7 +182,6 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||
|
||||
addLoader("LXPTI200", NULL);
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
freezeLoader();
|
||||
upx_byte const *p = getLoader();
|
||||
lsize = getLoaderSize();
|
||||
updateLoader(fo);
|
||||
|
||||
+4
-3
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
|
||||
virtual const char *getName() const { return "linux/elfi386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.interp"; }
|
||||
|
||||
virtual bool canPack();
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
+10
-10
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -71,12 +71,12 @@ umax(unsigned a, unsigned b)
|
||||
return a;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||
{
|
||||
unsigned const sz_fold = sizeof(linux_i386sh_fold);
|
||||
unsigned const sz_fold = sizeof(stub_i386_linux_elf_shell_fold);
|
||||
MemBuffer buf(sz_fold);
|
||||
memcpy(buf, linux_i386sh_fold, sz_fold);
|
||||
memcpy(buf, stub_i386_linux_elf_shell_fold, sz_fold);
|
||||
|
||||
checkPatch(NULL, 0, 0, 0); // reset
|
||||
patch_le32(buf,sz_fold,"UPX3",l_shname);
|
||||
@@ -85,7 +85,7 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||
// get fresh filter
|
||||
Filter fold_ft = *ft;
|
||||
fold_ft.init(ft->id, ft->addvalue);
|
||||
int preferred_ctos[2] = {ft->cto, -1};
|
||||
int preferred_ctos[2] = { ft->cto, -1 };
|
||||
fold_ft.preferred_ctos = preferred_ctos;
|
||||
|
||||
// filter
|
||||
@@ -99,8 +99,8 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
||||
UNUSED(success);
|
||||
|
||||
return buildLinuxLoader(
|
||||
linux_i386sh_loader, sizeof(linux_i386sh_loader),
|
||||
buildLinuxLoader(
|
||||
stub_i386_linux_elf_shell_entry, sizeof(stub_i386_linux_elf_shell_entry),
|
||||
buf, sz_fold, ft );
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ bool PackLinuxI386sh::canPack()
|
||||
void
|
||||
PackLinuxI386sh::pack1(OutputFile *fo, Filter &)
|
||||
{
|
||||
generateElfHdr(fo, linux_i386sh_fold, 0x08048000);
|
||||
generateElfHdr(fo, stub_i386_linux_elf_shell_fold, 0x08048000);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+5
-4
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -47,8 +47,9 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_LINUX_SH_i386; }
|
||||
virtual const char *getName() const { return "linux/sh386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.shell"; }
|
||||
virtual const int *getFilters() const { return NULL; }
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
|
||||
virtual void pack1(OutputFile *fo, Filter &ft);
|
||||
virtual void pack3(OutputFile *fo, Filter &ft);
|
||||
|
||||
+430
-67
@@ -2,7 +2,7 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 2004-2006 John Reiser
|
||||
Copyright (C) 2004-2007 John Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -39,28 +39,46 @@ static const
|
||||
static const
|
||||
#include "stub/powerpc-darwin.macho-fold.h"
|
||||
|
||||
PackMachPPC32::PackMachPPC32(InputFile *f) :
|
||||
super(f), n_segment(0), rawmseg(0), msegcmd(0)
|
||||
static const
|
||||
#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 [] 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.
|
||||
static const int m_nrv2e[] = { M_NRV2E_LE32, -1 };
|
||||
return m_nrv2e;
|
||||
// There really is no LE bias.
|
||||
return Packer::getDefaultCompressionMethods_le32(method, level);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -69,8 +87,14 @@ Linker *PackMachPPC32::newLinker() const
|
||||
return new ElfLinkerPpc32;
|
||||
}
|
||||
|
||||
Linker *PackMachI386::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
PackMachPPC32::addStubEntrySections(Filter const *)
|
||||
PackMachBase<T>::addStubEntrySections(Filter const *)
|
||||
{
|
||||
addLoader("MACOS000", NULL);
|
||||
//addLoader(getDecompressorSections(), NULL);
|
||||
@@ -83,15 +107,79 @@ PackMachPPC32::addStubEntrySections(Filter const *)
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PackMachPPC32::buildMachLoader(
|
||||
template <class T>
|
||||
void
|
||||
PackMachBase<T>::buildMachLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold,
|
||||
@@ -131,24 +219,34 @@ PackMachPPC32::buildMachLoader(
|
||||
|
||||
addStubEntrySections(ft);
|
||||
|
||||
freezeLoader();
|
||||
defineSymbols(ft);
|
||||
linker->relocate();
|
||||
return getLoaderSize();
|
||||
relocateLoader();
|
||||
}
|
||||
|
||||
int
|
||||
PackMachPPC32::buildLoader(const Filter *ft)
|
||||
{
|
||||
return buildMachLoader(
|
||||
l_mac_ppc32_loader, sizeof(l_mac_ppc32_loader),
|
||||
fold_machppc32, sizeof(fold_machppc32), ft );
|
||||
}
|
||||
void PackMachPPC32::patchLoader() { }
|
||||
void PackMachPPC32::updateLoader(OutputFile *) {}
|
||||
|
||||
void
|
||||
PackMachPPC32::patchLoaderChecksum()
|
||||
PackMachPPC32::buildLoader(const Filter *ft)
|
||||
{
|
||||
buildMachLoader(
|
||||
stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry),
|
||||
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
|
||||
}
|
||||
|
||||
void
|
||||
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();
|
||||
l_info *const lp = &linfo;
|
||||
@@ -162,8 +260,9 @@ PackMachPPC32::patchLoaderChecksum()
|
||||
lp->l_checksum = upx_adler32(ptr, lsize);
|
||||
}
|
||||
|
||||
static int __acc_cdecl_qsort
|
||||
compare_segment_command(void const *const aa, void const *const bb)
|
||||
template <class T>
|
||||
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 b = (Mach_segment_command const *)bb;
|
||||
@@ -176,8 +275,7 @@ compare_segment_command(void const *const aa, void const *const bb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
@@ -186,31 +284,59 @@ PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo.vmsize += segcmdo.filesize;
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->write(&segcmdo, sizeof(segcmdo));
|
||||
fo->write(&threado, sizeof(threado));
|
||||
fo->write(&linfo, sizeof(linfo));
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// 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;
|
||||
unsigned const zero = 0;
|
||||
unsigned len = fo->getBytesWritten();
|
||||
fo->write(&zero, 3& -len);
|
||||
len += (3& -len) + sizeof(disp);
|
||||
set_be32(&disp, 4+ len - sz_mach_headers); // 4: sizeof(instruction)
|
||||
fo->write(&zero, 3& (0u-len));
|
||||
len += (3& (0u-len)) + sizeof(disp);
|
||||
disp = 4+ len - sz_mach_headers; // 4: sizeof(instruction)
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
|
||||
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
|
||||
// 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.
|
||||
|
||||
unsigned PackMachPPC32::find_SEGMENT_gap(
|
||||
template <class T>
|
||||
unsigned PackMachBase<T>::find_SEGMENT_gap(
|
||||
unsigned const k
|
||||
)
|
||||
{
|
||||
@@ -218,8 +344,7 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
|
||||
|| 0==msegcmd[k].filesize ) {
|
||||
return 0;
|
||||
}
|
||||
unsigned const hi = get_native32(&msegcmd[k].fileoff) +
|
||||
get_native32(&msegcmd[k].filesize);
|
||||
unsigned const hi = msegcmd[k].fileoff + msegcmd[k].filesize;
|
||||
unsigned lo = ph.u_file_size;
|
||||
unsigned j = k;
|
||||
for (;;) { // circular search, optimize for adjacent ascending
|
||||
@@ -232,7 +357,7 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
|
||||
}
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd
|
||||
&& 0!=msegcmd[j].filesize ) {
|
||||
unsigned const t = get_native32(&msegcmd[j].fileoff);
|
||||
unsigned const t = msegcmd[j].fileoff;
|
||||
if ((t - hi) < (lo - hi)) {
|
||||
lo = t;
|
||||
if (hi==lo) {
|
||||
@@ -244,8 +369,20 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
|
||||
return lo - hi;
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
||||
template <class T>
|
||||
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;
|
||||
unsigned k;
|
||||
@@ -271,6 +408,17 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
||||
uip->ui_pass = 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;
|
||||
for (k = 0; k < n_segment; ++k)
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||
@@ -282,17 +430,20 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
||||
x.offset += 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,
|
||||
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
||||
? &ft : 0 ), fo, hdr_u_len );
|
||||
(do_filter ? &ft : 0 ), fo, hdr_u_len );
|
||||
if (do_filter) {
|
||||
exe_filesize_max = 0;
|
||||
}
|
||||
hdr_u_len = 0;
|
||||
++nx;
|
||||
}
|
||||
for (k = 0; k < n_segment; ++k) {
|
||||
x.size = find_SEGMENT_gap(k);
|
||||
if (x.size) {
|
||||
x.offset = get_native32(&msegcmd[k].fileoff) +
|
||||
get_native32(&msegcmd[k].filesize);
|
||||
x.offset = msegcmd[k].fileoff +msegcmd[k].filesize;
|
||||
packExtent(x, total_in, total_out, 0, fo);
|
||||
}
|
||||
}
|
||||
@@ -306,12 +457,33 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
||||
#undef PAGE_SIZE
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
#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.ncmds = 2;
|
||||
mhdro.sizeofcmds = sizeof(segcmdo) + sizeof(threado);
|
||||
mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;
|
||||
mhdro.flags = Mach_header::MH_NOUNDEFS;
|
||||
fo->write(&mhdro, sizeof(mhdro));
|
||||
|
||||
@@ -331,12 +503,7 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
|
||||
segcmdo.flags = 0;
|
||||
fo->write(&segcmdo, sizeof(segcmdo));
|
||||
|
||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
||||
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));
|
||||
pack1_setup_threado(fo);
|
||||
sz_mach_headers = fo->getBytesWritten();
|
||||
|
||||
memset((char *)&linfo, 0, sizeof(linfo));
|
||||
@@ -345,9 +512,11 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::unpack(OutputFile *fo)
|
||||
template <class T>
|
||||
void PackMachBase<T>::unpack(OutputFile *fo)
|
||||
{
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) +
|
||||
my_thread_command_size + sizeof(linfo);
|
||||
fi->seek(overlay_offset, SEEK_SET);
|
||||
p_info hbuf;
|
||||
fi->readx(&hbuf, sizeof(hbuf));
|
||||
@@ -361,6 +530,8 @@ PackMachPPC32::unpack(OutputFile *fo)
|
||||
fi->readx(&bhdr, sizeof(bhdr));
|
||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
||||
ph.method = bhdr.b_method;
|
||||
ph.filter = bhdr.b_ftid;
|
||||
ph.filter_cto = bhdr.b_cto8;
|
||||
|
||||
// Uncompress Macho headers
|
||||
@@ -398,15 +569,14 @@ PackMachPPC32::unpack(OutputFile *fo)
|
||||
) {
|
||||
if (Mach_segment_command::LC_SEGMENT==sc->cmd
|
||||
&& 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));
|
||||
}
|
||||
}
|
||||
for (unsigned j = 0; j < ncmds; ++j) {
|
||||
unsigned const size = find_SEGMENT_gap(j);
|
||||
if (size) {
|
||||
unsigned const where = get_native32(&msegcmd[k].fileoff) +
|
||||
get_native32(&msegcmd[k].filesize);
|
||||
unsigned const where = msegcmd[k].fileoff +msegcmd[k].filesize;
|
||||
if (fo)
|
||||
fo->seek(where, SEEK_SET);
|
||||
unpackExtent(size, fo, total_in, total_out,
|
||||
@@ -416,14 +586,14 @@ PackMachPPC32::unpack(OutputFile *fo)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackMachPPC32::canPack()
|
||||
template <class T>
|
||||
bool PackMachBase<T>::canPack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&mhdri, sizeof(mhdri));
|
||||
|
||||
if (Mach_header::MH_MAGIC !=mhdri.magic
|
||||
|| Mach_header::CPU_TYPE_POWERPC !=mhdri.cputype
|
||||
|| my_cputype !=mhdri.cputype
|
||||
|| Mach_header::MH_EXECUTE !=mhdri.filetype
|
||||
)
|
||||
return false;
|
||||
@@ -459,11 +629,204 @@ PackMachPPC32::canPack()
|
||||
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
|
||||
opt->o_unix.blocksize = file_size;
|
||||
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
|
||||
*/
|
||||
|
||||
+466
-129
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -29,163 +29,332 @@
|
||||
#ifndef __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 {
|
||||
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;
|
||||
namespace N_Mach {
|
||||
|
||||
struct Mach_segment_command {
|
||||
BE32 cmd;
|
||||
enum {
|
||||
LC_SEGMENT = 0x1,
|
||||
LC_THREAD = 0x4,
|
||||
LC_UNIXTHREAD = 0x5,
|
||||
LC_LOAD_DYLINKER = 0xe
|
||||
};
|
||||
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 */
|
||||
// integral types
|
||||
template <class TWord, class TXword, class TAddr, class TOff>
|
||||
struct MachITypes
|
||||
{
|
||||
typedef TWord Word;
|
||||
typedef TXword Xword;
|
||||
typedef TAddr Addr;
|
||||
typedef TOff Off;
|
||||
};
|
||||
|
||||
struct Mach_thread_command {
|
||||
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||
BE32 cmdsize; /* total size of this command */
|
||||
BE32 flavor;
|
||||
enum {
|
||||
PPC_THREAD_STATE = 1
|
||||
};
|
||||
BE32 count; /* sizeof(following_thread_state)/4 */
|
||||
enum {
|
||||
PPC_THREAD_STATE_COUNT = sizeof(struct Mach_ppc_thread_state)/4
|
||||
};
|
||||
struct Mach_ppc_thread_state state;
|
||||
template <class TMachITypes>
|
||||
struct Mach_header
|
||||
{
|
||||
typedef typename TMachITypes::Word Word;
|
||||
|
||||
Word magic;
|
||||
Word cputype;
|
||||
Word cpysubtype;
|
||||
Word filetype;
|
||||
Word ncmds;
|
||||
Word sizeofcmds;
|
||||
Word flags;
|
||||
#define WANT_MACH_HEADER_ENUM 1
|
||||
#include "p_mach_enum.h"
|
||||
}
|
||||
__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"
|
||||
|
||||
|
||||
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:
|
||||
PackMachPPC32(InputFile *f);
|
||||
virtual ~PackMachPPC32();
|
||||
PackMachBase(InputFile *, unsigned cpuid, unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size);
|
||||
virtual ~PackMachBase();
|
||||
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 *getFilters() const;
|
||||
|
||||
// called by the generic pack()
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||
virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
||||
virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader
|
||||
|
||||
virtual void pack1_setup_threado(OutputFile *const fo) = 0;
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual unsigned find_SEGMENT_gap(unsigned const k);
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void patchLoader();
|
||||
virtual void patchLoaderChecksum();
|
||||
virtual void updateLoader(OutputFile *);
|
||||
virtual int buildMachLoader(
|
||||
virtual void buildMachLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold,
|
||||
@@ -194,6 +363,13 @@ protected:
|
||||
virtual void defineSymbols(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 sz_segment;
|
||||
unsigned sz_mach_headers;
|
||||
@@ -203,11 +379,172 @@ protected:
|
||||
|
||||
Mach_header mhdro;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
+56
-76
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2002-2006 Jens Medoch
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2002-2007 Jens Medoch
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -53,7 +53,7 @@ static const
|
||||
#define K0_BS (0x80000000)
|
||||
#define K1_BS (0xa0000000)
|
||||
#define EXE_BS (ih.epc & K0_BS)
|
||||
#define FIX_PSVR (K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS)
|
||||
#define FIX_PSVR ((K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS))
|
||||
|
||||
// lui / addiu
|
||||
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||
@@ -61,6 +61,7 @@ static const
|
||||
#define MIPS_PC16(a) ((a) >> 2)
|
||||
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// ps1 exe looks like this:
|
||||
// 1. <header> 2048 bytes
|
||||
@@ -81,16 +82,18 @@ PackPs1::PackPs1(InputFile *f) :
|
||||
buildPart2(0), foundBss(0), sa_cnt(0), overlap(0), sz_lunc(0), sz_lcpr(0),
|
||||
pad_code(0), bss_start(0), bss_end(0)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136);
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44);
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5);
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136)
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44)
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_t)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_hb_t)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_chb_t)
|
||||
|
||||
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t))
|
||||
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40)
|
||||
|
||||
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
||||
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
|
||||
#if 0 // 1 || defined(WITH_NRV)
|
||||
COMPILE_TIME_ASSERT(sizeof(nrv_loader) == 14812);
|
||||
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0);
|
||||
#endif
|
||||
fdata_size = file_size - PS_HDR_SIZE;
|
||||
ram_size = !opt->ps1_exe.do_8mb ? 0x200000 : 0x800000;
|
||||
}
|
||||
@@ -110,30 +113,6 @@ const int *PackPs1::getFilters() const
|
||||
|
||||
Linker* PackPs1::newLinker() const
|
||||
{
|
||||
class ElfLinkerMipsLE : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
|
||||
virtual void relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (strcmp(type, "R_MIPS_HI16") == 0)
|
||||
set_le16(location, get_le16(location) + MIPS_HI(value));
|
||||
else if (strcmp(type, "R_MIPS_LO16") == 0)
|
||||
set_le16(location, get_le16(location) + MIPS_LO(value));
|
||||
else if (strcmp(type, "R_MIPS_PC16") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
set_le16(location, get_le16(location) + MIPS_PC16(value));
|
||||
}
|
||||
else if (strcmp(type, "R_MIPS_26") == 0)
|
||||
set_le32(location, get_le32(location) + MIPS_PC26(value));
|
||||
else if (strcmp(type, "R_MIPS_32") == 0)
|
||||
set_le32(location, get_le32(location) + value);
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
};
|
||||
return new ElfLinkerMipsLE;
|
||||
}
|
||||
|
||||
@@ -173,15 +152,15 @@ bool PackPs1::readBkupHeader()
|
||||
}
|
||||
|
||||
#define INIT_BH_BKUP(p, l) {(p)->id = '1'; (p)->len = l;}
|
||||
#define ADLER16(a) ((a) >> 16 ^ ((a) & 0xffff))
|
||||
#define ADLER16(a) (((a) >> 16) ^ ((a) & 0xffff))
|
||||
|
||||
void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len)
|
||||
{
|
||||
unsigned sz_cbh;
|
||||
unsigned sz_cbh = MemBuffer::getSizeForCompression(SZ_IH_BKUP);
|
||||
|
||||
if (src && dst)
|
||||
{
|
||||
unsigned char *cpr_bh = new unsigned char[MemBuffer::getSizeForCompression(SZ_IH_BKUP)];
|
||||
unsigned char *cpr_bh = new unsigned char[sz_cbh];
|
||||
|
||||
memset(cpr_bh, 0, sizeof(bh));
|
||||
ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh;
|
||||
@@ -191,7 +170,7 @@ void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsign
|
||||
if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP)
|
||||
throwInternalError("header compression failed");
|
||||
INIT_BH_BKUP(p, sz_cbh);
|
||||
*len = ALIGN_UP(sz_cbh + sizeof(ps1_exe_chb_t) - 1, 4);
|
||||
*len = ALIGN_UP(sz_cbh + (unsigned) sizeof(ps1_exe_chb_t) - 1, 4u);
|
||||
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
|
||||
memcpy(dst, cpr_bh, SZ_IH_BKUP);
|
||||
delete [] cpr_bh;
|
||||
@@ -300,7 +279,7 @@ bool PackPs1::canPack()
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackPs1::buildLoader(const Filter *)
|
||||
void PackPs1::buildLoader(const Filter *)
|
||||
{
|
||||
const char *method = NULL;
|
||||
|
||||
@@ -322,7 +301,7 @@ int PackPs1::buildLoader(const Filter *)
|
||||
else if (ph.method == M_NRV2E_LE32)
|
||||
method = isCon ? "nrv2e.small,32bit.sub,nrv.done" :
|
||||
"nrv2e.32bit,nrv.done";
|
||||
else if (ph.method == M_LZMA)
|
||||
else if (M_IS_LZMA(ph.method))
|
||||
method = "nrv2b.small,8bit.sub,nrv.done,lzma.prep";
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
@@ -336,14 +315,14 @@ int PackPs1::buildLoader(const Filter *)
|
||||
throwCantPack("packed data overlap (try --force)");
|
||||
}
|
||||
else
|
||||
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp),4);
|
||||
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp), 4u);
|
||||
}
|
||||
|
||||
foundBss = findBssSection();
|
||||
|
||||
if (ph.method == M_LZMA && !buildPart2)
|
||||
if (M_IS_LZMA(ph.method) && !buildPart2)
|
||||
{
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
|
||||
addLoader("decompressor.start",
|
||||
isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
|
||||
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short",
|
||||
@@ -351,7 +330,7 @@ int PackPs1::buildLoader(const Filter *)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ph.method == M_LZMA && buildPart2)
|
||||
if (M_IS_LZMA(ph.method) && buildPart2)
|
||||
{
|
||||
sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc);
|
||||
unsigned char *cprLoader = new unsigned char[sz_lcpr];
|
||||
@@ -359,20 +338,22 @@ int PackPs1::buildLoader(const Filter *)
|
||||
NULL, M_NRV2B_8, 10, NULL, NULL );
|
||||
if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
|
||||
throwInternalError("loader compression failed");
|
||||
initLoader(nrv_loader, sizeof(nrv_loader),
|
||||
(ph.method != M_LZMA || isCon) ? 0 : 1);
|
||||
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1),
|
||||
isCon || !M_IS_LZMA(ph.method) ? 0 : 1);
|
||||
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
|
||||
delete [] cprLoader;
|
||||
}
|
||||
else
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
|
||||
|
||||
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4);
|
||||
linker->addSection("pad.code", &pad_code, pad_code, 0);
|
||||
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4u);
|
||||
assert(pad_code < 4);
|
||||
static const unsigned char pad_buffer[4] = { 0, 0, 0, 0 };
|
||||
linker->addSection("pad.code", pad_buffer, pad_code, 0);
|
||||
|
||||
if (isCon)
|
||||
{
|
||||
if (ph.method == M_LZMA)
|
||||
if (M_IS_LZMA(ph.method))
|
||||
addLoader(!foundBss ? "con.start" : "bss.con.start",
|
||||
method,
|
||||
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||
@@ -388,7 +369,7 @@ int PackPs1::buildLoader(const Filter *)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ph.method == M_LZMA)
|
||||
if (M_IS_LZMA(ph.method))
|
||||
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
|
||||
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||
"lzma.exec", NULL);
|
||||
@@ -402,8 +383,6 @@ int PackPs1::buildLoader(const Filter *)
|
||||
}
|
||||
addLoader("UPX1HEAD", "IDENTSTR", NULL);
|
||||
}
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
#define OPTYPE(x) (((x) >> 13) & 0x7)
|
||||
@@ -411,7 +390,7 @@ int PackPs1::buildLoader(const Filter *)
|
||||
#define REG1(x) (((x) >> 5) & 0x1f)
|
||||
#define REG2(x) ((x) & 0x1f)
|
||||
|
||||
#define MIPS_IMM(a,b) (((a) - (((b) & 0x8000) >> 15) << 16) | (b))
|
||||
#define MIPS_IMM(a,b) ((((a) - (((b) & 0x8000) >> 15)) << 16) | (b))
|
||||
|
||||
// Type
|
||||
#define REGIMM 1
|
||||
@@ -461,12 +440,12 @@ bool PackPs1::findBssSection()
|
||||
bss_start = MIPS_IMM(p->hi1, p->lo1);
|
||||
bss_end = MIPS_IMM(p->hi2, p->lo2);
|
||||
|
||||
if (0 < ALIGN_DOWN(bss_end - bss_start, 4) )
|
||||
if (0 < ALIGN_DOWN(bss_end - bss_start, 4u))
|
||||
{
|
||||
unsigned wkmem_sz = (ph.method == M_LZMA) ? 32768 : 800;
|
||||
unsigned wkmem_sz = M_IS_LZMA(ph.method) ? 32768 : 800;
|
||||
unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
|
||||
if (bss_end > (end_offs + wkmem_sz))
|
||||
return (isCon || (!isCon && (ph.method == M_LZMA)));
|
||||
return isCon || (!isCon && M_IS_LZMA(ph.method));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -500,9 +479,9 @@ void PackPs1::pack(OutputFile *fo)
|
||||
while (!(*--p_scan)) { if (sa_cnt++ > (0x10000 << 5) || sa_cnt >= fdata_size - 1024) break; }
|
||||
|
||||
if (sa_cnt > (0x10000 << 2))
|
||||
sa_cnt = ALIGN_DOWN(sa_cnt,32);
|
||||
sa_cnt = ALIGN_DOWN(sa_cnt, 32u);
|
||||
else
|
||||
sa_cnt = ALIGN_DOWN(sa_cnt,4);
|
||||
sa_cnt = ALIGN_DOWN(sa_cnt, 4u);
|
||||
|
||||
// prepare packheader
|
||||
ph.u_len = (fdata_size - sa_cnt);
|
||||
@@ -513,7 +492,7 @@ void PackPs1::pack(OutputFile *fo)
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_ucl.max_match = 65535;
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, sa_cnt, 0, NULL, &cconf);
|
||||
compressWithFilters(&ft, sa_cnt, &cconf);
|
||||
|
||||
if (overlap)
|
||||
{
|
||||
@@ -529,7 +508,7 @@ void PackPs1::pack(OutputFile *fo)
|
||||
|
||||
unsigned lzma_init = 0;
|
||||
|
||||
if (ph.method == M_LZMA)
|
||||
if (M_IS_LZMA(ph.method))
|
||||
{
|
||||
sz_lunc = getLoaderSize();
|
||||
|
||||
@@ -538,7 +517,7 @@ void PackPs1::pack(OutputFile *fo)
|
||||
linker->defineSymbol("entry", ih.epc);
|
||||
linker->defineSymbol("SC",
|
||||
sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
|
||||
buildPart2 = true;
|
||||
buildLoader(&ft);
|
||||
@@ -558,8 +537,6 @@ void PackPs1::pack(OutputFile *fo)
|
||||
oh.bs_ptr = oh.bs_len = 0;
|
||||
|
||||
const int lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
unsigned filelen = ALIGN_UP(ih.tx_len, 4);
|
||||
|
||||
@@ -577,7 +554,7 @@ void PackPs1::pack(OutputFile *fo)
|
||||
}
|
||||
else
|
||||
{
|
||||
d_len = (lsize - h_len) - getLoaderSectionStart((ph.method == M_LZMA) ? "cdb.entry.lzma" : "cdb.entry");
|
||||
d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? "cdb.entry.lzma" : "cdb.entry");
|
||||
e_len = (lsize - d_len) - h_len;
|
||||
}
|
||||
|
||||
@@ -585,10 +562,10 @@ void PackPs1::pack(OutputFile *fo)
|
||||
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
|
||||
sa_cnt >> 5 : sa_cnt >> 2));
|
||||
linker->defineSymbol("DECO", decomp_data_start);
|
||||
linker->defineSymbol("ldr_sz", (ph.method == M_LZMA ? sz_lunc + 16 : (d_len-pad_code)));
|
||||
linker->defineSymbol("ldr_sz", M_IS_LZMA(ph.method) ? sz_lunc + 16 : (d_len-pad_code));
|
||||
|
||||
if (foundBss)
|
||||
if (ph.method == M_LZMA)
|
||||
if (M_IS_LZMA(ph.method))
|
||||
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
|
||||
- (sz_lunc + 16));
|
||||
else
|
||||
@@ -612,7 +589,7 @@ void PackPs1::pack(OutputFile *fo)
|
||||
ibuf.clear(0,fdata_size);
|
||||
upx_bytep paddata = ibuf;
|
||||
|
||||
if (ph.method == M_LZMA)
|
||||
if (M_IS_LZMA(ph.method))
|
||||
{
|
||||
linker->defineSymbol("lzma_init_off", lzma_init);
|
||||
linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));
|
||||
@@ -624,7 +601,7 @@ void PackPs1::pack(OutputFile *fo)
|
||||
if (isCon)
|
||||
{
|
||||
linker->defineSymbol("PAD", pad_code);
|
||||
if (ph.method == M_LZMA)
|
||||
if (M_IS_LZMA(ph.method))
|
||||
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
|
||||
else
|
||||
linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
|
||||
@@ -633,16 +610,19 @@ void PackPs1::pack(OutputFile *fo)
|
||||
{
|
||||
linker->defineSymbol("PSVR", FIX_PSVR);
|
||||
linker->defineSymbol("CPDO", comp_data_start);
|
||||
if (ph.method == M_LZMA)
|
||||
if (M_IS_LZMA(ph.method))
|
||||
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
|
||||
- getLoaderSectionStart("cdb.entry.lzma"));
|
||||
}
|
||||
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
//linker->dumpSymbols();
|
||||
MemBuffer loader(lsize);
|
||||
assert(lsize == getLoaderSize());
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
if (!isCon && ph.method == M_LZMA && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
|
||||
if (!isCon && M_IS_LZMA(ph.method) && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
|
||||
throwInternalError("lzma --boot-only loader > 2048");
|
||||
|
||||
// ps1_exe_t structure
|
||||
@@ -676,7 +656,7 @@ void PackPs1::pack(OutputFile *fo)
|
||||
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
|
||||
unsigned char i = 0;
|
||||
if (isCon) { if (foundBss) i = 1; }
|
||||
else { i = 2; if (ph.method == M_LZMA) { if (!foundBss) i = 3; else i = 4; } }
|
||||
else { i = 2; if (M_IS_LZMA(ph.method)) { if (!foundBss) i = 3; else i = 4; } }
|
||||
const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };
|
||||
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
|
||||
printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
|
||||
|
||||
+6
-5
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2002-2006 Jens Medoch
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2002-2007 Jens Medoch
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_PS1_EXE; }
|
||||
virtual const char *getName() const { return "ps1/exe"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "mipsel.r3000-ps1"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -59,7 +60,7 @@ protected:
|
||||
virtual void putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len);
|
||||
virtual bool getBkupHeader(unsigned char *src, unsigned char * dst);
|
||||
virtual bool readBkupHeader();
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual bool findBssSection();
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
@@ -111,7 +112,7 @@ protected:
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
typedef struct bss_nfo
|
||||
struct bss_nfo
|
||||
{
|
||||
LE16 hi1, op1, lo1, op2;
|
||||
LE16 hi2, op3, lo2, op4;
|
||||
|
||||
+7
-8
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -70,7 +70,7 @@ void PackSys::patchLoader(OutputFile *fo,
|
||||
{
|
||||
const int e_len = getLoaderSectionStart("SYSCUTPO");
|
||||
const int d_len = lsize - e_len;
|
||||
assert(e_len > 0 && e_len < 256);
|
||||
assert(e_len > 0 && e_len < 128);
|
||||
assert(d_len > 0 && d_len < 256);
|
||||
|
||||
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
|
||||
@@ -85,10 +85,11 @@ void PackSys::patchLoader(OutputFile *fo,
|
||||
linker->defineSymbol("calltrick_calls", calls);
|
||||
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||
linker->defineSymbol("copy_destination", copy_to);
|
||||
linker->defineSymbol("neg_e_len", 0 - e_len);
|
||||
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead + 1);
|
||||
linker->defineSymbol("original_strategy", get_le16(ibuf + 6));
|
||||
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
loader = getLoader();
|
||||
|
||||
patchPackHeader(loader,e_len);
|
||||
@@ -99,9 +100,9 @@ void PackSys::patchLoader(OutputFile *fo,
|
||||
}
|
||||
|
||||
|
||||
int PackSys::buildLoader(const Filter *ft)
|
||||
void PackSys::buildLoader(const Filter *ft)
|
||||
{
|
||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
||||
initLoader(stub_i086_dos16_sys, sizeof(stub_i086_dos16_sys));
|
||||
addLoader("SYSMAIN1",
|
||||
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
|
||||
"SYSMAIN2",
|
||||
@@ -122,8 +123,6 @@ int PackSys::buildLoader(const Filter *ft)
|
||||
"SYSJUMP1",
|
||||
NULL
|
||||
);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_DOS_SYS; }
|
||||
virtual const char *getName() const { return "dos/sys"; }
|
||||
virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.sys" : "i286-dos16.sys"; }
|
||||
|
||||
virtual bool canPack();
|
||||
|
||||
@@ -49,7 +50,7 @@ protected:
|
||||
virtual unsigned getCallTrickOffset() const { return 0; }
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
||||
};
|
||||
|
||||
|
||||
+18
-26
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -45,6 +45,7 @@ static const
|
||||
|
||||
PackTmt::PackTmt(InputFile *f) : super(f)
|
||||
{
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44);
|
||||
}
|
||||
|
||||
@@ -58,8 +59,9 @@ const int *PackTmt::getCompressionMethods(int method, int level) const
|
||||
const int *PackTmt::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x12, 0x15,
|
||||
-1 };
|
||||
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
||||
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -81,11 +83,13 @@ Linker* PackTmt::newLinker() const
|
||||
}
|
||||
|
||||
|
||||
int PackTmt::buildLoader(const Filter *ft)
|
||||
void PackTmt::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||
initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt));
|
||||
addLoader("IDENTSTR,TMTMAIN1",
|
||||
ph.first_offset_found == 1 ? "TMTMAIN1A" : "",
|
||||
"TMTMAIN1B",
|
||||
ft->id ? "TMTCALT1" : "",
|
||||
"TMTMAIN2,UPX1HEAD,TMTCUTPO",
|
||||
NULL);
|
||||
@@ -105,8 +109,6 @@ int PackTmt::buildLoader(const Filter *ft)
|
||||
"RELOC32J,TMTJUMP1",
|
||||
NULL
|
||||
);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +171,7 @@ int PackTmt::readFileHeader()
|
||||
|
||||
fi->seek(adam_offset,SEEK_SET);
|
||||
fi->readx(&ih,sizeof(ih));
|
||||
// FIXME: should add some checks for the values in `ih'
|
||||
// FIXME: should add some checks for the values in 'ih'
|
||||
|
||||
return UPX_F_TMT_ADAM;
|
||||
#undef H4
|
||||
@@ -185,19 +187,6 @@ bool PackTmt::canPack()
|
||||
}
|
||||
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
return false;
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
@@ -250,7 +239,10 @@ void PackTmt::pack(OutputFile *fo)
|
||||
Filter ft(ph.level);
|
||||
ft.buf_len = usize;
|
||||
// compress
|
||||
compressWithFilters(&ft, 512);
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
// limit stack size needed for runtime decompression
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 512, &cconf);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
||||
@@ -260,17 +252,17 @@ void PackTmt::pack(OutputFile *fo)
|
||||
|
||||
// patch loader
|
||||
linker->defineSymbol("original_entry", ih.entry);
|
||||
defineFilterSymbols(linker, &ft);
|
||||
defineDecompressorSymbols();
|
||||
defineFilterSymbols(&ft);
|
||||
|
||||
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len);
|
||||
linker->defineSymbol("copy_dest", ph.u_len + ph.overlap_overhead + d_len - 1);
|
||||
linker->defineSymbol("copy_dest", 0u - (ph.u_len + ph.overlap_overhead + d_len - 1));
|
||||
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n",
|
||||
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
|
||||
|
||||
linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead);
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader,getLoader(),lsize);
|
||||
|
||||
+4
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_TMT_ADAM; }
|
||||
virtual const char *getName() const { return "tmt/adam"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-dos32.tmt"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -57,7 +58,7 @@ protected:
|
||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||
unsigned range = 0,
|
||||
unsigned upper_limit = ~0u) const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
unsigned adam_offset;
|
||||
|
||||
+332
-260
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -37,7 +37,7 @@
|
||||
static const
|
||||
#include "stub/m68k-atari.tos.h"
|
||||
|
||||
// #define TESTING
|
||||
//#define TESTING 1
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -49,6 +49,7 @@ static const
|
||||
PackTos::PackTos(InputFile *f) :
|
||||
super(f)
|
||||
{
|
||||
bele = &N_BELE_RTP::be_policy;
|
||||
COMPILE_TIME_ASSERT(FH_SIZE == 28);
|
||||
}
|
||||
|
||||
@@ -72,42 +73,171 @@ Linker* PackTos::newLinker() const
|
||||
}
|
||||
|
||||
|
||||
int PackTos::buildLoader(const Filter *ft)
|
||||
void PackTos::LinkerSymbols::LoopInfo::init(unsigned count_, bool allow_dbra)
|
||||
{
|
||||
count = value = count_;
|
||||
if (count == 0)
|
||||
mode = LOOP_NONE;
|
||||
else if (count <= 65536 && allow_dbra)
|
||||
{
|
||||
mode = LOOP_DBRA;
|
||||
value -= 1;
|
||||
value &= 0xffff;
|
||||
}
|
||||
else if (count <= 65536)
|
||||
{
|
||||
mode = LOOP_SUBQ_W;
|
||||
value &= 0xffff;
|
||||
}
|
||||
else
|
||||
mode = LOOP_SUBQ_L;
|
||||
}
|
||||
|
||||
|
||||
unsigned PackTos::getDecomprOffset(int method, int small) const
|
||||
{
|
||||
UNUSED(small);
|
||||
if (M_IS_NRV2B(method))
|
||||
return 2; // FIXME: do not hardcode this value
|
||||
else if (M_IS_NRV2D(method))
|
||||
return 2; // FIXME: do not hardcode this value
|
||||
else if (M_IS_NRV2E(method))
|
||||
return 2; // FIXME: do not hardcode this value
|
||||
else if (M_IS_LZMA(method))
|
||||
return linker->getSectionSize("__mulsi3");
|
||||
else
|
||||
throwBadLoader();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PackTos::buildLoader(const Filter *ft)
|
||||
{
|
||||
assert(ft->id == 0);
|
||||
|
||||
const unsigned char *p = NULL;
|
||||
size_t l = 0;
|
||||
initLoader(stub_m68k_atari_tos, sizeof(stub_m68k_atari_tos));
|
||||
//linker->dumpSymbols();
|
||||
|
||||
//
|
||||
// part 1a
|
||||
//
|
||||
|
||||
addLoader("entry");
|
||||
|
||||
if (symbols.up21_a6 <= 32767)
|
||||
addLoader("set_up21_a6.w");
|
||||
else if (symbols.up21_d4 <= 32767)
|
||||
addLoader("set_up21_d4.w");
|
||||
else
|
||||
addLoader("set_up21_d4.l");
|
||||
|
||||
assert(symbols.loop1.count || symbols.loop2.count);
|
||||
if (symbols.loop1.count)
|
||||
{
|
||||
if (symbols.loop1.value <= 127)
|
||||
addLoader("loop1_set_count.b");
|
||||
else if (symbols.loop1.value <= 65535)
|
||||
addLoader("loop1_set_count.w");
|
||||
else
|
||||
addLoader("loop1_set_count.l");
|
||||
addLoader("loop1_label");
|
||||
addLoader(opt->small ? "loop1.small" : "loop1.fast");
|
||||
if (symbols.loop1.mode == symbols.LOOP_SUBQ_L)
|
||||
addLoader("loop1_subql");
|
||||
else if (symbols.loop1.mode == symbols.LOOP_SUBQ_W)
|
||||
addLoader("loop1_subqw");
|
||||
else if (symbols.loop1.mode == symbols.LOOP_DBRA)
|
||||
addLoader("loop1_dbra");
|
||||
else
|
||||
throwBadLoader();
|
||||
}
|
||||
if (symbols.loop2.count)
|
||||
{
|
||||
assert(symbols.loop2.mode == symbols.LOOP_DBRA);
|
||||
addLoader(opt->small ? "loop2.small" : "loop2.fast");
|
||||
}
|
||||
|
||||
addLoader("copy_to_stack");
|
||||
|
||||
if (M_IS_NRV2B(ph.method))
|
||||
addLoader("nrv2b.init");
|
||||
else if (M_IS_NRV2D(ph.method))
|
||||
addLoader("nrv2d.init");
|
||||
else if (M_IS_NRV2E(ph.method))
|
||||
addLoader("nrv2e.init");
|
||||
else if (M_IS_LZMA(ph.method))
|
||||
addLoader("lzma.init");
|
||||
else
|
||||
throwBadLoader();
|
||||
|
||||
symbols.up31_d4 = symbols.up31_base_d4 + getDecomprOffset(ph.method, opt->small);
|
||||
symbols.up31_a6 = symbols.up31_base_a6 + getDecomprOffset(ph.method, opt->small);
|
||||
if (symbols.up31_a6 <= 32767)
|
||||
addLoader("jmp_decompressor_a6.w");
|
||||
else if (symbols.up31_d4 <= 32767)
|
||||
addLoader("jmp_decompressor_d4.w");
|
||||
else if (symbols.up31_a6 <= 65534)
|
||||
addLoader("jmp_decompressor_a6.w2");
|
||||
else
|
||||
addLoader("jmp_decompressor_d4.l");
|
||||
|
||||
//
|
||||
// part 1b
|
||||
//
|
||||
|
||||
addLoader("code_on_stack");
|
||||
|
||||
addLoader("clear_dirty_bss");
|
||||
addLoader("loop3_label");
|
||||
addLoader(opt->small ? "loop3.small" : "loop3.fast");
|
||||
if (symbols.loop3.mode == symbols.LOOP_SUBQ_L)
|
||||
addLoader("loop3_subql");
|
||||
else if (symbols.loop3.mode == symbols.LOOP_SUBQ_W)
|
||||
addLoader("loop3_subqw");
|
||||
else if (symbols.loop3.mode == symbols.LOOP_DBRA)
|
||||
addLoader("loop3_dbra");
|
||||
else
|
||||
throwBadLoader();
|
||||
|
||||
addLoader("flush_cache");
|
||||
addLoader("restore_stack");
|
||||
#if 0
|
||||
addLoader("clear_dirty_stack");
|
||||
#endif
|
||||
addLoader("start_program");
|
||||
|
||||
addLoader("IDENTSTR,+40D,UPX1HEAD,CUTPOINT");
|
||||
|
||||
//
|
||||
// part 2
|
||||
//
|
||||
|
||||
p = nrv_loader;
|
||||
if (M_IS_NRV2B(ph.method)) {
|
||||
// p = opt->small ? nrv2b_loader_small : nrv2b_loader;
|
||||
// l = opt->small ? sizeof(nrv2b_loader_small) : sizeof(nrv2b_loader);
|
||||
addLoader(opt->small ? "nrv2b_8.small" : "nrv2b_8.fast");
|
||||
} else if (M_IS_NRV2D(ph.method)) {
|
||||
addLoader(opt->small ? "nrv2d_8.small" : "nrv2d_8.fast");
|
||||
} else if (M_IS_NRV2E(ph.method)) {
|
||||
addLoader(opt->small ? "nrv2e_8.small" : "nrv2e_8.fast");
|
||||
} else if (M_IS_LZMA(ph.method)) {
|
||||
addLoader("__mulsi3");
|
||||
addLoader(opt->small ? "lzma.small" : "lzma.fast");
|
||||
addLoader("lzma.finish");
|
||||
}
|
||||
if (M_IS_NRV2D(ph.method)) {
|
||||
// p = opt->small ? nrv2d_loader_small : nrv2d_loader;
|
||||
// l = opt->small ? sizeof(nrv2d_loader_small) : sizeof(nrv2d_loader);
|
||||
}
|
||||
if (M_IS_NRV2E(ph.method)) {
|
||||
// p = opt->small ? nrv2e_loader_small : nrv2e_loader;
|
||||
// l = opt->small ? sizeof(nrv2e_loader_small) : sizeof(nrv2e_loader);
|
||||
}
|
||||
initLoader(p, l);
|
||||
else
|
||||
throwBadLoader();
|
||||
|
||||
addLoader("tos0",
|
||||
true ? "subql_1d0" : "subqw_1d0",
|
||||
"s_bneloop0",
|
||||
true ? "subql_1d6" : "subqw_1d6",
|
||||
"s_bneloop3",
|
||||
"IDENTSTR,+40,UPX1HEAD",
|
||||
"CUTPOINT",
|
||||
true ? "reloc" : "",
|
||||
"jmpastack",
|
||||
NULL
|
||||
);
|
||||
if (symbols.need_reloc)
|
||||
addLoader("reloc");
|
||||
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
assert(symbols.loop3.count);
|
||||
if (symbols.loop3.value <= 127)
|
||||
addLoader("loop3_set_count.b");
|
||||
else if (symbols.loop3.value <= 65535)
|
||||
addLoader("loop3_set_count.w");
|
||||
else
|
||||
addLoader("loop3_set_count.l");
|
||||
|
||||
addLoader("jmp_stack");
|
||||
}
|
||||
|
||||
|
||||
@@ -177,142 +307,25 @@ bool PackTos::checkFileHeader()
|
||||
if ((f & F_PROTMODE) != F_PROT_P)
|
||||
{
|
||||
if (opt->force < 1)
|
||||
throwCantPack("no private memory protection; use option `-f' to force packing");
|
||||
throwCantPack("no private memory protection; use option '-f' to force packing");
|
||||
}
|
||||
if (f & F_SHTEXT)
|
||||
{
|
||||
if (opt->force < 1)
|
||||
throwCantPack("shared text segment; use option `-f' to force packing");
|
||||
throwCantPack("shared text segment; use option '-f' to force packing");
|
||||
}
|
||||
#if 0
|
||||
// fh_reserved seems to be unused
|
||||
if (ih.fh_reserved != 0)
|
||||
{
|
||||
if (opt->force < 1)
|
||||
throwCantPack("reserved header field set; use option `-f' to force packing");
|
||||
throwCantPack("reserved header field set; use option '-f' to force packing");
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// some 68000 opcodes for patching
|
||||
**************************************************************************/
|
||||
|
||||
#if 0
|
||||
enum m68k_reg_t {
|
||||
REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
|
||||
REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7
|
||||
};
|
||||
|
||||
static unsigned OP_DBRA(int d_reg)
|
||||
{
|
||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
||||
return 0x51c8 | (d_reg & 7);
|
||||
}
|
||||
|
||||
static unsigned OP_JMP(int a_reg)
|
||||
{
|
||||
// jmp (a0)
|
||||
assert(a_reg >= REG_A0 && a_reg <= REG_A7);
|
||||
return 0x4ed0 | (a_reg & 7);
|
||||
}
|
||||
|
||||
static unsigned OP_MOVEI_L(int d_reg)
|
||||
{
|
||||
// movei.l #XXXXXXXX,d0
|
||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
||||
return 0x203c | ((d_reg & 7) << 9);
|
||||
}
|
||||
|
||||
static unsigned OP_MOVEQ(int value, int d_reg)
|
||||
{
|
||||
// moveq.l #0,d0
|
||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
||||
assert(value >= -128 && value <= 127);
|
||||
return 0x7000 | ((d_reg & 7) << 9) | (value & 0xff);
|
||||
}
|
||||
|
||||
static unsigned OP_SUBQ_L(int value, int d_reg)
|
||||
{
|
||||
// subq.l #X,d0
|
||||
assert(value >= 1 && value <= 8);
|
||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
||||
return 0x5180 | ((value & 7) << 9) | (d_reg & 7);
|
||||
}
|
||||
|
||||
static unsigned OP_SUBQ_W(int value, int d_reg)
|
||||
{
|
||||
// subq.w #X,d0
|
||||
assert(value >= 1 && value <= 8);
|
||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
||||
return 0x5140 | ((value & 7) << 9) | (d_reg & 7);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
unsigned PackTos::patch_d_subq(void *b, int blen,
|
||||
int d_reg, unsigned d_value,
|
||||
const char *subq_marker)
|
||||
{
|
||||
// patch a "subq.l #1,d0" or "subq.w #1,d0".
|
||||
// also convert into "dbra" if possible
|
||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
||||
assert((int)d_value > 0);
|
||||
|
||||
int boff = find_be16(b, blen, get_be16(subq_marker));
|
||||
if (boff < 0)
|
||||
throwBadLoader();
|
||||
|
||||
upx_byte *p = (upx_byte *)b + boff;
|
||||
if (p[2] == 0x66) // bne.b XXX
|
||||
checkPatch(b, blen, boff, 4);
|
||||
else
|
||||
checkPatch(b, blen, boff, 2);
|
||||
|
||||
if (d_value > 65536)
|
||||
{
|
||||
set_be16(p, OP_SUBQ_L(1, d_reg)); // subq.l #1,d0
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p[2] == 0x66) // bne.b XXX
|
||||
{
|
||||
set_be16(p, OP_DBRA(d_reg)); // dbra d0,XXX
|
||||
// adjust and extend branch from 8 to 16 bits
|
||||
int branch = (signed char) p[3];
|
||||
set_be16(p+2, branch+2);
|
||||
// adjust d0
|
||||
d_value -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_be16(p, OP_SUBQ_W(1, d_reg)); // subq.w #1,d0
|
||||
}
|
||||
d_value &= 0xffff;
|
||||
}
|
||||
return d_value;
|
||||
}
|
||||
|
||||
|
||||
unsigned PackTos::patch_d_loop(void *b, int blen,
|
||||
int d_reg, unsigned d_value,
|
||||
const char *d_marker, const char *subq_marker)
|
||||
{
|
||||
d_value = patch_d_subq(b, blen, d_reg, d_value, subq_marker);
|
||||
|
||||
int boff = find_be32(b, blen, get_be32(d_marker));
|
||||
checkPatch(b, blen, boff, 4);
|
||||
upx_byte *p = (upx_byte *)b + boff;
|
||||
assert(get_be16(p - 2) == OP_MOVEI_L(d_reg)); // move.l #XXXXXXXX,d0
|
||||
set_be32(p, d_value);
|
||||
return d_value;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
// relocs
|
||||
**************************************************************************/
|
||||
@@ -366,18 +379,6 @@ static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
|
||||
|
||||
bool PackTos::canPack()
|
||||
{
|
||||
#if 0 // debug
|
||||
# define p(x) printf("%-30s 0x%04x\n", #x, x)
|
||||
p(OP_DBRA(REG_D0));
|
||||
p(OP_MOVEI_L(REG_D0));
|
||||
p(OP_MOVEQ(-1, REG_D0));
|
||||
p(OP_MOVEQ(1, REG_D2));
|
||||
p(OP_MOVEQ(1, REG_D3));
|
||||
p(OP_SUBQ_W(1, REG_D0));
|
||||
p(OP_SUBQ_L(1, REG_D0));
|
||||
# undef p
|
||||
#endif
|
||||
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
|
||||
@@ -409,7 +410,6 @@ void PackTos::fileInfo()
|
||||
|
||||
void PackTos::pack(OutputFile *fo)
|
||||
{
|
||||
throwInternalError("atari/tos is currenty broken; this will get fixed in UPX 2.91");
|
||||
unsigned t;
|
||||
unsigned nrelocs = 0;
|
||||
unsigned relocsize = 0;
|
||||
@@ -421,6 +421,15 @@ void PackTos::pack(OutputFile *fo)
|
||||
const unsigned i_bss = ih.fh_bss;
|
||||
|
||||
symbols.reset();
|
||||
symbols.need_reloc = false;
|
||||
// prepare symbols for buildLoader() - worst case
|
||||
symbols.loop1.init(65536 + 1);
|
||||
symbols.loop2.init((160 - 1) / 4);
|
||||
symbols.loop3.init(65536 + 1);
|
||||
symbols.up21_d4 = 65536 + 1;
|
||||
symbols.up21_a6 = 65536 + 1;
|
||||
symbols.up31_base_d4 = 65536 + 1;
|
||||
symbols.up31_base_a6 = 65536 + 1;
|
||||
|
||||
// read file
|
||||
const unsigned isize = file_size - i_sym;
|
||||
@@ -430,6 +439,8 @@ void PackTos::pack(OutputFile *fo)
|
||||
t = i_text + i_data;
|
||||
fi->readx(ibuf,t);
|
||||
// skip symbols
|
||||
if (i_sym && opt->exact)
|
||||
throwCantPackExact();
|
||||
fi->seek(i_sym,SEEK_CUR);
|
||||
// read relocations + overlay
|
||||
overlay = file_size - (FH_SIZE + i_text + i_data + i_sym);
|
||||
@@ -443,7 +454,6 @@ void PackTos::pack(OutputFile *fo)
|
||||
|
||||
// Check relocs (see load_and_reloc() in freemint/sys/memory.c).
|
||||
// Must work around TOS bugs and lots of broken programs.
|
||||
int r = 0;
|
||||
if (overlay < 4)
|
||||
{
|
||||
// Bug workaround: Whatever this is, silently keep it in
|
||||
@@ -459,15 +469,17 @@ void PackTos::pack(OutputFile *fo)
|
||||
}
|
||||
else if (ih.fh_reloc != 0)
|
||||
relocsize = 0;
|
||||
else
|
||||
r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
|
||||
else {
|
||||
int r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
|
||||
if (r != 0)
|
||||
throwCantPack("bad relocation table");
|
||||
symbols.need_reloc = true;
|
||||
}
|
||||
|
||||
#if 0 || defined(TESTING)
|
||||
printf("xx2: %d relocs: %d, overlay: %d, t: %d\n", nrelocs, relocsize, overlay, t);
|
||||
#endif
|
||||
|
||||
if (r != 0)
|
||||
throwCantPack("bad relocation table");
|
||||
checkOverlay(overlay);
|
||||
|
||||
// Append original fileheader.
|
||||
@@ -485,8 +497,8 @@ void PackTos::pack(OutputFile *fo)
|
||||
// After compression this will become the first part of the
|
||||
// data segement. The second part will be the decompressor.
|
||||
|
||||
// alloc buffer (2048 is for decompressor and the various alignments)
|
||||
obuf.allocForCompression(t, 2048);
|
||||
// alloc buffer (4096 is for decompressor and the various alignments)
|
||||
obuf.allocForCompression(t, 4096);
|
||||
|
||||
// prepare packheader
|
||||
ph.u_len = t;
|
||||
@@ -495,102 +507,163 @@ void PackTos::pack(OutputFile *fo)
|
||||
// compress (max_match = 65535)
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_ucl.max_match = 65535;
|
||||
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 512, &cconf);
|
||||
|
||||
// get loader
|
||||
const unsigned lsize = getLoaderSize();
|
||||
const unsigned e_len = getLoaderSectionStart("CUTPOINT");
|
||||
const unsigned d_len = lsize - e_len;
|
||||
const unsigned decomp_offset = linker->getSymbolOffset("decompr_start") - e_len;
|
||||
assert(decomp_offset != 0xdeaddead);
|
||||
assert((e_len & 3) == 0 && (d_len & 1) == 0);
|
||||
//
|
||||
// multipass buildLoader()
|
||||
//
|
||||
|
||||
// The decompressed data will now get placed at this offset:
|
||||
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
||||
// save initial loader
|
||||
const unsigned initial_lsize = getLoaderSize();
|
||||
unsigned last_lsize = initial_lsize;
|
||||
MemBuffer last_loader(last_lsize);
|
||||
memcpy(last_loader, getLoader(), last_lsize);
|
||||
|
||||
// compute addresses
|
||||
unsigned o_text, o_data, o_bss;
|
||||
o_text = e_len;
|
||||
o_data = ph.c_len;
|
||||
o_bss = i_bss;
|
||||
|
||||
// word align len of compressed data
|
||||
while (o_data & 1)
|
||||
unsigned e_len, d_len, d_off;
|
||||
for (;;)
|
||||
{
|
||||
obuf[o_data++] = 0;
|
||||
offset++;
|
||||
}
|
||||
// The decompressed data will now get placed at this offset:
|
||||
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
||||
|
||||
// append decompressor (part 2 of loader)
|
||||
const unsigned d_off = o_data;
|
||||
o_data += d_len;
|
||||
// get loader
|
||||
const unsigned lsize = getLoaderSize();
|
||||
e_len = getLoaderSectionStart("CUTPOINT");
|
||||
d_len = lsize - e_len;
|
||||
assert((e_len & 3) == 0 && (d_len & 1) == 0);
|
||||
|
||||
// dword align the len of the final data segment
|
||||
while (o_data & 3)
|
||||
{
|
||||
obuf[o_data++] = 0;
|
||||
offset++;
|
||||
}
|
||||
// dword align offset
|
||||
while (offset & 3)
|
||||
offset++;
|
||||
// compute section sizes
|
||||
o_text = e_len;
|
||||
o_data = ph.c_len;
|
||||
o_bss = i_bss;
|
||||
|
||||
// new bss
|
||||
if (i_text + i_data + i_bss > o_text + o_data + o_bss)
|
||||
o_bss = (i_text + i_data + i_bss) - (o_text + o_data);
|
||||
|
||||
// dirty bss
|
||||
unsigned dirty_bss = (o_data + offset) - (i_text + i_data);
|
||||
//printf("real dirty_bss: %d\n", dirty_bss);
|
||||
// dword align (or 16 - for speedup when clearing the dirty bss)
|
||||
const unsigned dirty_bss_align = opt->small ? 4 : 16;
|
||||
while (dirty_bss & (dirty_bss_align - 1))
|
||||
dirty_bss++;
|
||||
// adjust bss, assert room for some stack
|
||||
if (dirty_bss + 512 > o_bss)
|
||||
o_bss = dirty_bss + 512;
|
||||
|
||||
// dword align the len of the final bss segment
|
||||
while (o_bss & 3)
|
||||
o_bss++;
|
||||
|
||||
// patch "subq.l #1,d6" or "subq.w #1,d6" - see "up41" below
|
||||
const unsigned dirty_bss_d6 = dirty_bss / dirty_bss_align;
|
||||
// FIXME patch_d_subq(loader, o_text, REG_D6, dirty_bss / dirty_bss_align, "u4");
|
||||
linker->defineSymbol("up31", d_off + offset + decomp_offset);
|
||||
if (opt->small)
|
||||
; // patch_d_loop(loader, o_text, REG_D0, o_data/4, "up22", "u1");
|
||||
else
|
||||
{
|
||||
if (o_data <= 160)
|
||||
throwNotCompressible();
|
||||
unsigned loop1 = o_data / 160;
|
||||
unsigned loop2 = o_data % 160;
|
||||
if (loop2 == 0)
|
||||
// word align len of compressed data
|
||||
while (o_data & 1)
|
||||
{
|
||||
loop1--;
|
||||
loop2 = 160;
|
||||
obuf[o_data++] = 0;
|
||||
offset++;
|
||||
}
|
||||
linker->defineSymbol("copy_remain", loop2 / 4 - 1);
|
||||
//patch_be16(loader, o_text, "u2", OP_MOVEQ(loop2/4-1, REG_D0)); // moveq.l #X,d0
|
||||
//patch_d_loop(loader, o_text, REG_D0, loop1, "up22", "u1");
|
||||
|
||||
// append decompressor (part 2 of loader)
|
||||
d_off = o_data;
|
||||
////memcpy(obuf + d_off, getLoader() + e_len, d_len); // must be done after relocation
|
||||
o_data += d_len;
|
||||
|
||||
// dword align the len of the final data segment
|
||||
while (o_data & 3)
|
||||
{
|
||||
obuf[o_data++] = 0;
|
||||
offset++;
|
||||
}
|
||||
// dword align offset
|
||||
while (offset & 3)
|
||||
offset++;
|
||||
|
||||
// new bss
|
||||
if (i_text + i_data + i_bss > o_text + o_data + o_bss)
|
||||
o_bss = (i_text + i_data + i_bss) - (o_text + o_data);
|
||||
|
||||
// dirty bss
|
||||
unsigned dirty_bss = (o_data + offset) - (i_text + i_data);
|
||||
//printf("real dirty_bss: %d\n", dirty_bss);
|
||||
// dword align (or 16 - for speedup when clearing the dirty bss)
|
||||
const unsigned dirty_bss_align = opt->small ? 4 : 16;
|
||||
while (dirty_bss & (dirty_bss_align - 1))
|
||||
dirty_bss++;
|
||||
// adjust bss, assert room for some stack
|
||||
unsigned stack = 512 + getDecompressorWrkmemSize();
|
||||
if (dirty_bss + stack > o_bss)
|
||||
o_bss = dirty_bss + stack;
|
||||
|
||||
// dword align the len of the final bss segment
|
||||
while (o_bss & 3)
|
||||
o_bss++;
|
||||
|
||||
// update symbols for buildLoader()
|
||||
if (opt->small)
|
||||
{
|
||||
symbols.loop1.init(o_data / 4);
|
||||
symbols.loop2.init(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
symbols.loop1.init(o_data / 160);
|
||||
symbols.loop2.init((o_data % 160) / 4);
|
||||
}
|
||||
symbols.loop3.init(dirty_bss / dirty_bss_align);
|
||||
|
||||
symbols.up21_d4 = o_data + offset;
|
||||
symbols.up31_base_d4 = d_off + offset;
|
||||
symbols.up21_a6 = symbols.up21_d4 - (i_text + i_data);
|
||||
symbols.up31_base_a6 = symbols.up31_base_d4 - (i_text + i_data);
|
||||
assert((int)symbols.up21_a6 > 0);
|
||||
assert((int)symbols.up31_base_a6 > 0);
|
||||
|
||||
const unsigned c = linker->getSymbolOffset("code_on_stack");
|
||||
unsigned d;
|
||||
d = linker->getSymbolOffset("flush_cache_rts") - c;
|
||||
symbols.flush_cache_rts_offset = d;
|
||||
d = linker->getSymbolOffset("clear_dirty_stack_loop") - c;
|
||||
symbols.clear_dirty_stack_len = (d + 3) / 4 + 32 - 1;
|
||||
d = linker->getSymbolOffset("code_on_stack_end") - c;
|
||||
symbols.copy_to_stack_len = d / 2 - 1;
|
||||
|
||||
// now re-build loader
|
||||
buildLoader(&ft);
|
||||
unsigned new_lsize = getLoaderSize();
|
||||
//printf("buildLoader %d %d\n", new_lsize, initial_lsize);
|
||||
assert(new_lsize <= initial_lsize);
|
||||
if (new_lsize == last_lsize && memcmp(getLoader(), last_loader, last_lsize) == 0)
|
||||
break;
|
||||
last_lsize = new_lsize;
|
||||
memcpy(last_loader, getLoader(), last_lsize);
|
||||
}
|
||||
linker->defineSymbol("up22", opt->small ? o_data / 4 : (o_data - 1) / 160);
|
||||
linker->defineSymbol("up21", o_data + offset);
|
||||
linker->defineSymbol("up13", i_bss); // p_blen
|
||||
linker->defineSymbol("up12", i_data); // p_dlen
|
||||
linker->defineSymbol("up11", i_text); // p_tlen
|
||||
|
||||
const unsigned clear_size = linker->getSymbolOffset("clear_bss_end") -
|
||||
linker->getSymbolOffset("clear_bss");
|
||||
linker->defineSymbol("copy_to_stack_len", clear_size / 2 - 1);
|
||||
linker->defineSymbol("clear_bss_size_p4", clear_size + 4);
|
||||
//
|
||||
// define symbols and reloc
|
||||
//
|
||||
|
||||
// patch decompressor
|
||||
//upx_byte *p = obuf + d_off;
|
||||
// patch "moveq.l #1,d5" or "jmp (ASTACK)"
|
||||
//patch_be16(p, d_len, "u3", (nrelocs > 0) ? OP_MOVEQ(1, REG_D5) : OP_JMP(REG_A7));
|
||||
linker->defineSymbol("up41", dirty_bss_d6);
|
||||
defineDecompressorSymbols();
|
||||
|
||||
linker->defineSymbol("loop1_count", symbols.loop1.value);
|
||||
linker->defineSymbol("loop2_count", symbols.loop2.value);
|
||||
linker->defineSymbol("loop3_count", symbols.loop3.value);
|
||||
|
||||
linker->defineSymbol("orig_p_tlen", i_text);
|
||||
linker->defineSymbol("orig_p_dlen", i_data);
|
||||
linker->defineSymbol("orig_p_blen", i_bss);
|
||||
|
||||
if (symbols.up21_a6 <= 32767)
|
||||
linker->defineSymbol("up21_a6", symbols.up21_a6);
|
||||
else
|
||||
linker->defineSymbol("up21_d4", symbols.up21_d4);
|
||||
|
||||
if (symbols.up31_a6 <= 32767)
|
||||
linker->defineSymbol("up31_a6", symbols.up31_a6);
|
||||
else if (symbols.up31_d4 <= 32767)
|
||||
linker->defineSymbol("up31_d4", symbols.up31_d4);
|
||||
else if (symbols.up31_a6 <= 65534)
|
||||
linker->defineSymbol("up31_a6", symbols.up31_a6 - 32767);
|
||||
else
|
||||
linker->defineSymbol("up31_d4", symbols.up31_d4);
|
||||
#if 0
|
||||
printf("relocsize = %d\n", relocsize);
|
||||
printf("upx21(d4) = %d\n", symbols.up21_d4);
|
||||
printf("upx21(a6) = %d\n", symbols.up21_a6);
|
||||
printf("upx31(d4) = %d\n", symbols.up31_d4);
|
||||
printf("upx31(a6) = %d\n", symbols.up31_a6);
|
||||
#endif
|
||||
|
||||
linker->defineSymbol("flush_cache_rts_offset", symbols.flush_cache_rts_offset);
|
||||
linker->defineSymbol("copy_to_stack_len", symbols.copy_to_stack_len);
|
||||
linker->defineSymbol("clear_dirty_stack_len", symbols.clear_dirty_stack_len);
|
||||
|
||||
relocateLoader();
|
||||
|
||||
//
|
||||
// write
|
||||
//
|
||||
|
||||
// set new file_hdr
|
||||
memcpy(&oh, &ih, FH_SIZE);
|
||||
@@ -616,16 +689,14 @@ void PackTos::pack(OutputFile *fo)
|
||||
#if 0 || defined(TESTING)
|
||||
printf("old text: %6d, data: %6d, bss: %6d, reloc: %d, overlay: %d\n",
|
||||
i_text, i_data, i_bss, relocsize, overlay);
|
||||
printf("new text: %6d, data: %6d, bss: %6d, dirty_bss: %d, flag=0x%x\n",
|
||||
o_text, o_data, o_bss, dirty_bss, (int)oh.fh_flag);
|
||||
printf("new text: %6d, data: %6d, bss: %6d, flag=0x%x\n",
|
||||
o_text, o_data, o_bss, (int)oh.fh_flag);
|
||||
linker->dumpSymbols();
|
||||
#endif
|
||||
|
||||
linker->relocate();
|
||||
// prepare loader
|
||||
MemBuffer loader(o_text);
|
||||
memcpy(loader, getLoader(), o_text);
|
||||
memcpy(obuf+d_off, getLoader() + e_len, d_len);
|
||||
|
||||
patchPackHeader(loader, o_text);
|
||||
|
||||
// write new file header, loader and compressed file
|
||||
@@ -633,10 +704,11 @@ void PackTos::pack(OutputFile *fo)
|
||||
fo->write(loader, o_text); // entry
|
||||
if (opt->debug.dump_stub_loader)
|
||||
OutputFile::dump(opt->debug.dump_stub_loader, loader, o_text);
|
||||
memcpy(obuf + d_off, getLoader() + e_len, d_len); // copy decompressor
|
||||
fo->write(obuf, o_data); // compressed + decompressor
|
||||
|
||||
// write empty relocation fixup
|
||||
fo->write("\x00\x00\x00\x00",4);
|
||||
fo->write("\x00\x00\x00\x00", 4);
|
||||
|
||||
// verify
|
||||
verifyOverlappingDecompression();
|
||||
|
||||
+25
-16
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_ATARI_TOS; }
|
||||
virtual const char *getName() const { return "atari/tos"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "m68k-atari.tos"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -55,7 +56,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual Linker* newLinker() const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
unsigned getDecomprOffset(int method, int small) const;
|
||||
|
||||
virtual int readFileHeader();
|
||||
virtual bool checkFileHeader();
|
||||
@@ -75,27 +77,34 @@ protected:
|
||||
|
||||
tos_header_t ih, oh;
|
||||
|
||||
// symbols for buildLoader()
|
||||
struct LinkerSymbols
|
||||
{
|
||||
enum { LOOP_UNKNOWN, LOOP_SUBQ_L, LOOP_SUBQ_W, LOOP_DBRA };
|
||||
// before linker->relocate()
|
||||
unsigned loop1_count; int loop1_mode;
|
||||
unsigned loop2_count; int loop2_mode;
|
||||
unsigned loop3_count; int loop3_mode;
|
||||
// after linker->relocate()
|
||||
unsigned copy_to_stack_len;
|
||||
enum { LOOP_NONE, LOOP_SUBQ_L, LOOP_SUBQ_W, LOOP_DBRA };
|
||||
struct LoopInfo {
|
||||
unsigned mode; unsigned count; unsigned value;
|
||||
void init(unsigned count, bool allow_dbra=true);
|
||||
};
|
||||
// buildLoader() input
|
||||
bool need_reloc;
|
||||
LoopInfo loop1;
|
||||
LoopInfo loop2;
|
||||
LoopInfo loop3;
|
||||
unsigned up21_d4;
|
||||
unsigned up21_a6;
|
||||
unsigned up31_base_d4;
|
||||
unsigned up31_base_a6;
|
||||
// buildLoader() output
|
||||
unsigned up31_d4;
|
||||
unsigned up31_a6;
|
||||
// currently not used by buildLoader()
|
||||
unsigned flush_cache_rts_offset;
|
||||
unsigned clear_bss_size_p4;
|
||||
unsigned clear_dirty_stack_len;
|
||||
// FIXME: up11 etc.
|
||||
unsigned copy_to_stack_len;
|
||||
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
LinkerSymbols symbols;
|
||||
|
||||
protected:
|
||||
unsigned patch_d_subq(void *l, int llen, int, unsigned, const char*);
|
||||
unsigned patch_d_loop(void *l, int llen, int, unsigned, const char*, const char*);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+12
-13
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -62,7 +62,7 @@ bool PackUnix::canPack()
|
||||
#if defined(__unix__)
|
||||
// must be executable by owner
|
||||
if ((fi->st.st_mode & S_IXUSR) == 0)
|
||||
throwCantPack("file not executable; try `chmod +x'");
|
||||
throwCantPack("file not executable; try 'chmod +x'");
|
||||
#endif
|
||||
if (file_size < 4096)
|
||||
throwCantPack("file is too small");
|
||||
@@ -125,8 +125,8 @@ int PackUnix::getStrategy(Filter &/*ft*/)
|
||||
// Called just before reading and compressing each block.
|
||||
// Might want to adjust blocksize, etc.
|
||||
|
||||
// If user specified the filter, then use it (-2==strategy).
|
||||
// Else try the first two filters, and pick the better (2==strategy).
|
||||
// If user specified the filter, then use it (-2==filter_strategy).
|
||||
// Else try the first two filters, and pick the better (2==filter_strategy).
|
||||
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
|
||||
}
|
||||
|
||||
@@ -151,9 +151,9 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
||||
// which assumes it has free choice on each call [block].
|
||||
// And if the choices aren't the same on each block,
|
||||
// then un-filtering will give incorrect results.
|
||||
int strategy = getStrategy(ft);
|
||||
int filter_strategy = getStrategy(ft);
|
||||
if (file_size > (off_t)blocksize)
|
||||
strategy = -3; // no filters
|
||||
filter_strategy = -3; // no filters
|
||||
|
||||
int l = fi->readx(ibuf, UPX_MIN(blocksize, remaining));
|
||||
remaining -= l;
|
||||
@@ -170,7 +170,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
||||
// that is, AFTER filtering. We want BEFORE filtering,
|
||||
// so that decompression checks the end-to-end checksum.
|
||||
unsigned const end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler);
|
||||
compressWithFilters(&ft, OVERHEAD, strategy);
|
||||
compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy);
|
||||
|
||||
if (ph.c_len < ph.u_len) {
|
||||
ph.overlap_overhead = OVERHEAD;
|
||||
@@ -318,7 +318,7 @@ void PackUnix::packExtent(
|
||||
}
|
||||
fi->seek(x.offset, SEEK_SET);
|
||||
for (off_t rest = x.size; 0 != rest; ) {
|
||||
int const strategy = getStrategy(*ft);
|
||||
int const filter_strategy = getStrategy(*ft);
|
||||
int l = fi->readx(ibuf, UPX_MIN(rest, (off_t)blocksize));
|
||||
if (l == 0) {
|
||||
break;
|
||||
@@ -345,12 +345,11 @@ void PackUnix::packExtent(
|
||||
ft->id = 0;
|
||||
ft->cto = 0;
|
||||
|
||||
compressWithFilters(ft, OVERHEAD, strategy,
|
||||
NULL, NULL, 0, 0, // those 4 args are the defaults
|
||||
hdr_ibuf, hdr_u_len);
|
||||
compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy,
|
||||
0, 0, 0, hdr_ibuf, hdr_u_len);
|
||||
}
|
||||
else {
|
||||
(void) compress(ibuf, obuf); // ignore return value
|
||||
(void) compress(ibuf, ph.u_len, obuf); // ignore return value
|
||||
}
|
||||
|
||||
if (ph.c_len < ph.u_len) {
|
||||
|
||||
+8
-8
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -111,9 +111,9 @@ protected:
|
||||
}
|
||||
__attribute_packed;
|
||||
struct l_info { // 12-byte trailer in header for loader
|
||||
unsigned l_checksum;
|
||||
unsigned l_magic;
|
||||
unsigned short l_lsize;
|
||||
LE32 l_checksum;
|
||||
LE32 l_magic;
|
||||
LE16 l_lsize;
|
||||
unsigned char l_version;
|
||||
unsigned char l_format;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ class PackUnixBe32 : public PackUnix
|
||||
{
|
||||
typedef PackUnix super;
|
||||
protected:
|
||||
PackUnixBe32(InputFile *f) : super(f) { }
|
||||
PackUnixBe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; }
|
||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
||||
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
|
||||
virtual unsigned get_native16(const void *b) const { return get_be16(b); }
|
||||
@@ -182,7 +182,7 @@ class PackUnixLe32 : public PackUnix
|
||||
{
|
||||
typedef PackUnix super;
|
||||
protected:
|
||||
PackUnixLe32(InputFile *f) : super(f) { }
|
||||
PackUnixLe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
|
||||
@@ -235,7 +235,7 @@ public:
|
||||
virtual bool canPack();
|
||||
|
||||
protected:
|
||||
virtual const upx_byte *getLoader() const;
|
||||
virtual upx_byte *getLoader() const;
|
||||
virtual int getLoaderSize() const;
|
||||
|
||||
virtual void patchLoader();
|
||||
|
||||
+662
-254
File diff suppressed because it is too large
Load Diff
+124
-25
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -31,42 +31,141 @@
|
||||
|
||||
#include "p_elf.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// vmlinx/i386 (bare binary Linux kernel image)
|
||||
**************************************************************************/
|
||||
|
||||
class PackVmlinuxI386 : public Packer
|
||||
template <class TElfClass>
|
||||
class PackVmlinuxBase : public Packer
|
||||
{
|
||||
typedef Packer super;
|
||||
protected:
|
||||
typedef TElfClass ElfClass;
|
||||
typedef typename ElfClass::BeLePolicy BeLePolicy;
|
||||
typedef typename ElfClass::ElfITypes ElfITypes;
|
||||
// integral types
|
||||
typedef typename ElfClass::U16 U16;
|
||||
typedef typename ElfClass::U32 U32;
|
||||
typedef typename ElfClass::U64 U64;
|
||||
typedef typename ElfITypes::Addr Addr;
|
||||
// ELF types
|
||||
typedef typename ElfClass::Ehdr Ehdr;
|
||||
typedef typename ElfClass::Shdr Shdr;
|
||||
typedef typename ElfClass::Phdr Phdr;
|
||||
typedef typename ElfClass::Dyn Dyn;
|
||||
typedef typename ElfClass::Sym Sym;
|
||||
|
||||
public:
|
||||
PackVmlinuxI386(InputFile *f);
|
||||
virtual ~PackVmlinuxI386();
|
||||
PackVmlinuxBase(InputFile *, unsigned, unsigned, unsigned, char const *);
|
||||
virtual ~PackVmlinuxBase();
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_VMLINUX_i386; }
|
||||
virtual const char *getName() const { return "vmlinux/386"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
virtual void pack(OutputFile *fo);
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
// virtual const upx_byte *getLoader() const;
|
||||
// virtual int getLoaderSize() const;
|
||||
unsigned int const my_e_machine;
|
||||
unsigned char const my_elfclass;
|
||||
unsigned char const my_elfdata;
|
||||
char const *const my_boot_label;
|
||||
|
||||
int n_ptload;
|
||||
unsigned sz_ptload;
|
||||
Elf_LE32_Phdr *phdri; // from input file
|
||||
Elf_LE32_Shdr *shdri; // from input file
|
||||
Elf_LE32_Shdr *p_text;
|
||||
Elf_LE32_Shdr *p_note0;
|
||||
Elf_LE32_Shdr *p_note1;
|
||||
Elf_LE32_Ehdr ehdri; // from input file
|
||||
unsigned paddr_min;
|
||||
Phdr *phdri; // from input file
|
||||
Shdr *shdri; // from input file
|
||||
char *shstrtab; // from input file
|
||||
Shdr *p_text;
|
||||
Shdr *p_note0;
|
||||
Shdr *p_note1;
|
||||
Ehdr ehdri; // from input file
|
||||
|
||||
virtual Shdr const *getElfSections();
|
||||
virtual int getStrategy(Filter &/*ft*/);
|
||||
virtual bool is_valid_e_entry(Addr) = 0;
|
||||
virtual bool has_valid_vmlinux_head() = 0;
|
||||
virtual bool canPack();
|
||||
virtual void pack(OutputFile *fo);
|
||||
virtual int canUnpack(); // bool, except -1: format known, but not packed
|
||||
virtual void unpack(OutputFile *fo);
|
||||
virtual unsigned write_vmlinux_head(
|
||||
OutputFile *const fo,
|
||||
Shdr *const stxt
|
||||
) = 0;
|
||||
static int __acc_cdecl_qsort compare_Phdr(void const *aa, void const *bb);
|
||||
};
|
||||
|
||||
|
||||
class PackVmlinuxI386 : public PackVmlinuxBase<ElfClass_LE32>
|
||||
{
|
||||
typedef PackVmlinuxBase<ElfClass_LE32> super;
|
||||
public:
|
||||
PackVmlinuxI386(InputFile *f) : super(f, Ehdr::EM_386,
|
||||
Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "startup_32") { }
|
||||
virtual int getFormat() const { return UPX_F_VMLINUX_i386; }
|
||||
virtual const char *getName() const { return "vmlinux/386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.vmlinux"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual void defineDecompressorSymbols();
|
||||
virtual Linker* newLinker() const;
|
||||
virtual bool is_valid_e_entry(Addr);
|
||||
virtual bool has_valid_vmlinux_head();
|
||||
virtual unsigned write_vmlinux_head(
|
||||
OutputFile *const fo,
|
||||
Shdr *const stxt
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
class PackVmlinuxARM : public PackVmlinuxBase<ElfClass_LE32>
|
||||
{
|
||||
typedef PackVmlinuxBase<ElfClass_LE32> super;
|
||||
public:
|
||||
PackVmlinuxARM(InputFile *f) : super(f, Ehdr::EM_ARM,
|
||||
Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "decompress_kernel") { }
|
||||
virtual int getFormat() const { return UPX_F_VMLINUX_ARM; }
|
||||
virtual const char *getName() const { return "vmlinux/ARM"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "arm-linux.kernel.vmlinux"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual void defineDecompressorSymbols();
|
||||
virtual Linker* newLinker() const;
|
||||
virtual bool is_valid_e_entry(Addr);
|
||||
virtual bool has_valid_vmlinux_head();
|
||||
virtual unsigned write_vmlinux_head(
|
||||
OutputFile *const fo,
|
||||
Shdr *const stxt
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
class PackVmlinuxAMD64 : public PackVmlinuxBase<ElfClass_LE64>
|
||||
{
|
||||
typedef PackVmlinuxBase<ElfClass_LE64> super;
|
||||
public:
|
||||
PackVmlinuxAMD64(InputFile *f) : super(f, Ehdr::EM_X86_64,
|
||||
Ehdr::ELFCLASS64, Ehdr::ELFDATA2LSB, "startup_32") { }
|
||||
virtual int getFormat() const { return UPX_F_VMLINUX_AMD64; }
|
||||
virtual const char *getName() const { return "vmlinux/AMD64"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "amd64-linux.kernel.vmlinux"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual void defineDecompressorSymbols();
|
||||
virtual Linker* newLinker() const;
|
||||
virtual bool is_valid_e_entry(Addr);
|
||||
virtual bool has_valid_vmlinux_head();
|
||||
virtual unsigned write_vmlinux_head(
|
||||
OutputFile *const fo,
|
||||
Shdr *const stxt
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+58
-57
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -38,7 +38,6 @@
|
||||
static const
|
||||
#include "stub/i386-linux.kernel.vmlinuz.h"
|
||||
|
||||
static const unsigned kernel_entry = 0x100000;
|
||||
static const unsigned stack_offset_during_uncompression = 0x9000;
|
||||
// add to "real mode pointer" in %esi; total 0x99000 is typical
|
||||
|
||||
@@ -52,8 +51,9 @@ static const unsigned bzimage_offset = 0x100000;
|
||||
**************************************************************************/
|
||||
|
||||
PackVmlinuzI386::PackVmlinuzI386(InputFile *f) :
|
||||
super(f)
|
||||
super(f), physical_start(0x100000)
|
||||
{
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
COMPILE_TIME_ASSERT(sizeof(boot_sect_t) == 0x218);
|
||||
}
|
||||
|
||||
@@ -67,9 +67,9 @@ const int *PackVmlinuzI386::getCompressionMethods(int method, int level) const
|
||||
const int *PackVmlinuzI386::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x49,
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||
-1 };
|
||||
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
||||
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ int PackVmlinuzI386::readFileHeader()
|
||||
return 0;
|
||||
|
||||
int format = UPX_F_VMLINUZ_i386;
|
||||
unsigned sys_size = ALIGN_UP(file_size, 16) - setup_size;
|
||||
unsigned sys_size = ALIGN_UP((unsigned) file_size, 16u) - setup_size;
|
||||
|
||||
const unsigned char *p = (const unsigned char *) &h + 0x1e3;
|
||||
|
||||
@@ -133,7 +133,17 @@ int PackVmlinuzI386::decompressKernel()
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(obuf, file_size);
|
||||
|
||||
checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, 1024));
|
||||
// Find "ljmp $__BOOT_CS,$__PHYSICAL_START" if any.
|
||||
// See startup_32: in linux/arch/i386/boot/compressed/head.S
|
||||
char const *p = (char const *)&obuf[setup_size];
|
||||
for (int j= 0; j < 0x200; ++j, ++p)
|
||||
if (0==memcmp("\xEA\x00\x00", p, 3) && 0==(0xf & p[3]) && 0==p[4]) {
|
||||
/* whole megabyte < 16MB */
|
||||
physical_start = get_le32(1+ p);
|
||||
break;
|
||||
}
|
||||
|
||||
checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024));
|
||||
|
||||
for (int gzoff = setup_size; gzoff < file_size; gzoff++)
|
||||
{
|
||||
@@ -198,7 +208,7 @@ int PackVmlinuzI386::decompressKernel()
|
||||
if (fd_pos != file_size)
|
||||
{
|
||||
//printf("fd_pos: %ld, file_size: %ld\n", (long)fd_pos, (long)file_size);
|
||||
throwCantPack("trailing bytes after kernel image; use option `-f' to force packing");
|
||||
throwCantPack("trailing bytes after kernel image; use option '-f' to force packing");
|
||||
}
|
||||
|
||||
|
||||
@@ -209,8 +219,15 @@ int PackVmlinuzI386::decompressKernel()
|
||||
if (memcmp(ibuf, "\xFC\x0F\x01", 3) == 0) goto head_ok;
|
||||
// 2.6.x+grsecurity+strongswan+openwall+trustix: ljmp $0x10,...
|
||||
if (ibuf[0] == 0xEA && memcmp(ibuf+5, "\x10\x00", 2) == 0) goto head_ok;
|
||||
// x86_64 2.6.x
|
||||
if (0xB8==ibuf[0] // mov $...,%eax
|
||||
&& 0x8E==ibuf[5] && 0xD8==ibuf[6] // mov %eax,%ds
|
||||
&& 0x0F==ibuf[7] && 0x01==ibuf[8] && 020==(070 & ibuf[9]) // lgdtl
|
||||
&& 0xB8==ibuf[14] // mov $...,%eax
|
||||
&& 0x0F==ibuf[19] && 0xA2==ibuf[20] // cpuid
|
||||
) goto head_ok;
|
||||
|
||||
throwCantPack("unrecognized kernel architecture; use option `-f' to force packing");
|
||||
throwCantPack("unrecognized kernel architecture; use option '-f' to force packing");
|
||||
head_ok:
|
||||
|
||||
// FIXME: more checks for special magic bytes in ibuf ???
|
||||
@@ -253,11 +270,12 @@ Linker* PackVmlinuzI386::newLinker() const
|
||||
// vmlinuz specific
|
||||
**************************************************************************/
|
||||
|
||||
int PackVmlinuzI386::buildLoader(const Filter *ft)
|
||||
void PackVmlinuzI386::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz));
|
||||
addLoader("LINUZ000",
|
||||
ph.first_offset_found == 1 ? "LINUZ001" : "",
|
||||
ft->id ? "LZCALLT1" : "",
|
||||
"LZIMAGE0",
|
||||
getDecompressorSections(),
|
||||
@@ -270,24 +288,9 @@ int PackVmlinuzI386::buildLoader(const Filter *ft)
|
||||
addFilter32(ft->id);
|
||||
}
|
||||
addLoader("LINUZ990,IDENTSTR,UPX1HEAD", NULL);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
return false;
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PackVmlinuzI386::pack(OutputFile *fo)
|
||||
{
|
||||
readKernel();
|
||||
@@ -295,29 +298,29 @@ void PackVmlinuzI386::pack(OutputFile *fo)
|
||||
// prepare filter
|
||||
Filter ft(ph.level);
|
||||
ft.buf_len = ph.u_len;
|
||||
ft.addvalue = kernel_entry; // saves 4 bytes in unfilter code
|
||||
ft.addvalue = physical_start; // saves 4 bytes in unfilter code
|
||||
|
||||
// compress
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
// limit stack size needed for runtime decompression
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||
compressWithFilters(&ft, 512, &cconf);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
|
||||
defineFilterSymbols(linker, &ft);
|
||||
defineDecompressorSymbols();
|
||||
defineFilterSymbols(&ft);
|
||||
linker->defineSymbol("src_for_decompressor", zimage_offset + lsize);
|
||||
linker->defineSymbol("original_entry", kernel_entry);
|
||||
linker->defineSymbol("original_entry", physical_start);
|
||||
linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||
bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16) / 16;
|
||||
bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16u) / 16;
|
||||
|
||||
fo->write(setup_buf, setup_buf.getSize());
|
||||
fo->write(loader, lsize);
|
||||
@@ -341,11 +344,12 @@ void PackVmlinuzI386::pack(OutputFile *fo)
|
||||
// bvmlinuz specific
|
||||
**************************************************************************/
|
||||
|
||||
int PackBvmlinuzI386::buildLoader(const Filter *ft)
|
||||
void PackBvmlinuzI386::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz));
|
||||
addLoader("LINUZ000",
|
||||
ph.first_offset_found == 1 ? "LINUZ001" : "",
|
||||
(0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""),
|
||||
"LBZIMAGE,IDENTSTR",
|
||||
"+40", // align the stuff to 4 byte boundary
|
||||
@@ -371,8 +375,6 @@ int PackBvmlinuzI386::buildLoader(const Filter *ft)
|
||||
addFilter32(ft->id);
|
||||
}
|
||||
addLoader("LINUZ990", NULL);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -383,26 +385,28 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
|
||||
// prepare filter
|
||||
Filter ft(ph.level);
|
||||
ft.buf_len = ph.u_len;
|
||||
ft.addvalue = kernel_entry; // saves 4 bytes in unfilter code
|
||||
ft.addvalue = physical_start; // saves 4 bytes in unfilter code
|
||||
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
// limit stack size needed for runtime decompression
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||
compressWithFilters(&ft, 512, &cconf);
|
||||
|
||||
// align everything to dword boundary - it is easier to handle
|
||||
unsigned c_len = ph.c_len;
|
||||
memset(obuf + c_len, 0, 4);
|
||||
c_len = ALIGN_UP(c_len, 4);
|
||||
c_len = ALIGN_UP(c_len, 4u);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
|
||||
if (ph.method == M_LZMA) {
|
||||
if (M_IS_LZMA(ph.method)) {
|
||||
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||
unsigned const properties = // lc, lp, pb, dummy
|
||||
acc_uint32e_t properties = // lc, lp, pb, dummy
|
||||
(res->lit_context_bits << 0) |
|
||||
(res->lit_pos_bits << 8) |
|
||||
(res->pos_bits << 16);
|
||||
if (linker->bele->isBE()) // big endian - bswap32
|
||||
acc_swab32s(&properties);
|
||||
linker->defineSymbol("lzma_properties", properties);
|
||||
// -2 for properties
|
||||
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
||||
@@ -414,33 +418,30 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
|
||||
const int e_len = getLoaderSectionStart("LZCUTPOI");
|
||||
assert(e_len > 0);
|
||||
|
||||
const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4);
|
||||
const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16);
|
||||
const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4u);
|
||||
const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16u);
|
||||
const unsigned copy_size = c_len + d_len4;
|
||||
const unsigned edi = decompr_pos + d_len4 - 4; // copy to
|
||||
const unsigned esi = ALIGN_UP(c_len + lsize, 4) - 4; // copy from
|
||||
const unsigned esi = ALIGN_UP(c_len + lsize, 4u) - 4; // copy from
|
||||
|
||||
linker->defineSymbol("decompressor", decompr_pos);
|
||||
linker->defineSymbol("src_for_decompressor", bzimage_offset + decompr_pos - c_len);
|
||||
linker->defineSymbol("decompressor", decompr_pos - bzimage_offset + physical_start);
|
||||
linker->defineSymbol("src_for_decompressor", physical_start + decompr_pos - c_len);
|
||||
linker->defineSymbol("words_to_copy", copy_size / 4);
|
||||
linker->defineSymbol("copy_dest", bzimage_offset + edi);
|
||||
linker->defineSymbol("copy_dest", physical_start + edi);
|
||||
linker->defineSymbol("copy_source", bzimage_offset + esi);
|
||||
|
||||
defineFilterSymbols(linker, &ft);
|
||||
if (0x40==(0xf0 & ft.id)) {
|
||||
linker->defineSymbol("filter_length", ph.u_len); // redefine
|
||||
}
|
||||
defineFilterSymbols(&ft);
|
||||
defineDecompressorSymbols();
|
||||
linker->defineSymbol("original_entry", kernel_entry);
|
||||
linker->defineSymbol("original_entry", physical_start);
|
||||
linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
|
||||
linker->relocate();
|
||||
relocateLoader();
|
||||
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||
bs->sys_size = (ALIGN_UP(lsize + c_len, 16) / 16) & 0xffff;
|
||||
bs->sys_size = (ALIGN_UP(lsize + c_len, 16u) / 16) & 0xffff;
|
||||
|
||||
fo->write(setup_buf, setup_buf.getSize());
|
||||
fo->write(loader, e_len);
|
||||
@@ -493,7 +494,7 @@ void PackVmlinuzI386::unpack(OutputFile *fo)
|
||||
|
||||
// unfilter
|
||||
Filter ft(ph.level);
|
||||
ft.init(ph.filter, kernel_entry);
|
||||
ft.init(ph.filter, physical_start);
|
||||
ft.cto = (unsigned char) ph.filter_cto;
|
||||
ft.unfilter(obuf, ph.u_len);
|
||||
|
||||
|
||||
+10
-6
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_VMLINUZ_i386; }
|
||||
virtual const char *getName() const { return "vmlinuz/386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.vmlinuz"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -56,10 +57,10 @@ protected:
|
||||
virtual int decompressKernel();
|
||||
virtual void readKernel();
|
||||
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
// virtual const upx_byte *getLoader() const;
|
||||
// virtual upx_byte *getLoader() const;
|
||||
// virtual int getLoaderSize() const;
|
||||
|
||||
struct boot_sect_t
|
||||
@@ -86,6 +87,7 @@ protected:
|
||||
|
||||
MemBuffer setup_buf;
|
||||
int setup_size;
|
||||
unsigned physical_start;
|
||||
};
|
||||
|
||||
|
||||
@@ -100,11 +102,12 @@ public:
|
||||
PackBvmlinuzI386(InputFile *f) : super(f) { }
|
||||
virtual int getFormat() const { return UPX_F_BVMLINUZ_i386; }
|
||||
virtual const char *getName() const { return "bvmlinuz/386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.bvmlinuz"; }
|
||||
|
||||
virtual void pack(OutputFile *fo);
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
};
|
||||
|
||||
|
||||
@@ -119,6 +122,7 @@ public:
|
||||
PackElks8086(InputFile *f) : super(f) { }
|
||||
virtual int getFormat() const { return UPX_F_ELKS_8086; }
|
||||
virtual const char *getName() const { return "elks/8086"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i086-elks ???"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -131,7 +135,7 @@ protected:
|
||||
virtual int decompressKernel();
|
||||
virtual void readKernel();
|
||||
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -39,7 +39,7 @@ class PackVxd : public PackWcle
|
||||
typedef PackWcle super;
|
||||
public:
|
||||
PackVxd(InputFile *f);
|
||||
~PackVxd();
|
||||
virtual ~PackVxd();
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_VXD_LE; }
|
||||
virtual const char *getName() const { return "vxd/le"; }
|
||||
@@ -59,7 +59,7 @@ protected:
|
||||
virtual void encodeFixups();
|
||||
virtual void decodeFixups();
|
||||
|
||||
virtual void encodeImage(const Filter *ft);
|
||||
virtual void encodeImage(Filter *ft);
|
||||
virtual void decodeImage();
|
||||
};
|
||||
|
||||
|
||||
+4
-5
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -41,6 +41,7 @@
|
||||
PackW16Ne::PackW16Ne(InputFile *f) :
|
||||
super(f)
|
||||
{
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +58,7 @@ const int *PackW16Ne::getFilters() const
|
||||
}
|
||||
|
||||
|
||||
int PackW16Ne::buildLoader(const Filter *ft)
|
||||
void PackW16Ne::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
// initLoader(nrv_loader,sizeof(nrv_loader));
|
||||
@@ -68,8 +69,6 @@ int PackW16Ne::buildLoader(const Filter *ft)
|
||||
// addLoader("...");
|
||||
}
|
||||
//
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user