Compare commits

...

141 Commits

Author SHA1 Message Date
Markus F.X.J. Oberhumer 747e8370e0 Remove debug leftover. 2007-04-26 16:20:01 +02:00
Markus F.X.J. Oberhumer 2c67875781 Pass and verify original data in all xxx_test_overlap() functions. 2007-04-26 16:15:49 +02:00
Markus F.X.J. Oberhumer c96e8a8c19 Better underflow and overflow handling in Packer::findOverlapOverhead(). 2007-04-26 13:59:01 +02:00
Markus F.X.J. Oberhumer 5f203fc082 Avoid warnings. 2007-04-26 13:13:26 +02:00
John Reiser b943c9b471 fix upx_zlib_test_overlap 2007-04-25 20:24:30 -07:00
John Reiser 1a90a1daa8 Implement upx_zlib_test_overlap() following upx_lzma_test_overlap() 2007-04-25 20:19:40 -07:00
John Reiser 72dfc743fd upx_lzma_test_overlap cleanup 2007-04-25 20:11:04 -07:00
John Reiser 465307655b Implement real upx_lzma_test_overlap().
Also make Packer::findOverlapOverhead() more pessimistic in worst case.
2007-04-25 16:11:33 -07:00
John Reiser 6ce71e6694 upx_lzma_test_overlap revert to 256 [FIXME] 2007-04-25 10:54:00 -07:00
John Reiser 7f01b3b92a upx_lzma_test_overlap() heuristic overlap_overhead up to 0xA00 2007-04-25 09:19:29 -07:00
John Reiser 76950d56b9 PackUnix::canPack allow incompressible extents in getPackHeader() 2007-04-25 09:18:31 -07:00
Markus F.X.J. Oberhumer c11e0d02b3 Added parm "allow_incompressible" to Packer::{get,read}PackHeader(). 2007-04-25 17:33:39 +02:00
Markus F.X.J. Oberhumer 4c798c1718 Use official name "armeb" instead of "armbe". 2007-04-25 16:50:51 +02:00
Markus F.X.J. Oberhumer 450d7e9ad4 Merge. 2007-04-25 16:42:41 +02:00
Markus F.X.J. Oberhumer b8ab79c83e Use offical name "arm" instead of "armel". 2007-04-25 16:42:08 +02:00
John Reiser 6934bdd533 allow unpack of incompressible extents, such as
http://www.equi4.com/pub/tk/8.4.13/tclkit-linux-x86.gz
2007-04-25 07:34:24 -07:00
John Reiser 84dedb73a5 propagate changes arm*-linux.elf-fold.h 2007-04-24 16:08:34 -07:00
John Reiser 8964aa5221 fix endian issue with .b_method (arm-linux.elf-entry.S) 2007-04-24 12:05:53 -07:00
Markus F.X.J. Oberhumer 3481ae236c Added missing armeb generated files. 2007-04-23 18:11:24 +02:00
John Reiser 46adc5f8a4 armeb-linux.kernel.vmlinux.S 2007-04-23 09:00:28 -07:00
John Reiser 5296df5899 add armeb-linux.kernel.vmlinux-head.S 2007-04-23 08:53:53 -07:00
John Reiser 13dad4be16 merge 2007-04-23 07:22:36 -07:00
John Reiser b5d0c343b4 sync src/Makefile with Markus bfb3d24c1fe7 2007-04-23 07:15:42 -07:00
Markus F.X.J. Oberhumer b00b945264 src/Makefile: avoid rebuilding .depend file on clean targets 2007-04-23 08:23:01 +02:00
John Reiser 3bda09e105 more cleanup armel etc 2007-04-22 20:04:13 -07:00
John Reiser 32d32c4e4a cleanup ARMEL etc. 2007-04-22 19:52:23 -07:00
John Reiser 497441b54e merge 2007-04-22 16:19:13 -07:00
John Reiser 9c564fd4c7 Add file formst UPX_F_LINUX_ELF32_ARMEB and normalize spelling
of ARMEL, ARMEB, armel, armeb.
2007-04-22 16:09:18 -07:00
John Reiser 0c2263d0e9 fix O_INP etc because cto8 is not pushed.
This change should have paralleled 1382:367eb149f29c
(Sun Aug 20 11:19:37 2006 -0700)
2007-04-22 15:50:24 -07:00
John Reiser 3d4d30766d merge 2007-04-22 15:24:17 -07:00
John Reiser 99d84d44fc propagate change to O_INP 2007-04-22 14:50:58 -07:00
John Reiser 41ba7077ad propagate change to O_INP 2007-04-22 14:50:58 -07:00
John Reiser 8a929a91c3 Fix O_INP etc because calling sequence changed to omit cto8.
This parallel change was forgotten at:
   changeset:   1382:367eb149f29c
   date:        Sun Aug 20 11:19:37 2006 -0700
   summary:     i386-linux.elf decompress does not need cto8
2007-04-22 14:47:08 -07:00
Markus F.X.J. Oberhumer 0604f06841 Backed out changeset 1b7b0715e0ab0d3b2e8afc96ac95d46d44bf3618 2007-04-23 07:36:46 +02:00
John Reiser 229924adf9 Fix O_INP etc because calling sequence changed to omit cto8.
This parallel change was forgotten at:
   changeset:   1382:367eb149f29c
   date:        Sun Aug 20 11:19:37 2006 -0700
   summary:     i386-linux.elf decompress does not need cto8
2007-04-22 14:47:08 -07:00
Markus F.X.J. Oberhumer df988b7c69 Bump tentative release date. 2007-04-22 16:55:41 +02:00
John Reiser e8106e2e34 propagate change to 'loadcon8' macro 2007-04-18 09:55:15 -07:00
John Reiser c21d3e24f8 fix 'loadcon8'; was bad for big-endian vmlinux ARM 2007-04-18 09:52:52 -07:00
Markus F.X.J. Oberhumer 2d87aa0753 Better ctok32 fix. 2007-04-02 18:57:42 +02:00
László Molnár b2ad4dc9a0 another fix for ctok32 2007-04-02 14:12:16 +02:00
László Molnár 370f2ea98f tmt/adam: fixed a ctok32 related bug 2007-04-01 17:31:48 +02:00
László Molnár a05ca565ff fixed a bug in ctok32 2007-04-01 17:07:43 +02:00
László Molnár 52255637f2 give an error for x86/wince files 2007-03-22 13:45:03 +01:00
Markus F.X.J. Oberhumer 0fcaa3a2f5 Work around broken scanf() implementations. 2007-03-22 07:30:16 +01:00
László Molnár 0e2fa6eb9d no need to warn for x86 wince files 2007-03-20 09:30:30 +01:00
Markus F.X.J. Oberhumer 1aac462c83 Remove trailing whitespace. 2007-03-15 07:36:58 +01:00
Markus F.X.J. Oberhumer 2a0edfd8f7 Small update from Jens. 2007-03-15 01:41:07 +01:00
László Molnár 1f59a9f846 more PS1 updates from Jens 2007-03-12 12:11:17 +01:00
László Molnár 80c20a90ea PS1 updates from Jens 2007-03-12 11:56:16 +01:00
Markus F.X.J. Oberhumer 56a35649fe Update Makefiles. 2007-03-09 07:59:50 +01:00
Markus F.X.J. Oberhumer f07cea0b79 Update help string. 2007-03-09 07:59:36 +01:00
Markus F.X.J. Oberhumer 4c1b08a281 Bump version for next release. 2007-03-08 08:26:28 +01:00
Markus F.X.J. Oberhumer 117f9eddcd src/Makefile: use an explicit .depend file. 2007-03-08 08:19:27 +01:00
Markus F.X.J. Oberhumer 7bbbfce482 Added tag for RELEASE_293. 2007-03-08 06:16:24 +01:00
Markus F.X.J. Oberhumer f37a7811f9 Merge. 2007-03-08 03:00:00 +01:00
László Molnár 9173c10239 yet another spelling fix 2007-03-07 17:00:18 +01:00
László Molnár 318b31550d spelling fixes 2007-03-07 14:22:37 +01:00
Markus F.X.J. Oberhumer c18ebc63a6 dos/exe: enable optimized code paths. 2007-03-06 18:14:32 +01:00
Markus F.X.J. Oberhumer d704694272 Merge. 2007-03-06 15:57:13 +01:00
Markus F.X.J. Oberhumer 1cfec3bdf7 dos/exe: enable one small optimization. 2007-03-06 15:56:51 +01:00
John Reiser fe6ea6bc10 merge 2007-03-06 06:44:26 -08:00
Markus F.X.J. Oberhumer d29c8df45e dos/exe improvements, not enabled yet. 2007-03-06 15:08:24 +01:00
John Reiser 71f996af95 spelling 2007-03-05 21:26:36 -08:00
Markus F.X.J. Oberhumer d9722ad6b3 dos/exe: make sure minsp is even. 2007-03-04 19:27:04 +01:00
Markus F.X.J. Oberhumer 398fd8028c Spelling fixes. 2007-03-04 17:39:21 +01:00
Markus F.X.J. Oberhumer 1345a3cfd3 Bump tentative release date. 2007-03-04 17:13:11 +01:00
Markus F.X.J. Oberhumer 7eb0b195b8 dos/exe: don't clear the dirty stack - DOS does not do this either 2007-03-04 17:10:32 +01:00
Markus F.X.J. Oberhumer 009caee82d docs: typo fixes. 2007-03-04 17:01:50 +01:00
Markus F.X.J. Oberhumer 3bdc805a22 dos/exe: only use bx_magic when needed. 2007-03-04 17:01:32 +01:00
Markus F.X.J. Oberhumer ac457792b4 Minor dos/exe stub optimizations. 2007-03-04 16:47:13 +01:00
Markus F.X.J. Oberhumer 1377b54b9e dos/exe: optimize M_PIA_small. 2007-03-04 15:20:09 +01:00
Markus F.X.J. Oberhumer 66418ffc8c Reorganize dos/exe. No stub changes. 2007-03-04 15:14:44 +01:00
László Molnár b4c4b1fb70 dos/exe: fixed a bug in relocation handling 2007-03-01 16:57:12 +01:00
Markus F.X.J. Oberhumer ffe4a4b047 dos/exe: clear the dirty stack. 2007-02-26 13:55:12 +01:00
László Molnár 753ce45310 dos/exe: better minsp approximation 2007-02-26 12:54:49 +01:00
Markus F.X.J. Oberhumer fece0d73e7 Update NEWS. Bump version date. 2007-02-26 01:37:03 +01:00
Markus F.X.J. Oberhumer edce076e68 Minor Makefile updates. 2007-02-26 01:33:08 +01:00
Markus F.X.J. Oberhumer 675d0a009a Use M_IS_LZMA. 2007-02-26 01:32:36 +01:00
Markus F.X.J. Oberhumer 5d41b5a4db Fix shld macro. 2007-02-26 00:52:18 +01:00
László Molnár fe53b135eb pe: better icon compression handling 2007-02-24 23:25:11 +01:00
László Molnár 5b1c154ee2 NEWS update 2007-02-23 13:46:52 +01:00
László Molnár 816d882611 dos/exe: nrv2b compressed lzma decompressor added 2007-02-23 13:34:12 +01:00
Markus F.X.J. Oberhumer 12bcb09051 Small Makefile updates. 2007-02-21 17:11:42 +01:00
László Molnár c59c69a85f p_exe.cpp: added some comments 2007-02-20 13:49:18 +01:00
Markus F.X.J. Oberhumer bdd0daaf6f Added ElfLinker::addLoaderVA(). 2007-02-20 07:36:34 +01:00
Markus F.X.J. Oberhumer cfad7c8356 Small cleanups. 2007-02-19 03:52:33 +01:00
John Reiser b2b8a128d0 merge 2007-02-18 10:10:17 -08:00
Markus F.X.J. Oberhumer 1cfad80ca2 Introduce a special "ignore_reloc_overflow" section. 2007-02-18 18:29:26 +01:00
John Reiser a5a80e41b8 merge 2007-02-18 09:09:17 -08:00
Markus F.X.J. Oberhumer 152f8e92bf Yet some more Watcom optimizations. 2007-02-18 05:43:31 +01:00
Markus F.X.J. Oberhumer 0323560b49 More Watcom optimizations. 2007-02-18 04:41:33 +01:00
Markus F.X.J. Oberhumer d3bc84a2f7 Some Watcom optimizations. 2007-02-18 03:55:46 +01:00
Markus F.X.J. Oberhumer 8a82c259bd Switching back to using Watcom C - this seems to work. 2007-02-18 03:02:00 +01:00
Markus F.X.J. Oberhumer 46009c7658 i086 Makefile.extra update. 2007-02-18 02:32:47 +01:00
Markus F.X.J. Oberhumer 6f760308bd Some cleanasm.py updates. 2007-02-18 01:32:30 +01:00
John Reiser c346f8f17d merge 2007-02-16 08:06:37 -08:00
John Reiser af1d059fff PackUnix::getLoader() result is not 'const' 2007-02-16 08:05:10 -08:00
John Reiser 5562b21a20 PackMach* checkAlreadyPacked() 2007-02-16 08:02:59 -08:00
Markus F.X.J. Oberhumer 8f68f31877 Use Wine + Digital Mars C/C++ in small model. Does not work yet. 2007-02-16 15:22:01 +01:00
Markus F.X.J. Oberhumer ce7e94030c Added i086/l_test.c. Cleanups. 2007-02-16 08:52:31 +01:00
Markus F.X.J. Oberhumer ccf5a1b972 Add some more funcs to cc_test.c. 2007-02-13 09:48:37 +01:00
Markus F.X.J. Oberhumer 0d5ae77efc Some more dos/exe updates. 2007-02-13 02:25:32 +01:00
Markus F.X.J. Oberhumer 1695096d18 Commit rebuilt files as well. 2007-02-13 00:39:43 +01:00
Markus F.X.J. Oberhumer 6db0b7cf18 lzma for dos/exe works! 2007-02-13 00:39:15 +01:00
John Reiser 575b43b0d4 NEWS: Mach/i386 and Mach/fat 2007-02-12 15:22:22 -08:00
László Molnár 7b39b05894 lzma for dos/exe seems to work with tainted watcom macros 2007-02-12 18:28:24 +01:00
László Molnár 8bea9e0a5e fixed some watcom support macros 2007-02-12 15:38:47 +01:00
László Molnár 2255b32e45 LZMA for dos/exe integration work. Does not work yet. 2007-02-12 15:12:36 +01:00
Markus F.X.J. Oberhumer b62573ae8f More work on lzma for dos/exe. 2007-02-11 21:20:00 +01:00
Markus F.X.J. Oberhumer 44ed84f5cf Added lzma for dos/exe. Glue code and integration is still missing. 2007-02-11 07:54:16 +01:00
Markus F.X.J. Oberhumer d008c834be Merge. 2007-02-11 04:52:53 +01:00
Markus F.X.J. Oberhumer 2d3a914aee Some i086 updates. 2007-02-11 04:52:33 +01:00
John Reiser 7324f4c3d1 PackMach* filters only the [1st] largest executable LC_SEGMNET 2007-02-10 17:47:04 -08:00
Markus F.X.J. Oberhumer 50c8860a50 Added first version of a clean-room wcc support library implementation. 2007-02-11 01:06:37 +01:00
Markus F.X.J. Oberhumer 6456de7188 i086: added cc_test for examining internal compiler library calls. 2007-02-11 01:02:36 +01:00
John Reiser 23c629f2aa i386-darwin.macho works! 2007-02-10 13:14:27 -08:00
John Reiser 2bf154f74f i386-darwin.macho: decompressor overrun, bswap Mach_fat_header 2007-02-10 10:57:02 -08:00
John Reiser b598ad1bc0 i386-darwin.macho runtime stub 2007-02-10 09:16:49 -08:00
Markus F.X.J. Oberhumer ace24ad68e Minor portability fixes. 2007-02-08 16:17:32 +01:00
Markus F.X.J. Oberhumer 750c1a0f27 Avoid compiler warnings. 2007-02-08 15:00:42 +01:00
John Reiser 52d89bd66b PackMachFat has trouble with --fileinfo 2007-02-07 22:24:42 -08:00
John Reiser 8cfb9d35e9 fix ui report after PackMachFat::unpack 2007-02-07 22:03:15 -08:00
John Reiser 2f529158a0 OutputFile::unset_extent() sets bytes_written 2007-02-07 22:02:28 -08:00
John Reiser 6e68ab6d9e canUnpack() and unpack() for PackMachBase, PackMachFat 2007-02-07 21:30:18 -08:00
John Reiser 7a3c55af35 fix SEEK_END when set_extent() 2007-02-07 21:21:19 -08:00
John Reiser fb39d6304a Enable --lzma for PackMach*. 2007-02-07 11:23:21 -08:00
John Reiser 4cb57d9059 OutputFile::unset_extent(); endianness in Mach_fat_* and PackMachBase::b_info 2007-02-06 13:11:31 -08:00
John Reiser 42d69bd0e5 debug PackMachFat 2007-02-05 22:34:23 -08:00
John Reiser f27b399f81 PackMachFat 2007-02-05 14:00:41 -08:00
John Reiser a545a3938f FileBase::set_extent(offset, length) constrains seek() and tell() 2007-02-03 13:31:44 -08:00
John Reiser d1e352c9ee PackMachI386 2007-02-03 11:40:25 -08:00
John Reiser 99be1e798b PackMachPPC32 2007-02-03 11:04:57 -08:00
John Reiser 2132a28a17 UPX_F_MACH_i386 and skeleton stub. (Much of PackMachI386 is incomplete.) 2007-02-02 13:51:51 -08:00
John Reiser 8b1cc28783 templates to prepare for Mach-O i386 and Universal ("fat") executables 2007-01-31 20:25:13 -08:00
Markus F.X.J. Oberhumer 78364ac830 Small Watcom updates. 2007-01-31 14:28:15 +01:00
Markus F.X.J. Oberhumer 6e5f5732b5 brandelf.py: do not write "Linux" any longer as newer ldd's (e.g.
from glibc-common-2.5-10.fc6) do not like this.
2007-01-31 05:58:17 +01:00
Markus F.X.J. Oberhumer 87844254d1 Minor Makefile updates. 2007-01-31 05:53:38 +01:00
Markus F.X.J. Oberhumer 08ef9f69fb Very minor portability fixes. 2007-01-30 20:36:59 +01:00
Markus F.X.J. Oberhumer 5fbd1b78e7 Added non-working experimental infrastructure for using OpenWatcom 1.6
to support i086 + lzma.
2007-01-30 20:25:20 +01:00
Markus F.X.J. Oberhumer 39f5eb753f Bump version for next release. 2007-01-23 22:17:02 +01:00
Markus F.X.J. Oberhumer f4cbe3f300 Added tag for RELEASE_292. 2007-01-23 22:13:01 +01:00
115 changed files with 15847 additions and 2894 deletions
+4
View File
@@ -2,11 +2,15 @@ syntax: regexp
^\.bzr ^\.bzr
^ChangeLog ^ChangeLog
^Makevars.global
^build ^build
^maint ^maint
syntax: glob syntax: glob
.depend
Makevars.local
*.a *.a
*.dll *.dll
*.lib *.lib
+2
View File
@@ -4,6 +4,7 @@
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196 2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291 396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200 70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201 a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193 a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195 b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
@@ -12,3 +13,4 @@ c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290 d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110 eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191 ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
efa52753e366300c0e0ebe20631adcb24ed3c15b RELEASE_293
+11 -10
View File
@@ -1,16 +1,21 @@
# #
# UPX toplevel Makefile - needs GNU make 3.80 or better # UPX toplevel Makefile - needs GNU make 3.81 or better
# #
MAKEFLAGS += -rR MAKEFLAGS += -rR
.SUFFIXES: .SUFFIXES:
export SHELL = /bin/sh export SHELL = /bin/sh
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
$(error GNU make 3.81 or better is required)
endif
srcdir = . srcdir = .
top_srcdir = . top_srcdir = .
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
# info: src/stub needs GNU make 3.81 and special build tools # info: src/stub needs special build tools
BUILD_STUB = 0 BUILD_STUB = 0
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),) ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
BUILD_STUB = 1 BUILD_STUB = 1
@@ -18,9 +23,6 @@ endif
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),) ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
BUILD_STUB = 1 BUILD_STUB = 1
endif endif
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.79 3.79.1 3.80),)
BUILD_STUB = 0
endif
default: default:
@@ -33,15 +35,14 @@ endif
$(MAKE) -C src $@ $(MAKE) -C src $@
$(MAKE) -C doc $@ $(MAKE) -C doc $@
# automatically generate ChangeLog from Mercurial repo
ChangeLog:
ifneq ($(wildcard .hg/data/.),) ifneq ($(wildcard .hg/data/.),)
# automatically generate ChangeLog from local Mercurial repo
ChangeLog:
hg log --style=changelog > $@ hg log --style=changelog > $@
else .PHONY: ChangeLog
@echo "UPX info: no hg repo found"
endif endif
.PHONY: default all mostlyclean clean distclean maintainer-clean .PHONY: default all mostlyclean clean distclean maintainer-clean
.PHONY: ChangeLog
+18 -3
View File
@@ -2,6 +2,19 @@
User visible changes for UPX User visible changes for UPX
================================================================== ==================================================================
Changes in 3.00 (27 Apr 2007):
* watcom/le & tmt/adam: fixed a problem when using certain filters
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): Changes in 2.92 beta (23 Jan 2007):
* new option '--ultra-brute' which tries even more variants * new option '--ultra-brute' which tries even more variants
* slightly improved compression ratio for some files when * slightly improved compression ratio for some files when
@@ -302,8 +315,8 @@ Changes in 0.80 (03 Aug 1999)
* win32/pe: even better TLS support * win32/pe: even better TLS support
* win32/pe: versioninfo works on NT * win32/pe: versioninfo works on NT
* win32/pe: import by ordinal from kernel32.dll works * win32/pe: import by ordinal from kernel32.dll works
* win32/pe: other import improvements: importing a nonexistant DLL * win32/pe: other import improvements: importing a nonexistent DLL
results in a usual Windows message, importing a nonexistant function results in a usual Windows message, importing a nonexistent function
results in program exit (instead of crash ;-) results in program exit (instead of crash ;-)
* win32/pe: new option: '--compress-resources=0' * win32/pe: new option: '--compress-resources=0'
* win32/pe: reduced memory requirement during uncompression, some * win32/pe: reduced memory requirement during uncompression, some
@@ -355,7 +368,7 @@ Changes in 0.60 (06 Mar 1999)
* win32/pe: fixed file corruption when the size of the export data is invalid * win32/pe: fixed file corruption when the size of the export data is invalid
* win32/pe: fixed a problem with empty resource data * win32/pe: fixed a problem with empty resource data
* win32/pe: compressed file alignment set to minimum value * win32/pe: compressed file alignment set to minimum value
* win32/pe: made all compressed sections writeable * win32/pe: made all compressed sections writable
* fixed some other win32/pe bugs * fixed some other win32/pe bugs
* fixed an address optimization problem for some not Watcom LE files * fixed an address optimization problem for some not Watcom LE files
* fixed a bug which could make UPX hang when an exe header contained * fixed a bug which could make UPX hang when an exe header contained
@@ -396,3 +409,5 @@ Changes in 0.20 (05 Jul 1998)
Changes in 0.05 (26 May 1998) Changes in 0.05 (26 May 1998)
* first public beta release * first public beta release
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
+1 -1
View File
@@ -96,7 +96,7 @@ THE FUTURE
- We will *NOT* add any sort of protection and/or encryption. - We will *NOT* add any sort of protection and/or encryption.
This only gives people a false feeling of security because This only gives people a false feeling of security because
by definition all protectors/compressors can be broken. by definition all protectors/compressors can be broken.
And don't trust any advertisment of authors of other executable And don't trust any advertisement of authors of other executable
compressors about this topic - just do a websearch on "unpackers"... compressors about this topic - just do a websearch on "unpackers"...
- Fix all remaining bugs - keep your reports coming ;-) - Fix all remaining bugs - keep your reports coming ;-)
+1 -1
View File
@@ -57,7 +57,7 @@ Subroutine do_xmap() of src/stub/l_lx_elf.c performs the
"virtual execve()" using the compressed data as source, and stores "virtual execve()" using the compressed data as source, and stores
the decompressed bytes directly into the appropriate virtual addresses. the decompressed bytes directly into the appropriate virtual addresses.
Before transfering control to the PT_INTERP "program interpreter", Before transferring control to the PT_INTERP "program interpreter",
minor tricks are required to setup the Elf32_auxv_t entries, minor tricks are required to setup the Elf32_auxv_t entries,
clear the free portion of the stack (to compensate for ld-linux.so.2 clear the free portion of the stack (to compensate for ld-linux.so.2
assuming that its automatic stack variables are initialized to zero), assuming that its automatic stack variables are initialized to zero),
+1 -1
View File
@@ -45,6 +45,6 @@ These symbols can be defined later in C++ using
linker->defineSymbol("xx", yy) linker->defineSymbol("xx", yy)
This functionality (we could say it's a simple linker) is achived by This functionality (we could say it's a simple linker) is achieved by
compiling the assembly into an ELF object file which a little C++ compiling the assembly into an ELF object file which a little C++
module (src/linker.cpp) can interpret and work with. module (src/linker.cpp) can interpret and work with.
+22 -19
View File
@@ -197,7 +197,7 @@ For win32/pe programs there's B<--strip-relocs=0>. See notes below.
=head1 OVERLAY HANDLING OPTIONS =head1 OVERLAY HANDLING OPTIONS
Info: An "overlay" means auxillary data atached after the logical end of Info: An "overlay" means auxiliary data attached after the logical end of
an executable, and it often contains application specific data an executable, and it often contains application specific data
(this is a common practice to avoid an extra data file, though (this is a common practice to avoid an extra data file, though
it would be better to use resource sections). it would be better to use resource sections).
@@ -345,7 +345,7 @@ Extra options available for this executable format:
First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has
the very bad habit of replacing your stub with its own (outdated) version. the very bad habit of replacing your stub with its own (outdated) version.
Additionally B<UPX> corrects a bug/feature in strip v2.8.x: it Additionally B<UPX> corrects a bug/feature in strip v2.8.x: it
will fix the 4 KByte aligment of the stub. will fix the 4 KByte alignment of the stub.
B<UPX> includes the full functionality of stubify. This means it will B<UPX> includes the full functionality of stubify. This means it will
automatically stubify your COFF files. Use the option B<--coff> to automatically stubify your COFF files. Use the option B<--coff> to
@@ -380,7 +380,7 @@ Extra options available for this executable format:
Introduction Introduction
Linux/386 support in UPX consists of 3 different executable formats, Linux/386 support in UPX consists of 3 different executable formats,
one optimized for ELF excutables ("linux/elf386"), one optimized one optimized for ELF executables ("linux/elf386"), one optimized
for shell scripts ("linux/sh386"), and one generic format for shell scripts ("linux/sh386"), and one generic format
("linux/386"). ("linux/386").
@@ -408,14 +408,14 @@ General user's overview
or network I/O. or network I/O.
Depending on the statistics of usage and access, and the relative Depending on the statistics of usage and access, and the relative
speeds of CPU, RAM, swap space, /tmp, and filesystem storage, then speeds of CPU, RAM, swap space, /tmp, and file system storage, then
invoking and running a compressed executable can be faster than invoking and running a compressed executable can be faster than
directly running the corresponding uncompressed program. directly running the corresponding uncompressed program.
The operating system might perfrom fewer expensive I/O operations The operating system might perform fewer expensive I/O operations
to invoke the compressed program. Paging to or from swap space to invoke the compressed program. Paging to or from swap space
or /tmp might be faster than paging from the general filesystem. or /tmp might be faster than paging from the general file system.
``Medium-sized'' programs which access about 1/3 to 1/2 of their ``Medium-sized'' programs which access about 1/3 to 1/2 of their
stored program bytes can do particulary well with compression. stored program bytes can do particularly well with compression.
Small programs tend not to benefit as much because the absolute Small programs tend not to benefit as much because the absolute
savings is less. Big programs tend not to benefit proportionally savings is less. Big programs tend not to benefit proportionally
because each invocation may use only a small fraction of the program, because each invocation may use only a small fraction of the program,
@@ -424,7 +424,7 @@ General user's overview
then compression may win anyway. then compression may win anyway.
Currently, executables compressed by UPX do not share RAM at runtime Currently, executables compressed by UPX do not share RAM at runtime
in the way that executables mapped from a filesystem do. As a in the way that executables mapped from a file system do. As a
result, if the same program is run simultaneously by more than one result, if the same program is run simultaneously by more than one
process, then using the compressed version will require more RAM and/or process, then using the compressed version will require more RAM and/or
swap space. So, shell programs (bash, csh, etc.) and ``make'' swap space. So, shell programs (bash, csh, etc.) and ``make''
@@ -513,7 +513,7 @@ The linux/elf386 format decompresses directly into RAM,
uses only one exec, does not use space in /tmp, uses only one exec, does not use space in /tmp,
and does not use /proc. and does not use /proc.
Linux/elf386 is automatically selected for Linux ELF exectuables. Linux/elf386 is automatically selected for Linux ELF executables.
Packed programs will be byte-identical to the original after uncompression. Packed programs will be byte-identical to the original after uncompression.
@@ -602,7 +602,7 @@ Extra options available for this executable format:
Please read the general Linux description first. Please read the general Linux description first.
The generic linux/386 format decompresses to /tmp and needs The generic linux/386 format decompresses to /tmp and needs
/proc filesystem support. It starts the decompressed program /proc file system support. It starts the decompressed program
via the execve() syscall. via the execve() syscall.
Linux/386 is only selected if the specialized linux/elf386 Linux/386 is only selected if the specialized linux/elf386
@@ -614,11 +614,11 @@ How it works:
For files which are not ELF and not a script for a known "-c" shell, For files which are not ELF and not a script for a known "-c" shell,
UPX uses kernel execve(), which first requires decompressing to a UPX uses kernel execve(), which first requires decompressing to a
temporary file in the filesystem. Interestingly - temporary file in the file system. Interestingly -
because of the good memory management of the Linux kernel - this because of the good memory management of the Linux kernel - this
often does not introduce a noticable delay, and in fact there often does not introduce a noticeable delay, and in fact there
will be no disk access at all if you have enough free memory as will be no disk access at all if you have enough free memory as
the entire process takes places within the filesystem buffers. the entire process takes places within the file system buffers.
A compressed executable consists of the UPX stub and an overlay A compressed executable consists of the UPX stub and an overlay
which contains the original program in a compressed form. which contains the original program in a compressed form.
@@ -644,7 +644,7 @@ Specific drawbacks:
decompression, but you still need it for the full execution time decompression, but you still need it for the full execution time
of the program. of the program.
- You must have /proc filesystem support as the stub wants to open - You must have /proc file system support as the stub wants to open
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you /proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
cannot compress programs that are used during the boot sequence cannot compress programs that are used during the boot sequence
before /proc is mounted. before /proc is mounted.
@@ -656,7 +656,7 @@ Specific drawbacks:
- Because of temporary decompression to disk the decompression speed - Because of temporary decompression to disk the decompression speed
is not as fast as with the other executable formats. Still, I can see is not as fast as with the other executable formats. Still, I can see
no noticable delay when starting programs like my ~3 MB emacs (which no noticeable delay when starting programs like my ~3 MB emacs (which
is less than 1 MB when compressed :-). is less than 1 MB when compressed :-).
Extra options available for this executable format: Extra options available for this executable format:
@@ -683,7 +683,10 @@ Notes:
- UPX creates as default a suitable executable for CD-Mastering - UPX creates as default a suitable executable for CD-Mastering
and console transfer. For a CD-Master main executable you could also try and console transfer. For a CD-Master main executable you could also try
the special option "--boot-only" as descriped below. the special option "--boot-only" as described below.
It has been reported that upx packed executables are fully compatible with
the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in
Sony PlayStation (PSone) emulation mode.
- Normally the packed files use the same memory areas like the uncompressed - Normally the packed files use the same memory areas like the uncompressed
versions, so they will not override other memory areas while unpacking. versions, so they will not override other memory areas while unpacking.
@@ -759,7 +762,7 @@ Benefits:
- Better compression (but note that the kernel was already compressed, - Better compression (but note that the kernel was already compressed,
so the improvement is not as large as with other formats). so the improvement is not as large as with other formats).
Still, the bytes saved may be essential for special needs like Still, the bytes saved may be essential for special needs like
bootdisks. boot disks.
For example, this is what I get for my 2.2.16 kernel: For example, this is what I get for my 2.2.16 kernel:
1589708 vmlinux 1589708 vmlinux
@@ -806,13 +809,13 @@ Extra options available for this executable format:
=head2 NOTES FOR WIN32/PE =head2 NOTES FOR WIN32/PE
The PE support in B<UPX> is quite stable now, but probably there are The PE support in B<UPX> is quite stable now, but probably there are
still some incompabilities with some files. still some incompatibilities with some files.
Because of the way B<UPX> (and other packers for this format) works, you Because of the way B<UPX> (and other packers for this format) works, you
can see increased memory usage of your compressed files because the whole can see increased memory usage of your compressed files because the whole
program is loaded into memory at startup. program is loaded into memory at startup.
If you start several instances of huge compressed programs you're If you start several instances of huge compressed programs you're
wasting memory because the common segements of the program won't wasting memory because the common segments of the program won't
get shared across the instances. get shared across the instances.
On the other hand if you're compressing only smaller programs, or On the other hand if you're compressing only smaller programs, or
running only one instance of larger programs, then this penalty is running only one instance of larger programs, then this penalty is
+36 -11
View File
@@ -1,5 +1,5 @@
# #
# UPX Makefile - needs GNU make 3.80 or better # UPX Makefile - needs GNU make 3.81 or better
# #
MAKEFLAGS += -rR MAKEFLAGS += -rR
@@ -7,9 +7,19 @@ MAKEFLAGS += -rR
export SHELL = /bin/sh export SHELL = /bin/sh
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1) override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
srcdir ?= $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))) ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
ifneq ($(srcdir),./) $(error GNU make 3.81 or better is required)
endif
ifndef srcdir
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,') srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
endif
ifndef top_srcdir
top_srcdir := $(srcdir)/..
endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
ifneq ($(srcdir),.)
##$(info Info: using VPATH . $(srcdir)) ##$(info Info: using VPATH . $(srcdir))
VPATH := . $(srcdir) VPATH := . $(srcdir)
endif endif
@@ -17,11 +27,10 @@ endif
ifeq ($(CXX),) ifeq ($(CXX),)
CXX = g++ CXX = g++
endif endif
ifeq ($(firstword $(CXX)),g++) ifneq ($(findstring $(firstword $(CXX)),g++),)
USE_GNUC ?= 1 USE_GNUC ?= 1
endif endif
ifeq ($(USE_GNUC),1) ifeq ($(USE_GNUC),1)
CXXFLAGS += -MMD
ifeq ($(DEBUG),1) ifeq ($(DEBUG),1)
CXXFLAGS += -O0 -g CXXFLAGS += -O0 -g
else else
@@ -48,22 +57,31 @@ endif
LIBS += -lucl -lz LIBS += -lucl -lz
# you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2 # you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),) ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
DEFS += -DWITH_LZMA DEFS += -DWITH_LZMA=1
INCLUDES += -I$(UPX_LZMADIR) INCLUDES += -I$(UPX_LZMADIR)
endif endif
all: upx$(exeext) all: upx$(exeext) | .depend
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS) .DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS) .depend
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES) upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
$($(notdir $@).PRE_LINK_STEP) $($(notdir $@).PRE_LINK_STEP)
$(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS)) $(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS))
$($(notdir $@).POST_LINK_STEP) $($(notdir $@).POST_LINK_STEP)
%.o : %.cpp %.o : %.cpp | .depend
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<) $(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
.depend: $(wildcard $(srcdir)/*.cpp $(srcdir)/*.h) $(MAKEFILE_LIST)
@rm -f $@
ifeq ($(USE_GNUC),1)
@echo "Updating $@"
@$(strip $(CXX) $(call e,CPPFLAGS) -MM) $(filter %.cpp,$^) > $@
else
touch $@
endif
ifeq ($(USE_GNUC),1) ifeq ($(USE_GNUC),1)
##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer ##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer
@@ -76,7 +94,14 @@ endif
mostlyclean clean distclean maintainer-clean: mostlyclean clean distclean maintainer-clean:
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext) rm -f *.d *.map *.o *.obj *.res .depend upx.exe upx.out upx.ttp upx$(exeext)
-include *.d
.PHONY: all mostlyclean clean distclean maintainer-clean .PHONY: all mostlyclean clean distclean maintainer-clean
ifeq ($(MAKECMDGOALS),mostlyclean)
else ifeq ($(MAKECMDGOALS),clean)
else ifeq ($(MAKECMDGOALS),distclean)
else ifeq ($(MAKECMDGOALS),maintainer-clean)
else
-include .depend
endif
+7 -5
View File
@@ -182,8 +182,10 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
// //
**************************************************************************/ **************************************************************************/
int upx_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ) const upx_compress_result_t *cresult )
{ {
@@ -201,15 +203,15 @@ int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
} }
#if defined(WITH_LZMA) #if defined(WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
r = upx_lzma_test_overlap(buf, src_off, src_len, dst_len, method, cresult); r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif #endif
#if defined(WITH_NRV) #if defined(WITH_NRV)
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
r = upx_nrv_test_overlap(buf, src_off, src_len, dst_len, method, cresult); r = upx_nrv_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif #endif
#if defined(WITH_UCL) #if defined(WITH_UCL)
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
r = upx_ucl_test_overlap(buf, src_off, src_len, dst_len, method, cresult); r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif #endif
else { else {
throwInternalError("unknown decompression method"); throwInternalError("unknown decompression method");
+16 -8
View File
@@ -46,8 +46,10 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_lzma_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
@@ -65,8 +67,10 @@ int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_nrv_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_nrv_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
@@ -84,8 +88,10 @@ int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_ucl_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
@@ -102,8 +108,10 @@ int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_zlib_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
+19 -14
View File
@@ -28,6 +28,7 @@
#include "conf.h" #include "conf.h"
#include "compress.h" #include "compress.h"
#include "mem.h"
void lzma_compress_config_t::reset() void lzma_compress_config_t::reset()
@@ -483,28 +484,32 @@ error:
/************************************************************************* /*************************************************************************
// test_overlap // test_overlap - see <ucl/ucl.h> for semantics
**************************************************************************/ **************************************************************************/
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_lzma_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ) const upx_compress_result_t *cresult )
{ {
assert(M_IS_LZMA(method)); assert(M_IS_LZMA(method));
// FIXME - implement this MemBuffer b(src_off + src_len);
// Note that Packer::verifyOverlappingDecompression() will memcpy(b + src_off, buf + src_off, src_len);
// verify the final result in any case. unsigned saved_dst_len = *dst_len;
UNUSED(buf); int r = upx_lzma_decompress(b + src_off, src_len, b, dst_len, method, cresult);
if (r != UPX_E_OK)
unsigned overlap_overhead = src_off + src_len - *dst_len; return r;
//printf("upx_lzma_test_overlap: %d\n", overlap_overhead); if (*dst_len != saved_dst_len)
if ((int)overlap_overhead >= 256)
return UPX_E_OK;
UNUSED(cresult);
return UPX_E_ERROR; return UPX_E_ERROR;
// NOTE: there is a very tiny possibility that decompression has
// succeeded but the data is not restored correctly because of
// in-place buffer overlapping.
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
return UPX_E_ERROR;
return UPX_E_OK;
} }
+5 -2
View File
@@ -228,12 +228,15 @@ int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
// //
**************************************************************************/ **************************************************************************/
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_ucl_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ) const upx_compress_result_t *cresult )
{ {
int r; int r;
UNUSED(tbuf); // not needed for UCL
switch (method) switch (method)
{ {
+19 -14
View File
@@ -28,6 +28,7 @@
#include "conf.h" #include "conf.h"
#include "compress.h" #include "compress.h"
#include "mem.h"
void zlib_compress_config_t::reset() void zlib_compress_config_t::reset()
@@ -188,28 +189,32 @@ done:
/************************************************************************* /*************************************************************************
// test_overlap // test_overlap - see <ucl/ucl.h> for semantics
**************************************************************************/ **************************************************************************/
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_zlib_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ) const upx_compress_result_t *cresult )
{ {
assert(method == M_DEFLATE); assert(method == M_DEFLATE);
// FIXME - implement this MemBuffer b(src_off + src_len);
// Note that Packer::verifyOverlappingDecompression() will memcpy(b + src_off, buf + src_off, src_len);
// verify the final result in any case. unsigned saved_dst_len = *dst_len;
UNUSED(buf); int r = upx_zlib_decompress(b + src_off, src_len, b, dst_len, method, cresult);
if (r != UPX_E_OK)
unsigned overlap_overhead = src_off + src_len - *dst_len; return r;
//printf("upx_zlib_test_overlap: %d\n", overlap_overhead); if (*dst_len != saved_dst_len)
if ((int)overlap_overhead >= 256)
return UPX_E_OK;
UNUSED(cresult);
return UPX_E_ERROR; return UPX_E_ERROR;
// NOTE: there is a very tiny possibility that decompression has
// succeeded but the data is not restored correctly because of
// in-place buffer overlapping.
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
return UPX_E_ERROR;
return UPX_E_OK;
} }
+12 -7
View File
@@ -303,8 +303,8 @@
#undef __attribute_packed #undef __attribute_packed
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE) #if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
# if (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386)) # if (ACC_ARCH_I386) && (ACC_CC_INTELC && (__INTEL_COMPILER < 800))
# define __attribute_packed # elif (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386))
# else # else
# define __attribute_packed __attribute__((__packed__,__aligned__(1))) # define __attribute_packed __attribute__((__packed__,__aligned__(1)))
# endif # endif
@@ -448,13 +448,14 @@ private:
#define UPX_F_LINUX_ELFI_i386 20 #define UPX_F_LINUX_ELFI_i386 20
#define UPX_F_WINCE_ARM_PE 21 #define UPX_F_WINCE_ARM_PE 21
#define UPX_F_LINUX_ELF64_AMD 22 #define UPX_F_LINUX_ELF64_AMD 22
#define UPX_F_LINUX_ELF32_ARMLE 23 #define UPX_F_LINUX_ELF32_ARMEL 23
#define UPX_F_BSD_i386 24 #define UPX_F_BSD_i386 24
#define UPX_F_BSD_ELF_i386 25 #define UPX_F_BSD_ELF_i386 25
#define UPX_F_BSD_SH_i386 26 #define UPX_F_BSD_SH_i386 26
#define UPX_F_VMLINUX_AMD64 27 #define UPX_F_VMLINUX_AMD64 27
#define UPX_F_VMLINUX_ARM 28 #define UPX_F_VMLINUX_ARMEL 28
#define UPX_F_MACH_i386 29
#define UPX_F_PLAIN_TEXT 127 #define UPX_F_PLAIN_TEXT 127
@@ -462,7 +463,9 @@ private:
#define UPX_F_SOLARIS_SPARC 130 #define UPX_F_SOLARIS_SPARC 130
#define UPX_F_MACH_PPC32 131 #define UPX_F_MACH_PPC32 131
#define UPX_F_LINUX_ELFPPC32 132 #define UPX_F_LINUX_ELFPPC32 132
#define UPX_F_LINUX_ELF32_ARMBE 133 #define UPX_F_LINUX_ELF32_ARMEB 133
#define UPX_F_MACH_FAT 134
#define UPX_F_VMLINUX_ARMEB 135
// compression methods // compression methods
@@ -776,8 +779,10 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_test_overlap ( const upx_bytep buf, unsigned src_off, int upx_test_overlap ( const upx_bytep buf,
unsigned src_len, unsigned* dst_len, const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
+75 -4
View File
@@ -69,7 +69,7 @@ void File::unlink(const char *name)
**************************************************************************/ **************************************************************************/
FileBase::FileBase() : FileBase::FileBase() :
_fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL) _fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL), _offset(0), _length(0)
{ {
memset(&st,0,sizeof(st)); memset(&st,0,sizeof(st));
} }
@@ -104,6 +104,10 @@ void FileBase::sopen()
assert(0); assert(0);
#endif #endif
} }
if (!(_fd < 0)) {
::fstat(_fd, &st);
_length = st.st_size;
}
} }
@@ -117,6 +121,8 @@ bool FileBase::close()
_flags = 0; _flags = 0;
_mode = 0; _mode = 0;
_name = NULL; _name = NULL;
_offset = 0;
_length = 0;
return ok; return ok;
} }
@@ -164,10 +170,17 @@ void FileBase::seek(off_t off, int whence)
{ {
if (!isOpen()) if (!isOpen())
throwIOException("bad seek 1"); throwIOException("bad seek 1");
if (whence == SEEK_SET && off < 0) if (whence == SEEK_SET) {
if (off < 0)
throwIOException("bad seek 2"); throwIOException("bad seek 2");
if (whence == SEEK_END && off > 0) off += _offset;
}
if (whence == SEEK_END) {
if (off > 0)
throwIOException("bad seek 3"); throwIOException("bad seek 3");
off += _offset + _length;
whence = SEEK_SET;
}
if (::lseek(_fd,off,whence) < 0) if (::lseek(_fd,off,whence) < 0)
throwIOException("seek error",errno); throwIOException("seek error",errno);
} }
@@ -180,7 +193,19 @@ off_t FileBase::tell() const
off_t l = ::lseek(_fd, 0, SEEK_CUR); off_t l = ::lseek(_fd, 0, SEEK_CUR);
if (l < 0) if (l < 0)
throwIOException("tell error",errno); throwIOException("tell error",errno);
return l; return l - _offset;
}
void FileBase::set_extent(off_t offset, off_t length)
{
_offset = offset;
_length = length;
}
off_t FileBase::st_size() const
{
return _length;
} }
@@ -205,6 +230,8 @@ void InputFile::sopen(const char *name, int flags, int shflags)
_flags = flags; _flags = flags;
_shflags = shflags; _shflags = shflags;
_mode = 0; _mode = 0;
_offset = 0;
_length = 0;
FileBase::sopen(); FileBase::sopen();
if (!isOpen()) if (!isOpen())
{ {
@@ -289,6 +316,8 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
_flags = flags; _flags = flags;
_shflags = shflags; _shflags = shflags;
_mode = mode; _mode = mode;
_offset = 0;
_length = 0;
FileBase::sopen(); FileBase::sopen();
if (!isOpen()) if (!isOpen())
{ {
@@ -316,6 +345,8 @@ bool OutputFile::openStdout(int flags, bool force)
_flags = flags; _flags = flags;
_shflags = -1; _shflags = -1;
_mode = 0; _mode = 0;
_offset = 0;
_length = 0;
if (flags && acc_set_binmode(fd, 1) == -1) if (flags && acc_set_binmode(fd, 1) == -1)
throwIOException(_name, errno); throwIOException(_name, errno);
_fd = fd; _fd = fd;
@@ -329,6 +360,16 @@ void OutputFile::write(const void *buf, int len)
bytes_written += len; bytes_written += len;
} }
off_t OutputFile::st_size() const
{
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
return bytes_written; // too big if seek()+write() instead of rewrite()
}
struct stat my_st;
::fstat(_fd, &my_st);
return my_st.st_size;
}
void OutputFile::write(const MemBuffer *buf, int len) void OutputFile::write(const MemBuffer *buf, int len)
{ {
@@ -343,6 +384,36 @@ void OutputFile::write(const MemBuffer &buf, int len)
write(&buf, len); write(&buf, len);
} }
void OutputFile::rewrite(const void *buf, int len)
{
assert(!opt->to_stdout);
write(buf, len);
bytes_written -= len; // restore
}
void OutputFile::seek(off_t off, int whence)
{
assert(!opt->to_stdout);
super::seek(off,whence);
}
void OutputFile::set_extent(off_t offset, off_t length)
{
super::set_extent(offset, length);
bytes_written = 0;
if (0==offset && (off_t)~0u==length) {
::fstat(_fd, &st);
_length = st.st_size - offset;
}
}
off_t OutputFile::unset_extent()
{
_offset = 0;
_length = ::lseek(_fd, 0, SEEK_END);
bytes_written = _length;
return _length;
}
void OutputFile::dump(const char *name, const void *buf, int len, int flags) void OutputFile::dump(const char *name, const void *buf, int len, int flags)
{ {
+9 -11
View File
@@ -59,6 +59,8 @@ public:
virtual bool isOpen() const { return _fd >= 0; } virtual bool isOpen() const { return _fd >= 0; }
int getFd() const { return _fd; } int getFd() const { return _fd; }
const char *getName() const { return _name; } const char *getName() const { return _name; }
virtual off_t st_size() const; // { return _length; }
virtual void set_extent(off_t offset, off_t length);
protected: protected:
void sopen(); void sopen();
@@ -73,6 +75,8 @@ protected:
int _shflags; int _shflags;
int _mode; int _mode;
const char *_name; const char *_name;
off_t _offset;
off_t _length;
public: public:
struct stat st; struct stat st;
}; };
@@ -128,21 +132,15 @@ public:
virtual void write(const void *buf, int len); virtual void write(const void *buf, int len);
virtual void write(const MemBuffer *buf, int len); virtual void write(const MemBuffer *buf, int len);
virtual void write(const MemBuffer &buf, int len); virtual void write(const MemBuffer &buf, int len);
virtual void set_extent(off_t offset, off_t length);
virtual off_t unset_extent(); // returns actual length
off_t getBytesWritten() const { return bytes_written; } off_t getBytesWritten() const { return bytes_written; }
virtual off_t st_size() const; // { return _length; }
// FIXME - these won't work when using the '--stdout' option // FIXME - these won't work when using the '--stdout' option
virtual void seek(off_t off, int whence) virtual void seek(off_t off, int whence);
{ virtual void rewrite(const void *buf, int len);
assert(!opt->to_stdout);
super::seek(off,whence);
}
virtual void rewrite(const void *buf, int len)
{
assert(!opt->to_stdout);
write(buf, len);
bytes_written -= len; // restore
}
// util // util
static void dump(const char *name, const void *buf, int len, int flags=-1); static void dump(const char *name, const void *buf, int len, int flags=-1);
+2 -2
View File
@@ -205,8 +205,8 @@ void show_help(int verbose)
con_fprintf(f,"\nCompression tuning options:\n"); con_fprintf(f,"\nCompression tuning options:\n");
fg = con_fg(f,fg); fg = con_fg(f,fg);
con_fprintf(f, con_fprintf(f,
" --brute try all available compression methods & filters\n" " --brute try all available compression methods & filters [slow]\n"
" --ultra-brute try even more compression variants\n" " --ultra-brute try even more compression variants [very slow]\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f,FG_YELLOW);
con_fprintf(f,"Backup options:\n"); con_fprintf(f,"Backup options:\n");
+23
View File
@@ -235,7 +235,12 @@ void ElfLinker::preprocessSymbols(char *start, char *end)
addSymbol(s, "*ABS*", value); addSymbol(s, "*ABS*", value);
assert(offset == 0); assert(offset == 0);
} }
#if 0
else if (sscanf(start, "%x%*8c %1023s %*x %1023s", else if (sscanf(start, "%x%*8c %1023s %*x %1023s",
#else
// work around broken scanf implementations
else if (sscanf(start, "%x%*c%*c%*c%*c%*c%*c%*c%*c %1023s %*x %1023s",
#endif
&offset, section, symbol) == 3) &offset, section, symbol) == 3)
{ {
char *s = strstr(start, symbol); char *s = strstr(start, symbol);
@@ -439,6 +444,23 @@ int ElfLinker::addLoader(const char *sname)
return outputlen; return outputlen;
} }
void ElfLinker::addLoader(const char *s, va_list ap)
{
while (s != NULL)
{
addLoader(s);
s = va_arg(ap, const char *);
}
}
void __acc_cdecl_va ElfLinker::addLoaderVA(const char *s, ...)
{
va_list ap;
va_start(ap, s);
addLoader(s, ap);
va_end(ap);
}
int ElfLinker::getSection(const char *sname, int *slen) const int ElfLinker::getSection(const char *sname, int *slen) const
{ {
const Section *section = findSection(sname); const Section *section = findSection(sname);
@@ -585,6 +607,7 @@ void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
/************************************************************************* /*************************************************************************
// ElfLinker arch subclasses // ElfLinker arch subclasses
// FIXME: add more displacment overflow checks // FIXME: add more displacment overflow checks
// FIXME: add support for our special "ignore_reloc_overflow" section
**************************************************************************/ **************************************************************************/
#if 0 // FIXME #if 0 // FIXME
+6
View File
@@ -83,6 +83,12 @@ public:
virtual void init(const void *pdata, int plen); virtual void init(const void *pdata, int plen);
//virtual void setLoaderAlignOffset(int phase); //virtual void setLoaderAlignOffset(int phase);
virtual int addLoader(const char *sname); virtual int addLoader(const char *sname);
void addLoader(const char *s, va_list ap);
#if 1 && (ACC_CC_GNUC >= 0x040100)
void __acc_cdecl_va addLoaderVA(const char *s, ...) __attribute__((__sentinel__));
#else
void __acc_cdecl_va addLoaderVA(const char *s, ...);
#endif
virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align); virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align);
virtual int getSection(const char *sname, int *slen=NULL) const; virtual int getSection(const char *sname, int *slen=NULL) const;
virtual int getSectionSize(const char *sname) const; virtual int getSectionSize(const char *sname) const;
+5
View File
@@ -553,23 +553,28 @@ static int do_option(int optc, const char *arg)
// method // method
case 702: case 702:
opt->method_nrv2b_seen = true;
if (!set_method(M_NRV2B_LE32, -1)) if (!set_method(M_NRV2B_LE32, -1))
e_method(M_NRV2B_LE32, opt->level); e_method(M_NRV2B_LE32, opt->level);
break; break;
case 704: case 704:
opt->method_nrv2d_seen = true;
if (!set_method(M_NRV2D_LE32, -1)) if (!set_method(M_NRV2D_LE32, -1))
e_method(M_NRV2D_LE32, opt->level); e_method(M_NRV2D_LE32, opt->level);
break; break;
case 705: case 705:
opt->method_nrv2e_seen = true;
if (!set_method(M_NRV2E_LE32, -1)) if (!set_method(M_NRV2E_LE32, -1))
e_method(M_NRV2E_LE32, opt->level); e_method(M_NRV2E_LE32, opt->level);
break; break;
case 721: case 721:
opt->method_lzma_seen = true;
opt->all_methods_use_lzma = true; opt->all_methods_use_lzma = true;
if (!set_method(M_LZMA, -1)) if (!set_method(M_LZMA, -1))
e_method(M_LZMA, opt->level); e_method(M_LZMA, opt->level);
break; break;
case 722: case 722:
opt->method_lzma_seen = false;
opt->all_methods_use_lzma = false; opt->all_methods_use_lzma = false;
if (M_IS_LZMA(opt->method)) if (M_IS_LZMA(opt->method))
opt->method = -1; opt->method = -1;
+2 -2
View File
@@ -38,7 +38,7 @@
#ifndef __ACC_H_INCLUDED #ifndef __ACC_H_INCLUDED
#define __ACC_H_INCLUDED 1 #define __ACC_H_INCLUDED 1
#define ACC_VERSION 20070112L #define ACC_VERSION 20070113L
#if defined(__CYGWIN32__) && !defined(__CYGWIN__) #if defined(__CYGWIN32__) && !defined(__CYGWIN__)
# define __CYGWIN__ __CYGWIN32__ # define __CYGWIN__ __CYGWIN32__
#endif #endif
@@ -1302,7 +1302,7 @@ extern "C" {
#elif !defined(ACC_ABI_BIG_ENDIAN) && !defined(ACC_ABI_LITTLE_ENDIAN) #elif !defined(ACC_ABI_BIG_ENDIAN) && !defined(ACC_ABI_LITTLE_ENDIAN)
#if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP) #if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
# define ACC_ABI_BIG_ENDIAN 1 # define ACC_ABI_BIG_ENDIAN 1
#elif (ACC_ARCH_ALPHA || ACC_ARCH_AMD64 || ACC_ARCH_CRIS || ACC_ARCH_I086 || ACC_ARCH_I386 || ACC_ARCH_MSP430) #elif (ACC_ARCH_ALPHA || ACC_ARCH_AMD64 || ACC_ARCH_BLACKFIN || ACC_ARCH_CRIS || ACC_ARCH_I086 || ACC_ARCH_I386 || ACC_ARCH_MSP430)
# define ACC_ABI_LITTLE_ENDIAN 1 # define ACC_ABI_LITTLE_ENDIAN 1
#elif (ACC_ARCH_M68K || ACC_ARCH_S390) #elif (ACC_ARCH_M68K || ACC_ARCH_S390)
# define ACC_ABI_BIG_ENDIAN 1 # define ACC_ABI_BIG_ENDIAN 1
+4
View File
@@ -47,6 +47,10 @@ struct options_t {
// compression options // compression options
int method; int method;
bool method_lzma_seen;
bool method_nrv2b_seen;
bool method_nrv2d_seen;
bool method_nrv2e_seen;
int level; // compression level 1..10 int level; // compression level 1..10
int filter; // preferred filter from Packer::getFilters() int filter; // preferred filter from Packer::getFilters()
bool ultra_brute; bool ultra_brute;
+1 -1
View File
@@ -632,7 +632,7 @@ void PackArmPe::pack(OutputFile *fo)
//OutputFile::dump("x1", ibuf, usize); //OutputFile::dump("x1", ibuf, usize);
// some checks for broken linkers - disable filter if neccessary // some checks for broken linkers - disable filter if necessary
bool allow_filter = true; bool allow_filter = true;
if (ih.codebase == ih.database if (ih.codebase == ih.database
|| ih.codebase + ih.codesize > ih.imagesize || ih.codebase + ih.codesize > ih.imagesize
+2 -1
View File
@@ -76,10 +76,11 @@ const int *PackDjgpp2::getFilters() const
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf, unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
unsigned range, unsigned range,
unsigned upper_limit) const unsigned upper_limit) const
{ {
unsigned o = super::findOverlapOverhead(buf, range, upper_limit); unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
o = (o + 0x3ff) &~ 0x1ff; o = (o + 0x3ff) &~ 0x1ff;
return o; return o;
} }
+1
View File
@@ -58,6 +58,7 @@ protected:
virtual int readFileHeader(); virtual int readFileHeader();
virtual unsigned findOverlapOverhead(const upx_bytep buf, virtual unsigned findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
unsigned range = 0, unsigned range = 0,
unsigned upper_limit = ~0u) const; unsigned upper_limit = ~0u) const;
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
+1 -1
View File
@@ -29,7 +29,7 @@
/************************************************************************* /*************************************************************************
// Use the preprocessor to work around // Use the preprocessor to work around
// - that the types embedding these enums have to be PODs, and // - that the types embedding these enums have to be PODs, and
// deriving from an empty base class (which is the ususal C++ way // deriving from an empty base class (which is the usual C++ way
// of "importing" enums) does not yield a POD any more // of "importing" enums) does not yield a POD any more
// - that older compilers do not correctly perform EBCO // - that older compilers do not correctly perform EBCO
**************************************************************************/ **************************************************************************/
+197 -54
View File
@@ -53,24 +53,19 @@ PackExe::PackExe(InputFile *f) :
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32); COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
ih_exesize = ih_imagesize = ih_overlay = 0; ih_exesize = ih_imagesize = ih_overlay = 0;
stack_for_lzma = 0;
use_clear_dirty_stack = false;
// disable lzma for "--brute" unless explicitly given "--lzma"
if (opt->all_methods_use_lzma && !opt->method_lzma_seen)
opt->all_methods_use_lzma = false;
} }
const int *PackExe::getCompressionMethods(int method, int level) const const int *PackExe::getCompressionMethods(int method, int level) const
{ {
static const int m_all[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_END };
static const int m_nrv2b[] = { M_NRV2B_8, M_END };
static const int m_nrv2d[] = { M_NRV2D_8, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_END };
if (method == M_ALL) return m_all;
if (M_IS_NRV2B(method)) return m_nrv2b;
if (M_IS_NRV2D(method)) return m_nrv2d;
if (M_IS_NRV2E(method)) return m_nrv2e;
bool small = ih_imagesize <= 256*1024; bool small = ih_imagesize <= 256*1024;
if (level == 1 || small) return Packer::getDefaultCompressionMethods_8(method, level, small);
return m_nrv2b;
return m_nrv2e;
} }
@@ -85,7 +80,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
#define oh (*eh) #define oh (*eh)
// fill new exe header // fill new exe header
int flag = 0; int flag = 0;
if (!opt->dos_exe.no_reloc) if (!opt->dos_exe.no_reloc && !M_IS_LZMA(ph.method))
flag |= USEJUMP; flag |= USEJUMP;
if (ih.relocs == 0) if (ih.relocs == 0)
flag |= NORELOC; flag |= NORELOC;
@@ -94,7 +89,16 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
oh.ident = 'M' + 'Z' * 256; oh.ident = 'M' + 'Z' * 256;
oh.headsize16 = 2; oh.headsize16 = 2;
oh.sp = ih.sp > 0x200 ? (unsigned) ih.sp : 0x200; unsigned minsp = 0x200;
if (M_IS_LZMA(ph.method))
minsp = stack_for_lzma;
minsp = ALIGN_UP(minsp, 16u);
assert(minsp < 0xff00);
if (oh.sp > minsp)
minsp = oh.sp;
if (minsp < 0xff00 - 2)
minsp = ALIGN_UP(minsp, 2u);
oh.sp = minsp;
unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16; unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16;
oh.ss = ph.c_len/16 + destpara; oh.ss = ph.c_len/16 + destpara;
@@ -106,27 +110,118 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
if (oh.ss != ih.ss) if (oh.ss != ih.ss)
flag |= SS; flag |= SS;
if (oh.sp != ih.sp) if (oh.sp != ih.sp || M_IS_LZMA(ph.method))
flag |= SP; flag |= SP;
return flag; return flag;
#undef oh #undef oh
} }
void PackExe::addLoaderEpilogue(int flag)
{
addLoader("EXEMAIN5", NULL);
if (relocsize)
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
"EXERELO1",
has_9a ? "EXEREL9A" : "",
"EXERELO2",
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
"EXERELO3",
NULL
);
addLoader("EXEMAIN8",
device_driver ? "DEVICEEND" : "",
(flag & SS) ? "EXESTACK" : "",
(flag & SP) ? "EXESTASP" : "",
(flag & USEJUMP) ? "EXEJUMPF" : "",
NULL
);
if (!(flag & USEJUMP))
addLoader(ih.cs ? "EXERCSPO" : "",
"EXERETIP",
NULL
);
linker->defineSymbol("original_cs", ih.cs);
linker->defineSymbol("original_ip", ih.ip);
linker->defineSymbol("original_sp", ih.sp);
linker->defineSymbol("original_ss", ih.ss);
linker->defineSymbol("reloc_size",
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
>= relocsize ? 0 : MAXRELOCS) - relocsize);
}
void PackExe::buildLoader(const Filter *) void PackExe::buildLoader(const Filter *)
{ {
struct exe_header_t tmp_oh; // get flag
int flag = fillExeHeader(&tmp_oh); exe_header_t dummy_oh;
int flag = fillExeHeader(&dummy_oh);
// prepare loader
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe)); initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
if (M_IS_LZMA(ph.method))
{
addLoader("LZMA_DEC00",
opt->small ? "LZMA_DEC10" : "LZMA_DEC20",
"LZMA_DEC30",
use_clear_dirty_stack ? "LZMA_DEC31" : "",
"LZMA_DEC32",
ph.u_len > 0xffff ? "LZMA_DEC33" : "",
NULL
);
addLoaderEpilogue(flag);
defineDecompressorSymbols();
const unsigned lsize0 = getLoaderSize();
// Lzma decompression code starts at ss:0x10, and its size is
// lsize bytes. It also needs getDecompressorWrkmemSize() bytes
// during uncompression. It also uses some stack, so 0x100
// more bytes are allocated
stack_for_lzma = 0x10 + lsize0 + getDecompressorWrkmemSize() + 0x100;
stack_for_lzma = ALIGN_UP(stack_for_lzma, 16u);
unsigned clear_dirty_stack_low = 0x10 + lsize0;
clear_dirty_stack_low = ALIGN_UP(clear_dirty_stack_low, 2u);
if (use_clear_dirty_stack)
linker->defineSymbol("clear_dirty_stack_low", clear_dirty_stack_low);
relocateLoader();
const unsigned lsize = getLoaderSize();
assert(lsize0 == lsize);
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
MemBuffer compressed_lzma;
compressed_lzma.allocForCompression(lsize);
unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize);
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma,
NULL, M_NRV2B_LE16, 9, NULL, NULL);
assert(r == UPX_E_OK); assert(c_len_lzma < lsize);
info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma);
// reinit the loader
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
// prepare loader
if (device_driver) if (device_driver)
addLoader("DEVICEENTRY", NULL); addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", NULL);
linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0);
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2",
NULL);
}
else if (device_driver)
addLoader("DEVICEENTRY,DEVICEENTRY2", NULL);
addLoader("EXEENTRY", addLoader("EXEENTRY",
device_driver ? "DEVICESUB" : "EXESUB", M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
"JNCDOCOPY", "JNCDOCOPY",
relocsize ? "EXERELPU" : "", relocsize ? "EXERELPU" : "",
"EXEMAIN4,+G5DXXXX,UPX1HEAD,EXECUTPO", "EXEMAIN4",
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B",
"EXEMAIN4C",
M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "",
"+G5DXXXX,UPX1HEAD,EXECUTPO",
NULL NULL
); );
if (ph.method == M_NRV2B_8) if (ph.method == M_NRV2B_8)
@@ -165,30 +260,12 @@ void PackExe::buildLoader(const Filter *)
"NRV2EEX9", "NRV2EEX9",
NULL NULL
); );
else if M_IS_LZMA(ph.method)
return;
else else
throwInternalError("unknown compression method"); throwInternalError("unknown compression method");
addLoader("EXEMAIN5", NULL);
if (relocsize) addLoaderEpilogue(flag);
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
"EXERELO1",
has_9a ? "EXEREL9A" : "",
"EXERELO2",
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
"EXERELO3",
NULL
);
addLoader("EXEMAIN8",
device_driver ? "DEVICEEND" : "",
(flag & SS) ? "EXESTACK" : "",
(flag & SP) ? "EXESTASP" : "",
(flag & USEJUMP) ? "EXEJUMPF" : "",
NULL
);
if (!(flag & USEJUMP))
addLoader(ih.cs ? "EXERCSPO" : "",
"EXERETIP",
NULL
);
} }
@@ -324,7 +401,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
break; break;
} }
unsigned offs = addr - es*16; unsigned offs = addr - es*16;
if (offs >= 3 && b[es*16 + offs-3] == 0x9a) if (offs >= 3 && b[es*16 + offs-3] == 0x9a && offs > di + 3)
{ {
for (t = di; t < offs-3; t++) for (t = di; t < offs-3; t++)
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high) if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
@@ -429,7 +506,10 @@ void PackExe::pack(OutputFile *fo)
// compress (max_match = 8192) // compress (max_match = 8192)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
cconf.conf_ucl.max_match = MAXMATCH; cconf.conf_ucl.max_match = MAXMATCH;
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 32, &cconf); compressWithFilters(&ft, 32, &cconf);
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
if (ph.max_run_found + ph.max_match_found > 0x8000) if (ph.max_run_found + ph.max_match_found > 0x8000)
throwCantPack("decompressor limit exceeded, send a bugreport"); throwCantPack("decompressor limit exceeded, send a bugreport");
@@ -497,15 +577,13 @@ void PackExe::pack(OutputFile *fo)
} }
extra_info[eisize++] = (unsigned char) flag; extra_info[eisize++] = (unsigned char) flag;
linker->defineSymbol("original_cs", ih.cs); if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
linker->defineSymbol("original_ip", ih.ip);
linker->defineSymbol("original_sp", ih.sp);
linker->defineSymbol("original_ss", ih.ss);
linker->defineSymbol("reloc_size",
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
>= relocsize ? 0 : MAXRELOCS) - relocsize);
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1)); linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
linker->defineSymbol("decompressor_entry", (packedsize & 15) + 1);
unsigned decompressor_entry = 1 + (packedsize & 15);
if (M_IS_LZMA(ph.method))
decompressor_entry = 0x10;
linker->defineSymbol("decompressor_entry", decompressor_entry);
// patch loader // patch loader
if (flag & USEJUMP) if (flag & USEJUMP)
@@ -541,8 +619,10 @@ void PackExe::pack(OutputFile *fo)
oh.m512 = outputlen & 511; oh.m512 = outputlen & 511;
oh.p512 = (outputlen + 511) >> 9; oh.p512 = (outputlen + 511) >> 9;
oh.ip = device_driver ? getLoaderSection("EXEENTRY") - 2 : 0; const char *exeentry = M_IS_LZMA(ph.method) ? "LZMAENTRY" : "EXEENTRY";
oh.ip = device_driver ? getLoaderSection(exeentry) - 2 : 0;
defineDecompressorSymbols();
relocateLoader(); relocateLoader();
memcpy(loader, getLoader(), lsize); memcpy(loader, getLoader(), lsize);
patchPackHeader(loader,e_len); patchPackHeader(loader,e_len);
@@ -591,7 +671,7 @@ int PackExe::canUnpack()
return false; return false;
const off_t off = ih.headsize16 * 16; const off_t off = ih.headsize16 * 16;
fi->seek(off, SEEK_SET); fi->seek(off, SEEK_SET);
bool b = readPackHeader(256); bool b = readPackHeader(4096);
return b && (off + (off_t) ph.c_len <= file_size); return b && (off + (off_t) ph.c_len <= file_size);
} }
@@ -726,6 +806,69 @@ Linker* PackExe::newLinker() const
return new ElfLinkerX86(); return new ElfLinkerX86();
} }
/*
memory layout at decompression time
===================================
normal exe
----------
a, at load time
(e - copying code, C - compressed data, d - decompressor+relocator,
x - not specified, U - uncompressed code+data, R uncompressed relocation)
eeCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCdddd
^ CS:0 ^ SS:0
b, after copying
xxxxxxxxxxxxxxxCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCdddd
^ES:DI=0 ^ DS:SI=0 ^ CS=SS, IP in range 0..0xf
c, after uncompression
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUURRdddd
^ ES:DI
device driver
-------------
the file has 2 entry points, CS:0 in device driver mode, and
CS:exe_as_device_entry in normal mode. the code in section DEVICEENTRY
sets up the same environment for section EXEENTRY, as it would see in normal
execution mode.
lzma uncompression for normal exes
----------------------------------
(n - nrv2b uncompressor, l - nrv2b compressed lzma + relocator code)
a, at load time
nneelllCCCCCCCCCCCCCCCCCCCCCCCCC
^ CS:0 ^ SS:0
b, after nrv2b
nneelllCCCCCCCCCCCCCCCCCCCCCCCCC dddd
^ CS:0 ^ SS:0x10
after this, normal ee code runs
lzma + device driver
--------------------
(D - device driver adapter)
a, at load time
DDnneelllCCCCCCCCCCCCCCCCCCCCCCCCC
*/
/* /*
vi:ts=4:et vi:ts=4:et
+4
View File
@@ -71,6 +71,7 @@ protected:
virtual int fillExeHeader(struct exe_header_t *) const; virtual int fillExeHeader(struct exe_header_t *) const;
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
void addLoaderEpilogue(int flag);
struct exe_header_t struct exe_header_t
{ {
@@ -110,6 +111,9 @@ protected:
MINMEM = 16, MINMEM = 16,
MAXMEM = 32 MAXMEM = 32
}; };
unsigned stack_for_lzma; // stack size required for lzma
bool use_clear_dirty_stack;
}; };
+4 -4
View File
@@ -416,8 +416,8 @@ class PackLinuxElf32armLe : public PackLinuxElf32Le
public: public:
PackLinuxElf32armLe(InputFile *f); PackLinuxElf32armLe(InputFile *f);
virtual ~PackLinuxElf32armLe(); virtual ~PackLinuxElf32armLe();
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; } virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEL; }
virtual const char *getName() const { return "linux/armLE"; } virtual const char *getName() const { return "linux/armel"; }
virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; } virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; }
virtual const int *getFilters() const; virtual const int *getFilters() const;
@@ -436,8 +436,8 @@ class PackLinuxElf32armBe : public PackLinuxElf32Be
public: public:
PackLinuxElf32armBe(InputFile *f); PackLinuxElf32armBe(InputFile *f);
virtual ~PackLinuxElf32armBe(); virtual ~PackLinuxElf32armBe();
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; } virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEB; }
virtual const char *getName() const { return "linux/armBE"; } virtual const char *getName() const { return "linux/armeb"; }
virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; } virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; }
virtual const int *getFilters() const; virtual const int *getFilters() const;
+416 -51
View File
@@ -39,22 +39,34 @@ static const
static const static const
#include "stub/powerpc-darwin.macho-fold.h" #include "stub/powerpc-darwin.macho-fold.h"
PackMachPPC32::PackMachPPC32(InputFile *f) : static const
super(f), n_segment(0), rawmseg(0), msegcmd(0) #include "stub/i386-darwin.macho-entry.h"
static const
#include "stub/i386-darwin.macho-fold.h"
template <class T>
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned flavor,
unsigned count, unsigned size) :
super(f), my_cputype(cputype), my_thread_flavor(flavor),
my_thread_state_word_count(count), my_thread_command_size(size),
n_segment(0), rawmseg(NULL), msegcmd(NULL)
{ {
MachClass::compileTimeAssertions();
bele = N_BELE_CTP::getRTP<BeLePolicy>();
} }
PackMachPPC32::~PackMachPPC32() template <class T>
PackMachBase<T>::~PackMachBase()
{ {
delete [] msegcmd;
delete [] rawmseg; delete [] rawmseg;
delete [] msegcmd;
} }
const int *PackMachPPC32::getCompressionMethods(int /*method*/, int /*level*/) const template <class T>
const int *PackMachBase<T>::getCompressionMethods(int method, int level) const
{ {
// There really is no LE bias in M_NRV2E_LE32. // There really is no LE bias.
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END }; return Packer::getDefaultCompressionMethods_le32(method, level);
return m_nrv2e;
} }
@@ -64,13 +76,25 @@ const int *PackMachPPC32::getFilters() const
return filters; return filters;
} }
int const *PackMachI386::getFilters() const
{
static const int filters[] = { 0x49, FT_END };
return filters;
}
Linker *PackMachPPC32::newLinker() const Linker *PackMachPPC32::newLinker() const
{ {
return new ElfLinkerPpc32; return new ElfLinkerPpc32;
} }
Linker *PackMachI386::newLinker() const
{
return new ElfLinkerX86;
}
template <class T>
void void
PackMachPPC32::addStubEntrySections(Filter const *) PackMachBase<T>::addStubEntrySections(Filter const *)
{ {
addLoader("MACOS000", NULL); addLoader("MACOS000", NULL);
//addLoader(getDecompressorSections(), NULL); //addLoader(getDecompressorSections(), NULL);
@@ -83,15 +107,79 @@ PackMachPPC32::addStubEntrySections(Filter const *)
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL); addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
} }
void PackMachI386::addStubEntrySections(Filter const *ft)
{
int const n_mru = ft->n_mru; // FIXME: belongs to filter? packerf?
void PackMachPPC32::defineSymbols(Filter const *) // entry to stub
addLoader("LEXEC000", NULL);
if (ft->id) {
{ // decompr, unfilter are separate
addLoader("LXUNF000", NULL);
addLoader("LXUNF002", NULL);
if (0x80==(ft->id & 0xF0)) {
if (256==n_mru) {
addLoader("MRUBYTE0", NULL);
}
else if (n_mru) {
addLoader("LXMRU005", NULL);
}
if (n_mru) {
addLoader("LXMRU006", NULL);
}
else {
addLoader("LXMRU007", NULL);
}
}
else if (0x40==(ft->id & 0xF0)) {
addLoader("LXUNF008", NULL);
}
addLoader("LXUNF010", NULL);
}
if (n_mru) {
addLoader("LEXEC009", NULL);
}
}
addLoader("LEXEC010", NULL);
addLoader(getDecompressorSections(), NULL);
addLoader("LEXEC015", NULL);
if (ft->id) {
{ // decompr, unfilter are separate
if (0x80!=(ft->id & 0xF0)) {
addLoader("LXUNF042", NULL);
}
}
addFilter32(ft->id);
{ // decompr, unfilter are separate
if (0x80==(ft->id & 0xF0)) {
if (0==n_mru) {
addLoader("LXMRU058", NULL);
}
}
addLoader("LXUNF035", NULL);
}
}
else {
addLoader("LEXEC017", NULL);
}
addLoader("IDENTSTR", NULL);
addLoader("LEXEC020", NULL);
addLoader("FOLDEXEC", NULL);
}
template <class T>
void PackMachBase<T>::defineSymbols(Filter const *)
{ {
// empty // empty
} }
template <class T>
void void
PackMachPPC32::buildMachLoader( PackMachBase<T>::buildMachLoader(
upx_byte const *const proto, upx_byte const *const proto,
unsigned const szproto, unsigned const szproto,
upx_byte const *const fold, upx_byte const *const fold,
@@ -142,11 +230,23 @@ PackMachPPC32::buildLoader(const Filter *ft)
stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry), stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry),
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft ); stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
} }
void PackMachPPC32::patchLoader() { }
void PackMachPPC32::updateLoader(OutputFile *) {}
void void
PackMachPPC32::patchLoaderChecksum() PackMachI386::buildLoader(const Filter *ft)
{
buildMachLoader(
stub_i386_darwin_macho_entry, sizeof(stub_i386_darwin_macho_entry),
stub_i386_darwin_macho_fold, sizeof(stub_i386_darwin_macho_fold), ft );
}
template <class T>
void PackMachBase<T>::patchLoader() { }
template <class T>
void PackMachBase<T>::updateLoader(OutputFile *) {}
template <class T>
void PackMachBase<T>::patchLoaderChecksum()
{ {
unsigned char *const ptr = getLoader(); unsigned char *const ptr = getLoader();
l_info *const lp = &linfo; l_info *const lp = &linfo;
@@ -160,8 +260,9 @@ PackMachPPC32::patchLoaderChecksum()
lp->l_checksum = upx_adler32(ptr, lsize); lp->l_checksum = upx_adler32(ptr, lsize);
} }
static int __acc_cdecl_qsort template <class T>
compare_segment_command(void const *const aa, void const *const bb) int __acc_cdecl_qsort
PackMachBase<T>::compare_segment_command(void const *const aa, void const *const bb)
{ {
Mach_segment_command const *const a = (Mach_segment_command const *)aa; Mach_segment_command const *const a = (Mach_segment_command const *)aa;
Mach_segment_command const *const b = (Mach_segment_command const *)bb; Mach_segment_command const *const b = (Mach_segment_command const *)bb;
@@ -174,8 +275,7 @@ compare_segment_command(void const *const aa, void const *const bb)
return 0; return 0;
} }
void void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{ {
// offset of p_info in compressed file // offset of p_info in compressed file
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo); overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
@@ -184,31 +284,59 @@ PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
segcmdo.filesize = fo->getBytesWritten(); segcmdo.filesize = fo->getBytesWritten();
segcmdo.vmsize += segcmdo.filesize; segcmdo.vmsize += segcmdo.filesize;
fo->seek(sizeof(mhdro), SEEK_SET); fo->seek(sizeof(mhdro), SEEK_SET);
fo->write(&segcmdo, sizeof(segcmdo)); fo->rewrite(&segcmdo, sizeof(segcmdo));
fo->write(&threado, sizeof(threado)); fo->rewrite(&threado, sizeof(threado));
fo->write(&linfo, sizeof(linfo)); fo->rewrite(&linfo, sizeof(linfo));
} }
void void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader {
// offset of p_info in compressed file
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
super::pack4(fo, ft);
segcmdo.filesize = fo->getBytesWritten();
segcmdo.vmsize += segcmdo.filesize;
fo->seek(sizeof(mhdro), SEEK_SET);
fo->rewrite(&segcmdo, sizeof(segcmdo));
fo->rewrite(&threado, sizeof(threado));
fo->rewrite(&linfo, sizeof(linfo));
}
void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
BE32 disp; BE32 disp;
unsigned const zero = 0; unsigned const zero = 0;
unsigned len = fo->getBytesWritten(); unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len)); fo->write(&zero, 3& (0u-len));
len += (3& (0u-len)) + sizeof(disp); len += (3& (0u-len)) + sizeof(disp);
set_be32(&disp, 4+ len - sz_mach_headers); // 4: sizeof(instruction) disp = 4+ len - sz_mach_headers; // 4: sizeof(instruction)
fo->write(&disp, sizeof(disp)); fo->write(&disp, sizeof(disp));
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */ threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
super::pack3(fo, ft); super::pack3(fo, ft);
} }
void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
{
LE32 disp;
unsigned const zero = 0;
unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len));
len += (3& (0u-len));
disp = len - sz_mach_headers;
fo->write(&disp, sizeof(disp));
threado.state.eip = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
super::pack3(fo, ft);
}
// Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD // Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD
// which follows in the file (or end-of-file). Optimize for common case // which follows in the file (or end-of-file). Optimize for common case
// where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap. // where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap.
unsigned PackMachPPC32::find_SEGMENT_gap( template <class T>
unsigned PackMachBase<T>::find_SEGMENT_gap(
unsigned const k unsigned const k
) )
{ {
@@ -216,8 +344,7 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
|| 0==msegcmd[k].filesize ) { || 0==msegcmd[k].filesize ) {
return 0; return 0;
} }
unsigned const hi = get_native32(&msegcmd[k].fileoff) + unsigned const hi = msegcmd[k].fileoff + msegcmd[k].filesize;
get_native32(&msegcmd[k].filesize);
unsigned lo = ph.u_file_size; unsigned lo = ph.u_file_size;
unsigned j = k; unsigned j = k;
for (;;) { // circular search, optimize for adjacent ascending for (;;) { // circular search, optimize for adjacent ascending
@@ -230,7 +357,7 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
} }
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd
&& 0!=msegcmd[j].filesize ) { && 0!=msegcmd[j].filesize ) {
unsigned const t = get_native32(&msegcmd[j].fileoff); unsigned const t = msegcmd[j].fileoff;
if ((t - hi) < (lo - hi)) { if ((t - hi) < (lo - hi)) {
lo = t; lo = t;
if (hi==lo) { if (hi==lo) {
@@ -242,8 +369,20 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
return lo - hi; return lo - hi;
} }
void template <class T>
PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft)
{
PackUnix::pack4(fo, ft); // FIXME super() does not work?
}
template <class T>
void PackMachBase<T>::pack3(OutputFile *fo, Filter &ft)
{
PackUnix::pack3(fo, ft); // FIXME super() does not work?
}
template <class T>
void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed body
{ {
Extent x; Extent x;
unsigned k; unsigned k;
@@ -269,6 +408,17 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
uip->ui_pass = 0; uip->ui_pass = 0;
ft.addvalue = 0; ft.addvalue = 0;
// Packer::compressWithFilters chooses a filter for us, and the stubs
// can handle only one filter, and most filters are for executable
// instructions. So filter only the largest executable segment.
unsigned exe_filesize_max = 0;
for (k = 0; k < n_segment; ++k)
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
&& exe_filesize_max < msegcmd[k].filesize) {
exe_filesize_max = msegcmd[k].filesize;
}
int nx = 0; int nx = 0;
for (k = 0; k < n_segment; ++k) for (k = 0; k < n_segment; ++k)
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
@@ -280,17 +430,20 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
x.offset += delta; x.offset += delta;
x.size -= delta; x.size -= delta;
} }
bool const do_filter = (msegcmd[k].filesize==exe_filesize_max)
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot);
packExtent(x, total_in, total_out, packExtent(x, total_in, total_out,
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot) (do_filter ? &ft : 0 ), fo, hdr_u_len );
? &ft : 0 ), fo, hdr_u_len ); if (do_filter) {
exe_filesize_max = 0;
}
hdr_u_len = 0; hdr_u_len = 0;
++nx; ++nx;
} }
for (k = 0; k < n_segment; ++k) { for (k = 0; k < n_segment; ++k) {
x.size = find_SEGMENT_gap(k); x.size = find_SEGMENT_gap(k);
if (x.size) { if (x.size) {
x.offset = get_native32(&msegcmd[k].fileoff) + x.offset = msegcmd[k].fileoff +msegcmd[k].filesize;
get_native32(&msegcmd[k].filesize);
packExtent(x, total_in, total_out, 0, fo); packExtent(x, total_in, total_out, 0, fo);
} }
} }
@@ -304,12 +457,33 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
#undef PAGE_SIZE #undef PAGE_SIZE
#define PAGE_MASK (~0u<<12) #define PAGE_MASK (~0u<<12)
#define PAGE_SIZE -PAGE_MASK #define PAGE_SIZE -PAGE_MASK
void
PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable header void PackMachPPC32::pack1_setup_threado(OutputFile *const fo)
{
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
threado.cmdsize = sizeof(threado);
threado.flavor = my_thread_flavor;
threado.count = my_thread_state_word_count;
memset(&threado.state, 0, sizeof(threado.state));
fo->write(&threado, sizeof(threado));
}
void PackMachI386::pack1_setup_threado(OutputFile *const fo)
{
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
threado.cmdsize = sizeof(threado);
threado.flavor = my_thread_flavor;
threado.count = my_thread_state_word_count;
memset(&threado.state, 0, sizeof(threado.state));
fo->write(&threado, sizeof(threado));
}
template <class T>
void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header
{ {
mhdro = mhdri; mhdro = mhdri;
mhdro.ncmds = 2; mhdro.ncmds = 2;
mhdro.sizeofcmds = sizeof(segcmdo) + sizeof(threado); mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;
mhdro.flags = Mach_header::MH_NOUNDEFS; mhdro.flags = Mach_header::MH_NOUNDEFS;
fo->write(&mhdro, sizeof(mhdro)); fo->write(&mhdro, sizeof(mhdro));
@@ -329,12 +503,7 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
segcmdo.flags = 0; segcmdo.flags = 0;
fo->write(&segcmdo, sizeof(segcmdo)); fo->write(&segcmdo, sizeof(segcmdo));
threado.cmd = Mach_segment_command::LC_UNIXTHREAD; pack1_setup_threado(fo);
threado.cmdsize = sizeof(threado);
threado.flavor = Mach_thread_command::PPC_THREAD_STATE;
threado.count = Mach_thread_command::PPC_THREAD_STATE_COUNT;
memset(&threado.state, 0, sizeof(threado.state));
fo->write(&threado, sizeof(threado));
sz_mach_headers = fo->getBytesWritten(); sz_mach_headers = fo->getBytesWritten();
memset((char *)&linfo, 0, sizeof(linfo)); memset((char *)&linfo, 0, sizeof(linfo));
@@ -343,9 +512,11 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
return; return;
} }
void template <class T>
PackMachPPC32::unpack(OutputFile *fo) void PackMachBase<T>::unpack(OutputFile *fo)
{ {
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) +
my_thread_command_size + sizeof(linfo);
fi->seek(overlay_offset, SEEK_SET); fi->seek(overlay_offset, SEEK_SET);
p_info hbuf; p_info hbuf;
fi->readx(&hbuf, sizeof(hbuf)); fi->readx(&hbuf, sizeof(hbuf));
@@ -359,6 +530,8 @@ PackMachPPC32::unpack(OutputFile *fo)
fi->readx(&bhdr, sizeof(bhdr)); fi->readx(&bhdr, sizeof(bhdr));
ph.u_len = get_native32(&bhdr.sz_unc); ph.u_len = get_native32(&bhdr.sz_unc);
ph.c_len = get_native32(&bhdr.sz_cpr); ph.c_len = get_native32(&bhdr.sz_cpr);
ph.method = bhdr.b_method;
ph.filter = bhdr.b_ftid;
ph.filter_cto = bhdr.b_cto8; ph.filter_cto = bhdr.b_cto8;
// Uncompress Macho headers // Uncompress Macho headers
@@ -396,15 +569,14 @@ PackMachPPC32::unpack(OutputFile *fo)
) { ) {
if (Mach_segment_command::LC_SEGMENT==sc->cmd if (Mach_segment_command::LC_SEGMENT==sc->cmd
&& 0!=sc->filesize ) { && 0!=sc->filesize ) {
unsigned filesize = get_be32(&sc->filesize); unsigned filesize = sc->filesize;
unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr)); unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));
} }
} }
for (unsigned j = 0; j < ncmds; ++j) { for (unsigned j = 0; j < ncmds; ++j) {
unsigned const size = find_SEGMENT_gap(j); unsigned const size = find_SEGMENT_gap(j);
if (size) { if (size) {
unsigned const where = get_native32(&msegcmd[k].fileoff) + unsigned const where = msegcmd[k].fileoff +msegcmd[k].filesize;
get_native32(&msegcmd[k].filesize);
if (fo) if (fo)
fo->seek(where, SEEK_SET); fo->seek(where, SEEK_SET);
unpackExtent(size, fo, total_in, total_out, unpackExtent(size, fo, total_in, total_out,
@@ -414,14 +586,14 @@ PackMachPPC32::unpack(OutputFile *fo)
} }
bool template <class T>
PackMachPPC32::canPack() bool PackMachBase<T>::canPack()
{ {
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(&mhdri, sizeof(mhdri)); fi->readx(&mhdri, sizeof(mhdri));
if (Mach_header::MH_MAGIC !=mhdri.magic if (Mach_header::MH_MAGIC !=mhdri.magic
|| Mach_header::CPU_TYPE_POWERPC !=mhdri.cputype || my_cputype !=mhdri.cputype
|| Mach_header::MH_EXECUTE !=mhdri.filetype || Mach_header::MH_EXECUTE !=mhdri.filetype
) )
return false; return false;
@@ -457,11 +629,204 @@ PackMachPPC32::canPack()
sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff; sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;
} }
} }
// info: currently the header is 36 (32+4) bytes before EOF
unsigned char buf[256];
fi->seek(-(off_t)sizeof(buf), SEEK_END);
fi->readx(buf, sizeof(buf));
checkAlreadyPacked(buf, sizeof(buf));
// set options // set options
opt->o_unix.blocksize = file_size; opt->o_unix.blocksize = file_size;
return 0 < n_segment; return 0 < n_segment;
} }
template class PackMachBase<MachClass_BE32>;
template class PackMachBase<MachClass_LE32>;
PackMachFat::PackMachFat(InputFile *f) : super(f)
{
bele = &N_BELE_RTP::le_policy; // sham
}
PackMachFat::~PackMachFat()
{
}
const int *PackMachFat::getCompressionMethods(int /*method*/, int /*level*/) const
{
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
return m_nrv2e; // sham
}
const int *PackMachFat::getFilters() const
{
static const int filters[] = { 0x49, FT_END };
return filters; // sham
}
void PackMachFat::pack(OutputFile *fo)
{
unsigned const in_size = this->file_size;
fo->write(&fat_head, sizeof(fat_head.fat) +
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
unsigned length = 0;
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
unsigned base = fo->unset_extent(); // actual length
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
fo->seek(base, SEEK_SET);
fo->set_extent(base, ~0u);
ph.u_file_size = fat_head.arch[j].size;
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (fat_head.arch[j].cputype) {
case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi);
packer.initPackHeader();
packer.canPack();
packer.updatePackHeader();
packer.pack(fo);
} break;
case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi);
packer.initPackHeader();
packer.canPack();
packer.updatePackHeader();
packer.pack(fo);
} break;
} // switch cputype
fat_head.arch[j].offset = base;
length = fo->unset_extent();
fat_head.arch[j].size = length - base;
}
ph.u_file_size = in_size;
fi->set_extent(0, in_size);
fo->seek(0, SEEK_SET);
fo->rewrite(&fat_head, sizeof(fat_head.fat) +
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
fo->set_extent(0, length);
}
void PackMachFat::unpack(OutputFile *fo)
{
fo->seek(0, SEEK_SET);
fo->write(&fat_head, sizeof(fat_head.fat) +
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
unsigned length;
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
unsigned base = fo->unset_extent(); // actual length
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
fo->seek(base, SEEK_SET);
fo->set_extent(base, ~0u);
ph.u_file_size = fat_head.arch[j].size;
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (fat_head.arch[j].cputype) {
case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi);
packer.initPackHeader();
packer.canUnpack();
packer.unpack(fo);
} break;
case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi);
packer.initPackHeader();
packer.canUnpack();
packer.unpack(fo);
} break;
} // switch cputype
fat_head.arch[j].offset = base;
length = fo->unset_extent();
fat_head.arch[j].size = length - base;
}
fo->unset_extent();
fo->seek(0, SEEK_SET);
fo->rewrite(&fat_head, sizeof(fat_head.fat) +
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
}
bool PackMachFat::canPack()
{
struct Mach_fat_arch *arch = &fat_head.arch[0];
fi->readx(&fat_head, sizeof(fat_head));
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
return false;
}
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (arch[j].cputype) {
default: return false;
case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi);
if (!packer.canPack())
return false;
} break;
case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi);
if (!packer.canPack())
return false;
} break;
} // switch cputype
}
// info: currently the header is 36 (32+4) bytes before EOF
unsigned char buf[256];
fi->seek(-(off_t)sizeof(buf), SEEK_END);
fi->readx(buf, sizeof(buf));
checkAlreadyPacked(buf, sizeof(buf));
return true;
}
int PackMachFat::canUnpack()
{
struct Mach_fat_arch *arch = &fat_head.arch[0];
fi->readx(&fat_head, sizeof(fat_head));
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
return false;
}
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (arch[j].cputype) {
default: return false;
case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi);
if (!packer.canUnpack())
return 0;
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
} break;
case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi);
if (!packer.canUnpack())
return 0;
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
} break;
} // switch cputype
}
return 1;
}
void PackMachFat::buildLoader(const Filter */*ft*/)
{
assert(false);
}
Linker* PackMachFat::newLinker() const
{
return new ElfLinkerX86; // sham
}
void PackMachFat::list()
{
assert(false);
}
/* /*
vi:ts=4:et vi:ts=4:et
*/ */
+449 -114
View File
@@ -29,161 +29,328 @@
#ifndef __UPX_P_MACHO_H #ifndef __UPX_P_MACHO_H
#define __UPX_P_MACHO_H #define __UPX_P_MACHO_H
struct Mach_fat_header {
BE32 magic;
enum { // note conflict with java bytecode PackLinuxI386
FAT_MAGIC = 0xcafebabe,
FAT_MAGIC_SWAB = 0xbebafeca
};
BE32 nfat_arch; // Number of Mach_fat_arch which follow.
}
__attribute_packed;
struct Mach_fat_arch {
BE32 cputype;
BE32 cpusubtype;
BE32 offset;
BE32 size;
BE32 align; /* shift count; log base 2 */
}
__attribute_packed;
/************************************************************************* /*************************************************************************
// Mach Mach Object executable // Mach Mach Object executable; all structures are target-endian
// 'otool' is the Mach analog of 'readelf' (convert executable file to ASCII).
**************************************************************************/ **************************************************************************/
struct Mach_header { namespace N_Mach {
BE32 magic;
enum { // integral types
MH_MAGIC = 0xfeedface template <class TWord, class TXword, class TAddr, class TOff>
}; struct MachITypes
BE32 cputype; {
enum { typedef TWord Word;
CPU_TYPE_POWERPC = 18 typedef TXword Xword;
}; typedef TAddr Addr;
BE32 cpysubtype; typedef TOff Off;
BE32 filetype; };
enum {
MH_EXECUTE = 2 template <class TMachITypes>
}; struct Mach_header
BE32 ncmds; {
BE32 sizeofcmds; typedef typename TMachITypes::Word Word;
BE32 flags;
enum { Word magic;
MH_NOUNDEFS = 1 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; __attribute_packed;
struct Mach_segment_command { template <class TMachITypes>
BE32 cmd; struct Mach_header64
enum { { // only difference is padding to 0 mod 8
LC_SEGMENT = 0x1, typedef typename TMachITypes::Word Word;
LC_THREAD = 0x4,
LC_UNIXTHREAD = 0x5, Word magic;
LC_LOAD_DYLINKER = 0xe Word cputype;
}; Word cpysubtype;
BE32 cmdsize; 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]; char segname[16];
BE32 vmaddr; Addr vmaddr;
BE32 vmsize; Addr vmsize;
BE32 fileoff; Off fileoff;
BE32 filesize; Off filesize;
BE32 maxprot; Word maxprot;
enum { Word initprot;
VM_PROT_READ = 1, Word nsects;
VM_PROT_WRITE = 2, Word flags;
VM_PROT_EXECUTE = 4 #define WANT_MACH_SEGMENT_ENUM 1
}; #include "p_mach_enum.h"
BE32 initprot;
BE32 nsects;
BE32 flags;
} }
__attribute_packed; __attribute_packed;
struct Mach_section { 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 sectname[16];
char segname[16]; char segname[16];
BE32 addr; /* memory address */ Addr addr; /* memory address */
BE32 size; /* size in bytes */ Addr size; /* size in bytes */
BE32 offset; /* file offset */ Word offset; /* file offset */ // FIXME: 64 bit?
BE32 align; /* power of 2 */ Word align; /* power of 2 */
BE32 reloff; /* file offset of relocation entries */ Word reloff; /* file offset of relocation entries */
BE32 nreloc; /* number of relocation entries */ Word nreloc; /* number of relocation entries */
BE32 flags; /* section type and attributes */ Word flags; /* section type and attributes */
enum { Word reserved1;
S_REGULAR = 0, Word reserved2;
S_ZEROFILL, #define WANT_MACH_SECTION_ENUM 1
S_CSTRING_LITERALS, #include "p_mach_enum.h"
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; __attribute_packed;
struct Mach_ppc_thread_state { template <class TMachITypes>
BE32 srr0; /* Instruction address register (PC; entry addr) */ struct Mach_ppc_thread_state
BE32 srr1; /* Machine state register (supervisor) */ {
BE32 r0, r1, r2, r3, r4, r5, r6, r7; typedef typename TMachITypes::Addr Addr;
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 */ Addr srr0; /* Instruction address register (PC; entry addr) */
BE32 xer; /* User's integer exception register */ Addr srr1; /* Machine state register (supervisor) */
BE32 lr; /* Link register */ Addr r0, r1, r2, r3, r4, r5, r6, r7;
BE32 ctr; /* Count register */ Addr r8, r9,r10,r11,r12,r13,r14,r15;
BE32 mq; /* MQ register (601 only) */ Addr r16,r17,r18,r19,r20,r21,r22,r23;
Addr r24,r25,r26,r27,r28,r29,r30,r31;
BE32 vrsave; /* Vector Save Register */ 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; __attribute_packed;
struct Mach_thread_command { template <class TMachITypes>
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */ struct Mach_i386_thread_state
BE32 cmdsize; /* total size of this command */ {
BE32 flavor; typedef typename TMachITypes::Word Word;
enum {
PPC_THREAD_STATE = 1 Word eax, ebx, ecx, edx;
}; Word edi, esi, ebp;
BE32 count; /* sizeof(following_thread_state)/4 */ Word esp, ss;
enum { Word eflags;
PPC_THREAD_STATE_COUNT = sizeof(struct Mach_ppc_thread_state)/4 Word eip, cs;
}; Word ds, es, fs, gs;
struct Mach_ppc_thread_state state;
} }
__attribute_packed; __attribute_packed;
template <class TMachITypes>
struct Mach_i386_new_thread_state
{
typedef typename TMachITypes::Word Word;
Word gs, fs, es, ds;
Word edi, esi, ebp, esp;
Word ebx, edx, ecx, eax;
Word eip, cs, efl;
Word uesp, ss;
}
__attribute_packed;
} // namespace N_Mach
namespace N_Mach32 {
} // namespace N_Mach32
namespace N_Mach64 {
template <class TMachITypes>
struct Mach_ppc_thread_state64
{
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Xword Xword;
Xword srr0; /* Instruction address register (PC; entry addr) */
Xword srr1; /* Machine state register (supervisor) */
Xword r0, r1, r2, r3, r4, r5, r6, r7;
Xword r8, r9,r10,r11,r12,r13,r14,r15;
Xword r16,r17,r18,r19,r20,r21,r22,r23;
Xword r24,r25,r26,r27,r28,r29,r30,r31;
Word cr; /* Condition register */ // FIXME: Xword?
Xword xer; /* User's integer exception register */
Xword lr; /* Link register */
Xword ctr; /* Count register */
Word vrsave; /* Vector Save Register */
}
__attribute_packed;
} // namespace N_Mach64
namespace N_Mach {
template <class TP>
struct MachClass_32
{
typedef TP BeLePolicy;
// integral types
typedef typename TP::U16 U16;
typedef typename TP::U32 U32;
typedef typename TP::U64 U64;
typedef N_Mach::MachITypes<U32, U64, U32, U32> MachITypes;
#if (ACC_CC_BORLANDC)
typedef U32 Addr;
#else
typedef typename MachITypes::Addr Addr;
#endif
// Mach types
typedef N_Mach::Mach_header<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state;
static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions();
COMPILE_TIME_ASSERT(sizeof(Addr) == 4)
}
};
template <class TP>
struct MachClass_64
{
typedef TP BeLePolicy;
// integral types
typedef typename TP::U16 U16;
typedef typename TP::U32 U32;
typedef typename TP::U64 U64;
typedef N_Mach::MachITypes<U32, U64, U64, U64> MachITypes;
// Mach types
typedef N_Mach::Mach_header64<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions();
}
};
} // namespace N_Mach
typedef N_Mach::MachClass_32<N_BELE_CTP::HostPolicy> MachClass_Host32;
typedef N_Mach::MachClass_64<N_BELE_CTP::HostPolicy> MachClass_Host64;
typedef N_Mach::MachClass_32<N_BELE_CTP::BEPolicy> MachClass_BE32;
typedef N_Mach::MachClass_64<N_BELE_CTP::BEPolicy> MachClass_BE64;
typedef N_Mach::MachClass_32<N_BELE_CTP::LEPolicy> MachClass_LE32;
typedef N_Mach::MachClass_64<N_BELE_CTP::LEPolicy> MachClass_LE64;
// shortcuts
typedef MachClass_Host32::Mach_segment_command Mach32_segment_command;
typedef MachClass_Host32::Mach_section_command Mach32_section_command;
typedef MachClass_Host64::Mach_segment_command Mach64_segment_command;
typedef MachClass_Host64::Mach_section_command Mach64_section_command;
typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command;
typedef MachClass_BE32::Mach_section_command MachBE32_section_command;
typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command;
typedef MachClass_BE64::Mach_section_command MachBE64_section_command;
typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command;
typedef MachClass_LE32::Mach_section_command MachLE32_section_command;
typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command;
typedef MachClass_LE64::Mach_section_command MachLE64_section_command;
typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state;
typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state;
#include "p_unix.h" #include "p_unix.h"
class PackMachPPC32 : public PackUnixBe32 template <class TMachClass>
class PackMachBase : public PackUnix
{ {
typedef PackUnixBe32 super; typedef PackUnix super;
protected:
typedef TMachClass MachClass;
typedef typename MachClass::BeLePolicy BeLePolicy;
typedef typename MachClass::MachITypes MachITypes;
// integral types
typedef typename MachClass::U16 U16;
typedef typename MachClass::U32 U32;
typedef typename MachClass::U64 U64;
typedef typename MachClass::Addr Addr;
// Mach types
typedef typename MachClass::Mach_header Mach_header;
typedef typename MachClass::Mach_segment_command Mach_segment_command;
typedef typename MachClass::Mach_section_command Mach_section_command;
public: public:
PackMachPPC32(InputFile *f); PackMachBase(InputFile *, unsigned cpuid, unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size);
virtual ~PackMachPPC32(); virtual ~PackMachBase();
virtual int getVersion() const { return 13; } virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
virtual const char *getName() const { return "Mach/ppc32"; }
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; }
virtual const int *getCompressionMethods(int method, int level) const; virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
// called by the generic pack() // called by the generic pack()
virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual void pack2(OutputFile *, Filter &); // append compressed data virtual void pack2(OutputFile *, Filter &); // append compressed data
virtual void pack3(OutputFile *, Filter &); // append loader virtual void pack3(OutputFile *, Filter &) = 0; // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader
virtual void pack1_setup_threado(OutputFile *const fo) = 0;
virtual void unpack(OutputFile *fo); virtual void unpack(OutputFile *fo);
virtual bool canPack(); virtual bool canPack();
virtual unsigned find_SEGMENT_gap(unsigned const k); virtual unsigned find_SEGMENT_gap(unsigned const k);
protected: protected:
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
virtual void patchLoader(); virtual void patchLoader();
virtual void patchLoaderChecksum(); virtual void patchLoaderChecksum();
virtual void updateLoader(OutputFile *); virtual void updateLoader(OutputFile *);
@@ -196,6 +363,13 @@ protected:
virtual void defineSymbols(Filter const *); virtual void defineSymbols(Filter const *);
virtual void addStubEntrySections(Filter const *); virtual void addStubEntrySections(Filter const *);
static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb);
unsigned my_cputype;
unsigned my_thread_flavor;
unsigned my_thread_state_word_count;
unsigned my_thread_command_size;
unsigned n_segment; unsigned n_segment;
unsigned sz_segment; unsigned sz_segment;
unsigned sz_mach_headers; unsigned sz_mach_headers;
@@ -205,11 +379,172 @@ protected:
Mach_header mhdro; Mach_header mhdro;
Mach_segment_command segcmdo; Mach_segment_command segcmdo;
Mach_thread_command threado;
struct b_info { // 12-byte header before each compressed block
U32 sz_unc; // uncompressed_size
U32 sz_cpr; // compressed_size
unsigned char b_method; // compression algorithm
unsigned char b_ftid; // filter id
unsigned char b_cto8; // filter parameter
unsigned char b_unused;
}
__attribute_packed;
struct l_info { // 12-byte trailer in header for loader
U32 l_checksum;
LE32 l_magic;
U16 l_lsize;
unsigned char l_version;
unsigned char l_format;
}
__attribute_packed;
struct p_info { // 12-byte packed program header
U32 p_progid;
U32 p_filesize;
U32 p_blocksize;
}
__attribute_packed;
struct l_info linfo; struct l_info linfo;
}; };
class PackMachPPC32 : public PackMachBase<MachClass_BE32>
{
typedef PackMachBase<MachClass_BE32> super;
public:
PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC,
Mach_thread_command::PPC_THREAD_STATE,
sizeof(Mach_ppc_thread_state)>>2, sizeof(threado)) { }
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
virtual const char *getName() const { return "Mach/ppc32"; }
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; }
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
virtual unsigned get_native16(const void *b) const { return get_be16(b); }
virtual void set_native64(void *b, acc_uint64l_t v) const { set_be64(b, v); }
virtual void set_native32(void *b, unsigned v) const { set_be32(b, v); }
virtual void set_native16(void *b, unsigned v) const { set_be16(b, v); }
protected:
virtual const int *getFilters() const;
virtual void pack1_setup_threado(OutputFile *const fo);
virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader
virtual Linker* newLinker() const;
virtual void buildLoader(const Filter *ft);
struct Mach_thread_command
{
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
BE32 cmdsize; /* total size of this command */
BE32 flavor;
BE32 count; /* sizeof(following_thread_state)/4 */
Mach_ppc_thread_state state;
#define WANT_MACH_THREAD_ENUM
#include "p_mach_enum.h"
}
__attribute_packed;
Mach_thread_command threado;
};
class PackMachI386 : public PackMachBase<MachClass_LE32>
{
typedef PackMachBase<MachClass_LE32> super;
public:
PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386,
(unsigned)Mach_thread_command::i386_THREAD_STATE,
sizeof(Mach_i386_thread_state)>>2, sizeof(threado)) { }
virtual int getFormat() const { return UPX_F_MACH_i386; }
virtual const char *getName() const { return "Mach/i386"; }
virtual const char *getFullName(const options_t *) const { return "i386-darwin.macho"; }
protected:
virtual const int *getFilters() const;
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
virtual void set_native64(void *b, acc_uint64l_t v) const { set_le64(b, v); }
virtual void set_native32(void *b, unsigned v) const { set_le32(b, v); }
virtual void set_native16(void *b, unsigned v) const { set_le16(b, v); }
virtual void pack1_setup_threado(OutputFile *const fo);
virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader
virtual Linker* newLinker() const;
virtual void buildLoader(const Filter *ft);
virtual void addStubEntrySections(Filter const *);
struct Mach_thread_command
{
LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
LE32 cmdsize; /* total size of this command */
LE32 flavor;
LE32 count; /* sizeof(following_thread_state)/4 */
Mach_i386_thread_state state;
#define WANT_MACH_THREAD_ENUM
#include "p_mach_enum.h"
}
__attribute_packed;
Mach_thread_command threado;
};
class PackMachFat : public Packer
{
typedef Packer super;
public:
PackMachFat(InputFile *f);
virtual ~PackMachFat();
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_MACH_FAT; }
virtual const char *getName() const { return "Mach/fat"; }
virtual const char *getFullName(const options_t *) const { return "fat-darwin.macho"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
protected:
// implementation
virtual void pack(OutputFile *fo);
virtual void unpack(OutputFile *fo);
virtual void list();
public:
virtual bool canPack();
virtual int canUnpack();
protected:
// loader core
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
#if (ACC_CC_BORLANDC)
public:
#endif
enum { N_FAT_ARCH = 5 };
protected:
struct Fat_head {
struct Mach_fat_header fat;
struct Mach_fat_arch arch[N_FAT_ARCH];
}
__attribute_packed;
Fat_head fat_head;
// UI handler
UiPacker *uip;
// linker
Linker *linker;
#define WANT_MACH_HEADER_ENUM
#include "p_mach_enum.h"
};
#endif /* already included */ #endif /* already included */
+108
View File
@@ -0,0 +1,108 @@
/* p_mach_enum.h --
This file is part of the UPX executable compressor.
Copyright (C) 2007 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
John F. Reiser
<jreiser@users.sourceforge.net>
*/
/*************************************************************************
// Use the preprocessor to work around
// - that the types embedding these enums have to be PODs, and
// deriving from an empty base class (which is the usual C++ way
// of "importing" enums) does not yield a POD any more
// - that older compilers do not correctly perform EBCO
**************************************************************************/
#ifdef WANT_MACH_HEADER_ENUM /*{*/
#undef WANT_MACH_HEADER_ENUM
enum { // magic
MH_MAGIC = 0xfeedface
};
enum { // cputype
CPU_TYPE_I386 = 7,
CPU_TYPE_POWERPC = 0x00000012,
CPU_TYPE_POWERPC64 = 0x01000012
};
enum { // filetype
MH_EXECUTE = 2
};
enum { // flags
MH_NOUNDEFS = 1
};
#endif /*}*/
#ifdef WANT_MACH_SEGMENT_ENUM /*{*/
#undef WANT_MACH_SEGMENT_ENUM
enum { // cmd
LC_SEGMENT = 0x1,
LC_THREAD = 0x4,
LC_UNIXTHREAD = 0x5,
LC_LOAD_DYLINKER = 0xe,
LC_SEGMENT_64 = 0x19
};
enum { // maxprot
VM_PROT_READ = 1,
VM_PROT_WRITE = 2,
VM_PROT_EXECUTE = 4
};
#endif /*}*/
#ifdef WANT_MACH_SECTION_ENUM /*{*/
#undef WANT_MACH_SECTION_ENUM
enum { // section flags
S_REGULAR = 0,
S_ZEROFILL,
S_CSTRING_LITERALS,
S_4BYTE_LITERALS,
S_8BYTE_LITERALS,
S_LITERAL_POINTERS,
S_NON_LAZY_SYMBOL_POINTERS,
S_LAZY_SYMBOL_POINTERS,
S_SYMBOL_STUBS,
S_MOD_INIT_FUNC_POINTERS,
S_MOD_TERM_FNC_POINTERS,
S_COALESCED
};
enum {
S_ATTR_PURE_INSTRUCTIONS = 0x80000000,
S_ATTR_NO_TOC = 0x40000000,
S_ATTR_STRIP_STATIC_SYMS = 0x20000000,
S_ATTR_SOME_INSTRUCTIONS = 0x00000400,
S_ATTR_EXT_RELOC = 0x00000200,
S_ATTR_LOC_RELOC = 0x00000100
};
#endif /*}*/
#ifdef WANT_MACH_THREAD_ENUM /*{*/
#undef WANT_MACH_THREAD_ENUM
enum { // thread flavor
PPC_THREAD_STATE = 1,
i386_THREAD_STATE = 1,
i386_OLD_THREAD_STATE = -1
};
#endif /*}*/
/*
vi:ts=4:et
*/
+18 -7
View File
@@ -318,6 +318,7 @@ void PackPs1::buildLoader(const Filter *)
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp), 4u); sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp), 4u);
} }
if (isCon || !isCon && M_IS_LZMA(ph.method))
foundBss = findBssSection(); foundBss = findBssSection();
if (M_IS_LZMA(ph.method) && !buildPart2) if (M_IS_LZMA(ph.method) && !buildPart2)
@@ -370,16 +371,20 @@ void PackPs1::buildLoader(const Filter *)
else else
{ {
if (M_IS_LZMA(ph.method)) if (M_IS_LZMA(ph.method))
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr", addLoader(!foundBss ? "cdb.start.lzma" : "bss.cdb.start.lzma", "pad.code",
!foundBss ? "cdb.entry.lzma" : "bss.cdb.entry.lzma",
method, "cdb.lzma.cpr",
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi", ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"lzma.exec", NULL); "lzma.exec", NULL);
else else
{
assert(foundBss != true);
addLoader("cdb.start", "pad.code", "cdb.entry", addLoader("cdb.start", "pad.code", "cdb.entry",
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi", ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
method, method,
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "", sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
!foundBss ? "cdb.exit" : "bss.exit", "cdb.exit", NULL);
"pad.code", NULL); }
} }
addLoader("UPX1HEAD", "IDENTSTR", NULL); addLoader("UPX1HEAD", "IDENTSTR", NULL);
} }
@@ -554,7 +559,9 @@ void PackPs1::pack(OutputFile *fo)
} }
else else
{ {
d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? "cdb.entry.lzma" : "cdb.entry"); const char* entry_lzma = !foundBss ? "cdb.entry.lzma" : "bss.cdb.entry.lzma";
d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? entry_lzma : "cdb.entry");
e_len = (lsize - d_len) - h_len; e_len = (lsize - d_len) - h_len;
} }
@@ -578,7 +585,7 @@ void PackPs1::pack(OutputFile *fo)
unsigned pad = 0; unsigned pad = 0;
if (!opt->ps1_exe.no_align) if (!opt->ps1_exe.no_align || !isCon)
{ {
pad = oh.tx_len; pad = oh.tx_len;
oh.tx_len = ALIGN_UP(oh.tx_len, CD_SEC); oh.tx_len = ALIGN_UP(oh.tx_len, CD_SEC);
@@ -611,8 +618,12 @@ void PackPs1::pack(OutputFile *fo)
linker->defineSymbol("PSVR", FIX_PSVR); linker->defineSymbol("PSVR", FIX_PSVR);
linker->defineSymbol("CPDO", comp_data_start); linker->defineSymbol("CPDO", comp_data_start);
if (M_IS_LZMA(ph.method)) if (M_IS_LZMA(ph.method))
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec") {
- getLoaderSectionStart("cdb.entry.lzma")); unsigned entry_lzma = getLoaderSectionStart( !foundBss ? "cdb.entry.lzma" :
"bss.cdb.entry.lzma");
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec") - entry_lzma);
}
} }
relocateLoader(); relocateLoader();
+2 -1
View File
@@ -67,11 +67,12 @@ const int *PackTmt::getFilters() const
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf, unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
unsigned range, unsigned range,
unsigned upper_limit) const unsigned upper_limit) const
{ {
// make sure the decompressor will be paragraph aligned // make sure the decompressor will be paragraph aligned
unsigned o = super::findOverlapOverhead(buf, range, upper_limit); unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
o = ((o + 0x20) &~ 0xf) - (ph.u_len & 0xf); o = ((o + 0x20) &~ 0xf) - (ph.u_len & 0xf);
return o; return o;
} }
+1
View File
@@ -56,6 +56,7 @@ protected:
virtual int readFileHeader(); virtual int readFileHeader();
virtual unsigned findOverlapOverhead(const upx_bytep buf, virtual unsigned findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
unsigned range = 0, unsigned range = 0,
unsigned upper_limit = ~0u) const; unsigned upper_limit = ~0u) const;
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
+7 -3
View File
@@ -173,8 +173,10 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy); compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy);
if (ph.c_len < ph.u_len) { if (ph.c_len < ph.u_len) {
const upx_bytep tbuf = NULL;
if (ft.id == 0) tbuf = ibuf;
ph.overlap_overhead = OVERHEAD; ph.overlap_overhead = OVERHEAD;
if (!testOverlappingDecompression(obuf, ph.overlap_overhead)) { if (!testOverlappingDecompression(obuf, tbuf, ph.overlap_overhead)) {
// not in-place compressible // not in-place compressible
ph.c_len = ph.u_len; ph.c_len = ph.u_len;
} }
@@ -353,8 +355,10 @@ void PackUnix::packExtent(
} }
if (ph.c_len < ph.u_len) { if (ph.c_len < ph.u_len) {
const upx_bytep tbuf = NULL;
if (ft == NULL || ft->id == 0) tbuf = ibuf;
ph.overlap_overhead = OVERHEAD; ph.overlap_overhead = OVERHEAD;
if (!testOverlappingDecompression(obuf, ph.overlap_overhead)) { if (!testOverlappingDecompression(obuf, tbuf, ph.overlap_overhead)) {
// not in-place compressible // not in-place compressible
ph.c_len = ph.u_len; ph.c_len = ph.u_len;
} }
@@ -499,7 +503,7 @@ int PackUnix::canUnpack()
fi->seek(-bufsize, SEEK_END); fi->seek(-bufsize, SEEK_END);
fi->readx(buf, bufsize); fi->readx(buf, bufsize);
if (!getPackHeader(buf, bufsize)) if (!getPackHeader(buf, bufsize, true)) // allow incompressible extents
return false; return false;
int l = ph.buf_offset + ph.getPackHeaderSize(); int l = ph.buf_offset + ph.getPackHeaderSize();
+1 -1
View File
@@ -235,7 +235,7 @@ public:
virtual bool canPack(); virtual bool canPack();
protected: protected:
virtual const upx_byte *getLoader() const; virtual upx_byte *getLoader() const;
virtual int getLoaderSize() const; virtual int getLoaderSize() const;
virtual void patchLoader(); virtual void patchLoader();
+102 -9
View File
@@ -44,6 +44,8 @@ static const
#include "stub/amd64-linux.kernel.vmlinux.h" #include "stub/amd64-linux.kernel.vmlinux.h"
static const static const
#include "stub/arm-linux.kernel.vmlinux.h" #include "stub/arm-linux.kernel.vmlinux.h"
static const
#include "stub/armeb-linux.kernel.vmlinux.h"
/************************************************************************* /*************************************************************************
@@ -66,9 +68,9 @@ PackVmlinuxBase<T>::PackVmlinuxBase(InputFile *f,
template <class T> template <class T>
PackVmlinuxBase<T>::~PackVmlinuxBase() PackVmlinuxBase<T>::~PackVmlinuxBase()
{ {
delete [] shstrtab;
delete [] phdri; delete [] phdri;
delete [] shdri; delete [] shdri;
delete [] shstrtab;
} }
template <class T> template <class T>
@@ -547,18 +549,29 @@ const int *PackVmlinuxI386::getFilters() const
return filters; return filters;
} }
const int *PackVmlinuxARM::getCompressionMethods(int method, int level) const const int *PackVmlinuxARMEL::getCompressionMethods(int method, int level) const
{
return Packer::getDefaultCompressionMethods_8(method, level);
}
const int *PackVmlinuxARMEB::getCompressionMethods(int method, int level) const
{ {
return Packer::getDefaultCompressionMethods_8(method, level); return Packer::getDefaultCompressionMethods_8(method, level);
} }
const int *PackVmlinuxARM::getFilters() const const int *PackVmlinuxARMEL::getFilters() const
{ {
static const int f50[] = { 0x50, FT_END }; static const int f50[] = { 0x50, FT_END };
return f50; return f50;
} }
const int *PackVmlinuxARMEB::getFilters() const
{
static const int f51[] = { 0x51, FT_END };
return f51;
}
// //
// Examples as of 2004-07-16 [readelf --segments vmlinux # before fiddling]: // Examples as of 2004-07-16 [readelf --segments vmlinux # before fiddling]:
// //
@@ -646,18 +659,29 @@ void PackVmlinuxAMD64::buildLoader(const Filter *ft)
"LINUX992,IDENTSTR,UPX1HEAD", NULL); "LINUX992,IDENTSTR,UPX1HEAD", NULL);
} }
bool PackVmlinuxARM::is_valid_e_entry(Addr e_entry) bool PackVmlinuxARMEL::is_valid_e_entry(Addr e_entry)
{ {
return 0xc0008000==e_entry; return 0xc0008000==e_entry;
} }
Linker* PackVmlinuxARM::newLinker() const bool PackVmlinuxARMEB::is_valid_e_entry(Addr e_entry)
{
return 0xc0008000==e_entry;
}
Linker* PackVmlinuxARMEL::newLinker() const
{ {
return new ElfLinkerArmLE; return new ElfLinkerArmLE;
} }
Linker* PackVmlinuxARMEB::newLinker() const
{
return new ElfLinkerArmBE;
}
void PackVmlinuxARM::buildLoader(const Filter *ft)
void PackVmlinuxARMEL::buildLoader(const Filter *ft)
{ {
// prepare loader // prepare loader
initLoader(stub_arm_linux_kernel_vmlinux, sizeof(stub_arm_linux_kernel_vmlinux)); initLoader(stub_arm_linux_kernel_vmlinux, sizeof(stub_arm_linux_kernel_vmlinux));
@@ -679,6 +703,28 @@ void PackVmlinuxARM::buildLoader(const Filter *ft)
addLoader("IDENTSTR,UPX1HEAD", NULL); addLoader("IDENTSTR,UPX1HEAD", NULL);
} }
void PackVmlinuxARMEB::buildLoader(const Filter *ft)
{
// prepare loader
initLoader(stub_armeb_linux_kernel_vmlinux, sizeof(stub_armeb_linux_kernel_vmlinux));
addLoader("LINUX000", NULL);
if (ft->id) {
assert(ft->calls > 0);
addLoader("LINUX010", NULL);
}
addLoader("LINUX020", NULL);
if (ft->id) {
addFilter32(ft->id);
}
addLoader("LINUX030", NULL);
if (ph.method == M_NRV2E_8) addLoader("NRV2E", NULL);
else if (ph.method == M_NRV2B_8) addLoader("NRV2B", NULL);
else if (ph.method == M_NRV2D_8) addLoader("NRV2D", NULL);
else if (M_IS_LZMA(ph.method)) addLoader("LZMA_ELF00,LZMA_DEC10,LZMA_DEC30", NULL);
else throwBadLoader();
addLoader("IDENTSTR,UPX1HEAD", NULL);
}
static const static const
#include "stub/i386-linux.kernel.vmlinux-head.h" #include "stub/i386-linux.kernel.vmlinux-head.h"
@@ -686,6 +732,8 @@ static const
#include "stub/amd64-linux.kernel.vmlinux-head.h" #include "stub/amd64-linux.kernel.vmlinux-head.h"
static const static const
#include "stub/arm-linux.kernel.vmlinux-head.h" #include "stub/arm-linux.kernel.vmlinux-head.h"
static const
#include "stub/armeb-linux.kernel.vmlinux-head.h"
unsigned PackVmlinuxI386::write_vmlinux_head( unsigned PackVmlinuxI386::write_vmlinux_head(
OutputFile *const fo, OutputFile *const fo,
@@ -719,7 +767,15 @@ printf("UnCompressed length=0x%x\n", ph.u_len);
return sizeof(stub_amd64_linux_kernel_vmlinux_head); return sizeof(stub_amd64_linux_kernel_vmlinux_head);
} }
void PackVmlinuxARM::defineDecompressorSymbols() void PackVmlinuxARMEL::defineDecompressorSymbols()
{
super::defineDecompressorSymbols();
linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len);
linker->defineSymbol("UNCOMPRESSED_LENGTH", ph.u_len);
linker->defineSymbol("METHOD", ph.method);
}
void PackVmlinuxARMEB::defineDecompressorSymbols()
{ {
super::defineDecompressorSymbols(); super::defineDecompressorSymbols();
linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len); linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len);
@@ -744,7 +800,7 @@ void PackVmlinuxAMD64::defineDecompressorSymbols()
linker->defineSymbol("PHYSICAL_START", phdri[0].p_paddr); linker->defineSymbol("PHYSICAL_START", phdri[0].p_paddr);
} }
unsigned PackVmlinuxARM::write_vmlinux_head( unsigned PackVmlinuxARMEL::write_vmlinux_head(
OutputFile *const fo, OutputFile *const fo,
Shdr *const stxt Shdr *const stxt
) )
@@ -766,8 +822,30 @@ unsigned PackVmlinuxARM::write_vmlinux_head(
return sizeof(stub_arm_linux_kernel_vmlinux_head); return sizeof(stub_arm_linux_kernel_vmlinux_head);
} }
unsigned PackVmlinuxARMEB::write_vmlinux_head(
OutputFile *const fo,
Shdr *const stxt
)
{
// First word from vmlinux-head.S
fo->write(&stub_armeb_linux_kernel_vmlinux_head[0], 4);
bool PackVmlinuxARM::has_valid_vmlinux_head() // Second word
U32 tmp_u32;
unsigned const t = (0xff000000 &
BeLePolicy::get32(&stub_armeb_linux_kernel_vmlinux_head[4]))
| (0x00ffffff & (0u - 1 + ((3+ ph.c_len)>>2)));
tmp_u32 = t;
fo->write(&tmp_u32, 4);
stxt->sh_addralign = 4;
stxt->sh_size += sizeof(stub_armeb_linux_kernel_vmlinux_head);
return sizeof(stub_armeb_linux_kernel_vmlinux_head);
}
bool PackVmlinuxARMEL::has_valid_vmlinux_head()
{ {
U32 buf[2]; U32 buf[2];
fi->seek(p_text->sh_offset + sizeof(stub_arm_linux_kernel_vmlinux_head) -8, SEEK_SET); fi->seek(p_text->sh_offset + sizeof(stub_arm_linux_kernel_vmlinux_head) -8, SEEK_SET);
@@ -781,6 +859,20 @@ bool PackVmlinuxARM::has_valid_vmlinux_head()
return false; return false;
} }
bool PackVmlinuxARMEB::has_valid_vmlinux_head()
{
U32 buf[2];
fi->seek(p_text->sh_offset + sizeof(stub_armeb_linux_kernel_vmlinux_head) -8, SEEK_SET);
fi->readx(buf, sizeof(buf));
//unsigned const word0 = buf[0];
unsigned const word1 = buf[1];
if (0xeb==(word1>>24)
&& (0x00ffffff& word1)==(0u - 1 + ((3+ ph.c_len)>>2))) {
return true;
}
return false;
}
bool PackVmlinuxI386::has_valid_vmlinux_head() bool PackVmlinuxI386::has_valid_vmlinux_head()
{ {
unsigned char buf[5]; unsigned char buf[5];
@@ -1058,6 +1150,7 @@ Linker* PackVmlinuxAMD64::newLinker() const
// instantiate instances // instantiate instances
template class PackVmlinuxBase<ElfClass_LE32>; template class PackVmlinuxBase<ElfClass_LE32>;
template class PackVmlinuxBase<ElfClass_BE32>;
template class PackVmlinuxBase<ElfClass_LE64>; template class PackVmlinuxBase<ElfClass_LE64>;
+28 -4
View File
@@ -119,14 +119,14 @@ protected:
}; };
class PackVmlinuxARM : public PackVmlinuxBase<ElfClass_LE32> class PackVmlinuxARMEL : public PackVmlinuxBase<ElfClass_LE32>
{ {
typedef PackVmlinuxBase<ElfClass_LE32> super; typedef PackVmlinuxBase<ElfClass_LE32> super;
public: public:
PackVmlinuxARM(InputFile *f) : super(f, Ehdr::EM_ARM, PackVmlinuxARMEL(InputFile *f) : super(f, Ehdr::EM_ARM,
Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "decompress_kernel") { } Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "decompress_kernel") { }
virtual int getFormat() const { return UPX_F_VMLINUX_ARM; } virtual int getFormat() const { return UPX_F_VMLINUX_ARMEL; }
virtual const char *getName() const { return "vmlinux/ARM"; } virtual const char *getName() const { return "vmlinux/armel"; }
virtual const char *getFullName(const options_t *) const { return "arm-linux.kernel.vmlinux"; } 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 *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
@@ -143,6 +143,30 @@ protected:
); );
}; };
class PackVmlinuxARMEB : public PackVmlinuxBase<ElfClass_BE32>
{
typedef PackVmlinuxBase<ElfClass_BE32> super;
public:
PackVmlinuxARMEB(InputFile *f) : super(f, Ehdr::EM_ARM,
Ehdr::ELFCLASS32, Ehdr::ELFDATA2MSB, "decompress_kernel") { }
virtual int getFormat() const { return UPX_F_VMLINUX_ARMEB; }
virtual const char *getName() const { return "vmlinux/armeb"; }
virtual const char *getFullName(const options_t *) const { return "armeb-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> class PackVmlinuxAMD64 : public PackVmlinuxBase<ElfClass_LE64>
{ {
+1 -1
View File
@@ -60,7 +60,7 @@ protected:
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
// virtual const upx_byte *getLoader() const; // virtual upx_byte *getLoader() const;
// virtual int getLoaderSize() const; // virtual int getLoaderSize() const;
struct boot_sect_t struct boot_sect_t
+6 -2
View File
@@ -607,7 +607,8 @@ void PackW32Pe::pack(OutputFile *fo)
(ih.cpu < 0x14c || ih.cpu > 0x150) (ih.cpu < 0x14c || ih.cpu > 0x150)
|| (ih.opthdrsize != 0xe0) || (ih.opthdrsize != 0xe0)
|| ((ih.flags & EXECUTABLE) == 0) || ((ih.flags & EXECUTABLE) == 0)
|| (ih.subsystem != 2 && ih.subsystem != 3 && ih.subsystem != 1) || (ih.subsystem != 2 && ih.subsystem != 3
&& ih.subsystem != 1 && ih.subsystem != 9)
|| (ih.entry == 0 && !isdll) || (ih.entry == 0 && !isdll)
|| (ih.ddirsentries != 16) || (ih.ddirsentries != 16)
|| IDSIZE(PEDIR_EXCEPTION) // is this used on i386? || IDSIZE(PEDIR_EXCEPTION) // is this used on i386?
@@ -615,6 +616,9 @@ void PackW32Pe::pack(OutputFile *fo)
)) ))
throwCantPack("unexpected value in PE header (try --force)"); throwCantPack("unexpected value in PE header (try --force)");
if (ih.subsystem == 9)
throwCantPack("x86/wince files are not yet supported");
if (IDSIZE(PEDIR_SEC)) if (IDSIZE(PEDIR_SEC))
IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0; IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0;
if (IDSIZE(PEDIR_COMRT)) if (IDSIZE(PEDIR_COMRT))
@@ -717,7 +721,7 @@ void PackW32Pe::pack(OutputFile *fo)
//OutputFile::dump("x1", ibuf, usize); //OutputFile::dump("x1", ibuf, usize);
// some checks for broken linkers - disable filter if neccessary // some checks for broken linkers - disable filter if necessary
bool allow_filter = true; bool allow_filter = true;
if (ih.codebase == ih.database if (ih.codebase == ih.database
|| ih.codebase + ih.codesize > ih.imagesize || ih.codebase + ih.codesize > ih.imagesize
+29 -26
View File
@@ -46,7 +46,7 @@ Packer::Packer(InputFile *f) :
last_patch(NULL), last_patch_len(0), last_patch_off(0) last_patch(NULL), last_patch_len(0), last_patch_off(0)
{ {
if (fi != NULL) if (fi != NULL)
file_size = fi->st.st_size; file_size = fi->st_size();
uip = new UiPacker(this); uip = new UiPacker(this);
memset(&ph, 0, sizeof(ph)); memset(&ph, 0, sizeof(ph));
} }
@@ -386,13 +386,16 @@ void Packer::decompress(const upx_bytep in, upx_bytep out,
// overlapping decompression // overlapping decompression
**************************************************************************/ **************************************************************************/
bool ph_testOverlappingDecompression(const PackHeader &ph, const upx_bytep buf, bool ph_testOverlappingDecompression(const PackHeader &ph,
const upx_bytep buf,
const upx_bytep tbuf,
unsigned overlap_overhead) unsigned overlap_overhead)
{ {
if (ph.c_len >= ph.u_len) if (ph.c_len >= ph.u_len)
return false; return false;
assert((int)overlap_overhead >= 0); assert((int) overlap_overhead >= 0);
assert((int) (ph.u_len + overlap_overhead) >= 0);
// Because upx_test_overlap() does not use the asm_fast decompressor // Because upx_test_overlap() does not use the asm_fast decompressor
// we must account for extra 3 bytes that asm_fast does use, // we must account for extra 3 bytes that asm_fast does use,
@@ -406,16 +409,17 @@ bool ph_testOverlappingDecompression(const PackHeader &ph, const upx_bytep buf,
unsigned src_off = ph.u_len + overlap_overhead - ph.c_len; unsigned src_off = ph.u_len + overlap_overhead - ph.c_len;
unsigned new_len = ph.u_len; unsigned new_len = ph.u_len;
int r = upx_test_overlap(buf - src_off, src_off, int r = upx_test_overlap(buf - src_off, tbuf,
ph.c_len, &new_len, ph.method, &ph.compress_result); src_off, ph.c_len, &new_len,
ph.method, &ph.compress_result);
return (r == UPX_E_OK && new_len == ph.u_len); return (r == UPX_E_OK && new_len == ph.u_len);
} }
bool Packer::testOverlappingDecompression(const upx_bytep buf, bool Packer::testOverlappingDecompression(const upx_bytep buf, const upx_bytep tbuf,
unsigned overlap_overhead) const unsigned overlap_overhead) const
{ {
return ph_testOverlappingDecompression(ph, buf, overlap_overhead); return ph_testOverlappingDecompression(ph, buf, tbuf, overlap_overhead);
} }
@@ -474,6 +478,7 @@ void Packer::verifyOverlappingDecompression(upx_bytep o_ptr, unsigned o_size, Fi
**************************************************************************/ **************************************************************************/
unsigned Packer::findOverlapOverhead(const upx_bytep buf, unsigned Packer::findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
unsigned range, unsigned range,
unsigned upper_limit) const unsigned upper_limit) const
{ {
@@ -481,7 +486,7 @@ unsigned Packer::findOverlapOverhead(const upx_bytep buf,
// prepare to deal with very pessimistic values // prepare to deal with very pessimistic values
unsigned low = 1; unsigned low = 1;
unsigned high = UPX_MIN(ph.u_len / 4 + 512, upper_limit); unsigned high = UPX_MIN(ph.u_len + 512, upper_limit);
// but be optimistic for first try (speedup) // but be optimistic for first try (speedup)
unsigned m = UPX_MIN(16u, high); unsigned m = UPX_MIN(16u, high);
// //
@@ -493,21 +498,23 @@ unsigned Packer::findOverlapOverhead(const upx_bytep buf,
assert(m >= low); assert(m <= high); assert(m >= low); assert(m <= high);
assert(m < overhead || overhead == 0); assert(m < overhead || overhead == 0);
nr++; nr++;
bool success = testOverlappingDecompression(buf, m); bool success = testOverlappingDecompression(buf, tbuf, m);
//printf("testOverlapOverhead: %d %d -> %d\n", nr, m, (int)success); //printf("testOverlapOverhead(%d): %d %d: %d -> %d\n", nr, low, high, m, (int)success);
if (success) if (success)
{ {
overhead = m; overhead = m;
// Succeed early if m lies in [low .. low+range-1], i.e. if // Succeed early if m lies in [low .. low+range-1], i.e. if
// if the range of the current interval is <= range. // if the range of the current interval is <= range.
//if (m <= low + range - 1) // if (m <= low + range - 1)
if (m + 1 <= low + range) // avoid underflow // if (m < low + range)
if (m - low < range) // avoid underflow
break; break;
high = m - 1; high = m - 1;
} }
else else
low = m + 1; low = m + 1;
m = (low + high) / 2; ////m = (low + high) / 2;
m = (low & high) + ((low ^ high) >> 1); // avoid overflow
} }
//printf("findOverlapOverhead: %d (%d tries)\n", overhead, nr); //printf("findOverlapOverhead: %d (%d tries)\n", overhead, nr);
@@ -684,7 +691,7 @@ int Packer::patchPackHeader(void *b, int blen)
} }
bool Packer::getPackHeader(void *b, int blen) bool Packer::getPackHeader(void *b, int blen, bool allow_incompressible)
{ {
if (!ph.fillPackHeader((unsigned char *)b, blen)) if (!ph.fillPackHeader((unsigned char *)b, blen))
return false; return false;
@@ -697,7 +704,9 @@ bool Packer::getPackHeader(void *b, int blen)
if (!testUnpackVersion(ph.version)) if (!testUnpackVersion(ph.version))
return false; return false;
if (ph.c_len >= ph.u_len || (off_t)ph.c_len >= file_size if (ph.c_len > ph.u_len
|| (ph.c_len == ph.u_len && !allow_incompressible)
|| (off_t)ph.c_len >= file_size
|| ph.version <= 0 || ph.version >= 0xff) || ph.version <= 0 || ph.version >= 0xff)
throwCantUnpack("header corrupted"); throwCantUnpack("header corrupted");
else if ((off_t)ph.u_len > ph.u_file_size) else if ((off_t)ph.u_len > ph.u_file_size)
@@ -722,14 +731,14 @@ bool Packer::getPackHeader(void *b, int blen)
} }
bool Packer::readPackHeader(int len) bool Packer::readPackHeader(int len, bool allow_incompressible)
{ {
assert((int)len > 0); assert((int)len > 0);
MemBuffer buf(len); MemBuffer buf(len);
len = fi->read(buf, len); len = fi->read(buf, len);
if (len <= 0) if (len <= 0)
return false; return false;
return getPackHeader(buf, len); return getPackHeader(buf, len, allow_incompressible);
} }
@@ -1082,14 +1091,8 @@ void Packer::addLoader(C a, C b, C c, C d, C e, C f, C g, C h, C i, C j)
void __acc_cdecl_va Packer::addLoaderVA(const char *s, ...) void __acc_cdecl_va Packer::addLoaderVA(const char *s, ...)
{ {
va_list ap; va_list ap;
const char *t = s;
va_start(ap, s); va_start(ap, s);
while (t != NULL) linker->addLoader(s, ap);
{
linker->addLoader(t);
t = va_arg(ap, const char *);
}
va_end(ap); va_end(ap);
} }
@@ -1196,7 +1199,7 @@ void Packer::relocateLoader()
// The workaround is for hdr_buf and hdr_u_len to describe the Elf headers // The workaround is for hdr_buf and hdr_u_len to describe the Elf headers
// (typically less than 512 bytes) when .text is passed in, and include // (typically less than 512 bytes) when .text is passed in, and include
// them in the calculation of shortest output. Then the result // them in the calculation of shortest output. Then the result
// this->ph.method will say which [single] method to use for everthing. // this->ph.method will say which [single] method to use for everything.
// The Elf headers are never filtered. They are short enough (< 512 bytes) // The Elf headers are never filtered. They are short enough (< 512 bytes)
// that compressing them more than once per method (once here when choosing, // that compressing them more than once per method (once here when choosing,
// once again just before writing [because compressWithFilters discards]) // once again just before writing [because compressWithFilters discards])
@@ -1415,7 +1418,7 @@ void Packer::compressWithFilters(upx_bytep i_ptr, unsigned i_len,
if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len) if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len)
{ {
// get results // get results
ph.overlap_overhead = findOverlapOverhead(o_tmp, overlap_range); ph.overlap_overhead = findOverlapOverhead(o_tmp, i_ptr, overlap_range);
buildLoader(&ft); buildLoader(&ft);
lsize = getLoaderSize(); lsize = getLoaderSize();
assert(lsize > 0); assert(lsize > 0);
+4 -2
View File
@@ -203,9 +203,11 @@ protected:
// util for verifying overlapping decompresion // util for verifying overlapping decompresion
// non-destructive test // non-destructive test
virtual bool testOverlappingDecompression(const upx_bytep buf, virtual bool testOverlappingDecompression(const upx_bytep buf,
const upx_bytep tbuf,
unsigned overlap_overhead) const; unsigned overlap_overhead) const;
// non-destructive find // non-destructive find
virtual unsigned findOverlapOverhead(const upx_bytep buf, virtual unsigned findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
unsigned range = 0, unsigned range = 0,
unsigned upper_limit = ~0u) const; unsigned upper_limit = ~0u) const;
// destructive decompress + verify // destructive decompress + verify
@@ -214,8 +216,8 @@ protected:
// packheader handling // packheader handling
virtual int patchPackHeader(void *b, int blen); virtual int patchPackHeader(void *b, int blen);
virtual bool getPackHeader(void *b, int blen); virtual bool getPackHeader(void *b, int blen, bool allow_incompressible=false);
virtual bool readPackHeader(int len); virtual bool readPackHeader(int len, bool allow_incompressible=false);
virtual void checkAlreadyPacked(const void *b, int blen); virtual void checkAlreadyPacked(const void *b, int blen);
// loader core // loader core
+21 -6
View File
@@ -208,11 +208,14 @@ const char *Packer::getDecompressorSections() const
if (UPX_F_LINUX_ELF_i386 ==ph.format if (UPX_F_LINUX_ELF_i386 ==ph.format
|| UPX_F_LINUX_ELFI_i386 ==ph.format || UPX_F_LINUX_ELFI_i386 ==ph.format
|| UPX_F_LINUX_ELF64_AMD ==ph.format || UPX_F_LINUX_ELF64_AMD ==ph.format
|| UPX_F_LINUX_ELF32_ARMLE==ph.format || UPX_F_LINUX_ELF32_ARMEL==ph.format
|| UPX_F_LINUX_ELFPPC32 ==ph.format || UPX_F_LINUX_ELFPPC32 ==ph.format
|| UPX_F_LINUX_ELF32_ARMBE==ph.format || UPX_F_LINUX_ELF32_ARMEB==ph.format
|| UPX_F_BSD_ELF_i386 ==ph.format || UPX_F_BSD_ELF_i386 ==ph.format
|| UPX_F_VMLINUX_ARM ==ph.format || UPX_F_VMLINUX_ARMEL ==ph.format
|| UPX_F_VMLINUX_ARMEB ==ph.format
|| UPX_F_MACH_PPC32 ==ph.format
|| UPX_F_MACH_i386 ==ph.format
) { ) {
return opt->small ? lzma_elf_small : lzma_elf_fast; return opt->small ? lzma_elf_small : lzma_elf_fast;
} }
@@ -242,11 +245,14 @@ void Packer::defineDecompressorSymbols()
if (UPX_F_LINUX_ELF_i386 ==ph.format if (UPX_F_LINUX_ELF_i386 ==ph.format
|| UPX_F_LINUX_ELFI_i386 ==ph.format || UPX_F_LINUX_ELFI_i386 ==ph.format
|| UPX_F_LINUX_ELF64_AMD ==ph.format || UPX_F_LINUX_ELF64_AMD ==ph.format
|| UPX_F_LINUX_ELF32_ARMLE==ph.format || UPX_F_LINUX_ELF32_ARMEL==ph.format
|| UPX_F_LINUX_ELFPPC32 ==ph.format || UPX_F_LINUX_ELFPPC32 ==ph.format
|| UPX_F_LINUX_ELF32_ARMBE==ph.format || UPX_F_LINUX_ELF32_ARMEB==ph.format
|| UPX_F_BSD_ELF_i386 ==ph.format || UPX_F_BSD_ELF_i386 ==ph.format
|| UPX_F_VMLINUX_ARM ==ph.format || UPX_F_VMLINUX_ARMEL ==ph.format
|| UPX_F_VMLINUX_ARMEB ==ph.format
|| UPX_F_MACH_PPC32 ==ph.format
|| UPX_F_MACH_i386 ==ph.format
) { ) {
// ELF calls the decompressor many times; the parameters change! // ELF calls the decompressor many times; the parameters change!
return; return;
@@ -268,6 +274,15 @@ void Packer::defineDecompressorSymbols()
linker->defineSymbol("lzma_u_len", ph.u_len); linker->defineSymbol("lzma_u_len", ph.u_len);
unsigned stack = getDecompressorWrkmemSize(); unsigned stack = getDecompressorWrkmemSize();
linker->defineSymbol("lzma_stack_adjust", 0u - stack); linker->defineSymbol("lzma_stack_adjust", 0u - stack);
if (ph.format == UPX_F_DOS_EXE)
{
linker->defineSymbol("lzma_properties_hi", properties / 65536);
// -2 for properties
linker->defineSymbol("lzma_c_len_hi", (ph.c_len - 2) / 65536);
linker->defineSymbol("lzma_u_len_hi", ph.u_len / 65536);
linker->defineSymbol("lzma_u_len_segment", (ph.u_len & 0xf0000) >> 4);
}
} }
} }
+8 -2
View File
@@ -192,7 +192,9 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
// //
// linux kernel // linux kernel
// //
if ((p = func(new PackVmlinuxARM(f), user)) != NULL) if ((p = func(new PackVmlinuxARMEL(f), user)) != NULL)
return p;
if ((p = func(new PackVmlinuxARMEB(f), user)) != NULL)
return p; return p;
if ((p = func(new PackVmlinuxAMD64(f), user)) != NULL) if ((p = func(new PackVmlinuxAMD64(f), user)) != NULL)
return p; return p;
@@ -244,7 +246,9 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
} }
if ((p = func(new PackBSDI386(f), user)) != NULL) if ((p = func(new PackBSDI386(f), user)) != NULL)
return p; return p;
if ((p = func(new PackLinuxI386(f), user)) != NULL) if ((p = func(new PackMachFat(f), user)) != NULL) // cafebabe conflict
return p;
if ((p = func(new PackLinuxI386(f), user)) != NULL) // cafebabe conflict
return p; return p;
// //
@@ -264,6 +268,8 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
// Mach (MacOS X PowerPC) // Mach (MacOS X PowerPC)
if ((p = func(new PackMachPPC32(f), user)) != NULL) if ((p = func(new PackMachPPC32(f), user)) != NULL)
return p; return p;
if ((p = func(new PackMachI386(f), user)) != NULL)
return p;
return NULL; return NULL;
} }
+43 -31
View File
@@ -50,18 +50,6 @@
# define strcpy(a,b) strcpy((char *)(a),(const char *)(b)) # define strcpy(a,b) strcpy((char *)(a),(const char *)(b))
#endif #endif
// Unicode string compare
static bool ustrsame(const void *s1, const void *s2)
{
unsigned len1 = get_le16(s1);
unsigned len2 = get_le16(s2);
if (len1 != len2)
return false;
return memcmp(s1, s2, 2 + 2*len1) == 0;
}
#if (__ACC_CXX_HAVE_PLACEMENT_DELETE) || defined(__DJGPP__) #if (__ACC_CXX_HAVE_PLACEMENT_DELETE) || defined(__DJGPP__)
#include "bptr.h" #include "bptr.h"
#define IPTR(type, var) BoundedPtr<type> var(ibuf, ibuf.getSize()) #define IPTR(type, var) BoundedPtr<type> var(ibuf, ibuf.getSize())
@@ -1245,6 +1233,12 @@ upx_byte *PeFile::Resource::build()
newstart = new upx_byte [dirsize()]; newstart = new upx_byte [dirsize()];
unsigned bpos = 0,spos = dsize; unsigned bpos = 0,spos = dsize;
build(root,bpos,spos,0); build(root,bpos,spos,0);
// dirsize() is 4 bytes aligned, so we may need to zero
// up to 2 bytes to make valgrind happy
while (spos < dirsize())
newstart[spos++] = 0;
return newstart; return newstart;
} }
@@ -1349,7 +1343,7 @@ static bool match(unsigned itype, const unsigned char *ntype,
if (unistr[2 + ic * 2] != (unsigned char) mkeep[ic]) if (unistr[2 + ic * 2] != (unsigned char) mkeep[ic])
return false; return false;
return mkeep[ic] == 0 || mkeep[ic] == ',' || mkeep[ic] == '/'; return mkeep[ic] == 0 || mkeep[ic] == ',' || mkeep[ic] == '/';
}; }
}; };
// FIXME this comparison is not too exact // FIXME this comparison is not too exact
@@ -1404,15 +1398,31 @@ void PeFile::processResources(Resource *res)
oresources = new upx_byte[soresources]; oresources = new upx_byte[soresources];
upx_byte *ores = oresources + res->dirsize(); upx_byte *ores = oresources + res->dirsize();
char *keep_icons = NULL; // icon ids in the first icon group
unsigned iconsin1stdir = 0; unsigned iconsin1stdir = 0;
if (opt->win32_pe.compress_icons == 2) if (opt->win32_pe.compress_icons == 2)
while (res->next()) // there is no rewind() in Resource while (res->next()) // there is no rewind() in Resource
if (res->itype() == RT_GROUP_ICON && iconsin1stdir == 0) if (res->itype() == RT_GROUP_ICON && iconsin1stdir == 0)
{
iconsin1stdir = get_le16(ibuf + res->offs() + 4); iconsin1stdir = get_le16(ibuf + res->offs() + 4);
keep_icons = new char[1 + iconsin1stdir * 9];
*keep_icons = 0;
for (unsigned ic = 0; ic < iconsin1stdir; ic++)
snprintf(keep_icons + strlen(keep_icons), 9, "3/%u,",
get_le16(ibuf + res->offs() + 6 + ic * 14 + 12));
if (*keep_icons)
keep_icons[strlen(keep_icons) - 1] = 0;
}
bool compress_icon = opt->win32_pe.compress_icons == 3; // the icon id which should not be compressed when compress_icons == 1
bool compress_idir = false; unsigned first_icon_id = (unsigned) -1;
unsigned iconcnt = 0; if (opt->win32_pe.compress_icons == 1)
while (res->next())
if (res->itype() == RT_GROUP_ICON && first_icon_id == (unsigned) -1)
first_icon_id = get_le16(ibuf + res->offs() + 6 + 12);
bool compress_icon = opt->win32_pe.compress_icons > 1;
bool compress_idir = opt->win32_pe.compress_icons == 3;
// some statistics // some statistics
unsigned usize = 0; unsigned usize = 0;
@@ -1426,25 +1436,26 @@ void PeFile::processResources(Resource *res)
bool do_compress = true; bool do_compress = true;
if (!opt->win32_pe.compress_resources) if (!opt->win32_pe.compress_resources)
do_compress = false; do_compress = false;
else if (rtype == RT_VERSION) // version info
do_compress = false;
else if (rtype == RT_ICON) // icon else if (rtype == RT_ICON) // icon
do_compress = compress_icon && opt->win32_pe.compress_icons; {
if (opt->win32_pe.compress_icons == 0)
do_compress = false;
else if (opt->win32_pe.compress_icons == 1)
if ((first_icon_id == (unsigned) -1
|| first_icon_id == res->iname()))
do_compress = compress_icon;
}
else if (rtype == RT_GROUP_ICON) // icon directory else if (rtype == RT_GROUP_ICON) // icon directory
do_compress = compress_idir && opt->win32_pe.compress_icons; do_compress = compress_idir && opt->win32_pe.compress_icons;
else if (rtype > 0 && rtype < RT_LAST) else if (rtype > 0 && rtype < RT_LAST)
do_compress = opt->win32_pe.compress_rt[rtype] ? true : false; do_compress = opt->win32_pe.compress_rt[rtype] ? true : false;
else if (res->ntype()) // named resource type
{
const upx_byte * const t = res->ntype();
if (ustrsame(t, "\x7\x0T\x0Y\x0P\x0""E\x0L\x0I\x0""B\x0"))
do_compress = false; // u"TYPELIB"
else if (ustrsame(t, "\x8\x0R\x0""E\x0G\x0I\x0S\x0T\x0R\x0Y\x0"))
do_compress = false; // u"REGISTRY"
}
if (do_compress && opt->win32_pe.keep_resource[0]) if (keep_icons)
do_compress ^= match(res->itype(), res->ntype(), res->iname(), do_compress &= !match(res->itype(), res->ntype(), res->iname(),
res->nname(), keep_icons);
do_compress &= !match(res->itype(), res->ntype(), res->iname(),
res->nname(), "TYPELIB,REGISTRY,16");
do_compress &= !match(res->itype(), res->ntype(), res->iname(),
res->nname(), opt->win32_pe.keep_resource); res->nname(), opt->win32_pe.keep_resource);
if (do_compress) if (do_compress)
@@ -1463,8 +1474,8 @@ void PeFile::processResources(Resource *res)
memcpy(ores, ibuf + res->offs(), res->size()); memcpy(ores, ibuf + res->offs(), res->size());
ibuf.fill(res->offs(), res->size(), FILLVAL); ibuf.fill(res->offs(), res->size(), FILLVAL);
res->newoffs() = ptr_diff(ores,oresources); res->newoffs() = ptr_diff(ores,oresources);
if (rtype == RT_ICON) if (rtype == RT_ICON && opt->win32_pe.compress_icons == 1)
compress_icon = (++iconcnt >= iconsin1stdir || opt->win32_pe.compress_icons == 1); compress_icon = true;
else if (rtype == RT_GROUP_ICON) else if (rtype == RT_GROUP_ICON)
{ {
if (opt->win32_pe.compress_icons == 1) if (opt->win32_pe.compress_icons == 1)
@@ -1479,6 +1490,7 @@ void PeFile::processResources(Resource *res)
} }
soresources = ptr_diff(ores,oresources); soresources = ptr_diff(ores,oresources);
delete[] keep_icons;
if (!res->clear()) if (!res->clear())
{ {
// The area occupied by the resource directory is not continuous // The area occupied by the resource directory is not continuous
+89 -22
View File
@@ -18,10 +18,19 @@ empty :=
space := $(empty) $(empty) space := $(empty) $(empty)
tab := $(empty) $(empty) tab := $(empty) $(empty)
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.79 3.79.1 3.80),) ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
$(error GNU make 3.81 or better is required) $(error GNU make 3.81 or better is required)
endif endif
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 $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
# update $PATH for our special stub build tools # update $PATH for our special stub build tools
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),) ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
export PATH := $(HOME)/local/bin/bin-upx:$(PATH) export PATH := $(HOME)/local/bin/bin-upx:$(PATH)
@@ -35,14 +44,6 @@ endif
# // # //
# ************************************************************************/ # ************************************************************************/
ifndef srcdir
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
endif
ifndef top_srcdir
top_srcdir := $(srcdir)/../..
endif
ifndef STUBS ifndef STUBS
STUBS += amd64-linux.elf-entry.h STUBS += amd64-linux.elf-entry.h
STUBS += amd64-linux.elf-fold.h STUBS += amd64-linux.elf-fold.h
@@ -55,6 +56,8 @@ STUBS += arm-linux.kernel.vmlinux.h
STUBS += arm-linux.kernel.vmlinux-head.h STUBS += arm-linux.kernel.vmlinux-head.h
STUBS += armeb-linux.elf-entry.h STUBS += armeb-linux.elf-entry.h
STUBS += armeb-linux.elf-fold.h STUBS += armeb-linux.elf-fold.h
STUBS += armeb-linux.kernel.vmlinux.h
STUBS += armeb-linux.kernel.vmlinux-head.h
STUBS += arm.v4a-wince.pe.h STUBS += arm.v4a-wince.pe.h
STUBS += arm.v4t-wince.pe.h STUBS += arm.v4t-wince.pe.h
STUBS += i086-dos16.com.h STUBS += i086-dos16.com.h
@@ -64,6 +67,8 @@ STUBS += i386-bsd.elf-entry.h
STUBS += i386-bsd.elf-fold.h STUBS += i386-bsd.elf-fold.h
STUBS += i386-bsd.elf.execve-entry.h STUBS += i386-bsd.elf.execve-entry.h
STUBS += i386-bsd.elf.execve-fold.h STUBS += i386-bsd.elf.execve-fold.h
STUBS += i386-darwin.macho-entry.h
STUBS += i386-darwin.macho-fold.h
STUBS += i386-openbsd.elf-fold.h STUBS += i386-openbsd.elf-fold.h
STUBS += i386-dos32.djgpp2.h STUBS += i386-dos32.djgpp2.h
STUBS += i386-dos32.djgpp2-stubify.h STUBS += i386-dos32.djgpp2-stubify.h
@@ -101,14 +106,16 @@ default: $$(default.targets)
endif endif
endif endif
all.targets ?= .upx-stubtools-stamp tmp/.tmp-stamp .all-stamp all.targets ?= .upx-stubtools-stamp tmp/.tmp-stamp .all-stamp
all: $$(all.targets) all: $$(all.targets)
.upx-stubtools-stamp: $(MAKEFILE_LIST) .upx-stubtools-stamp: $(MAKEFILE_LIST)
upx-stubtools-check-version 20060823 upx-stubtools-check-version 20060823
@echo "timestamp" > $@ @echo "timestamp" > $@
tmp/.tmp-stamp: %/.tmp-stamp:
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
@echo "timestamp" > $@ @echo "timestamp" > $@
.PRECIOUS: %/.tmp-stamp
.all-stamp: $$(STUBS) .all-stamp: $$(STUBS)
@echo "timestamp" > $@ @echo "timestamp" > $@
@@ -131,13 +138,6 @@ maintainer-clean:
# util var for use in the rules - basename of the current target # util var for use in the rules - basename of the current target
override T = $(basename $(notdir $@)) override T = $(basename $(notdir $@))
# trim (strip) trailing whitespace
RTRIM := sed -e 's/[ $(tab)]*$$//'
# squeeze duplicate blank lines, delete empty first & last line
BLSQUEEZE := $(RTRIM) | cat --squeeze-blank | sed -e '1{/^$$/d}' -e '$${/^$$/d}'
# delete blank lines
BLDEL := $(RTRIM) | sed -e '/^$$/d'
# clear some vars, just in case # clear some vars, just in case
LABEL_PREFIX = LABEL_PREFIX =
PP_FLAGS = PP_FLAGS =
@@ -146,6 +146,21 @@ tc_bfdname =
tc_list = tc_list =
tc_objdump_disasm_options = tc_objdump_disasm_options =
# commands
PYTHON = python
UNIX2DOS := perl -i -pe 's/$$/\r/;'
# trim (strip) trailing whitespace
RTRIM := sed -e 's/[ $(tab)]*$$//'
# squeeze duplicate blank lines, delete empty first & last line
BLSQUEEZE := $(RTRIM) | cat --squeeze-blank | sed -e '1{/^$$/d}' -e '$${/^$$/d}'
# delete blank lines
BLDEL := $(RTRIM) | sed -e '/^$$/d'
# delete blank lines at top (beginning) of file
BLDELTOP := sed -e '/./,$$!d'
# delete blank lines at bottom (end) of file
BLDELBOT := sed -e ':a' -e '/^\n*$$/{$$d;N;ba' -e '}'
# /*********************************************************************** # /***********************************************************************
# // setup toolchain globals # // setup toolchain globals
@@ -165,17 +180,18 @@ define tc
endef endef
# default tools # default tools
tc.default.bin2h = python $(top_srcdir)/src/stub/scripts/bin2h.py --ident=auto-stub tc.default.bin2h = $(PYTHON) $(top_srcdir)/src/stub/scripts/bin2h.py --ident=auto-stub
##tc.default.bin2h-c = $(call tc,bin2h) --compress=14,15,0 ##tc.default.bin2h-c = $(call tc,bin2h) --compress=14,15,0
tc.default.bin2h-c = $(call tc,bin2h) --compress=0 tc.default.bin2h-c = $(call tc,bin2h) --compress=0
tc.default.brandelf = python $(top_srcdir)/src/stub/scripts/brandelf.py $(if $(tc_bfdname),--bfdname=$(tc_bfdname)) tc.default.brandelf = $(PYTHON) $(top_srcdir)/src/stub/scripts/brandelf.py $(if $(tc_bfdname),--bfdname=$(tc_bfdname))
tc.default.gpp_inc = python $(top_srcdir)/src/stub/scripts/gpp_inc.py tc.default.gpp_inc = $(PYTHON) $(top_srcdir)/src/stub/scripts/gpp_inc.py
tc.default.gpp_mkdep = python $(top_srcdir)/src/stub/scripts/gpp_inc.py -o /dev/null tc.default.gpp_mkdep = $(PYTHON) $(top_srcdir)/src/stub/scripts/gpp_inc.py -o /dev/null
tc.default.pp-as = i386-linux-gcc-3.4.6 -E -nostdinc -x assembler-with-cpp -Wall tc.default.pp-as = i386-linux-gcc-3.4.6 -E -nostdinc -x assembler-with-cpp -Wall
tc.default.sstrip = sstrip tc.default.sstrip = sstrip
tc.default.xstrip = python $(top_srcdir)/src/stub/scripts/xstrip.py tc.default.xstrip = $(PYTHON) $(top_srcdir)/src/stub/scripts/xstrip.py
# default multiarch-binutils # default multiarch-binutils
tc.default.m-ar = multiarch-ar-2.17
tc.default.m-ld = multiarch-ld-2.17 $(if $(tc_bfdname),-b $(tc_bfdname)) tc.default.m-ld = multiarch-ld-2.17 $(if $(tc_bfdname),-b $(tc_bfdname))
tc.default.m-nm = multiarch-nm-2.17 $(if $(tc_bfdname),--target=$(tc_bfdname)) tc.default.m-nm = multiarch-nm-2.17 $(if $(tc_bfdname),--target=$(tc_bfdname))
tc.default.m-objcopy = multiarch-objcopy-2.17 $(if $(tc_bfdname),-F $(tc_bfdname)) tc.default.m-objcopy = multiarch-objcopy-2.17 $(if $(tc_bfdname),-F $(tc_bfdname))
@@ -207,6 +223,7 @@ endef
# some common arch settings # some common arch settings
tc.arch-i086.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@ tc.arch-i086.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@
tc.arch-i086.wdis = $(WATCOM)/binl/wdis
tc.arch-i386.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@ tc.arch-i386.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@
tc.arch-i386.djasm = djasm tc.arch-i386.djasm = djasm
@@ -321,6 +338,28 @@ arm-linux.kernel.vmlinux-head.h : $(srcdir)/src/$$T.S
$(call tc,bin2h) tmp/$T.bin $@ $(call tc,bin2h) tmp/$T.bin $@
# /***********************************************************************
# // armeb-linux.kernel.vmlinux
# // armeb-linux.kernel.vmlinuz
# // armeb-linux.kernel.vmlinux-head
# ************************************************************************/
armeb-linux.kernel.vmlinu%.h : tc_list = armeb-linux.kernel default
armeb-linux.kernel.vmlinu%.h : tc_bfdname = elf32-bigarm
tc.armeb-linux.kernel.gcc = $(tc.arm-linux.elf.gcc) -mbig-endian
armeb-linux.kernel.vmlinu%.h : $(srcdir)/src/$$T.S
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.bin
$(call tc,f-embed_objinfo,tmp/$T.bin)
$(call tc,bin2h-c) tmp/$T.bin $@
armeb-linux.kernel.vmlinux-head.h : $(srcdir)/src/$$T.S
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.o
$(call tc,objcopy) --output-target binary --only-section .text tmp/$T.o tmp/$T.bin
$(call tc,bin2h) tmp/$T.bin $@
# /*********************************************************************** # /***********************************************************************
# // armeb-linux.elf # // armeb-linux.elf
# ************************************************************************/ # ************************************************************************/
@@ -507,6 +546,34 @@ tmp/i386-bsd.elf.execve-upx_itoa.o : $(srcdir)/src/$$T.S
$(call tc,f-objstrip,$@) $(call tc,f-objstrip,$@)
# /***********************************************************************
# // i386-darwin.macho
# ************************************************************************/
# info: we use the tc settings from i386-linux.elf
i386-darwin.macho%.h : tc_list = i386-linux.elf default
i386-darwin.macho%.h : tc_bfdname = elf32-i386
i386-darwin.macho-entry.h : $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o tmp/$T.bin
$(call tc,f-embed_objinfo,tmp/$T.bin)
$(call tc,bin2h) tmp/$T.bin $@
i386-darwin.macho-fold.h : tmp/$$T.o tmp/i386-darwin.macho-main.o
$(call tc,ld) --no-warn-mismatch --strip-all --oformat binary -Map tmp/$T.map $(filter %.o,$^) -o tmp/$T.bin
chmod a-x tmp/$T.bin
$(call tc,bin2h) tmp/$T.bin $@
tmp/i386-darwin.macho-fold.o : $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
$(call tc,f-objstrip,$@)
tmp/i386-darwin.macho-main.o : $(srcdir)/src/$$T.c
$(call tc,gcc) -c -Os $< -o $@
$(call tc,f-objstrip,$@)
$(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm
# /*********************************************************************** # /***********************************************************************
# // i386-dos32.djgpp2 # // i386-dos32.djgpp2
# ************************************************************************/ # ************************************************************************/
+3 -3
View File
@@ -29,8 +29,8 @@
#define STUB_ARM_LINUX_ELF_ENTRY_SIZE 16296 #define STUB_ARM_LINUX_ELF_ENTRY_SIZE 16296
#define STUB_ARM_LINUX_ELF_ENTRY_ADLER32 0x9b815c2e #define STUB_ARM_LINUX_ELF_ENTRY_ADLER32 0xdf115bee
#define STUB_ARM_LINUX_ELF_ENTRY_CRC32 0x3b801af9 #define STUB_ARM_LINUX_ELF_ENTRY_CRC32 0x8704e1a1
unsigned char stub_arm_linux_elf_entry[16296] = { unsigned char stub_arm_linux_elf_entry[16296] = {
127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
@@ -44,7 +44,7 @@ unsigned char stub_arm_linux_elf_entry[16296] = {
254, 1,160,232, 15, 0, 0, 58, 9, 64, 64,224, 80, 80,143,226, /* 0x 80 */ 254, 1,160,232, 15, 0, 0, 58, 9, 64, 64,224, 80, 80,143,226, /* 0x 80 */
0,224,160,225, 4, 80,133,224, 5, 0,160,225, 4, 16,137,224, /* 0x 90 */ 0,224,160,225, 4, 80,133,224, 5, 0,160,225, 4, 16,137,224, /* 0x 90 */
0, 32,160,227, 2, 0,159,239, 0,144,156,229,140,144, 73,226, /* 0x a0 */ 0, 32,160,227, 2, 0,159,239, 0,144,156,229,140,144, 73,226, /* 0x a0 */
9,160, 76,224, 4,160,138,224, 8, 0,219,229, 1, 64, 45,233, /* 0x b0 */ 9,160, 76,224, 4,160,138,224, 8, 0,155,229, 1, 64, 45,233, /* 0x b0 */
0, 48,155,229, 12, 0,139,226, 4, 16,155,229, 14, 32,160,225, /* 0x c0 */ 0, 48,155,229, 12, 0,139,226, 4, 16,155,229, 14, 32,160,225, /* 0x c0 */
8, 48,141,229, 8, 48,141,226, 15,224,160,225, 5,240,160,225, /* 0x d0 */ 8, 48,141,229, 8, 48,141,226, 15,224,160,225, 5,240,160,225, /* 0x d0 */
2,128,189,232,252, 64, 45,233, 0,112,129,224, 0, 80,224,227, /* 0x e0 */ 2,128,189,232,252, 64, 45,233, 0,112,129,224, 0, 80,224,227, /* 0x e0 */
+5 -5
View File
@@ -29,8 +29,8 @@
#define STUB_ARM_LINUX_KERNEL_VMLINUX_SIZE 17091 #define STUB_ARM_LINUX_KERNEL_VMLINUX_SIZE 17091
#define STUB_ARM_LINUX_KERNEL_VMLINUX_ADLER32 0x3d6cea16 #define STUB_ARM_LINUX_KERNEL_VMLINUX_ADLER32 0x2af6ea3d
#define STUB_ARM_LINUX_KERNEL_VMLINUX_CRC32 0xab8eacad #define STUB_ARM_LINUX_KERNEL_VMLINUX_CRC32 0x12d16cc6
unsigned char stub_arm_linux_kernel_vmlinux[17091] = { unsigned char stub_arm_linux_kernel_vmlinux[17091] = {
127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
@@ -570,7 +570,7 @@ unsigned char stub_arm_linux_kernel_vmlinux[17091] = {
10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 84, 89, 80, 69, 32, 32, /* 0x2160 */ 10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 84, 89, 80, 69, 32, 32, /* 0x2160 */
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, /* 0x2170 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, /* 0x2170 */
69, 10, 48, 48, 48, 48, 48, 48, 49, 52, 32, 82, 95, 65, 82, 77, /* 0x2180 */ 69, 10, 48, 48, 48, 48, 48, 48, 49, 52, 32, 82, 95, 65, 82, 77, /* 0x2180 */
95, 65, 66, 83, 56, 32, 32, 32, 32, 32, 32, 32, 32, 77, 69, 84, /* 0x2190 */ 95, 65, 66, 83, 51, 50, 32, 32, 32, 32, 32, 32, 32, 77, 69, 84, /* 0x2190 */
72, 79, 68, 10, 48, 48, 48, 48, 48, 48, 51, 48, 32, 82, 95, 65, /* 0x21a0 */ 72, 79, 68, 10, 48, 48, 48, 48, 48, 48, 51, 48, 32, 82, 95, 65, /* 0x21a0 */
82, 77, 95, 80, 67, 50, 52, 32, 32, 32, 32, 32, 32, 32, 32, 76, /* 0x21b0 */ 82, 77, 95, 80, 67, 50, 52, 32, 32, 32, 32, 32, 32, 32, 32, 76, /* 0x21b0 */
73, 78, 85, 88, 48, 51, 48, 10, 48, 48, 48, 48, 48, 48, 51, 52, /* 0x21c0 */ 73, 78, 85, 88, 48, 51, 48, 10, 48, 48, 48, 48, 48, 48, 51, 52, /* 0x21c0 */
@@ -589,9 +589,9 @@ unsigned char stub_arm_linux_kernel_vmlinux[17091] = {
79, 70, 70, 83, 69, 84, 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, /* 0x2290 */ 79, 70, 70, 83, 69, 84, 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, /* 0x2290 */
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, /* 0x22a0 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, /* 0x22a0 */
10, 48, 48, 48, 48, 48, 48, 48, 56, 32, 82, 95, 65, 82, 77, 95, /* 0x22b0 */ 10, 48, 48, 48, 48, 48, 48, 48, 56, 32, 82, 95, 65, 82, 77, 95, /* 0x22b0 */
65, 66, 83, 56, 32, 32, 32, 32, 32, 32, 32, 32,102,105,108,116, /* 0x22c0 */ 65, 66, 83, 51, 50, 32, 32, 32, 32, 32, 32, 32,102,105,108,116, /* 0x22c0 */
101,114, 95, 99,116,111, 10, 48, 48, 48, 48, 48, 48, 48, 99, 32, /* 0x22d0 */ 101,114, 95, 99,116,111, 10, 48, 48, 48, 48, 48, 48, 48, 99, 32, /* 0x22d0 */
82, 95, 65, 82, 77, 95, 65, 66, 83, 56, 32, 32, 32, 32, 32, 32, /* 0x22e0 */ 82, 95, 65, 82, 77, 95, 65, 66, 83, 51, 50, 32, 32, 32, 32, 32, /* 0x22e0 */
32, 32,102,105,108,116,101,114, 95,105,100, 10, 48, 48, 48, 48, /* 0x22f0 */ 32, 32,102,105,108,116,101,114, 95,105,100, 10, 48, 48, 48, 48, /* 0x22f0 */
48, 48, 49, 48, 32, 82, 95, 65, 82, 77, 95, 80, 67, 50, 52, 32, /* 0x2300 */ 48, 48, 49, 48, 32, 82, 95, 65, 82, 77, 95, 80, 67, 50, 52, 32, /* 0x2300 */
32, 32, 32, 32, 32, 32, 32, 99,116,111,107, 51, 50, 46, 48, 48, /* 0x2310 */ 32, 32, 32, 32, 32, 32, 32, 99,116,111,107, 51, 50, 46, 48, 48, /* 0x2310 */
+3 -3
View File
@@ -29,8 +29,8 @@
#define STUB_ARMEB_LINUX_ELF_ENTRY_SIZE 16295 #define STUB_ARMEB_LINUX_ELF_ENTRY_SIZE 16295
#define STUB_ARMEB_LINUX_ELF_ENTRY_ADLER32 0x87435b9a #define STUB_ARMEB_LINUX_ELF_ENTRY_ADLER32 0xcad35b5a
#define STUB_ARMEB_LINUX_ELF_ENTRY_CRC32 0x7cf93476 #define STUB_ARMEB_LINUX_ELF_ENTRY_CRC32 0xc07dcf2e
unsigned char stub_armeb_linux_elf_entry[16295] = { unsigned char stub_armeb_linux_elf_entry[16295] = {
127, 69, 76, 70, 1, 2, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 2, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
@@ -44,7 +44,7 @@ unsigned char stub_armeb_linux_elf_entry[16295] = {
232,160, 1,254, 58, 0, 0, 15,224, 64, 64, 9,226,143, 80, 80, /* 0x 80 */ 232,160, 1,254, 58, 0, 0, 15,224, 64, 64, 9,226,143, 80, 80, /* 0x 80 */
225,160,224, 0,224,133, 80, 4,225,160, 0, 5,224,137, 16, 4, /* 0x 90 */ 225,160,224, 0,224,133, 80, 4,225,160, 0, 5,224,137, 16, 4, /* 0x 90 */
227,160, 32, 0,239,159, 0, 2,229,156,144, 0,226, 73,144,140, /* 0x a0 */ 227,160, 32, 0,239,159, 0, 2,229,156,144, 0,226, 73,144,140, /* 0x a0 */
224, 76,160, 9,224,138,160, 4,229,219, 0, 8,233, 45, 64, 1, /* 0x b0 */ 224, 76,160, 9,224,138,160, 4,229,155, 0, 8,233, 45, 64, 1, /* 0x b0 */
229,155, 48, 0,226,139, 0, 12,229,155, 16, 4,225,160, 32, 14, /* 0x c0 */ 229,155, 48, 0,226,139, 0, 12,229,155, 16, 4,225,160, 32, 14, /* 0x c0 */
229,141, 48, 8,226,141, 48, 8,225,160,224, 15,225,160,240, 5, /* 0x d0 */ 229,141, 48, 8,226,141, 48, 8,225,160,224, 15,225,160,240, 5, /* 0x d0 */
232,189,128, 2,233, 45, 64,252,224,129,112, 0,227,224, 80, 0, /* 0x e0 */ 232,189,128, 2,233, 45, 64,252,224,129,112, 0,227,224, 80, 0, /* 0x e0 */
@@ -0,0 +1,37 @@
/* armeb-linux.kernel.vmlinux-head.h
created from armeb-linux.kernel.vmlinux-head.bin, 8 (0x8) bytes
This file is part of the UPX executable compressor.
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
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>
*/
#define STUB_ARMEB_LINUX_KERNEL_VMLINUX_HEAD_SIZE 8
#define STUB_ARMEB_LINUX_KERNEL_VMLINUX_HEAD_ADLER32 0x19db0637
#define STUB_ARMEB_LINUX_KERNEL_VMLINUX_HEAD_CRC32 0xb5ec5990
unsigned char stub_armeb_linux_kernel_vmlinux_head[8] = {
225,160,192, 14,235,255,255,254 /* 0x 0 */
};
File diff suppressed because it is too large Load Diff
+1915 -817
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -29,15 +29,15 @@
#define STUB_I386_BSD_ELF_ENTRY_SIZE 37562 #define STUB_I386_BSD_ELF_ENTRY_SIZE 37562
#define STUB_I386_BSD_ELF_ENTRY_ADLER32 0xb6d5917d #define STUB_I386_BSD_ELF_ENTRY_ADLER32 0x0c31915d
#define STUB_I386_BSD_ELF_ENTRY_CRC32 0x57a02d3a #define STUB_I386_BSD_ELF_ENTRY_CRC32 0x68fd1b14
unsigned char stub_i386_bsd_elf_entry[37562] = { unsigned char stub_i386_bsd_elf_entry[37562] = {
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
1, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 10 */ 1, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 10 */
116, 34, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 40, 0, /* 0x 20 */ 116, 34, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 40, 0, /* 0x 20 */
243, 0,240, 0,232,123, 0, 0, 0, 96,139,116, 36, 40,139,124, /* 0x 30 */ 243, 0,240, 0,232,123, 0, 0, 0, 96,139,116, 36, 36,139,124, /* 0x 30 */
36, 48,131,205,255,235, 3,164,235, 3,138, 6, 70,136, 7, 71, /* 0x 40 */ 36, 44,131,205,255,235, 3,164,235, 3,138, 6, 70,136, 7, 71, /* 0x 40 */
1,219,117, 7,139, 30,131,238,252, 17,219,114, 1, 49,192, 64, /* 0x 50 */ 1,219,117, 7,139, 30,131,238,252, 17,219,114, 1, 49,192, 64, /* 0x 50 */
138, 7,114,255,184, 1, 0, 0, 0, 1,219,117, 7,139, 30,131, /* 0x 60 */ 138, 7,114,255,184, 1, 0, 0, 0, 1,219,117, 7,139, 30,131, /* 0x 60 */
238,252, 17,219, 17,192, 1,219,117, 7,139, 30,131,238,252, 17, /* 0x 70 */ 238,252, 17,219, 17,192, 1,219,117, 7,139, 30,131,238,252, 17, /* 0x 70 */
@@ -88,10 +88,10 @@ unsigned char stub_i386_bsd_elf_entry[37562] = {
4,119,241, 1,207,233,252,255,255,255,137,229,141,156, 36, 0, /* 0x 340 */ 4,119,241, 1,207,233,252,255,255,255,137,229,141,156, 36, 0, /* 0x 340 */
0, 0, 0, 49,192, 80, 57,220,117,251, 70, 70, 83,104, 0, 0, /* 0x 350 */ 0, 0, 0, 49,192, 80, 57,220,117,251, 70, 70, 83,104, 0, 0, /* 0x 350 */
0, 0, 87,131,195, 4, 83,104, 0, 0, 0, 0, 86,131,195, 4, /* 0x 360 */ 0, 0, 87,131,195, 4, 83,104, 0, 0, 0, 0, 86,131,195, 4, /* 0x 360 */
83, 80,199, 3, 0, 0, 0, 0,137,229,139, 85, 44,172, 74,136, /* 0x 370 */ 83, 80,199, 3, 0, 0, 0, 0,137,229,139, 85, 40,172, 74,136, /* 0x 370 */
193, 36, 7,192,233, 3,187, 0,253,255,255,211,227,141,164, 92, /* 0x 380 */ 193, 36, 7,192,233, 3,187, 0,253,255,255,211,227,141,164, 92, /* 0x 380 */
144,241,255,255,131,228,224,106, 0,106, 0,137,227, 83,131,195, /* 0x 390 */ 144,241,255,255,131,228,224,106, 0,106, 0,137,227, 83,131,195, /* 0x 390 */
4,139, 77, 52,255, 49, 87, 83,131,195, 4,136, 67, 2,172, 74, /* 0x 3a0 */ 4,139, 77, 48,255, 49, 87, 83,131,195, 4,136, 67, 2,172, 74, /* 0x 3a0 */
136,193, 36, 15,136, 3,192,233, 4,136, 75, 1, 82, 86, 83, 80, /* 0x 3b0 */ 136,193, 36, 15,136, 3,192,233, 4,136, 75, 1, 82, 86, 83, 80, /* 0x 3b0 */
85, 87, 86, 83,131,236,124,139,148, 36,144, 0, 0, 0,199, 68, /* 0x 3c0 */ 85, 87, 86, 83,131,236,124,139,148, 36,144, 0, 0, 0,199, 68, /* 0x 3c0 */
36,116, 0, 0, 0, 0,198, 68, 36,115, 0,139,172, 36,156, 0, /* 0x 3d0 */ 36,116, 0, 0, 0, 0,198, 68, 36,115, 0,139,172, 36,156, 0, /* 0x 3d0 */
@@ -431,8 +431,8 @@ unsigned char stub_i386_bsd_elf_entry[37562] = {
148, 36,156, 0, 0, 0,139, 76, 36,116,137, 26,139,156, 36,168, /* 0x18b0 */ 148, 36,156, 0, 0, 0,139, 76, 36,116,137, 26,139,156, 36,168, /* 0x18b0 */
0, 0, 0,137, 11,131,196,124, 91, 94, 95, 93, 3,115,252, 3, /* 0x18c0 */ 0, 0, 0,137, 11,131,196,124, 91, 94, 95, 93, 3,115,252, 3, /* 0x18c0 */
123,248, 49,192,141,140, 36, 0,255,255,255,137,236, 80, 57,204, /* 0x18d0 */ 123,248, 49,192,141,140, 36, 0,255,255,255,137,236, 80, 57,204, /* 0x18d0 */
117,251,137,236, 49,201,139, 84, 36, 40, 3, 84, 36, 44, 57,214, /* 0x18e0 */ 117,251,137,236, 49,201,139, 84, 36, 36, 3, 84, 36, 40, 57,214, /* 0x18e0 */
116, 1, 72, 43,124, 36, 48,139, 84, 36, 52,137, 58,137, 68, 36, /* 0x18f0 */ 116, 1, 72, 43,124, 36, 44,139, 84, 36, 48,137, 58,137, 68, 36, /* 0x18f0 */
28, 97,195,235, 4, 90, 88, 89,151, 96, 49,219,187, 0, 0, 0, /* 0x1900 */ 28, 97,195,235, 4, 90, 88, 89,151, 96, 49,219,187, 0, 0, 0, /* 0x1900 */
0,106, 15, 88,138,100, 36, 32,106, 15, 91,138,124, 36, 32,138, /* 0x1910 */ 0,106, 15, 88,138,100, 36, 32,106, 15, 91,138,124, 36, 32,138, /* 0x1910 */
84, 36, 32,233,252,255,255,255, 15,183, 47, 43,110, 12, 41,221, /* 0x1920 */ 84, 36, 32,233,252,255,255,255, 15,183, 47, 43,110, 12, 41,221, /* 0x1920 */
File diff suppressed because it is too large Load Diff
+106
View File
@@ -0,0 +1,106 @@
/* i386-darwin.macho-fold.h
created from i386-darwin.macho-fold.bin, 1105 (0x451) bytes
This file is part of the UPX executable compressor.
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
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>
*/
#define STUB_I386_DARWIN_MACHO_FOLD_SIZE 1105
#define STUB_I386_DARWIN_MACHO_FOLD_ADLER32 0x5ad106a1
#define STUB_I386_DARWIN_MACHO_FOLD_CRC32 0x01a4878b
unsigned char stub_i386_darwin_macho_fold[1105] = {
106, 0,137,231,141,117, 2,139, 19,137,217, 41,209,139, 89, 24, /* 0x 0 */
184, 0, 8, 0, 0, 57,216,118, 2,137,195, 41,220, 96,232, 6, /* 0x 10 */
3, 0, 0,139, 76, 36, 16,141,100, 12, 32,255, 96, 40,139, 68, /* 0x 20 */
36, 4,139, 76, 36, 8,139, 16, 15,202,137, 16,131,233, 4,141, /* 0x 30 */
64, 4,115,242,195, 90, 15, 52,176, 1,235, 2,176, 74,235, 2, /* 0x 40 */
176, 73,235, 2,176,153,235, 2,176, 6,235, 2,176, 5,235, 2, /* 0x 50 */
176,197,235, 2,176, 3, 15,182,192,137,225,232,213,255,255,255, /* 0x 60 */
115, 3,131,200,255,195,144,144, 85,137,229, 87, 86,139,125, 8, /* 0x 70 */
83,137,195, 57, 56,139,112, 4,115, 7,106,127,232,183,255,255, /* 0x 80 */
255,133,255,116, 10,137,249,138, 6, 70,136, 2, 66,226,248, 1, /* 0x 90 */
123, 4, 41, 59,141,101,244, 91, 94, 95,201,195, 85,137,229, 87, /* 0x a0 */
86,137,198, 83,137,211,131,236, 24,139, 69, 8,139,125, 12,137, /* 0x b0 */
69,220,131, 58, 0, 15,132,172, 0, 0, 0,141, 85,228,137,240, /* 0x c0 */
106, 12,232,161,255,255,255,139, 69,228, 90,133,192,139, 77,232, /* 0x d0 */
117, 19,129,249, 85, 80, 88, 33,117, 15,131, 62, 0, 15,132,132, /* 0x e0 */
0, 0, 0,235, 4,133,201,117, 7,106,127,232, 72,255,255,255, /* 0x f0 */
57,193,119,245, 59, 3,119,241, 57,193,115, 76,137, 69,224, 15, /* 0x 100 */
182, 69,236, 80,141, 69,224, 80,255,115, 4, 81,255,118, 4,255, /* 0x 110 */
85,220,131,196, 20,133,192,117,208,139, 85,224, 59, 85,228,117, /* 0x 120 */
200,138, 69,237,132,192,116, 22,133,255,116, 18, 15,182,192, 80, /* 0x 130 */
15,182, 69,238, 80, 82,255,115, 4,255,215,131,196, 16,139, 69, /* 0x 140 */
232, 1, 70, 4, 41, 6,235, 12,139, 83, 4, 81,137,240,232, 21, /* 0x 150 */
255,255,255, 88,139, 85,228,139, 3, 1, 83, 4, 41,208,133,192, /* 0x 160 */
137, 3,233, 78,255,255,255,141,101,244, 91, 94, 95,201,195, 85, /* 0x 170 */
137,229, 87, 86, 83,131,236, 48,137, 69,232,139, 69, 8,137, 85, /* 0x 180 */
228,139, 85, 12,199, 69,208, 0, 0, 0, 0,137, 69,224,139, 69, /* 0x 190 */
20,137, 85,220,139, 85, 24,137, 69,216,139, 93,232,139, 69,232, /* 0x 1a0 */
137, 85,212, 49,210,131,195, 28,199, 69,204, 0, 0, 0, 0, 59, /* 0x 1b0 */
80, 16, 15,131, 86, 1, 0, 0,139, 3,131,248, 1, 15,133, 29, /* 0x 1c0 */
1, 0, 0,139, 83, 24,139, 67, 28,139, 75, 36,137,214, 1,208, /* 0x 1d0 */
137, 85,240,137, 69,200,137,208, 37,255, 15, 0, 0,137,207, 41, /* 0x 1e0 */
198, 1,199,137, 77,236,116, 69,139, 69,228, 49,210, 3, 67, 32, /* 0x 1f0 */
82,133,201, 80,139, 69,220,117, 3,131,200,255,131,125,224, 0, /* 0x 200 */
80,117, 9,133,201,184, 18, 0, 0, 0,117, 5,184, 18, 16, 0, /* 0x 210 */
0,131,125,224, 0, 80,106, 3,137,248,116, 3,141, 71, 3, 80, /* 0x 220 */
86,232, 42,254,255,255,131,196, 28, 57,198,117, 94,131,125,224, /* 0x 230 */
0,116, 42,131,123, 36, 0,116, 36,131,123, 32, 0,117, 11,131, /* 0x 240 */
125, 16, 0,116, 5,139, 85, 16,137, 50,255,117,212,255,117,216, /* 0x 250 */
141, 85,236,139, 69,224,232, 65,254,255,255, 88, 90,137,248,141, /* 0x 260 */
20, 62,247,216, 37,255, 15, 0, 0,137, 69,196,116, 8,137,193, /* 0x 270 */
198, 2, 0, 66,226,250,133,255,116, 24,255,115, 44, 87, 86,232, /* 0x 280 */
184,253,255,255,131,196, 12,133,192,116, 7,106,127,232,166,253, /* 0x 290 */
255,255,139, 85,196,141, 4, 23, 1,198, 59,117,200,115, 35,106, /* 0x 2a0 */
0,106, 0,106,255,104, 18, 16, 0, 0,255,115, 44, 41,117,200, /* 0x 2b0 */
255,117,200, 86,232,151,253,255,255,131,196, 28, 57,198,116, 58, /* 0x 2c0 */
235,201,131,125,224, 0,116, 50,141, 71, 3, 37,255, 15, 0, 0, /* 0x 2d0 */
131,248, 3,119, 37, 80, 86,232,100,253,255,255, 89, 94,235, 26, /* 0x 2e0 */
131,232, 4,131,248, 1,119, 18,131,123, 8, 1,117, 12,131,123, /* 0x 2f0 */
12, 16,117, 6,141, 67, 16,137, 69,208,255, 69,204,139, 85,232, /* 0x 300 */
139, 69,204, 3, 91, 4, 59, 66, 16,233,164,254,255,255,139, 69, /* 0x 310 */
208,141,101,244, 91, 94, 95,201,195, 85,137,229, 87, 86, 83,131, /* 0x 320 */
236, 32,199, 69,212, 0, 0, 0, 0,139, 85, 32,139, 69, 24,139, /* 0x 330 */
93, 16,137, 69,216,139,117, 20,141, 66, 24,137,117,232,137, 69, /* 0x 340 */
240,139, 69, 28,131,232, 24,137, 69,236,139, 66, 24,139, 85,240, /* 0x 350 */
106, 0,137, 69,228,139, 69,236,137, 85,224,137, 69,220,141, 85, /* 0x 360 */
228,141, 69,236, 83,232, 50,253,255,255,255,117, 12, 83, 49,210, /* 0x 370 */
255,117, 8,141, 69,220,106,255, 80,137,240,232,239,253,255,255, /* 0x 380 */
49,210,137,195,141, 70, 28,131,196, 28,139, 78, 16, 57,202, 15, /* 0x 390 */
131,162, 0, 0, 0,131, 56, 14, 15,133,144, 0, 0, 0, 3, 64, /* 0x 3a0 */
8,106, 0,106, 0, 80,232,161,252,255,255,131,196, 12,133,192, /* 0x 3b0 */
137,199,120, 25, 49,210,139, 69,212, 82, 80,255,117,216, 86, 87, /* 0x 3c0 */
232,127,252,255,255,131,196, 20, 57, 69,216,116, 15,106,127,232, /* 0x 3d0 */
100,252,255,255,139, 91, 8,137, 93,212,235,216,129, 62,202,254, /* 0x 3e0 */
186,190,117, 42, 15,182, 70, 7,141, 94, 8,107,192, 20,131,192, /* 0x 3f0 */
8, 80, 86,232, 38,252,255,255, 89, 90, 49,192,139, 86, 4, 57, /* 0x 400 */
208,115, 11,131, 59, 7,116,204, 64,131,195, 20,235,241,106, 0, /* 0x 410 */
139, 85,212,106, 0,137,240,106, 0, 87,106, 0,232, 78,253,255, /* 0x 420 */
255, 87,137,195,232, 31,252,255,255,131,196, 24,235, 9, 3, 64, /* 0x 430 */
4, 66,233, 86,255,255,255,141,101,244,137,216, 91, 94, 95,201, /* 0x 440 */
195 /* 0x 450 */
};
+3 -3
View File
@@ -29,8 +29,8 @@
#define STUB_I386_DOS32_TMT_SIZE 27032 #define STUB_I386_DOS32_TMT_SIZE 27032
#define STUB_I386_DOS32_TMT_ADLER32 0xe058a94c #define STUB_I386_DOS32_TMT_ADLER32 0x60faa944
#define STUB_I386_DOS32_TMT_CRC32 0x76e13290 #define STUB_I386_DOS32_TMT_CRC32 0x1e38f90e
unsigned char stub_i386_dos32_tmt[27032] = { unsigned char stub_i386_dos32_tmt[27032] = {
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
@@ -444,7 +444,7 @@ unsigned char stub_i386_dos32_tmt[27032] = {
0, 0,235, 30,138, 7,131,199, 1, 60,128,114, 10, 60,143,119, /* 0x1980 */ 0, 0,235, 30,138, 7,131,199, 1, 60,128,114, 10, 60,143,119, /* 0x1980 */
6,128,127,254, 15,116, 5, 44,232, 60, 1,119,255,128, 63, 0, /* 0x1990 */ 6,128,127,254, 15,116, 5, 44,232, 60, 1,119,255,128, 63, 0, /* 0x1990 */
117,255,139, 7,102,193,232, 8,193,192, 16,134,196, 41,248, 1, /* 0x19a0 */ 117,255,139, 7,102,193,232, 8,193,192, 16,134,196, 41,248, 1, /* 0x19a0 */
240,137, 7,131,199, 4,131,233, 4,138, 7,131,199, 1,226, 13, /* 0x19b0 */ 232,137, 7,131,199, 4,131,233, 4,138, 7,131,199, 1,226, 13, /* 0x19b0 */
131,233, 1,127, 6,141,125,252, 49,192,138, 6, 70, 9,192,116, /* 0x19c0 */ 131,233, 1,127, 6,141,125,252, 49,192,138, 6, 70, 9,192,116, /* 0x19c0 */
1, 60,239,119, 17, 1,199,139, 7,134,196,193,192, 16,134,196, /* 0x19d0 */ 1, 60,239,119, 17, 1,199,139, 7,134,196,193,192, 16,134,196, /* 0x19d0 */
1,232,137, 7,235,226, 36, 15,193,224, 16,102,139, 6,131,198, /* 0x19e0 */ 1,232,137, 7,235,226, 36, 15,193,224, 16,102,139, 6,131,198, /* 0x19e0 */
+3 -3
View File
@@ -29,8 +29,8 @@
#define STUB_I386_DOS32_WATCOM_LE_SIZE 27436 #define STUB_I386_DOS32_WATCOM_LE_SIZE 27436
#define STUB_I386_DOS32_WATCOM_LE_ADLER32 0x1fda144c #define STUB_I386_DOS32_WATCOM_LE_ADLER32 0x946d1444
#define STUB_I386_DOS32_WATCOM_LE_CRC32 0xd84b8031 #define STUB_I386_DOS32_WATCOM_LE_CRC32 0x39b33888
unsigned char stub_i386_dos32_watcom_le[27436] = { unsigned char stub_i386_dos32_watcom_le[27436] = {
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
@@ -445,7 +445,7 @@ unsigned char stub_i386_dos32_watcom_le[27436] = {
4,185, 0, 0, 0, 0,235, 30,138, 7,131,199, 1, 60,128,114, /* 0x1990 */ 4,185, 0, 0, 0, 0,235, 30,138, 7,131,199, 1, 60,128,114, /* 0x1990 */
10, 60,143,119, 6,128,127,254, 15,116, 5, 44,232, 60, 1,119, /* 0x19a0 */ 10, 60,143,119, 6,128,127,254, 15,116, 5, 44,232, 60, 1,119, /* 0x19a0 */
255,128, 63, 0,117,255,139, 7,102,193,232, 8,193,192, 16,134, /* 0x19b0 */ 255,128, 63, 0,117,255,139, 7,102,193,232, 8,193,192, 16,134, /* 0x19b0 */
196, 41,248, 1,240,137, 7,131,199, 4,131,233, 4,138, 7,131, /* 0x19c0 */ 196, 41,248, 1,232,137, 7,131,199, 4,131,233, 4,138, 7,131, /* 0x19c0 */
199, 1,226, 13,131,233, 1,127, 6,141,125,252, 49,192,138, 6, /* 0x19d0 */ 199, 1,226, 13,131,233, 1,127, 6,141,125,252, 49,192,138, 6, /* 0x19d0 */
70, 9,192,116, 1, 60,239,119, 17, 1,199,139, 7,134,196,193, /* 0x19e0 */ 70, 9,192,116, 1, 60,239,119, 17, 1,199,139, 7,134,196,193, /* 0x19e0 */
192, 16,134,196, 1,232,137, 7,235,226, 36, 15,193,224, 16,102, /* 0x19f0 */ 192, 16,134,196, 1,232,137, 7,235,226, 36, 15,193,224, 16,102, /* 0x19f0 */
+3 -3
View File
@@ -29,11 +29,11 @@
#define STUB_I386_LINUX_ELF_FOLD_SIZE 1691 #define STUB_I386_LINUX_ELF_FOLD_SIZE 1691
#define STUB_I386_LINUX_ELF_FOLD_ADLER32 0xe27fd53e #define STUB_I386_LINUX_ELF_FOLD_ADLER32 0x5710d32e
#define STUB_I386_LINUX_ELF_FOLD_CRC32 0x75829ac3 #define STUB_I386_LINUX_ELF_FOLD_CRC32 0xcf21929e
unsigned char stub_i386_linux_elf_fold[1691] = { unsigned char stub_i386_linux_elf_fold[1691] = {
127, 69, 76, 70, 1, 1, 1, 0, 76,105,110,117,120, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
2, 0, 3, 0, 1, 0, 0, 0,128, 16,192, 0, 52, 0, 0, 0, /* 0x 10 */ 2, 0, 3, 0, 1, 0, 0, 0,128, 16,192, 0, 52, 0, 0, 0, /* 0x 10 */
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */ 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16,192, 0, /* 0x 30 */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16,192, 0, /* 0x 30 */
+3 -3
View File
@@ -29,11 +29,11 @@
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_SIZE 931 #define STUB_I386_LINUX_ELF_EXECVE_FOLD_SIZE 931
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_ADLER32 0x488877dc #define STUB_I386_LINUX_ELF_EXECVE_FOLD_ADLER32 0xdce475cc
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_CRC32 0x399780ea #define STUB_I386_LINUX_ELF_EXECVE_FOLD_CRC32 0x512b1d3a
unsigned char stub_i386_linux_elf_execve_fold[931] = { unsigned char stub_i386_linux_elf_execve_fold[931] = {
127, 69, 76, 70, 1, 1, 1, 0, 76,105,110,117,120, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x 10 */ 2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x 10 */
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */ 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16, 64, 0, /* 0x 30 */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16, 64, 0, /* 0x 30 */
+3 -3
View File
@@ -29,11 +29,11 @@
#define STUB_I386_LINUX_ELF_INTERP_FOLD_SIZE 1519 #define STUB_I386_LINUX_ELF_INTERP_FOLD_SIZE 1519
#define STUB_I386_LINUX_ELF_INTERP_FOLD_ADLER32 0xe82498de #define STUB_I386_LINUX_ELF_INTERP_FOLD_ADLER32 0xbf8496ce
#define STUB_I386_LINUX_ELF_INTERP_FOLD_CRC32 0xd7e223de #define STUB_I386_LINUX_ELF_INTERP_FOLD_CRC32 0xe6675cdc
unsigned char stub_i386_linux_elf_interp_fold[1519] = { unsigned char stub_i386_linux_elf_interp_fold[1519] = {
127, 69, 76, 70, 1, 1, 1, 0, 76,105,110,117,120, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
2, 0, 3, 0, 1, 0, 0, 0,116, 0, 1, 0, 52, 0, 0, 0, /* 0x 10 */ 2, 0, 3, 0, 1, 0, 0, 0,116, 0, 1, 0, 52, 0, 0, 0, /* 0x 10 */
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */ 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 0x 30 */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 0x 30 */
+3 -3
View File
@@ -29,11 +29,11 @@
#define STUB_I386_LINUX_ELF_SHELL_FOLD_SIZE 1194 #define STUB_I386_LINUX_ELF_SHELL_FOLD_SIZE 1194
#define STUB_I386_LINUX_ELF_SHELL_FOLD_ADLER32 0x63b3f90a #define STUB_I386_LINUX_ELF_SHELL_FOLD_ADLER32 0xd981f6fa
#define STUB_I386_LINUX_ELF_SHELL_FOLD_CRC32 0xe2bc019d #define STUB_I386_LINUX_ELF_SHELL_FOLD_CRC32 0x5d287cd0
unsigned char stub_i386_linux_elf_shell_fold[1194] = { unsigned char stub_i386_linux_elf_shell_fold[1194] = {
127, 69, 76, 70, 1, 1, 1, 0, 76,105,110,117,120, 0, 0, 0, /* 0x 0 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x 10 */ 2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x 10 */
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */ 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, /* 0x 30 */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, /* 0x 30 */
+1320 -1297
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -67,7 +67,8 @@ def do_file(fn):
elif opts.bfdname == "elf32-i386" and opts.elfosabi == "linux": elif opts.bfdname == "elf32-i386" and opts.elfosabi == "linux":
if e_ident[4:7] != "\x01\x01\x01": if e_ident[4:7] != "\x01\x01\x01":
raise Exception, "%s is not %s" % (fn, opts.bfdname) raise Exception, "%s is not %s" % (fn, opts.bfdname)
write("\x00Linux\x00\x00\x00") ##write("\x00Linux\x00\x00\x00")
write("\x00" * 9)
elif opts.bfdname == "elf32-i386" and opts.elfosabi == "openbsd": elif opts.bfdname == "elf32-i386" and opts.elfosabi == "openbsd":
if e_ident[4:7] != "\x01\x01\x01": if e_ident[4:7] != "\x01\x01\x01":
raise Exception, "%s is not %s" % (fn, opts.bfdname) raise Exception, "%s is not %s" % (fn, opts.bfdname)
@@ -75,11 +76,13 @@ def do_file(fn):
elif opts.bfdname == "elf32-powerpc" and opts.elfosabi == "linux": elif opts.bfdname == "elf32-powerpc" and opts.elfosabi == "linux":
if e_ident[4:7] != "\x01\x02\x01": if e_ident[4:7] != "\x01\x02\x01":
raise Exception, "%s is not %s" % (fn, opts.bfdname) raise Exception, "%s is not %s" % (fn, opts.bfdname)
write("\x00Linux\x00\x00\x00") ##write("\x00Linux\x00\x00\x00")
write("\x00" * 9)
elif opts.bfdname == "elf64-x86_64" and opts.elfosabi == "linux": elif opts.bfdname == "elf64-x86_64" and opts.elfosabi == "linux":
if e_ident[4:7] != "\x02\x01\x01": if e_ident[4:7] != "\x02\x01\x01":
raise Exception, "%s is not %s" % (fn, opts.bfdname) raise Exception, "%s is not %s" % (fn, opts.bfdname)
write("\x00Linux\x00\x00\x00") ##write("\x00Linux\x00\x00\x00")
write("\x00" * 9)
else: else:
done = 0 done = 0
else: else:
+3
View File
@@ -88,6 +88,7 @@ def create_bindump(bindump_fn, dump_fn):
e = f[1], int(f[2], 16), int(f[5], 16), int(f[6][3:], 10), len(sections) e = f[1], int(f[2], 16), int(f[5], 16), int(f[6][3:], 10), len(sections)
sections.append(e) sections.append(e)
assert not section_names.has_key(e[0]), e assert not section_names.has_key(e[0]), e
assert not e[0].endswith(":"), ("bad section name", e)
section_names[e[0]] = e section_names[e[0]] = e
##print sections ##print sections
# preprocessSymbols # preprocessSymbols
@@ -100,6 +101,8 @@ def create_bindump(bindump_fn, dump_fn):
assert f[1] in "gl", (l, f) assert f[1] in "gl", (l, f)
assert f[2] in "dFO", (l, f) assert f[2] in "dFO", (l, f)
section = section_names[f[3]] section = section_names[f[3]]
elif len(f) == 5 and f[2] == "*ABS*":
pass
elif len(f) == 5: elif len(f) == 5:
assert f[1] in "gl", (l, f) assert f[1] in "gl", (l, f)
section = section_names[f[2]] section = section_names[f[2]]
+1
View File
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3) __dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND) top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c vpath %.c $(top_srcdir)/src/stub/src/c
STUBS = STUBS =
+1
View File
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3) __dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND) top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c vpath %.c $(top_srcdir)/src/stub/src/c
STUBS = STUBS =
+1
View File
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3) __dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND) top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c vpath %.c $(top_srcdir)/src/stub/src/c
STUBS = STUBS =
+1 -1
View File
@@ -35,7 +35,7 @@
.endm .endm
.macro loadcon8 reg,val8 .macro loadcon8 reg,val8
.byte \val8, \reg<<4, 0xa0, 0xe3 /* mov \reg,#\val8 */ .long (0xe3<<24)|(0xa0<<16)|((\reg<<4)<<8)+(\val8) /* mov \reg,#\val8 */
.endm .endm
// vi:ts=8:et:nowrap // vi:ts=8:et:nowrap
+291
View File
@@ -0,0 +1,291 @@
#
# highly experimental support for i086 using Open Watcom C/C++
#
##export WATCOM ?= /opt/cc-i386-linux/watcom/open-watcom-1.6
#
MAKEFLAGS += -rR
.SUFFIXES:
.SECONDEXPANSION:
ifndef top_srcdir
__dir_list = . .. ../.. ../../.. ../../../.. ../../../../..
__dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c
STUBS =
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
STUBS += lzma_d_cf.S lzma_d_cs.S
endif
endif
default.targets = all
ifeq ($(strip $(STUBS)),)
STUBS = NO_STUBS
all.targets =
endif
include $(top_srcdir)/src/stub/Makefile
# /***********************************************************************
# //
# ************************************************************************/
# enumerate the names of all environment variables
# FIXME: "origin" does not work for things like "export LC_ALL = C"
##__minienv_varlist = $(foreach v,$1,$(if $(findstring environment,$(origin $v)),$v))
__minienv_varlist = $(foreach v,$1,$(if $($v),$v))
# enumerate the names of all environment variables
__minienv_expand = $(foreach v,$(call __minienv_varlist,$1),$v='$($v)')
DOSBOX = true
DOSBOX = dosbox
DOSBOX = /usr/bin/time -p dosbox -exit
ifneq ($(wildcard /usr/bin/wine),)
WINEENV = @env
WINEENV = @env -i $(call __minienv_expand,DISPLAY HOME PATH USER TERM)
winedir_s = z:$(shell winepath -s $(realpath $1))
winedir_w = $(shell winepath -w $(realpath $1))
else
WINEENV = false 'WINEENV'
winedir_s = $1
winedir_w = $1
endif
# work around limitations of wine's cmd.exe
define mkbat
echo -E '@set PATH=$3;%PATH%' > $1
echo -E '@set INCLUDE=$4' >> $1
echo -E '@set LIB=$5' >> $1
echo -E '@set a=%1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
echo -e '@shift\n@shift\n@shift\n@shift\n@shift' >> $1
echo -e '@shift\n@shift\n@shift\n@shift' >> $1
echo -E '@set b=%1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
echo -e '@shift\n@shift\n@shift\n@shift\n@shift' >> $1
echo -e '@shift\n@shift\n@shift\n@shift' >> $1
echo -E '$2 %a% %b% %1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
$(UNIX2DOS) $1
endef
TMP_DEPS = tmp/.tmp-stamp tmp/bcc.bat tmp/cl.bat tmp/dmc.bat
tmp/bcc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
@$(call mkbat,$@,bcc.exe,$(call winedir_w,$(BC502DIR)/bin))
tmp/cl.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
@$(call mkbat,$@,cl.exe,$(call winedir_w,$(VC152DIR)/bin),$(call winedir_w,$(VC152DIR)/include),$(call winedir_w,$(VC152DIR)/lib))
tmp/dmc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
@$(call mkbat,$@,dmc.exe,$(call winedir_w,$(DM849DIR)/bin))
# /***********************************************************************
# // method-lzma
# ************************************************************************/
lzma_d_c% : tc_list = method-lzma arch-i086 default
lzma_d_c% : tc_bfdname =
# gcc
c := tc.arch-i086.gcc
$c += -MF /dev/null
$c += -Wall -W
$c += -I$(UPX_LZMADIR)
$c += -I$(top_srcdir)/src
# Borland C/C++ 5.02
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
c := tc.method-lzma.bcc
$c = $(WINEENV) wine cmd.exe /c tmp/bcc.bat
$c += -ms
$c += -O1 -1
$c += -w
$c += -D__INT_MAX__=32767
$c += -I$(subst \,/,$(call winedir_w,$(UPX_LZMADIR)/C/7zip/Compress/LZMA_C))
$c += -I$(top_srcdir)/src
endif
# Digital Mars C/C++ 8.49
# http://www.digitalmars.com/download/freecompiler.html
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
c := tc.method-lzma.dmc
$c = $(WINEENV) CFLAGS='$(DMC)' wine cmd.exe /c tmp/dmc.bat
$c += -ms -R
$c += -NS
$c += -w- -w7 -r
DMC := -o -0
DMC += -D__INT_MAX__=32767
DMC += -I$(call winedir_w,$(UPX_LZMADIR))
DMC += -I$(call winedir_w,$(top_srcdir)/src)
endif
# Visual C/C++ 1.52 (8.00c)
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
c := tc.method-lzma.cl
$c = $(WINEENV) CL='$(CL)' wine cmd.exe /c tmp/cl.bat
$c += -AS -Gd
$c += -Gy
$c += -O2 -Gf -Gs -G0
$c += -W4
CL := -nologo
CL += -D__INT_MAX__=32767
CL += -I$(call winedir_s,$(UPX_LZMADIR))
CL += -I$(call winedir_s,$(top_srcdir)/src)
endif
# Open Watcom C/C++ 1.6
# http://www.openwatcom.com/
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
c := tc.method-lzma.wcl
$c = PATH='$(WATCOM)/binl:$(PATH)' $(WATCOM)/binl/wcl -zq -bt=dos
$c += -ms -ecc
$c += -zm -zc
$c += -os -s -0 -d0
$c += -w5 -we -fr=/dev/null
$c += -D__INT_MAX__=32767
$c += -I$(UPX_LZMADIR)
$c += -I$(top_srcdir)/src
endif
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
lzma_d_c%.S : tmp/lzma_d_c%.i cleanasm.py $(MAKEFILE_LIST)
$(PYTHON) cleanasm.py --label-prefix=$(LABEL_PREFIX) $< $@
tmp/lzma_d_c%.i : lzma_d_c.c wdis2gas.py $(MAKEFILE_LIST) $(TMP_DEPS)
rm -f tmp/$T*.i tmp/$T*.o tmp/$T*.obj tmp/$T*.S
# compile
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
## $(call tc,bcc) $(PP_FLAGS) -c -otmp/$T_bc.obj $<
## $(call tc,wdis) tmp/$T_bc.obj | $(RTRIM) > tmp/$T_bc.obj.disasm
endif
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
$(call tc,dmc) $(PP_FLAGS) -c -otmp/$T_dm.obj $<
$(call tc,wdis) tmp/$T_dm.obj | $(RTRIM) > tmp/$T_dm.obj.disasm
endif
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
$(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T_vc.obj $<
$(call tc,wdis) tmp/$T_vc.obj | $(RTRIM) > tmp/$T_vc.obj.disasm
endif
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
$(call tc,wcl) $(PP_FLAGS) -c -fo=tmp/$T_wc.obj $<
$(call tc,wdis) tmp/$T_wc.obj | $(RTRIM) > tmp/$T_wc.obj.disasm
endif
# convert
$(PYTHON) wdis2gas.py tmp/$T_wc.obj.disasm tmp/$T.S
$(call tc,gcc) -c -o tmp/$T.o tmp/$T.S
$(call tc,f-objstrip,tmp/$T.o)
$(call tc,objdump) -b elf32-i386 -m i8086 -M intel -dr -j .text.LzmaDecode --no-show -w tmp/$T.o | $(RTRIM) | perl -pe 's/DWORD/dword/g; s/WORD/word/g; s/BYTE/byte/g; s/PTR/ptr/g;' > $@
.PRECIOUS: lzma_d_c%.i tmp/lzma_d_c%.i
endif
endif
lzma_d_cf.% : PP_FLAGS = -DFAST
lzma_d_cs.% : PP_FLAGS = -DSMALL
lzma_d_cf.% : LABEL_PREFIX = .Lf
lzma_d_cs.% : LABEL_PREFIX = .Ls
# /***********************************************************************
# // cc_test
# ************************************************************************/
ifneq ($(wildcard $(WATCOM)/binl/wdis),)
CC_TEST_DEPS = $(MAKEFILE_LIST) $(TMP_DEPS)
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
cc_test_bc : tc_list = method-lzma arch-i086 default
cc_test_bc: cc_test.c $(CC_TEST_DEPS)
$(call tc,bcc) $(PP_FLAGS) -c -otmp/$T.obj $<
$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
cc_test_all: cc_test_bc
endif
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
cc_test_dm : tc_list = method-lzma arch-i086 default
cc_test_dm: cc_test.c $(CC_TEST_DEPS)
$(call tc,dmc) $(PP_FLAGS) -c -otmp/$T.obj $<
$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
cc_test_all: cc_test_dm
endif
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
cc_test_vc : tc_list = method-lzma arch-i086 default
cc_test_vc: cc_test.c $(CC_TEST_DEPS)
$(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T.obj $<
$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
cc_test_all: cc_test_vc
endif
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
cc_test_wc : tc_list = method-lzma arch-i086 default
cc_test_wc: cc_test.c $(CC_TEST_DEPS)
$(call tc,wcl) $(PP_FLAGS) -c -fo=tmp/$T.obj $<
$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
cc_test_all: cc_test_wc
endif
.PHONY: cc_test_all
endif # wdis
# /***********************************************************************
# // l_test
# ************************************************************************/
L_TEST_DEPS = lzma_d_c.c $(MAKEFILE_LIST) $(TMP_DEPS)
tmp/l_test_gcc_i386.% : tc_list = arch-i086 default
tmp/l_test_gcc_i386.out: l_test.c $(L_TEST_DEPS)
$(call tc,gcc) -O0 -g -o $@ $<
./$@
l_test_all: tmp/l_test_gcc_i386.out
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
tmp/l_test_bc.% : tc_list = method-lzma arch-i086 default
tmp/l_test_bc.exe: l_test.c $(L_TEST_DEPS)
$(call tc,bcc) -o$(subst /,\\,$@) $<
@rm -f l_test.o l_test.obj
cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
##l_test_all: tmp/l_test_bc.exe
endif
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
tmp/l_test_dm.% : tc_list = method-lzma arch-i086 default
tmp/l_test_dm.exe: l_test.c $(L_TEST_DEPS)
$(call tc,dmc) -ml -o$(subst /,\\,$@) $<
@rm -f l_test.o l_test.obj
cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
l_test_all: tmp/l_test_dm.exe
endif
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
tmp/l_test_vc.% : tc_list = method-lzma arch-i086 default
tmp/l_test_vc.exe: l_test.c $(L_TEST_DEPS)
$(call tc,cl) -Fe$(subst /,\\,$@) $<
@rm -f l_test.o l_test.obj
cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
l_test_all: tmp/l_test_vc.exe
endif
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
tmp/l_test_wc.% : tc_list = method-lzma arch-i086 default
tmp/l_test_wc.exe: l_test.c $(L_TEST_DEPS)
$(call tc,wcl) -fe=$@ $<
@rm -f l_test.o l_test.obj
cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
l_test_all: tmp/l_test_wc.exe
endif
.PHONY: l_test_all
+110
View File
@@ -0,0 +1,110 @@
/* cc_test.c -- examine compiler-generated library calls
This file is part of the UPX executable compressor.
Copyright (C) 2006-2007 Markus Franz Xaver Johannes Oberhumer
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
<mfx@users.sourceforge.net>
*/
#if 0 && defined(__WATCOMC__)
#define __cdecl __watcall
#endif
/*************************************************************************
//
**************************************************************************/
typedef short int16_t;
typedef unsigned short uint16_t;
typedef long int32_t;
typedef unsigned long uint32_t;
#if 1
// simulated 32-bit pointer
typedef char __huge* hptr;
typedef long hptrdiff_t;
typedef unsigned long hsize_t;
#elif 1
// ignore segment overflow
typedef char __far* hptr;
typedef long hptrdiff_t;
typedef unsigned long hsize_t;
#else
// no segment
typedef char __near* hptr;
typedef short hptrdiff_t;
typedef unsigned short hsize_t;
#endif
// pia - pointer add
hptr __cdecl pia(hptr a, hsize_t d) { return a + d; }
hptr __cdecl pia1(hptr a) { return a + 1; }
// pis - pointer subtract
hptr __cdecl pis(hptr a, hsize_t d) { return a - d; }
hptr __cdecl pis1(hptr a) { return a - 1; }
// pts - pointer diff
hptrdiff_t __cdecl pts(hptr a, hptr b) { return a - b; }
// ptc - pointer compare (__PTC sets zero and carry flags)
int __cdecl ptc_eq(hptr a, hptr b) { return a == b; }
int __cdecl ptc_ne(hptr a, hptr b) { return a != b; }
int __cdecl ptc_lt(hptr a, hptr b) { return a < b; }
int __cdecl ptc_le(hptr a, hptr b) { return a <= b; }
int __cdecl ptc_gt(hptr a, hptr b) { return a > b; }
int __cdecl ptc_ge(hptr a, hptr b) { return a >= b; }
// u4m - unsigned multiplication
uint32_t __cdecl u4m(uint32_t a, uint32_t b) { return a * b; }
uint32_t __pascal u4m_p(uint32_t a, uint32_t b) { return b * a; }
// i4m - signed multiplication
int32_t __cdecl i4m(int32_t a, int32_t b) { return a * b; }
int32_t __pascal i4m_p(int32_t a, int32_t b) { return b * a; }
// just for testing
uint16_t __cdecl u2m(uint16_t a, uint16_t b) { return a * b; }
int16_t __cdecl i2m(int16_t a, int16_t b) { return a * b; }
uint32_t __cdecl u2m4(uint16_t a, uint16_t b) { return a * b; }
int32_t __cdecl i2m4(int16_t a, int16_t b) { return a * b; }
uint16_t __cdecl u2shl8 (uint16_t a) { return a << 8; }
uint32_t __cdecl u4shl8 (uint32_t a) { return a << 8; }
uint16_t __cdecl u2shl12(uint16_t a) { return a << 12; }
uint32_t __cdecl u4shl12(uint32_t a) { return a << 12; }
uint32_t __cdecl u4shl16(uint32_t a) { return a << 16; }
uint32_t __cdecl u4shl24(uint32_t a) { return a << 24; }
uint16_t __cdecl u2shlv(uint16_t a, unsigned v) { return a << v; }
uint32_t __cdecl u4shlv(uint32_t a, unsigned v) { return a << v; }
void __pascal p4nshlv_v(unsigned char v, uint32_t __near *a) { *a <<= v; }
void __pascal p4fshlv_v(unsigned char v, uint32_t __far *a) { *a <<= v; }
uint32_t __pascal p4nshlv(unsigned char v, uint32_t __near *a) { return *a <<= v; }
uint32_t __pascal p4fshlv(unsigned char v, uint32_t __far *a) { return *a <<= v; }
hptrdiff_t __cdecl hptr2int(hptr a) { return (hptrdiff_t) a; }
hptr __cdecl int2hptr(hptrdiff_t a) { return (hptr) a; }
/* vim:set ts=4 et: */
+409
View File
@@ -0,0 +1,409 @@
#! /usr/bin/env python
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
#
# cleanasm.py --
#
# This file is part of the UPX executable compressor.
#
# Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
# 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>
#
import getopt, os, re, string, sys
class opts:
label_prefix = ".L"
verbose = 0
# optimizer flags
auto_inline = 1
call_rewrite = 1
loop_rewrite = 1
inline_map = {
"__aNNalshl": ["M_aNNalshl", 1],
"__aNahdiff": ["M_aNahdiff", 1],
"__PIA": ["M_PIA", 999],
"__PTS": ["M_PTS", 999],
"__PTC": ["M_PTC", 999],
"__U4M": ["M_U4M", 999],
}
# /***********************************************************************
# // main
# ************************************************************************/
def main(argv):
shortopts, longopts = "qv", [
"label-prefix=", "quiet", "verbose"
]
xopts, args = getopt.gnu_getopt(argv[1:], shortopts, longopts)
for opt, optarg in xopts:
if 0: pass
elif opt in ["-q", "--quiet"]: opts.verbose = opts.verbose - 1
elif opt in ["-v", "--verbose"]: opts.verbose = opts.verbose + 1
elif opt in ["--label-prefix"]: opts.label_prefix = optarg
else: assert 0, ("getopt problem:", opt, optarg, xopts, args)
#
assert opts.label_prefix
assert len(args) == 2
ifile = args[0]
ofile = args[1]
# read ifile
lines = open(ifile, "rb").readlines()
lines = filter(None, map(string.rstrip, lines))
#
#
labels = {}
def parse_label(inst, args):
k = v = None
m = re.search(r"^(.*?)\b(2|R_386_PC16)\s+(__\w+)$", args)
if m and k is None:
# external 2-byte label
k, v = m.group(3).strip(), [1, 2, None, 0]
m = re.search("^0x([0-9a-z]+)$", args)
if m and k is None:
# local label
k, v = m.group(1).strip(), [0, 0, None, 0]
m = re.search("^([0-9a-z]+)\s+<", args)
if m and k is None:
# local label
k, v = m.group(1).strip(), [0, 0, None, 0]
assert k and v, (inst, args)
v[2] = k # new name
if labels.has_key(k):
assert labels[k][:2] == v[:2]
return k, v
def add_label(k, v):
if labels.has_key(k):
assert labels[k][:2] == v[:2]
else:
labels[k] = v
labels[k][3] += 1 # usage counter
return k
olines = []
def omatch(pos, mlen, m, debug=0):
assert len(m) >= abs(mlen)
def sgn(x):
if x < 0: return -1
if x > 0: return 1
return 0
def match(a, b):
if b is None:
return False
if "^" in a or "*" in a:
# regexp
return re.search(a, b.lower())
else:
return a.lower() == b.lower()
mpos = []
while len(mpos) != abs(mlen):
if pos < 0 or pos >= len(olines):
return []
o = olines[pos]
if o[1] != "*DEL*":
mpos.append(pos)
pos += sgn(mlen)
if mlen < 0:
mpos.reverse()
if debug and 1: print mlen, m, [olines[x] for x in mpos]
dpos = []
i = -abs(mlen)
while i < 0:
pos = mpos[i]
o = olines[pos]
assert o[1] != "*DEL*"
assert len(m[i]) == 2, (i, m)
m0 = match(m[i][0], o[1])
m1 = match(m[i][1], o[2])
if not m0 or not m1:
return []
dpos.append([pos, m0, m1])
i += 1
assert len(dpos) == abs(mlen)
return dpos
def orewrite_inst(i, inst, args, dpos):
for pos, m0, m1 in dpos:
olines[pos][1] = "*DEL*"
olines[i][1] = inst
olines[i][2] = args
olines[i][3] = None
def orewrite_call(i, k, v, dpos):
for pos, m0, m1 in dpos:
olines[pos][1] = "*DEL*"
v[2] = k
olines[i][2] = None
olines[i][3] = add_label(k, v)
#
# pass 1
func = None
for i in range(len(lines)):
l = lines[i]
m = re.search(r"^0{8,16}\s*<(\.text\.)?(\w+)>:", l)
if m:
func = re.sub(r"^_+|_+$", "", m.group(2))
if not func in ["LzmaDecode"]:
continue
m = re.search(r"^(\s*[0-9a-z]+):\s+(\w+)(.*)", l)
if not m:
continue
label = m.group(1).strip()
inst = m.group(2).strip()
args = ""
if m.group(3): args = m.group(3).strip()
#
if inst in ["movl",] and re.search(r"\b[de]s\b", args):
# fix bug in objdump
inst = "movw"
m = re.search(r"^(.+?)\b0x0\s+(\w+):\s+(1|2|R_386_16|R_386_PC16)\s+(__\w+)$", args)
if m:
# 1 or 2 byte reloc
args = m.group(1) + m.group(4)
olines.append([label, inst, args, None])
#
# pass 2
for i in range(len(olines)):
label, inst, args, args_label = olines[i]
#
if inst == "*DEL*":
continue
#
if opts.call_rewrite and inst in ["call"]:
k, v = parse_label(inst, args)
if v[:2] == [1, 2]: # external 2-byte
if k == "__aNahdiff":
s = [
["push", "word ptr [bp+8]"],
["push", "word ptr [bp+6]"],
["push", r"word ptr \[bp([+-]\d+)\]$"],
["push", r"word ptr \[bp([+-]\d+)\]$"],
]
dpos = omatch(i-1, -4, s)
if dpos:
orewrite_inst(i, "*DEL*", "", dpos)
continue
if k in ["__LMUL", "__U4M",]:
s1 = [
["mov", "bx,0x300"],
["xor", "cx,cx"],
]
s2 = [
["shl", "ax,1"],
["rcl", "dx,1"],
]
dpos1 = omatch(i-1, -2, s1)
dpos2 = omatch(i+1, 2, s2)
if dpos1 and dpos2:
orewrite_inst(i, "M_U4M_dxax_0x0600", "", dpos1 + dpos2)
continue
s = [
["mov", "bx,word ptr [bx]"],
["xor", "cx,cx"],
]
dpos = omatch(i-1, -2, s, debug=0)
if 0 and dpos:
orewrite_inst(i, "M_U4M_dxax_00bx_ptr", "", dpos)
continue
dpos = omatch(i-1, -1, s)
if dpos:
orewrite_inst(i, "M_U4M_dxax_00bx", "", dpos)
continue
if k == "__PIA":
s = [
["mov", "bx,0x1"],
["xor", "cx,cx"],
]
dpos = omatch(i-1, -2, s)
if dpos:
orewrite_inst(i, "M_PIA1", "", dpos)
continue
if k == "__PTC":
s = [
["jne", "(.*)"],
]
dpos = omatch(i+1, 1, s)
if dpos:
olines[i][1] = "M_PTC_JNE"
k, v = parse_label("jne", dpos[0][2].group(1))
orewrite_call(i, k, v, dpos)
continue
if opts.loop_rewrite and inst in ["loop"]:
s = [
["mov", r"^c[lx],0xb$"],
["shr", "dx,1"],
["rcr", "ax,1"],
]
dpos = omatch(i-1, -3, s)
if dpos:
orewrite_inst(i, "M_shrd_11", "", dpos)
continue
s = [
["mov", r"^c[lx],0x8$"],
["shl", "ax,1"],
["rcl", "dx,1"],
]
dpos = omatch(i-1, -3, s)
if dpos:
orewrite_inst(i, "M_shld_8", "", dpos)
continue
s1 = [
["mov", r"^c[lx],0x8$"],
["shl", "si,1"],
["rcl", "di,1"],
]
s2 = [
["les", r"^bx,dword ptr \[bp([+-]\d+)\]$"],
]
dpos1 = omatch(i-1, -3, s1)
dpos2 = omatch(i+1, 1, s2)
if 1 and dpos1 and dpos2:
# bx and cx are free for use
orewrite_inst(i, "M_shld_disi_8_bxcx", "", dpos1)
continue
s1 = [
["mov", "ax,si"],
["mov", r"^c[lx],0x8$"],
["shl", "ax,1"],
["rcl", "di,1"],
]
s2 = [
["mov", "si,ax"],
["les", r"^bx,dword ptr \[bp([+-]\d+)\]$"],
]
dpos1 = omatch(i-1, -4, s1)
dpos2 = omatch(i+1, 2, s2)
if 1 and dpos1 and dpos2:
# bx and cx are free for use
orewrite_inst(i, "M_shld_diax_8_bxcx", "", dpos1[-3:])
continue
s1 = [
["mov", r"^c[lx],0x8$"],
["shl", r"^word ptr \[bp([+-]\d+)\],1$"],
["rcl", r"^word ptr \[bp([+-]\d+)\],1$"],
]
s2 = [
["mov", r"^dx,word ptr"],
["mov", r"^ax,word ptr"],
]
s3 = [
["mov", r"^ax,word ptr"],
["mov", r"^dx,word ptr"],
]
dpos1 = omatch(i-1, -3, s1)
dpos2 = omatch(i+1, 2, s2)
dpos3 = omatch(i+1, 2, s3)
if dpos1 and (dpos2 or dos3):
bp_dx, bp_ax = dpos1[-1][2].group(1), dpos1[-2][2].group(1)
m = "M_shld_8_bp %s %s" % (bp_dx, bp_ax)
orewrite_inst(i, m, "", dpos1)
continue
s1 = [
["mov", r"^word ptr \[bp([+-]\d+)\],si$"],
["mov", r"^word ptr \[bp([+-]\d+)\],di$"],
["mov", r"^c[lx],0xb$"],
["shr", r"^word ptr \[bp([+-]\d+)\],1$"],
["rcr", r"^word ptr \[bp([+-]\d+)\],1$"],
]
s2 = [
["mov", r"^bx,word ptr"],
["mov", r"^bx,word ptr"],
["mov", r"^ax,word ptr \[bp([+-]\d+)\]$"],
["mov", r"^dx,word ptr \[bp([+-]\d+)\]$"],
]
dpos1 = omatch(i-1, -5, s1)
dpos2 = omatch(i+1, 4, s2)
if dpos1 and dpos2:
bp_dx, bp_ax = dpos1[-2][2].group(1), dpos1[-1][2].group(1)
bp_di, bp_si = dpos1[-4][2].group(1), dpos1[-5][2].group(1)
assert bp_dx == dpos2[-1][2].group(1)
assert bp_ax == dpos2[-2][2].group(1)
assert bp_dx == bp_di
assert bp_ax == bp_si
m = "M_shrd_11_disi_bp %s %s" % (bp_dx, bp_ax)
orewrite_inst(i, m, "", dpos1 + dpos2[-2:])
continue
#
if inst in [
"call", "ja", "jae", "jb", "jbe", "jcxz", "je",
"jg", "jge", "jl", "jle", "jmp", "jne", "loop",
]:
k, v = parse_label(inst, args)
olines[i][2] = None
olines[i][3] = add_label(k, v)
#
# pass 3
digits, i = 1, len(labels)
while i >= 10:
digits += 1
i /= 10
format = "%s0%dd" % ("%", digits)
counter = 0
for i in range(len(olines)):
label, inst, args, args_label = olines[i]
# rewrite local labels
v = labels.get(label)
if v is not None:
assert v[:3] == [0, 0, label], (label, v)
v[2] = opts.label_prefix + format % counter
counter += 1
# handle inlining
if opts.auto_inline and inst == "call":
v = labels[args_label]
if v[:2] == [1, 2]: # external 2-byte
x = inline_map.get(v[2])
if x and v[3] <= x[1]: # max. number of calls
##print "inline", v, x
if x:
olines[i][1] = x[0]
olines[i][2] = "/* inlined */"
olines[i][2] = ""
olines[i][3] = None
#
# write ofile
ofp = open(ofile, "wb")
for label, inst, args, args_label in olines:
if labels.has_key(label):
if opts.verbose:
ofp.write("%s: /* %d */\n" % (labels[label][2], labels[label][3]))
else:
ofp.write("%s:\n" % (labels[label][2]))
if inst == "*DEL*":
continue
if args_label:
if opts.verbose:
args = "%s /* %d */" % (labels[args_label][2], labels[args_label][3])
else:
args = labels[args_label][2]
l = "%8s%-7s %s" % ("", inst, args)
ofp.write(l.rstrip() + "\n")
ofp.close()
##print olines
if __name__ == "__main__":
sys.exit(main(sys.argv))
+127
View File
@@ -0,0 +1,127 @@
/* l_test.c --
This file is part of the UPX executable compressor.
Copyright (C) 2007-2007 Markus Franz Xaver Johannes Oberhumer
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
<mfx@users.sourceforge.net>
*/
#include "stub/src/c/lzma_d_c.c"
#if (ACC_ARCH_I086)
#define bytep unsigned char __huge *
typedef unsigned long uint32_t;
#else
#define bytep unsigned char *
typedef unsigned int uint32_t;
#endif
#if (ACC_OS_DOS16)
# if (ACC_CC_BORLANDC || ACC_CC_TURBOC)
int __cdecl printf(const char *, ...);
void * __cdecl malloc(unsigned);
void __far * __cdecl farmalloc(unsigned long);
# define acc_halloc(x) ((void __huge *) farmalloc(x))
# elif (ACC_CC_DMC || ACC_CC_MSC)
# include <stdio.h>
# include <malloc.h>
# define acc_halloc(x) _halloc(x,1)
# elif (ACC_CC_WATCOMC)
int __watcall printf(const char *, ...);
void * __watcall malloc(unsigned);
void __huge * __watcall halloc(long, unsigned);
# define acc_halloc(x) halloc(x,1)
# else
# endif
#else
# define printf __builtin_printf
# define malloc(x) __builtin_malloc(x)
# define acc_halloc(x) malloc(x)
#endif
/*************************************************************************
//
**************************************************************************/
/*
>>> import pylzma; d="\1" + "\0"*131070 + "\2"; print len(d)
>>> c=pylzma.compress(d, eos=0)[5:]; print len(c), map(ord, c)
*/
static const unsigned char c_data[92] = {
0, 0, 128, 65, 72, 1, 140, 46, 188, 80, 161, 51, 135, 75, 212, 2, 20, 181, 241, 145, 230, 34, 107, 72, 201, 86, 118, 176, 70, 120, 214, 184, 247, 212, 250, 132, 59, 160, 44, 112, 185, 177, 245, 126, 103, 190, 14, 145, 73, 36, 148, 246, 166, 58, 41, 192, 68, 167, 144, 98, 122, 42, 61, 195, 135, 248, 98, 136, 254, 191, 96, 21, 192, 75, 86, 63, 228, 231, 15, 70, 52, 239, 169, 194, 249, 109, 126, 11, 123, 48, 0, 0
};
int main()
{
uint32_t i;
int r;
uint32_t src_len = sizeof(c_data);
uint32_t dst_len = 131072ul;
uint32_t src_out = 0;
uint32_t dst_out = 0;
const bytep src;
bytep dst;
CLzmaDecoderState *s;
printf("Decompress %lu %lu\n", (long)src_len, (long)dst_len);
s = (CLzmaDecoderState *) malloc(32768u);
src = c_data;
dst = (bytep) acc_halloc(dst_len);
if (!s || !dst) {
printf("ERROR: Out of memory!\n");
return 1;
}
for (i = 0; i != dst_len; ++i)
dst[i] = 255;
s->Properties.lc = 3; s->Properties.lp = 0; s->Properties.pb = 2;
r = LzmaDecode(s, src, src_len, &src_out, dst, dst_len, &dst_out);
if (r != 0 || src_out != src_len || dst_out != dst_len)
{
printf("ERROR: Decompression error %d %lu %lu\n", r, (long)src_out, (long)dst_out);
return 1;
}
i = 0;
if (dst[i] != 1)
goto data_error;
while (++i != dst_len - 1)
if (dst[i] != 0)
goto data_error;
if (dst[i] != 2)
goto data_error;
printf("Decompression test passed. All done.\n");
return 0;
data_error:
printf("ERROR: Decompression data error at offset %lu.\n", (long)i);
return 1;
}
/* vim:set ts=4 et: */
+147
View File
@@ -0,0 +1,147 @@
/*
; lzma_d.ash -- 16-bit assembly
;
; This file is part of the UPX executable compressor.
;
; Copyright (C) 2006-2007 Markus Franz Xaver Johannes Oberhumer
; 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
; <markus@oberhumer.com>
; http://www.oberhumer.com/opensource/upx/
;
; ------------- DECOMPRESSION -------------
; Input:
; ds:si - source
; es:di - dest
; cld
; Output:
*/
/*************************************************************************
//
**************************************************************************/
// init
section LZMA_DEC00
//.byte 0xcc
mov bp, sp
#if 0
// DEBUG - check for enough stack
lea bx, [bp + lzma_stack_adjust - 256]
cmp bp, bx
1: jcs 1b
#endif
lea bx, [bp + lzma_stack_adjust]
#if 0
// clear stack
xor ax, ax
1: push ax
cmp sp, bx
jnzs 1b
#else
mov sp, bx
#endif
inc si
inc si
push bx // &outSizeProcessed __near [bp + 24]
mov ax, offset lzma_u_len_hi // outSize
push ax // [bp + 22]
mov ax, offset lzma_u_len
push ax // [bp + 20]
push es // out [bp + 18]
push di // [bp + 16]
add bx, 4
push bx // &inSizeProcessed __near [bp + 14]
mov ax, offset lzma_c_len_hi // inSize
push ax // [bp + 12]
mov ax, offset lzma_c_len
push ax // [bp + 10]
push ds // in [bp + 8]
push si // [bp + 6]
add bx, 4
push bx // &state __near [bp + 4]
// enter small memory model
push ds // save ds && dummy for call
push ss
pop ds
// fill properties
movw [bx], offset lzma_properties
movw [bx+2], offset lzma_properties_hi
ignore_reloc_overflow lzma_u_len
ignore_reloc_overflow lzma_c_len
ignore_reloc_overflow lzma_properties
#define ret
section LZMA_DEC10
.arch i8086, nojumps
#define SMALL 1
#include "lzma_m.h"
#include "lzma_d_cs.S"
#undef SMALL
section LZMA_DEC20
.arch i8086, nojumps
#define FAST 1
#include "lzma_m.h"
#include "lzma_d_cf.S"
#undef FAST
.arch i8086, jumps
#undef ret
// cleanup
section LZMA_DEC30
pop ds
section LZMA_DEC31
// clear dirty stack
mov sp, bp
mov bx, offset clear_dirty_stack_low
xor ax, ax
1: push ax
cmp sp, bx
jnzs 1b
section LZMA_DEC32
mov sp, bp
mov di, offset lzma_u_len
ignore_reloc_overflow lzma_u_len
section LZMA_DEC33
pop ax
push ax
add ax, offset lzma_u_len_segment
mov es, ax
// vi:ts=4:et
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+430
View File
@@ -0,0 +1,430 @@
/*
; lzma_m.h -- 16-bit assembly
;
; This file is part of the UPX executable compressor.
;
; Copyright (C) 2006-2007 Markus Franz Xaver Johannes Oberhumer
; 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
; <markus@oberhumer.com>
; http://www.oberhumer.com/opensource/upx/
;
*/
#ifndef __AHSHIFT
/* DOS real mode */
#define __AHSHIFT 12
#define __AHINCR (1 << __AHSHIFT) /* 4096 */
/*************************************************************************
// support macros: PIA, PIS, PTS, PTC
**************************************************************************/
// huge pointer add: dx:ax = dx:ax + cx:bx
.macro M_PIA_small
add ax, bx
adc cx, 0
#if 0
// code size: 8 bytes
// i086: 2+4+56+3 == 65 clocks
// i286: 2+2+17+2 == 23 clocks
mov bx, cx
mov cl, __AHSHIFT
shl bx, cl
add dx, bx
#else
// code size: 8 bytes
// i086: 2+4+20+3 == 29 clocks
// i286: 2+2+ 9+2 == 15 clocks
mov bl, cl
mov cl, __AHSHIFT - 8
shl bl, cl
add dh, bl
#endif
.endm
.macro M_PIA_fast
add ax, bx
adc cx, 0
// code size: 10 bytes
// i086: 4*2+3 == 11 clocks
// i286: 4*2+2 == 10 clocks
shl cl
shl cl
shl cl
shl cl
add dh, cl
.endm
.macro M_PIA1_small
// code size: 6 bytes
// i086: 3+16 == 19 clocks (jump taken)
// i286: 2+ 7+m ~~ 11 clocks (jump taken)
local L1
inc ax
jnes L1
//add dx, __AHINCR
add dh, __AHINCR >> 8
L1:
.endm
.macro M_PIA1_fast
// WARNING: this trashes "bx" !
// code size: 10 bytes
// i086: 3+3+3+3 == 12 clocks
// i286: 2+2+2+2 == 8 clocks
add ax, 1
sbb bl, bl
and bl, __AHINCR >> 8
add dh, bl
.endm
#if 0
// huge pointer sub: dx:ax = dx:ax - cx:bx
.macro M_PIS
sub ax, bx
adc cx, 0
mov bx, cx
mov cl, __AHSHIFT
shl bx, cl
sub dx, bx
.endm
#endif
// huge pointer diff: dx:ax = dx:ax - cx:bx
.macro M_PTS
#if 0
// normalize
// FIXME
// subtract
sub ax, bx
sbb dx, cx
#endif
.endm
// huge pointer compare: set zero and carry flags: dx:ax cmp cx:bx
.macro M_PTC
// NOTE: no pointer normalization!
local L1
cmp dx, cx
jnes L1
cmp ax, bx
L1:
.endm
.macro M_PTC_JNE l
cmp ax, bx
jnes l
cmp dx, cx
jnes l
.endm
/*************************************************************************
// support macros: U4M, shld, shrd
**************************************************************************/
// umul32: dx:ax = dx:ax * 00:bx
.macro M_U4M_dxax_00bx
// mult high-word
mov cx, ax // save ax
mov ax, dx
mul bx
xchg ax, cx // save high-word result, get saved ax
// mult low-word
mul bx // dx:ax := ax * bx
// add high-word
add dx, cx // add high-word result
.endm
// umul32: dx:ax = dx:ax * word ptr [bx]
.macro M_U4M_dxax_00bx_ptr
// mult high-word
mov cx, ax // save ax
mov ax, dx
mul word ptr [bx]
xchg ax, cx // save high-word result, get saved ax
// mult low-word
mul word ptr [bx]
// add high-word
add dx, cx // add high-word result
.endm
// umul32: dx:ax = ax:cx * 00:bx
.macro M_U4M_axcx_00bx
// mult high-word
mul bx
xchg ax, cx // save high-word result, get low
// mult low-word
mul bx
// add high-word
add dx, cx // add high-word result
.endm
// umul32: dx:ax = dx:ax * 0x0600
.macro M_U4M_dxax_0x0600
#if 0
// code size: 18 bytes
// i086: > 140 clocks (mul needs 70 clocks)
// i286: > 26 clocks (mul needs 13 clocks)
mov bx, 0x300
M_U4M_dxax_00bx
shl ax
rcl dx
#elif 0
// code size: 14 bytes
// i086: > 140 clocks (mul needs 70 clocks)
// i286: > 26 clocks (mul needs 13 clocks)
mov bx, 0x600
M_U4M_dxax_00bx
#else
// code size: 16+8 == 24 bytes
// i086: 18+9 == 27 clocks
// i286: 16+8 == 24 clocks
// FIXME: can we further optimize this ?
shl ax
rcl dx // dx:ax <<= 1 v * 2
mov cx, dx
mov bx, ax // cx:bx = dx:ax v * 2
shl ax
rcl dx // dx:ax <<= 1 v * 4
add ax, bx
adc dx, cx // dx:ax += cx:bx v * 6
M_shld_8 // dx:ax <<= 8 v * 0x600
#endif
.endm
// shld: dx:ax <<= 8
.macro M_shld_8
// code size: 8 bytes
// i086: 9 clocks
// i286: 8 clocks
mov dh, dl
mov dl, ah
mov ah, al
xor al, al
.endm
// shld: di:si <<= 8; bx and cx are free
.macro M_shld_disi_8_bxcx
#if 0
// code size: 9 bytes
// i086: 2 + 7*(2+2+18) + (2+2+5) == 165 clocks
// i286: 2 + 7*(2+2+10) + (2+2+4) == 108 clocks
local L1
mov cx, 8
L1: shl si
rcl di
loop L1
#else
// code size: 16 bytes
// i086: 17 clocks
// i286: 16 clocks
mov bx, di
mov cx, si
mov bh, bl
mov bl, ch
mov ch, cl
xor cl, cl
mov di, bx
mov si, cx
#endif
.endm
// shld: di:ax <<= 8; bx and cx are free
.macro M_shld_diax_8_bxcx
#if 0
// code size: 9 bytes
// i086: 2 + 7*(2+2+18) + (2+2+5) == 165 clocks
// i286: 2 + 7*(2+2+10) + (2+2+4) == 108 clocks
local L1
mov cx, 8
L1: shl ax
rcl di
loop L1
#else
// code size: 12 bytes
// i086: 13 clocks
// i286: 12 clocks
mov bx, di
mov bh, bl
mov bl, ah
mov ah, al
xor al, al
mov di, bx
#endif
.endm
.macro M_shld_8_bp h l
mov dx, word ptr[bp+h]
mov ax, word ptr[bp+l]
M_shld_8
mov word ptr[bp+h], dx
mov word ptr[bp+l], ax
.endm
// shld: dx:ax <<= cl; trashes cl and register "r1" (bx, di, si or bp)
// REQUIRED: 0 <= cl <= 15
.macro M_shld_00_15 r1
mov r1, ax // save ax
shl dx, cl
shl ax, cl
sub cl, 16
neg cl // cl = 16 - cl
shr r1, cl
or dx, r1
.endm
// shld: dx:ax <<= cl; trashes cl
// REQUIRED: 16 <= cl <= 32
.macro M_shld_16_32
sub cl, 16
shl ax, cl
mov dx, ax
xor ax, ax
.endm
// shld: dx:ax <<= cl; trashes cl and register "r1" (bx, di, si or bp)
// REQUIRED: 0 <= cl <= 32
.macro M_shld r1
local L1, L2
cmp cl, 16
jaes L1
// 0 <= cl <= 15
M_shld_00_15 r1
jmps L2
L1:
// 16 <= cl <= 32
M_shld_16_32
L2:
.endm
// shld: dx:ax >>= 11
.macro M_shrd_11_small
// WARNING: this trashes "bx" !
// code size: 14 bytes
// i086: 4+2+52+52+4+28+3 == 145 clocks
// i286: 2+2+16+16+2+10+2 == 50 clocks
mov cl, 11
mov bx, dx // save dx
shr ax, cl
shr dx, cl
mov cl, 5 // cl = 16 - cl
shl bx, cl
or ax, bx
.endm
.macro M_shrd_11_fast
// code size: 20 bytes
// i086: 21 clocks
// i286: 20 clocks
mov al, ah
mov ah, dl
mov dl, dh
xor dh, dh
shr dx
rcr ax
shr dx
rcr ax
shr dx
rcr ax
.endm
.macro M_shrd_11_bp_small h l
mov dx, word ptr[bp+h]
mov ax, word ptr[bp+l]
M_shrd_11_small
mov word ptr[bp+h], dx
mov word ptr[bp+l], ax
.endm
.macro M_shrd_11_bp_fast h l
mov dx, word ptr[bp+h]
mov ax, word ptr[bp+l]
M_shrd_11_fast
mov word ptr[bp+h], dx
mov word ptr[bp+l], ax
.endm
.macro M_shrd_11_disi_bp_small h l
mov dx, di
mov ax, si
M_shrd_11_small
mov word ptr[bp+h], dx
mov word ptr[bp+l], ax
.endm
.macro M_shrd_11_disi_bp_fast h l
mov dx, di
mov ax, si
M_shrd_11_fast
mov word ptr[bp+h], dx
mov word ptr[bp+l], ax
.endm
/*************************************************************************
//
**************************************************************************/
#endif /* ifndef __AHSHIFT */
#undef M_PIA
#undef M_PIA1
#undef M_shrd_11
#undef M_shrd_11_bp
#undef M_shrd_11_disi_bp
#if defined(FAST)
# define M_PIA M_PIA_fast
# define M_PIA1 M_PIA1_fast
# define M_shrd_11 M_shrd_11_fast
# define M_shrd_11_bp M_shrd_11_bp_fast
# define M_shrd_11_disi_bp M_shrd_11_disi_bp_fast
#elif defined(SMALL)
# define M_PIA M_PIA_small
# define M_PIA1 M_PIA1_small
# define M_shrd_11 M_shrd_11_small
# define M_shrd_11_bp M_shrd_11_bp_small
# define M_shrd_11_disi_bp M_shrd_11_disi_bp_small
#else
# error
#endif
// vi:ts=4:et
+11
View File
@@ -41,6 +41,14 @@
.macro section name .macro section name
.section \name .section \name
.code16 .code16
.set current_section,\name
.endm
.macro ignore_reloc_overflow sym
.pushsection ignore_reloc_overflow
.byte \sym
.byte current_section
.popsection
.endm .endm
.macro CPU id .macro CPU id
@@ -120,6 +128,7 @@
.byte 0x7f, \target - . - 1 .byte 0x7f, \target - . - 1
.endm .endm
#define jaes jncs
#define jbes jnas #define jbes jnas
#define jbs jcs #define jbs jcs
#define jes jzs #define jes jzs
@@ -158,6 +167,7 @@ section CALLTRI2
lodsw lodsw
loop cjt16_L1 loop cjt16_L1
/* /*
; ============= ; =============
*/ */
@@ -193,6 +203,7 @@ section CALLTRI6
cjt16_L2: cjt16_L2:
.endm .endm
/* /*
; vi:ts=8:et:nowrap ; vi:ts=8:et:nowrap
*/ */
+7 -5
View File
@@ -37,6 +37,10 @@
; bp - -1 ; bp - -1
*/ */
#ifndef COPY_MATCH
# define COPY_MATCH rep movsb
#endif
section NRV2B160 section NRV2B160
literal_n2b: literal_n2b:
movsb movsb
@@ -79,8 +83,7 @@ section NRVGTD00
section NRVDECO2 section NRVDECO2
lea ax, [bp+di] lea ax, [bp+di]
xchg ax, si xchg ax, si
rep COPY_MATCH
movsb
xchg ax, si xchg ax, si
jmps decomp_start_n2b jmps decomp_start_n2b
getbit_cx_n2b: getbit_cx_n2b:
@@ -105,6 +108,5 @@ decomp_done_n2b:
cjt16 decomp_ret_n2b cjt16 decomp_ret_n2b
/*
; vi:ts=8:et /* vim:set ts=4 et: */
*/
+1 -1
View File
@@ -152,5 +152,5 @@ f2_n2b:
ret ret
decomp_done_n2b: decomp_done_n2b:
/* vi:ts=8:et */
/* vim:set ts=4 et: */
+1 -1
View File
@@ -162,5 +162,5 @@ f2_n2d:
ret ret
decomp_done_n2d: decomp_done_n2d:
/* vi:ts=8:et */
/* vim:set ts=4 et: */
+2 -1
View File
@@ -168,4 +168,5 @@ f2_n2e:
ret ret
decomp_done_n2e: decomp_done_n2e:
/* vi:ts=8:et */
/* vim:set ts=4 et: */
+146
View File
@@ -0,0 +1,146 @@
#! /usr/bin/env python
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
#
# wdis2gas.py --
#
# This file is part of the UPX executable compressor.
#
# Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
# 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>
#
import getopt, os, re, string, sys
class opts:
arch = "i086"
label_prefix = ".L"
verbose = 0
# /***********************************************************************
# // main
# ************************************************************************/
def main(argv):
shortopts, longopts = "qv", [
"arch", "label-prefix=", "quiet", "verbose"
]
xopts, args = getopt.gnu_getopt(argv[1:], shortopts, longopts)
for opt, optarg in xopts:
if 0: pass
elif opt in ["-q", "--quiet"]: opts.verbose = opts.verbose - 1
elif opt in ["-v", "--verbose"]: opts.verbose = opts.verbose + 1
elif opt in ["--arch"]: opts.arch = optarg
elif opt in ["--label-prefix"]: opts.label_prefix = optarg
else: assert 0, ("getopt problem:", opt, optarg, xopts, args)
#
assert len(args) == 2
ifile = args[0]
ofile = args[1]
# read ifile
lines = open(ifile, "rb").readlines()
lines = map(string.rstrip, lines)
#
section = None
func = None
olines = []
for i in range(len(lines)):
l = lines[i]
if not l: continue
m = re.search(r"^No disassembly errors", l)
if m: continue
m = re.search(r"^Module:", l)
if m: continue
m = re.search(r"^GROUP:", l)
if m: continue
m = re.search(r"^(BSS|Routine) Size:", l)
if m: continue
m = re.search(r"^Segment:\s+(.+)\s+([0-9a-fA-F]+)\s+bytes$", l)
if m:
s = re.split(r"\s+", m.group(1))
assert len(s) == 3, (i, l, s, m.groups())
section = s
func = None
continue
m = re.search(r"^Comdat:\s+(.+)\s+SEGMENT NONE '(\w+)'\s+([0-9a-fA-F]+)\s+bytes$", l)
if m:
section = [m.group(2)]
assert section[0].endswith("_TEXT"), (i, l, section)
func = re.sub(r"^[_@]+|[_@]+$", "", m.group(1))
olines.append(".section .text." + func)
continue
assert section, (i, l)
m = re.search(r"^0000\s+(\w+):$", l)
if m:
assert section[0].endswith("_TEXT"), (i, l, section)
func = re.sub(r"^[_@]+|[_@]+$", "", m.group(1))
olines.append(".section .text." + func)
continue
assert func, (i, l, section)
m = re.search(r"^[0-9a-fA-F]{4}\s+L\$(\d+):$", l)
if m:
olines.append(opts.label_prefix + m.group(1) + ":")
continue
m = re.search(r"^[0-9a-fA-F]{4} (([0-9a-fA-F]{2} )+)\s+(.+)$", l)
assert m, (i, l)
if m.group(3).startswith("call"):
s = re.split(r"\s+", m.group(3))
assert len(s) == 2, (i, l, s, m.groups())
f = re.sub(r"^[@]+|[@]+$", "", s[1])
olines.append(" call " + f)
elif 1:
s = m.group(3).strip()
s = re.sub(r"L\$(\d+)", opts.label_prefix + r"\g<1>", s)
olines.append(" " + s)
else:
s = re.split(r"\s+", m.group(1).strip())
assert 1 <= len(s) <= 5, (i, l, s, m.groups())
s = ["0x" + x for x in s]
olines.append(" .byte " + ",".join(s))
# write ofile
ofp = open(ofile, "wb")
ofp.write(".code16\n")
ofp.write(".intel_syntax noprefix\n")
if opts.arch in ["i086", "8086", "i8086"]:
ofp.write(".arch i8086, jumps\n")
elif opts.arch in ["i286"]:
ofp.write(".arch i286, jumps\n")
else:
assert 0, ("invalid arch", opts.arch)
if 0:
for sym in ["__AHSHIFT", "__AHINCR", "__LMUL", "__aNahdiff"]:
ofp.write(".extern %s\n" % (sym))
ofp.write(".type %s,@function\n" % (sym))
ofp.write(".size %s,2\n" % (sym))
for l in olines:
ofp.write(l.rstrip() + "\n")
ofp.close()
##print olines
if __name__ == "__main__":
sys.exit(main(sys.argv))
+1
View File
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3) __dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND) top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c vpath %.c $(top_srcdir)/src/stub/src/c
STUBS = STUBS =
+7 -1
View File
@@ -300,8 +300,10 @@ ctend:
// 2nd param: where is cto8 (dl, bl, or literal) // 2nd param: where is cto8 (dl, bl, or literal)
section ctok32.00 section ctok32.00
.ifnc \addvalue, 0
.ifc \addvalue, edi .ifc \addvalue, edi
mov esi, \addvalue mov esi, edi
.endif
.endif .endif
jmps ckstart jmps ckstart
ckloop3: ckloop3:
@@ -333,7 +335,11 @@ ckmark:
sub eax, edi sub eax, edi
.ifnc \addvalue, 0 .ifnc \addvalue, 0
.ifc \addvalue, edi
add eax, esi add eax, esi
.else
add eax, \addvalue
.endif
.endif .endif
mov [edi], eax mov [edi], eax
add edi, 4 add edi, 4
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3) __dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND) top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c vpath %.c $(top_srcdir)/src/stub/src/c
STUBS = STUBS =
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3) __dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND) top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c vpath %.c $(top_srcdir)/src/stub/src/c
STUBS = STUBS =
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3) __dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND) top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c vpath %.c $(top_srcdir)/src/stub/src/c
STUBS = STUBS =
@@ -55,7 +56,7 @@ $c += -fmodulo-sched
$c += -floop-optimize2 $c += -floop-optimize2
$c += -ffixed-30 $c += -ffixed-30
else ifneq ($(findstring -gcc-4.2.0,$(firstword $($c))),) else ifneq ($(findstring -gcc-4.2.0,$(firstword $($c))),)
# gcc-4.2.0-20060826 snapshot # gcc-4.2.0-20060826.tar.bz2 snapshot
$c += -fno-wrapv $c += -fno-wrapv
$c += -mtune=r4000 $c += -mtune=r4000
$c += -fno-regmove $c += -fno-regmove
@@ -68,7 +69,9 @@ $c += -ffixed-30
else else
$(error unknown gcc version: $(firstword $($c))) $(error unknown gcc version: $(firstword $($c)))
endif endif
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
$c += -I$(UPX_LZMADIR) $c += -I$(UPX_LZMADIR)
endif
$c += -I$(top_srcdir)/src $c += -I$(top_srcdir)/src
lzma_d_c%.S : lzma_d_c.c lzma_d_c%.S : lzma_d_c.c
@@ -84,7 +87,7 @@ lzma_d_cs.% : PP_FLAGS = -DSMALL
# /*********************************************************************** # /***********************************************************************
# // test-stub-compression (needs UPX_UCLPACK) # // test-stub-compression (needs UPX_UCL_UCLPACK)
# ************************************************************************/ # ************************************************************************/
define __test_stub_compression define __test_stub_compression
@@ -93,11 +96,13 @@ define __test_stub_compression
@rm -f $1.tmp.* @rm -f $1.tmp.*
@bzip2 -9 < $1 > $1.tmp.bz2 @bzip2 -9 < $1 > $1.tmp.bz2
@gzip -9mn < $1 > $1.tmp.gz @gzip -9mn < $1 > $1.tmp.gz
$(if $(UPX_UCLPACK),@$(UPX_UCLPACK) --nrv2b --10 $1 $1.tmp.uclpack-nrv2b | egrep ' into ') $(if $(UPX_UCL_UCLPACK),@$(UPX_UCL_UCLPACK) --nrv2b --10 $1 $1.tmp.uclpack-nrv2b | egrep ' into ')
@ls -l $1.tmp.* @ls -l $1.tmp.*
endef endef
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
test-stub-compression: tc_list = mipsel.r3000-ps1 default test-stub-compression: tc_list = mipsel.r3000-ps1 default
test-stub-compression: lzma_d_cf.S lzma_d_cs.S test-stub-compression: lzma_d_cf.S lzma_d_cs.S
$(call __test_stub_compression,tmp/lzma_d_cs.out,tmp/lzma_d_cs.o) $(call __test_stub_compression,tmp/lzma_d_cs.out,tmp/lzma_d_cs.o)
.PHONY: test-stub-compression .PHONY: test-stub-compression
endif
+214 -77
View File
@@ -34,11 +34,15 @@
#ifndef _MR3K_STD_CONF_ #ifndef _MR3K_STD_CONF_
#define _MR3K_STD_CONF_ #define _MR3K_STD_CONF_
#define JOHN 1
#define ALT_SMALL 1
;////////////////////////////////////// ;//////////////////////////////////////
;// register defines ;// register defines
;////////////////////////////////////// ;//////////////////////////////////////
#if 1
#define tmp at #define tmp at
#define dst t0 #define dst t0
@@ -58,6 +62,31 @@
#define m_off t7 #define m_off t7
#define m_pos t7 #define m_pos t7
#else
.print "\nwarning redefined src / dst\n"
#define tmp v1
#define src a0
#define dst a1
#define pc v0
#define cnt a2
#define src_ilen src
#define bb t1
#define ilen t2
#define last_m_off t3
#define m_len t4
#define bc t5
#define var t6
#define m_off t7
#define m_pos t7
#endif
;////////////////////////////////////// ;//////////////////////////////////////
;// init bitaccess ;// init bitaccess
@@ -89,12 +118,32 @@
.macro init .macro init
init_sz = .
.if (JOHN == 0)
move bc,zero move bc,zero
.else // John's method
.if (UCL_SMALL == 1)
.if (ALT_SMALL == 1)
lui bc,1 << (31 - 16)
move bb,bc
.else
move bc,zero
.endif
.else
lui bc,1 << (31 - 16)
move bb,bc
.endif
.endif
li last_m_off,1 li last_m_off,1
.if (src != src_ilen) .if (src != src_ilen)
move src_ilen,src move src_ilen,src
.endif .endif
init_sz = . - init_sz
.endm .endm
@@ -104,6 +153,7 @@
.macro ADDBITS .macro ADDBITS
.if (JOHN == 0)
.if (UCL_SMALL == 1) .if (UCL_SMALL == 1)
addiu bc, -1 addiu bc, -1
bltz bc, 2b bltz bc, 2b
@@ -112,32 +162,92 @@
addiu bc, -1 addiu bc, -1
.endif .endif
.else // John's method
.if (UCL_SMALL == 1)
.if (ALT_SMALL == 1)
beq bc,bb,2b # detect flag bit [empty]
.else
addiu bc,-1
bltz bc,2b
.endif
.else
srl var,bb,31 # var= most significant bit of bb
bne bc,bb,2f # detect flag bit [empty]
sll bb,1
.endif
.endif
.endm .endm
.macro ADDBITS_DONE .macro ADDBITS_DONE
.if (JOHN == 0)
srlv var,bb,bc srlv var,bb,bc
.if (UCL_SMALL == 1) .if (UCL_SMALL == 1)
jr ra jr ra
.endif .endif
andi var,0x0001 andi var,0x0001
.else // John's method
.if (UCL_SMALL == 1)
.if (ALT_SMALL == 1)
srl var,bb,31 # var= most significant bit of bb
jr ra
sll bb,1
.else
srlv var,bb,bc
jr ra
andi var,0x0001
.endif
.else
.if (UCL_NRV_BB == 8)
sll bb,1
addiu bb,1 # the flag bit
srl var,bb,8 # var= most significant bit of bb
sll bb,24 # left-justify in register
.else
srl var,bb,31 # var= most significant bit of bb
sll bb,1
addiu bb,1
.endif
.endif
.endif
.endm .endm
.macro FILLBYTES_8 .macro FILLBYTES_8
.if (UCL_SMALL == 1) .if (JOHN == 0)
li bc,8
.else
li bc,7 li bc,7
.endif
lbu bb,0(src_ilen) lbu bb,0(src_ilen)
addiu src_ilen,1 addiu src_ilen,1
.else // John's method
.if (ALT_SMALL == 0)
.if (UCL_SMALL == 1)
li bc,8
.endif
.endif
lbu bb,0(src_ilen)
addiu src_ilen,1
.if ((ALT_SMALL == 1) && (UCL_SMALL == 1))
sll bb,1
addiu bb,1 # the flag bit
sll bb,24-1 # left-justify in register
.endif
.endif
.endm .endm
.macro FILLBYTES_32 .macro FILLBYTES_32
.if (JOHN == 0)
.if (UCL_SMALL == 1) .if (UCL_SMALL == 1)
li bc,32 li bc,32
.else .else
@@ -147,9 +257,27 @@
lwl bb,3(src_ilen) lwl bb,3(src_ilen)
addiu src_ilen,4 addiu src_ilen,4
.else // John's method
.if (ALT_SMALL == 0)
.if (UCL_SMALL == 1)
li bc,32
.endif
.endif
lwr bb,0(src_ilen)
lwl bb,3(src_ilen)
addiu src_ilen,4
.if ((ALT_SMALL == 1) && (UCL_SMALL == 1))
srl var,bb,31 # var= most significant bit of bb
sll bb,1
jr ra
addiu bb,1
.endif
.endif
.endm .endm
.macro FILLBYTES .macro FILLBITS
.if (UCL_NRV_BB == 8) .if (UCL_NRV_BB == 8)
FILLBYTES_8 FILLBYTES_8
@@ -159,79 +287,29 @@
.endm .endm
// This alternate for UCL_SMALL is 1 cycle faster for most getbit
// at a cost of 1 cycle (32 bits) or 3 cycles (8 bits) during refill.
// [Refill could save 1 cycle if MIPS had "set CarryIn" for ADD or SHIFT.]
// Call 'getbit'; it returns the next bit (0 or 1), in register 'var'.
// Register 'bb' is the bit buffer; register 'bc' contains the 'empty' value.
// The cases for widths 8 and 32 are not as similar as before,
// and 64-bit registers would require other code.
// But it is 1 cycle faster 31/32 of the time.
// [Indentation after control transfer emphasizes delay slot.]
//
//init:
// lui bc,1<<(31 - 16) # 1<<31 the flag bit
// lui bb,1<<(31 - 16) # 1<<31 empty
//--
// .if (8==UCL_NRV_BB)
//refill:
// lbu bb,0(src_ilen)
// addiu src_len,1
// sll bb,1
// ori bb,1 # the flag bit
// sll bb,24-1 # left-justify in register
// // falling through the 'beq' below saves 3 words of space
// .endif
//getbit:
// beq bc,bb,refill # detect flag bit [empty]
// srl var,bb,31 # var= most significant bit of bb
// jr ra
// sll bb,1
// .if (32==UCL_NRV_BB)
//refill:
// lwr bb,0(src_ilen)
// lwl bb,3(src_ilen)
// addiu src_ilen,4
// srl var,bb,31 # var= most significant bit of bb
// sll bb,1
// jr ra
// ori bb,1 # the flag bit
// .endif
// 2006-09-06 Faster by 3 cycles for inline expansion:
// beq bc,bb,7f # detect flag bit [empty]
// srl var,bb,31 # var= most significant bit of bb
// sll bb,1
//6:
// .subsection 1 # somewhere out-of-line
//7:
// b refill
// addi ra,r_bd_base,6b - bd_base # return past the 'sll' above
// .subsection 0 # return to main in-line code
//
// which is 3 cycles usually, +2 cycles for entering refill,
// +8 bytes (2 instructions) per getbit [7 in nrv2b, 9 in nrv2e]
// and requires another register r_bd_base which holds a handy
// address within +/- 32KB of the returns from refill.
//
.macro GBIT .macro GBIT
.if (UCL_SMALL == 1) .if (UCL_SMALL == 1)
2: 2:
FILLBYTES FILLBITS
1: 1:
ADDBITS ADDBITS
ADDBITS_DONE ADDBITS_DONE
.else .else
ADDBITS ADDBITS
FILLBYTES FILLBITS
.if (JOHN == 1)
ADDBITS_DONE
2:
.else
2: 2:
ADDBITS_DONE ADDBITS_DONE
.endif
.endif .endif
.endm .endm
;////////////////////////////////////// ;//////////////////////////////////////
;// getbit call macro for SMALL version ;// getbit call macro for SMALL version
;////////////////////////////////////// ;//////////////////////////////////////
@@ -247,8 +325,23 @@
.ifb p1 .ifb p1
bal t // gb_sub bal t // gb_sub
.else .else
.if (JOHN == 0)
bal t+4 // gb_sub+4 bal t+4 // gb_sub+4
addiu bc,-1 addiu bc,-1
.else // John's method
.if (UCL_SMALL == 1)
.if (ALT_SMALL == 0)
bal t+4 // gb_sub+4
addiu bc,-1
.else
bal t // gb_sub+4
nop
.endif
.endif
.endif
.endif .endif
.else .else
GBIT GBIT
@@ -271,20 +364,20 @@
.endif .endif
\type decomp_done \type decomp_done
.if (UCL_SMALL == 1) .if (UCL_SMALL == 1)
WITHOUT_SUB = 0
GBIT GBIT
.endif .endif
.else .else
.ifc "\option", "sub_only" .ifc "\option", "sub_only"
2: 2:
FILLBYTES FILLBITS
.ifnb label .ifnb label
.global \label .global \label
\label: \label:
.endif .endif
ADDBITS ADDBITS
ADDBITS_DONE ADDBITS_DONE
.else .else
.ifc "\option", "without_sub" .ifc "\option", "without_sub"
.if (UCL_SMALL == 1) .if (UCL_SMALL == 1)
@@ -309,12 +402,12 @@
.macro uclmcpy ret .macro uclmcpy ret
local wordchk, bcpy local wordchk, prepbcpy
local bcpy_chk, skip local bcopy, skip
.if (UCL_FAST == 1) .if (UCL_FAST == 1)
slti var,m_off,4 slti var,m_off,4
bnez var,bcpy bnez var,prepbcpy
subu m_pos,dst,m_off subu m_pos,dst,m_off
wordchk: wordchk:
slti var,m_len,4 slti var,m_len,4
@@ -327,22 +420,66 @@ wordchk:
addiu m_pos,4 addiu m_pos,4
bnez m_len,wordchk bnez m_len,wordchk
addiu dst,4 addiu dst,4
.if (UCL_SMALL == 1)
.if (WITHOUT_SUB == 1)
t = gb_e
.else
t = 1f
.endif
.if (1 == 1)
b \ret b \ret
nop nop
.else .else
subu m_pos,dst,m_off bal t
addiu ra, (\ret + 4) - (. + 4)
.endif .endif
bcpy_chk: .else
beqz m_len,\ret .if (JOHN == 0)
bcpy: b \ret
nop
.else
b \ret + 4
srl var,bb,31 # var= most significant bit of bb
.endif
.endif
prepbcpy:
.else
subu m_pos,dst,m_off
.endif
bcopy:
lbu var,0(m_pos) lbu var,0(m_pos)
skip: skip:
addiu m_len,-1 addiu m_len,-1
sb var,0(dst)
addiu m_pos,1 addiu m_pos,1
b bcpy_chk
addiu dst,1 addiu dst,1
bnez m_len,bcopy
sb var,-1(dst)
.if (UCL_SMALL == 1)
.if (WITHOUT_SUB == 1)
t = gb_e
.else
t = 1f
.endif
.if (1 == 1)
b \ret
nop
.else
bal t
addiu ra, (\ret + 4) - (. + 4)
.endif
.else
.if (JOHN == 0)
b \ret
nop
.else
b \ret + 4
srl var,bb,31 # var= most significant bit of bb
.endif
.endif
.endm .endm
#endif //_MR3K_STD_CONF_ #endif //_MR3K_STD_CONF_
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3) __dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND) top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c vpath %.c $(top_srcdir)/src/stub/src/c
STUBS = STUBS =
+1 -1
View File
@@ -103,7 +103,7 @@ copy:
sub r10,r12,r9 // &b_info sub r10,r12,r9 // &b_info
add r10,r10,r4 // relocated &b_info add r10,r10,r4 // relocated &b_info
ldrb r0,[r11,# b_method ] // 5th param ldr r0,[r11,# b_method ] // 5th param (whole word: endian issues!)
stmdb sp!,{r0,lr} stmdb sp!,{r0,lr}
ldr r3,[r11,# sz_unc] ldr r3,[r11,# sz_unc]
add r0, r11,# sz_b_info add r0, r11,# sz_b_info
@@ -0,0 +1,30 @@
/*
; armeb-linux.kernel.vmlinux-head.S -- set up stack for vmlinux/armeb format
;
; This file is part of the UPX executable compressor.
;
; Copyright (C) 2006-2007 John 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 Reiser
; <jreiser@users.sourceforge.net>
*/
#include "arm-linux.kernel.vmlinux-head.S"
// vi:ts=8:et:nowrap
+35
View File
@@ -0,0 +1,35 @@
/*
; armeb-linux.kernel.vmlinux.S -- loader & decompressor for the vmlinux/armeb format
;
; This file is part of the UPX executable compressor.
;
; Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
; Copyright (C) 1996-2007 Laszlo Molnar
; Copyright (C) 2004-2007 John 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.
;
; Markus F.X.J. Oberhumer Laszlo Molnar
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
;
; John Reiser
; <jreiser@users.sourceforge.net>
*/
#include "arm-linux.kernel.vmlinux.S"
// vi:ts=8:et:nowrap
+29 -2
View File
@@ -30,7 +30,7 @@
**************************************************************************/ **************************************************************************/
#define ACC_LIBC_NAKED 1 #define ACC_LIBC_NAKED 1
#define ACC_OS_FREESTANDING 1 /*#define ACC_OS_FREESTANDING 1*/
#include "miniacc.h" #include "miniacc.h"
#if 0 #if 0
@@ -39,6 +39,15 @@
#undef _LZMA_PROB32 #undef _LZMA_PROB32
#undef _LZMA_LOC_OPT #undef _LZMA_LOC_OPT
#endif #endif
#if (ACC_ARCH_I086)
# define Byte unsigned char
# define _7ZIP_BYTE_DEFINED 1
#endif
#if !defined(_LZMA_UINT32_IS_ULONG)
# if defined(__INT_MAX__) && ((__INT_MAX__)+0 == 32767)
# define _LZMA_UINT32_IS_ULONG 1
# endif
#endif
#if 0 #if 0
@@ -52,9 +61,15 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(CLzmaDecoderState) == 16)
#else #else
#define CLzmaDecoderState CLzmaDecoderState_dummy #define CLzmaDecoderState CLzmaDecoderState_dummy
#define LzmaDecodeProperties LzmaDecodeProperties_dummy
#define LzmaDecode LzmaDecode_dummy #define LzmaDecode LzmaDecode_dummy
#if (ACC_CC_BORLANDC)
#include "LzmaDecode.h"
#else
#include "C/7zip/Compress/LZMA_C/LzmaDecode.h" #include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
#endif
#undef CLzmaDecoderState #undef CLzmaDecoderState
#undef LzmaDecodeProperties
#undef LzmaDecode #undef LzmaDecode
typedef struct { typedef struct {
struct { unsigned char lc, lp, pb, dummy; } Properties; struct { unsigned char lc, lp, pb, dummy; } Properties;
@@ -64,10 +79,22 @@ typedef struct {
CProb Probs[16382]; CProb Probs[16382];
#endif #endif
} CLzmaDecoderState; } CLzmaDecoderState;
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(CLzmaDecoderState) == 32768) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(CLzmaDecoderState) == 32768u)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(SizeT) >= 4)
#if (ACC_ARCH_I086)
# define char char __huge
#elif (ACC_CC_WATCOMC)
#else
#define CLzmaDecoderState const CLzmaDecoderState #define CLzmaDecoderState const CLzmaDecoderState
#endif
#if (ACC_CC_BORLANDC)
#include "LzmaDecode.c"
#else
#include "C/7zip/Compress/LZMA_C/LzmaDecode.c" #include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
#endif
#undef char
#undef CLzmaDecoderState
#endif #endif
+35 -5
View File
@@ -59,15 +59,40 @@ strategy:
push bp push bp
push ds push ds
push es push es
section LZMADEVICE
sub ax, offset exe_stack_ss + 0x10
mov ds, ax /* ds = cs - 0x10 */
section DEVICEENTRY2
.byte 0x72 /* "jc 0xf9" but flag C is 0 => nop */ .byte 0x72 /* "jc 0xf9" but flag C is 0 => nop */
exe_as_device_entry: exe_as_device_entry:
stc /* flag C is 1 */ stc /* flag C is 1 */
pushf pushf
/* ============= */
section LZMAENTRY
push ss
pop es
mov bx, 0x8000
xor cx, cx
mov si, offset COMPRESSED_LZMA_START + 0x100 /* ds = cs - 0x10 */
mov di, 0x10
mov bp, -1
.byte 0xa8 /* skips the following "movsb" */
#define COPY_MATCH .byte 0x26; rep movsb
#include "arch/i086/nrv2b_d16.S" /* for uncompressing lzma */
#define literal_n2b literal_n2b_
#define copy_match_n2b copy_match_n2b_
#define getbit_cx_n2b getbit_cx_n2b_
#define getbit_n2b getbit_n2b_
#define decomp_done_n2b decomp_done_n2b_
/* ============= */ /* ============= */
section EXEENTRY section EXEENTRY
exe_entry:
mov cx, offset words_to_copy mov cx, offset words_to_copy
mov si, offset copy_offset mov si, offset copy_offset
mov di, si mov di, si
@@ -86,11 +111,10 @@ addaxds:
rep rep
movsw movsw
cld cld
section DEVICESUB section LONGSUB
/* subb [cs:si + addaxds + 4], 0x10 */ subb [cs:si + addaxds + 4], 0x10
section SHORTSUB
.byte 0x2e, 0x80, 0x6c, addaxds + 4, 0x10 .byte 0x2e, 0x80, 0x6c, addaxds + 4, 0x10
section EXESUB
subb [cs:si + addaxds - exe_entry + 4], 0x10
section JNCDOCOPY section JNCDOCOPY
jncs do_copy jncs do_copy
xchg ax, dx xchg ax, dx
@@ -106,10 +130,14 @@ section EXEMAIN4
pop es pop es
push ss push ss
mov bp, offset decompressor_entry mov bp, offset decompressor_entry
section EXEMAIN4B
mov bx, offset bx_magic /* 0x800F + 0x10*bp - 0x10 */ mov bx, offset bx_magic /* 0x800F + 0x10*bp - 0x10 */
section EXEMAIN4C
push bp push bp
lret lret
section COMPRESSED_LZMA_START
#include "include/header.S" #include "include/header.S"
section EXECUTPO section EXECUTPO
@@ -117,6 +145,7 @@ section EXECUTPO
#include "arch/i086/nrv2b_d8.S" #include "arch/i086/nrv2b_d8.S"
#include "arch/i086/nrv2d_d8.S" #include "arch/i086/nrv2d_d8.S"
#include "arch/i086/nrv2e_d8.S" #include "arch/i086/nrv2e_d8.S"
#include "arch/i086/lzma_d.S"
section EXEMAIN5 section EXEMAIN5
pop bp pop bp
@@ -217,6 +246,7 @@ section EXERETIP
push ax push ax
lret lret
/* /*
vi:ts=8:et:nowrap vi:ts=8:et:nowrap
*/ */
+6 -6
View File
@@ -67,12 +67,12 @@ decompress:
// // C callable decompressor // // C callable decompressor
// **************************************************************************/ // **************************************************************************/
// /* Offsets to parameters, allowing for {push + pusha + call} */ // /* Offsets to parameters, allowing for {pusha + call} */
#define O_INP (4+ 8*4 +1*4) #define O_INP (8*4 +1*4)
#define O_INS (4+ 8*4 +2*4) #define O_INS (8*4 +2*4)
#define O_OUTP (4+ 8*4 +3*4) #define O_OUTP (8*4 +3*4)
#define O_OUTS (4+ 8*4 +4*4) #define O_OUTS (8*4 +4*4)
#define O_PARAM (4+ 8*4 +5*4) #define O_PARAM (8*4 +5*4)
#define INP dword ptr [esp+O_INP] #define INP dword ptr [esp+O_INP]
#define INS dword ptr [esp+O_INS] #define INS dword ptr [esp+O_INS]
+164
View File
@@ -0,0 +1,164 @@
/*
; i386-darwin.macho-entry.S -- program entry point & decompressor (i386 Mach-o)
;
; This file is part of the UPX executable compressor.
;
; 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
; 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>
;
; John F. Reiser
; <jreiser@users.sourceforge.net>
;
*/
#include "arch/i386/macros.S"
/*************************************************************************
// program entry point
// see glibc/sysdeps/i386/elf/start.S
**************************************************************************/
section LEXEC000
_start: .globl _start
//// int3
/*
;; How to debug this code: Uncomment the 'int3' breakpoint instruction above.
;; Build the stubs and upx. Compress a testcase, such as a copy of /bin/date.
;; Invoke gdb, and give a 'run' command. Define a single-step macro such as
;; define g
;; stepi
;; x/i $pc
;; end
;; and a step-over macro such as
;; define h
;; x/2i $pc
;; tbreak *$_
;; continue
;; x/i $pc
;; end
;; Step through the code; remember that <Enter> repeats the previous command.
;;
*/
call main // push address of decompress subroutine
decompress:
// /*************************************************************************
// // C callable decompressor
// **************************************************************************/
// /* Offsets to parameters, allowing for {pusha + call} */
#define O_INP (8*4 +1*4)
#define O_INS (8*4 +2*4)
#define O_OUTP (8*4 +3*4)
#define O_OUTS (8*4 +4*4)
#define O_PARAM (8*4 +5*4)
#define INP dword ptr [esp+O_INP]
#define INS dword ptr [esp+O_INS]
#define OUTP dword ptr [esp+O_OUTP]
#define OUTS dword ptr [esp+O_OUTS]
#define PARM dword ptr [esp+O_PARAM]
section LEXEC009
//; empty section for commonality with l_lx_exec86.asm
section LEXEC010
pusha
// cld
mov esi, INP
mov edi, OUTP
or ebp, -1
//;; align 8
#include "arch/i386/nrv2b_d32.S"
#include "arch/i386/nrv2d_d32.S"
#include "arch/i386/nrv2e_d32.S"
#include "arch/i386/lzma_d.S"
section LEXEC015
// eax is 0 from decompressor code
//xor eax, eax ; return code
// check compressed size
mov edx, INP
add edx, INS
cmp esi, edx
jz .ok
dec eax
.ok:
// write back the uncompressed size
sub edi, OUTP
mov edx, OUTS
mov [edx], edi
mov [7*4 + esp], eax
popa
ret
ctojr32
ctok32 edi, dl
cit32 edi
section LEXEC017
popa
ret
section LEXEC020
#define PAGE_SIZE ( 1<<12)
sz_b_info= 12
sz_unc= 0
sz_cpr= 4
b_method= 8
// Decompress the rest of this loader, and jump to it.
unfold:
pop esi // &{ b_info:{sz_unc, sz_cpr, 4{byte}}, compressed_data...}
mov eax,[sz_cpr + esi]
lea edx,[sz_b_info + eax + esi]
push edx // &destination
cld
lodsd
push eax // sz_uncompressed (maximum dstlen for lzma)
mov ecx,esp // save &dstlen
push eax // space for 5th param
push ecx // &dstlen
push edx // &dst
lodsd
push eax // sz_compressed (srclen)
lodsd
mov [4*3 + esp],eax // last 4 bytes of b_info
push esi // &compressed_data
call ebp // decompress(&src, srclen, &dst, &dstlen, b_info.misc)
add esp, (5+1)*4 // (5+1) args to decompress
ret // &destination
main:
pop ebp // &decompress
lea ebx,[-4+ _start - decompress + ebp] // &total_length
call unfold
// compressed fold_elf86 follows
// vi:ts=8:et:nowrap
+139
View File
@@ -0,0 +1,139 @@
/* i386-darwin.macho-fold.S -- linkage to C code to process Mach-o binary
*
* This file is part of the UPX executable compressor.
*
* 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
* 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>
*
* John F. Reiser
* <jreiser@users.sourceforge.net>
*/
#include "arch/i386/macros.S"
sz_b_info= 12
sz_unc= 0
sz_cpr= 4
sz_l_info= 12
sz_p_info= 12
_start: .globl _start # ignored, but silence "cannot find entry symbol _start" from ld
i386_ts_eax = 0*4
i386_ts_ebx = 1*4
i386_ts_ecx = 2*4
i386_ts_edx = 3*4
i386_ts_edi = 4*4
i386_ts_esi = 5*4
i386_ts_ebp = 6*4
i386_ts_esp = 7*4
i386_ts_ss = 8*4
i386_ts_eflags = 9*4
i386_ts_eip = 10*4
i386_ts_cs = 11*4
i386_ts_ds = 12*4
i386_ts_es = 13*4
i386_ts_fs = 14*4
i386_ts_gs = 15*4
fold_begin: // In: ebx= &total_length
//// int3
push 0 # default value for mhdrp
mov edi,esp # &mhdrp
lea esi,[ 2+ ebp] # &f_unfilter
mov edx,[ebx] # sz_total
mov ecx,ebx
sub ecx,edx # src= &{l_info; p_info; b_info}
mov ebx,[sz_unc + sz_p_info + sz_l_info + ecx] # sz_mach_headers
mov eax,2048 # allow for /usr/lib/dyld
cmp eax,ebx
jbe 0f
mov ebx,eax
0:
sub esp,ebx # alloca
pusha # (mhdrpp, f_unfilter, f_decompress, mhdr, sz_mhdr, sz_total, src, junk)
call upx_main # Out: eax= &Mach_i386_thread_state of dyld
mov ecx,[4*4 + esp] # sz_mhdr
lea esp,[8*4 + 1*ecx + esp] # un_pusha, un_alloca; keep mhdrp
jmp [i386_ts_eip + eax] # esp: mhdrp, argc, argv...
bswap: .globl bswap
mov eax,[4+ esp] # ptr
mov ecx,[8+ esp] # len
0:
mov edx,[eax]
.byte 0x0f,0xc8+2 // bswap edx
mov [eax],edx
sub ecx,4
lea eax,[4+ eax]
jae 0b
ret
SYS_exit =1
SYS_fork =2
SYS_read =3
SYS_write =4
SYS_open =5
SYS_close =6
SYS_pread =153
SYS_mmap =197
SYS_munmap = 73
SYS_mprotect= 74
sysgo:
pop edx # return address for sysenter
.byte 0x0f, 0x34 # sysenter
// lazy jmps enable compression of this code
exit: .globl exit
mov al,SYS_exit; jmps 2+ 0f; 0:
mprotect: .globl mprotect
mov al,SYS_mprotect; jmps 2+ 0f; 0:
munmap: .globl munmap
mov al,SYS_munmap; jmps 2+ 0f; 0:
pread: .globl pread
mov al,SYS_pread; jmps 2+ 0f; 0:
close: .globl close
mov al,SYS_close; jmps 2+ 0f; 0:
open: .globl open
mov al,SYS_open; jmps 2+ 0f; 0:
mmap: .globl mmap
mov al,SYS_mmap; jmps 2+ 0f; 0:
read: .globl read
mov al,SYS_read
movzbl eax,al # SYS_nnnnn
mov ecx,esp # &{user_ret_addr, arg1, arg2, ...}
call sysgo
jncs 0f
//mov errno,eax
or eax,~0
0:
ret
/*
vi:ts=8:et:nowrap
*/
+460
View File
@@ -0,0 +1,460 @@
/* i386-darwin.macho-main.c -- loader stub for Mach-o i386
This file is part of the UPX executable compressor.
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
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>
John F. Reiser
<jreiser@users.sourceforge.net>
*/
#include "include/darwin.h"
/*************************************************************************
// configuration section
**************************************************************************/
// In order to make it much easier to move this code at runtime and execute
// it at an address different from it load address: there must be no
// static data, and no string constants.
/*************************************************************************
// "file" util
**************************************************************************/
typedef struct {
size_t size; // must be first to match size[0] uncompressed size
char *buf;
} Extent;
static void
xread(Extent *x, char *buf, size_t count)
{
char *p=x->buf, *q=buf;
size_t j;
if (x->size < count) {
exit(127);
}
for (j = count; 0!=j--; ++p, ++q) {
*q = *p;
}
x->buf += count;
x->size -= count;
}
/*************************************************************************
// util
**************************************************************************/
#if 1 //{ save space
#define ERR_LAB error: exit(127);
#define err_exit(a) goto error
#else //}{ save debugging time
#define ERR_LAB
static void
err_exit(int a)
{
(void)a; // debugging convenience
exit(127);
}
#endif //}
/*************************************************************************
// UPX & NRV stuff
**************************************************************************/
struct l_info { // 12-byte trailer for loader (after macho headers)
unsigned l_checksum;
unsigned l_magic; // UPX_MAGIC_LE32
unsigned short l_lsize;
unsigned char l_version;
unsigned char l_format;
};
struct p_info { // 12-byte packed program header
unsigned p_progid;
unsigned p_filesize;
unsigned p_blocksize;
};
struct b_info { // 12-byte header before each compressed block
unsigned sz_unc; // uncompressed_size
unsigned 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;
};
typedef void f_unfilter(
nrv_byte *, // also addvalue
nrv_uint,
unsigned cto8, // junk in high 24 bits
unsigned ftid
);
typedef int f_expand(
const nrv_byte *, nrv_uint,
nrv_byte *, nrv_uint *, unsigned );
static void
unpackExtent(
Extent *const xi, // input
Extent *const xo, // output
f_expand *const f_decompress,
f_unfilter *f_unf
)
{
while (xo->size) {
struct b_info h;
// Note: if h.sz_unc == h.sz_cpr then the block was not
// compressible and is stored in its uncompressed form.
// Read and check block sizes.
xread(xi, (char *)&h, sizeof(h));
if (h.sz_unc == 0) { // uncompressed size 0 -> EOF
if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic
err_exit(2);
if (xi->size != 0) // all bytes must be written
err_exit(3);
break;
}
if (h.sz_cpr <= 0) {
err_exit(4);
ERR_LAB
}
if (h.sz_cpr > h.sz_unc
|| h.sz_unc > xo->size ) {
err_exit(5);
}
// Now we have:
// assert(h.sz_cpr <= h.sz_unc);
// assert(h.sz_unc > 0 && h.sz_unc <= blocksize);
// assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize);
if (h.sz_cpr < h.sz_unc) { // Decompress block
nrv_uint out_len = h.sz_unc; // EOF for lzma
int const j = (*f_decompress)(xi->buf, h.sz_cpr,
xo->buf, &out_len, h.b_method);
if (j != 0 || out_len != (nrv_uint)h.sz_unc)
err_exit(7);
if (h.b_ftid!=0 && f_unf) { // have filter
(*f_unf)(xo->buf, out_len, h.b_cto8, h.b_ftid);
}
xi->buf += h.sz_cpr;
xi->size -= h.sz_cpr;
}
else { // copy literal block
xread(xi, xo->buf, h.sz_cpr);
}
xo->buf += h.sz_unc;
xo->size -= h.sz_unc;
}
}
static void
upx_bzero(char *p, size_t len)
{
if (len) do {
*p++= 0;
} while (--len);
}
#define bzero upx_bzero
// The PF_* and PROT_* bits are {1,2,4}; the conversion table fits in 32 bits.
#define REP8(x) \
((x)|((x)<<4)|((x)<<8)|((x)<<12)|((x)<<16)|((x)<<20)|((x)<<24)|((x)<<28))
#define EXP8(y) \
((1&(y)) ? 0xf0f0f0f0 : (2&(y)) ? 0xff00ff00 : (4&(y)) ? 0xffff0000 : 0)
#define PF_TO_PROT(pf) \
((PROT_READ|PROT_WRITE|PROT_EXEC) & ( \
( (REP8(PROT_EXEC ) & EXP8(PF_X)) \
|(REP8(PROT_READ ) & EXP8(PF_R)) \
|(REP8(PROT_WRITE) & EXP8(PF_W)) \
) >> ((pf & (PF_R|PF_W|PF_X))<<2) ))
typedef struct {
unsigned magic;
unsigned nfat_arch;
} Fat_header;
typedef struct {
unsigned cputype;
unsigned cpusubtype;
unsigned offset;
unsigned size;
unsigned align; /* shift count; log base 2 */
} Fat_arch;
enum e8 {
FAT_MAGIC = 0xbebafeca // 0xcafebabe in big endian
};
enum e9 {
CPU_TYPE_I386 = 7,
CPU_TYPE_AMD64 = 0x01000007,
CPU_TYPE_POWERPC = 0x00000012,
CPU_TYPE_POWERPC64 = 0x01000012
};
typedef struct {
unsigned magic;
unsigned cputype;
unsigned cpysubtype;
unsigned filetype;
unsigned ncmds;
unsigned sizeofcmds;
unsigned flags;
} Mach_header;
enum e0 {
MH_MAGIC = 0xfeedface
};
enum e2 {
MH_EXECUTE = 2
};
enum e3 {
MH_NOUNDEFS = 1
};
typedef struct {
unsigned cmd;
unsigned cmdsize;
} Mach_load_command;
enum e4 {
LC_SEGMENT = 0x1,
LC_THREAD = 0x4,
LC_UNIXTHREAD = 0x5,
LC_LOAD_DYLINKER = 0xe
};
typedef struct {
unsigned cmd;
unsigned cmdsize;
char segname[16];
unsigned vmaddr;
unsigned vmsize;
unsigned fileoff;
unsigned filesize;
unsigned maxprot;
unsigned initprot;
unsigned nsects;
unsigned flags;
} Mach_segment_command;
enum e5 {
VM_PROT_READ = 1,
VM_PROT_WRITE = 2,
VM_PROT_EXECUTE = 4
};
typedef struct {
unsigned eax, ebx, ecx, edx;
unsigned edi, esi, ebp;
unsigned esp, ss;
unsigned eflags;
unsigned eip, cs;
unsigned ds, es, fs, gs;
} Mach_i386_thread_state;
typedef struct {
unsigned cmd; /* LC_THREAD or LC_UNIXTHREAD */
unsigned cmdsize; /* total size of this command */
unsigned flavor;
unsigned count; /* sizeof(following_thread_state)/4 */
Mach_i386_thread_state state;
} Mach_thread_command;
enum e6 {
i386_THREAD_STATE = 1
};
enum e7 {
i386_THREAD_STATE_COUNT = sizeof(Mach_i386_thread_state)/4
};
typedef union {
unsigned long offset; /* from start of load command to string */
char *ptr;
} Mach_lc_str;
#define MAP_FIXED 0x10
#define MAP_PRIVATE 0x02
#define MAP_ANON 0x1000
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
typedef long long off_t;
extern char *mmap(char *, size_t, unsigned, unsigned, int, off_t);
extern ssize_t pread(int, void *, size_t, off_t);
extern void bswap(void *, unsigned);
static Mach_i386_thread_state const *
do_xmap(
Mach_header const *const mhdr,
unsigned const fat_offset,
Extent *const xi,
int const fdi,
Mach_header **mhdrpp,
f_expand *const f_decompress,
f_unfilter *const f_unf
)
{
Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr);
Mach_i386_thread_state const *entry = 0;
unsigned j;
for ( j=0; j < mhdr->ncmds; ++j,
(sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc))
) if (LC_SEGMENT==sc->cmd) {
Extent xo;
size_t mlen = xo.size = sc->filesize;
char *addr = xo.buf = (char *)sc->vmaddr;
char *haddr = sc->vmsize + addr;
size_t frag = (int)addr &~ PAGE_MASK;
addr -= frag;
mlen += frag;
// Decompressor can overrun the destination by 3 bytes. [i386 only]
if (0!=mlen && addr != mmap(addr, mlen + (xi ? 3 : 0),
VM_PROT_READ | VM_PROT_WRITE,
MAP_FIXED | MAP_PRIVATE |
((xi || 0==sc->filesize) ? MAP_ANON : 0),
((0==sc->filesize) ? -1 : fdi), sc->fileoff + fat_offset) ) {
err_exit(8);
}
if (xi && 0!=sc->filesize) {
if (0==sc->fileoff && 0!=mhdrpp) {
*mhdrpp = (Mach_header *)addr;
}
unpackExtent(xi, &xo, f_decompress, f_unf);
}
/*bzero(addr, frag);*/ // fragment at lo end
frag = (-mlen) &~ PAGE_MASK; // distance to next page boundary
bzero(mlen+addr, frag); // fragment at hi end
if (0!=mlen && 0!=mprotect(addr, mlen, sc->initprot)) {
err_exit(10);
ERR_LAB
}
addr += mlen + frag; /* page boundary on hi end */
if (addr < haddr) { // need pages for .bss
if (addr != mmap(addr, haddr - addr, sc->initprot,
MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0 ) ) {
err_exit(9);
}
}
else if (xi) { // cleanup if decompressor overrun crosses page boundary
mlen = ~PAGE_MASK & (3+ mlen);
if (mlen<=3) { // page fragment was overrun buffer only
munmap(addr, mlen);
}
}
}
else if (LC_UNIXTHREAD==sc->cmd || LC_THREAD==sc->cmd) {
Mach_thread_command const *const thrc = (Mach_thread_command const *)sc;
if (i386_THREAD_STATE ==thrc->flavor
&& i386_THREAD_STATE_COUNT==thrc->count ) {
entry = &thrc->state;
}
}
return entry;
}
/*************************************************************************
// upx_main - called by our entry code
//
**************************************************************************/
Mach_i386_thread_state const *
upx_main(
Mach_header **const mhdrpp, // Out: *mhdrpp= &real Mach_header
f_unfilter *const f_unf,
f_expand *const f_decompress,
Mach_header *const mhdr, // temp char[sz_mhdr] for decompressing
size_t const sz_mhdr,
size_t volatile sz_compressed, // total length
struct l_info const *const li
)
{
Mach_i386_thread_state const *entry;
unsigned fat_offset = 0;
Extent xi, xo, xi0;
xi.buf = CONST_CAST(char *, 1+ (struct p_info const *)(1+ li)); // &b_info
xi.size = sz_compressed - (sizeof(struct l_info) + sizeof(struct p_info));
xo.buf = (char *)mhdr;
xo.size = ((struct b_info const *)xi.buf)->sz_unc;
xi0 = xi;
// Uncompress Macho headers
unpackExtent(&xi, &xo, f_decompress, 0); // never filtered?
entry = do_xmap(mhdr, fat_offset, &xi0, -1, mhdrpp, f_decompress, f_unf);
{ // Map dyld dynamic loader
Mach_load_command const *lc = (Mach_load_command const *)(1+ mhdr);
unsigned j;
for (j=0; j < mhdr->ncmds; ++j,
(lc = (Mach_load_command const *)(lc->cmdsize + (char const *)lc))
) if (LC_LOAD_DYLINKER==lc->cmd) {
char const *const dyld_name = ((Mach_lc_str const *)(1+ lc))->offset +
(char const *)lc;
int const fdi = open(dyld_name, O_RDONLY, 0);
if (0 > fdi) {
err_exit(18);
}
fat:
if ((ssize_t)sz_mhdr!=pread(fdi, (void *)mhdr, sz_mhdr, fat_offset)) {
ERR_LAB
err_exit(19);
}
switch (mhdr->magic) {
case MH_MAGIC: break;
case FAT_MAGIC: {
// stupid Apple: waste code and a page fault on EVERY execve
Fat_header *const fh = (Fat_header *)mhdr;
Fat_arch *fa = (Fat_arch *)(1+ fh);
bswap(fh, sizeof(*fh) + (fh->nfat_arch>>24)*sizeof(*fa));
for (j= 0; j < fh->nfat_arch; ++j, ++fa) {
if (CPU_TYPE_I386==fa->cputype) {
fat_offset= fa->offset;
goto fat;
}
}
} break;
} // switch
entry = do_xmap(mhdr, fat_offset, 0, fdi, 0, 0, 0);
close(fdi);
break;
}
}
return entry;
}
/*
vi:ts=4:et:nowrap
*/

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