diff --git a/.cvsignore b/.cvsignore index 0b65399d..82614b61 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,5 +1,4 @@ .cvsignore -.mfxcvsup ChangeLog.cvs* build maint diff --git a/BUGS b/BUGS index 63118845..03384d15 100644 --- a/BUGS +++ b/BUGS @@ -8,9 +8,8 @@ The Ultimate Packer for eXecutables - Copyright (c) 1996-2001 Markus Oberhumer & Laszlo Molnar - http://wildsau.idv.uni-linz.ac.at/mfx/upx.html - http://upx.tsx.org + Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar + http://upx.sourceforge.net Limitations and other things which are not (yet) supported: diff --git a/NEWS b/NEWS index fc7a6c4a..69876ee3 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ User visible changes for UPX ================================================================== -Changes in 1.12 beta (XX Jan 2001): +Changes in 1.90 beta (XX Jul 2002): * UNSTABLE BETA VERSION - DO NOT USE EXCEPT FOR TESTING * implemented several new options for finer compression control: `--all-methods', `--all-filters' and `--brute' @@ -20,6 +20,34 @@ Changes in 1.11 beta (20 Dec 2000): * reduced overall memory requirements during packing * quite a number of internal source code rearrangements +Changes in 1.22 (27 Jun 2002) + * atari/tos: the stub now flushes the CPU cache to avoid + problems on 68030+ machines + * source code: additional compiler support for Borland C++ 5.5.1, + Digital Mars C++ 8.28 and Watcom C++ 11.0c + +Changes in 1.21 (01 Jun 2002) + * New option `--crp-ms=' for slightly better compression at the cost + of higher memory requirements during compression. + Try `upx --best --crp-ms=100000'. See the docs for more info. + * source code: portability fixes + * source code: compile fixes for g++ 3.0 and g++ 3.1 + +Changes in 1.20 (23 May 2001) + * slightly faster compression + * work around a gcc problem in the latest djgpp2 distribution + * watcom/le: fixed detection of already compressed files + * win32/pe: do not compress RT_MANIFEST resource types + * win32/pe: improved the error message for empty resource sections + * [NOTE: the jump from 1.08 to 1.20 is to avoid confusion with + our unstable development releases 1.1x and 1.9x] + +Changes in 1.08 (30 Apr 2001) + * INFO: http://upx.sourceforge.net now is the new permanent UPX home page + * new native port to atari/tos + * win32/pe: shortened the identstring + * source code: portability fixes - UPX now builds cleanly under m68k CPUs + Changes in 1.07 (20 Feb 2001) * win32/pe: corrected the TLS callback check * win32/pe: really fixed that rare bug in relocation handling diff --git a/PROJECTS b/PROJECTS index f3964ef6..d4fbfc72 100644 --- a/PROJECTS +++ b/PROJECTS @@ -8,9 +8,8 @@ The Ultimate Packer for eXecutables - Copyright (c) 1996-2001 Markus Oberhumer & Laszlo Molnar - http://wildsau.idv.uni-linz.ac.at/mfx/upx.html - http://upx.tsx.org + Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar + http://upx.sourceforge.net Here are some possible projects from which you can choose if you'd like to diff --git a/README b/README index 618fb852..36acdbfb 100644 --- a/README +++ b/README @@ -8,23 +8,22 @@ The Ultimate Packer for eXecutables - Copyright (c) 1996-2001 Markus Oberhumer & Laszlo Molnar - http://wildsau.idv.uni-linz.ac.at/mfx/upx.html - http://upx.tsx.org + Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar + http://upx.sourceforge.net WARNING - UNSTABLE BETA VERSION =============================== -All versions 1.1x are unstable beta releases - use them only for testing, +All versions 1.9x are unstable beta releases - use them only for testing, and never distribute a program that is packed with them ! There will be hidden bugs. Really. -The current stable release is 1.06, and the next stable release -will be called version 1.20. +The current stable release is 1.22, and the next stable release +will be called version 2.00. -The main news since 1.06 are support for bootable Linux kernels ("vmlinuz/386") +The main news since 1.22 are support for bootable Linux kernels ("vmlinuz/386") and direct Linux ELF-to-memory decompression ("linux/elf386"), so there's no reason to use the unstable versions unless you want to try the new formats. @@ -32,10 +31,9 @@ no reason to use the unstable versions unless you want to try the new formats. WELCOME ======= -Welcome to UPX 1.0, the first production release after almost two years -of beta testing. +Welcome to UPX ! -Please don't forget to read the new LICENSE - UPX is now distributed +Please don't forget to read the file LICENSE - UPX is distributed under the GNU General Public License (GPL) with special exceptions allowing the distribution of all compressed executables, including commercial programs. @@ -54,8 +52,8 @@ and run exactly as before, with no runtime or memory penalty for most of the supported formats. UPX supports a number of different executable formats, including -Win95/98/ME/NT/2000 programs and DLLs, DOS programs, and Linux -executables and kernels. +Windows 95/98/ME/NT/2000/XP programs and DLLs, DOS programs, +and Linux executables and kernels. UPX is free software distributed under the term of the GNU General Public License. Full source code is available. @@ -64,7 +62,7 @@ UPX may be distributed and used freely, even with commercial applications. See the UPX License Agreement for details. UPX is rated number one in the well known Archive Comparison Test. Visit -http://web.act.by.net/~act/act-exepack.html +http://compression.ca/ . UPX aims to be Commercial Quality Freeware. @@ -87,7 +85,7 @@ UPX comes with ABSOLUTELY NO WARRANTY; for details see the file LICENSE. Having said that, we think that UPX is quite stable now. Indeed we have compressed lots of files without any problems. Also, the current version has undergone several months of beta testing - -actually it's almost 2 years since our first public beta. +actually it's more than 4 years since our first public beta. This is the first production quality release, and we plan that future releases will be backward compatible with this version. @@ -125,8 +123,8 @@ THE FUTURE COPYRIGHT ========= -Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer -Copyright (C) 1996-2001 Laszlo Molnar +Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer +Copyright (C) 1996-2002 Laszlo Molnar This program may be used freely, and you are welcome to redistribute it under certain conditions. diff --git a/README.SRC b/README.SRC index 884745c4..34a273bd 100644 --- a/README.SRC +++ b/README.SRC @@ -60,17 +60,17 @@ Prerequisites ------------- - first of all you need to build the UCL compression library - http://wildsau.idv.uni-linz.ac.at/mfx/ucl.html + http://www.oberhumer.com/opensource/ucl/ Tools needed to build/modify the UPX sources -------------------------------------------- - - A modern C++ compiler like gcc 2.95.2 or Visual C++ 6 + - A modern C++ compiler like gcc 2.95.3 or Visual C++ 6 (egcs 1.1.x may work, half-baked implementations like Borland C++ 5.5 won't) - GNU make for Win32 - http://wildsau.idv.uni-linz.ac.at/mfx/download/upx/tools/ + http://upx.sourceforge.net/download/tools/ - GNU make for DOS ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/ @@ -81,34 +81,35 @@ To compile the packer sources set the environment variable UCLDIR to point to your UCL installation, e.g. - set UCLDIR=c:\src\ucl-0.92 (DOS / Windows) - export UCLDIR=$HOME/local/src/ucl-0.92 (Unix) + set UCLDIR=c:\src\ucl-1.01 (DOS / Windows) + export UCLDIR=$HOME/local/src/ucl-1.01 (Unix) then type - make target=linux # on linux - make target=djgpp2 # for djgpp2 - make target=mingw32 # for mingw32 - make target=no-cygwin # for mingw32 as included in cygwin - make target=msc # for Visual C++ 6.0 + make target=linux # on linux + make target=djgpp2 # for djgpp2 + make target=mingw32 # for mingw32 + make target=cygwin # cygwin 1.3.x + make target=no-cygwin # for mingw32 as included in cygwin + make target=vc6 # for Visual C++ 6.0 If you want to modify the stub sources you'll also need ------------------------------------------------------- - - Nasm - the Netwide Assembler - http://www.cryogen.com/Nasm - - - Perl 5.004 or better - ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/perl*b.zip + - Nasm 0.98.08 - the Netwide Assembler + http://upx.sourceforge.net/download/tools/ + http://nasm.sourceforge.net/ - A68K - a 68000 macro assembler - http://wildsau.idv.uni-linz.ac.at/mfx/download/upx/tools/ + http://upx.sourceforge.net/download/tools/ - djasm - an assembler for the djgpp stub - http://wildsau.idv.uni-linz.ac.at/mfx/download/upx/tools/ + http://upx.sourceforge.net/download/tools/ - - Linux (for the linux/i386 stubs) + - Perl 5.004 or better + + - Linux (for the linux/386 stubs) Misc. notes diff --git a/THANKS b/THANKS index d9861f86..c67c7645 100644 --- a/THANKS +++ b/THANKS @@ -8,9 +8,8 @@ The Ultimate Packer for eXecutables - Copyright (c) 1996-2001 Markus Oberhumer & Laszlo Molnar - http://wildsau.idv.uni-linz.ac.at/mfx/upx.html - http://upx.tsx.org + Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar + http://upx.sourceforge.net .___.. . diff --git a/TODO b/TODO index 1c006ce8..428d4e00 100644 --- a/TODO +++ b/TODO @@ -2,12 +2,24 @@ UPX TODO list. Last updated 2002-07-16. - rotten code, bring back to life and resync with UPX 1.2 branch + [mostly done] + +- resync stub with UPX 1.2 branch - p_psx.cpp (psx/exe) needs some work - src/stub/l_lx_elf86.lds does not work with current binutils (generates a several MB file) +- check all to make sure they are not invalid + + +TEST: + +- test new linux formats +- test unpacking of old linux formats +- test new filters + IMPROVED COMPRESSION RATIO diff --git a/src/Makefile b/src/Makefile index 42d7f056..3865faff 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,12 +1,19 @@ -# UPX Makefile (GNU make) - works with djgpp2/win32/unix +# +# UPX Makefile (GNU make) - works with unix/win32/djgpp2 # # usage: -# `make target=linux' # linux -# `make target=djggp2' # djggp2 2.03 -# `make target=cygwin' # cygwin 1.1.x -# `make target=mingw32' # mingw32 -# `make target=no-cygwin' # mingw32 as included in cygwin 1.1.x -# `make target=vc6' # Visual C++ 6.0 +# `make target=linux' # linux +# `make target=djggp2' # dos32 - djggp2 2.03 +# `make target=cygwin' # win32 - cygwin 1.3.x +# `make target=mingw32' # win32 - mingw32 +# `make target=no-cygwin' # win32 - mingw32 as included in cygwin 1.3.x +# `make target=bcc' # win32 - Borland C++ 5.5.1 +# `make target=dmc' # win32 - Digital Mars C++ 8.28 +# `make target=vc6' # win32 - Visual C++ 6.0 +# `make target=wcc' # win32 - Watcom C++ 11.0c +# `make target=cross-m68k-linux' # m68k-linux cross compiler +# `make target=cross-mingw32' # i586-mingw32msvc cross compiler +# `make target=cross-mint' # m68k-atari-mint cross compiler # @@ -14,7 +21,7 @@ ifeq ($(strip $(UCLDIR)),) # change this to reflect where the UCL library is -UCLDIR = $(HOME)/local/src/ucl-0.92 +UCLDIR = $(HOME)/local/src/ucl-1.01 endif DEBUG = 0 @@ -28,23 +35,28 @@ SHELL = /bin/sh .SUFFIXES: -.SUFFIXES: .a .c .cpp .exe .lib .o .obj +.SUFFIXES: .a .c .cpp .exe .lib .o .obj .rc .res .ttp srcdir = . top_srcdir = .. +VPATH = $(srcdir) + # auto-detect the target unless given on the commandline -target = djgpp2 +ifeq ($(strip $(target)),) +##target = djgpp2 ifneq ($(strip $(wildcard /usr/include/linux)),) target = linux endif -ifneq ($(strip $(wildcard /platform/sun4?/kernel/unix)),) -target = sparc +##ifneq ($(strip $(wildcard /platform/sun4?/kernel/unix)),) +##target = sparc +##endif endif -ifeq ($(target),msc) -override target = vc6 + +ifeq ($(strip $(target)),) +include please_specify_a_target endif @@ -77,44 +89,55 @@ OBJECTS2 = \ OBJECTS3 = OBJECTS = $(OBJECTS1) $(OBJECTS2) $(OBJECTS3) +LIBS = +RESOURCES = # /*********************************************************************** # // compiler settings # ************************************************************************/ -# default to a gcc unix-type compiler +### +### default compiler (gcc under unix) +### + +o = .o +a = .a +e = + CC = gcc -CXX = $(CC) DEFS = +INCLUDES = INCLUDES = -I. -I$(srcdir) CFLAGS_OUTPUT = -o $@ -CXXFLAGS_OUTPUT = $(CFLAGS_OUTPUT) -LINK_EXE = $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) +LINK_EXE = $(CXXLD) $(LDFLAGS) -o $@ $^ $(LDLIBS) STUBEDIT_EXE = STUBIFY_EXE = CHMOD_EXE = -o = .o -a = .a -e = .exe +# C++ defaults are set later +CXX = +CXXLD = +CXXFLAGS_OUTPUT = ### ### gcc defaults ### -##CFLAGS_O = -Os -CFLAGS_O = -O2 ##CFLAGS_WERROR = -Werror +CFLAGS_WERROR = CFLAGS_W = $(CFLAGS_WERROR) -CFLAGS_W += -Wall -W -Wcast-align -Wcast-qual -Wmissing-declarations -Wmissing-prototypes -Wshadow -Wwrite-strings -##CFLAGS_M = -fno-builtin -## CFLAGS_M += -malign-functions=0 -malign-jumps=0 -malign-loops=0 +CFLAGS_W += -Wall -W -Wcast-align -Wcast-qual -Wmissing-prototypes -Wpointer-arith -Wshadow -Wwrite-strings +CFLAGS_M = +##CFLAGS_M += -fno-builtin +##CFLAGS_M += -malign-functions=0 -malign-jumps=0 -malign-loops=0 +##CFLAGS_O = -Os -fstrict-aliasing +##CFLAGS_O = -O2 -fstrict-aliasing +CFLAGS_O = -O2 -fno-strict-aliasing -CFLAGS = $(CFLAGS_W) $(CFLAGS_O) $(CFLAGS_M) -CFLAGS += -Wp,-MMD,.deps/$(*F).pp +CFLAGS = $(CFLAGS_W) $(CFLAGS_M) $(CFLAGS_O) CXXFLAGS = $(CFLAGS) -Wsynth -fconserve-space CXXFLAGS1 = $(CXXFLAGS) ##CXXFLAGS1 += -fasynchronous-exceptions @@ -131,9 +154,9 @@ else LDFLAGS = -s endif LDFLAGS += -Wl,-Map,$T.map -LDLIBS = LDLIBS = -lz LIBDIRS = +DOS_LDLIBS = DOS_LIBDIRS = @@ -154,7 +177,7 @@ ifneq ($(strip $(wildcard $(NRVDIR)/include/nrv)),) include $(srcdir)/Makefile.inc endif -tmp := -Wl,--rpath, +override tmp := -Wl,--rpath, LDRPATH := $(addprefix $(tmp),$(LIBDIRS)) LIBDIRS += . LDLIBDIRS := $(addprefix -L,$(LIBDIRS)) @@ -164,17 +187,18 @@ LDFLAGS += $(LDLIBDIRS) ### -### linux/i386 +### Linux ### ifeq ($(target),linux) -e = -###CC = /usr/local/packages/gcc-cvs/bin/g++ +override arch := $(shell uname -m | sed -e 's/^i[3456789]86$$/i386/') DEFS += '-DUPX_CONFIG_H="config_h/linux.h"' -##CFLAGS_M += -mno-schedule-prologue -CFLAGS_M += -march=i386 -mcpu=pentium -CFLAGS_WERROR = -Werror LDLIBS += -lmcheck +ifeq ($(arch),i386) + CC += -march=i386 -mcpu=i586 + ##CFLAGS_M += -mno-schedule-prologue +endif +##CFLAGS_WERROR = -Werror ifeq (1,2) # checkergcc CC = checkergcc @@ -187,21 +211,83 @@ ifeq ($(DEBUG),1) else ##LDFLAGS += -static STUBEDIT_EXE = objcopy -S -R .comment -R .note $@ - STUBIFY_EXE = perl $(srcdir)/stub/scripts/brandelf.pl $@ + ifeq ($(arch),i386) + STUBIFY_EXE = perl $(srcdir)/stub/scripts/brandelf.pl $@ + CHMOD_EXE = chmod 755 $@ + endif endif -CHMOD_EXE = chmod 755 $@ endif endif # linux +### +### Linux cross compilers +### + +ifeq ($(target),cross-m68k-linux) +CC = m68k-linux-gcc +DEFS += '-DUPX_CONFIG_H="config_h/linux.h"' +##LDLIBS += -lmcheck +endif # cross-m68k-linux + + +### +### sparc-sun-solaris2.8 +### + +ifeq ($(target),sparc) +CC = gcc +DEFS += '-DUPX_CONFIG_H="config_h/sparc_sun_solaris28.h"' +endif # sparc + + +ifeq ($(target),XXX-sparc) +DEFS += '-DUPX_CONFIG_H="config_h/sparc_sun_solaris28.h"' +INCLUDES += -I/home/ethmola/local/include + +ifeq (1,2) # native compiler + CFLAGS = -O0 -g + CXXFLAGS1 = + CXXFLAGS2 = + DEFS += -DUSE_STDNAMESPACE +else # gcc + CFLAGS += -O0 -gstabs+ +endif + +ifeq (1,2) # purify + DEFS += -D__PURIFY__ + CXXLD := purify $(CXXLD) +endif + +endif # XXX-sparc + + +### +### Atari cross compiler +### + +ifeq ($(target),cross-mint) +e = .ttp +CC = m68k-atari-mint-gcc +CC += -m68000 +endif + +ifeq ($(target),cross-mint-m68040) +e = .ttp +CC = m68k-atari-mint-gcc +CC += -m68040 +endif + + ### ### djgpp2 ### ifeq ($(target),djgpp2) -CFLAGS_M += -mno-schedule-prologue -CFLAGS_M += -march=i386 -mcpu=pentium +e = .exe +CC += -march=i386 -mcpu=i586 +##CFLAGS_M += -mno-schedule-prologue CFLAGS_WERROR = -Werror STUBEDIT_EXE = stubedit $@ bufsize=0xfc00 ifneq ($(strip $(wildcard $(DJDIR)/bin/mfxdjstubify.exe)),) @@ -217,113 +303,50 @@ endif # djgpp2 ### ifeq ($(target),cygwin) -CFLAGS_M += -mno-schedule-prologue -CFLAGS_M += -march=i386 -mcpu=pentium -CFLAGS_WERROR = -Werror +e = .exe +CC += -march=i386 -mcpu=i586 +##CFLAGS_M += -mno-schedule-prologue endif ifeq ($(target),mingw32) -CFLAGS_M += -mno-schedule-prologue -CFLAGS_M += -march=i386 -mcpu=pentium +e = .exe +CC = gcc -mno-cygwin +CC += -march=i386 -mcpu=i586 +##CFLAGS_M += -mno-schedule-prologue endif # mingw32 as included in cygwin ifeq ($(target),no-cygwin) +e = .exe CC = gcc -mno-cygwin -CFLAGS_M += -mno-schedule-prologue -CFLAGS_M += -march=i386 -mcpu=pentium -CFLAGS_WERROR = -Werror +CC += -march=i386 -mcpu=i586 +##CFLAGS_M += -mno-schedule-prologue +endif + +# mingw32 cross compiler +ifeq ($(target),cross-mingw32) +e = .exe +CC = i586-mingw32msvc-gcc +CC += -march=i386 -mcpu=i586 +##CFLAGS_M += -mno-schedule-prologue endif ### -### Microsoft 32-bit C/C++ Compiler 12.00 (aka Visual C++ 6) -### - -ifeq ($(target),vc6) -o = .obj -a = .lib -CC = cl -nologo -CFLAGS = -W4 -WX -CXXFLAGS1 = $(CFLAGS) -GR -GX -EHa -CXXFLAGS2 = $(CFLAGS) -LDFLAGS = -LINK_LDFLAGS = /link /map:$T.map - -ifneq ($(strip $(DOS_LIBDIRS)),) -LIB := $(DOS_LIBDIRS);$(LIB) -endif -export LIB - -ifeq (1,2) - # statically link libc.lib - CC += -ML - ##LDLIBS = $(u)_s.lib zlib_s.lib setargv.obj - LDLIBS = $(u)_s.lib setargv.obj -else - # link against msvcrt.dll - CC += -MD - LDLIBS = $(DOS_LDLIBS) zlib.lib setargv.obj -endif -ifeq ($(DEBUG),1) - CFLAGS += -Od -ZI - LINK_LDFLAGS += /debug -else - CFLAGS += -O2 -GF - LINK_LDFLAGS += /release -endif - -##LINK_LDFLAGS += /verbose -LINK_EXE = $(CC) $(LDFLAGS) -Fe$@ $^ $(LDLIBS) $(LINK_LDFLAGS) - -endif # vc6 - - -### -### sparc -### - -ifeq ($(target),sparc) -e = -DEFS += '-DUPX_CONFIG_H="config_h/sparc.h"' -INCLUDES += -I/home/ethmola/local/include - -ifeq (1,2) # native compiler - CFLAGS = -O0 -g - CXXFLAGS1 = - CXXFLAGS2 = - CFLAGS_M = - DEFS += -DUSE_STDNAMESPACE -else # gcc - CFLAGS += -O0 -gstabs+ -endif - -ifeq (1,2) # purify - DEFS += -D__PURIFY__ - LDFLAGS = -g -L/home/ethmola/local/lib - LINK_EXE = purify $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) -else - LDFLAGS += -g -L/home/ethmola/local/lib - LINK_EXE = $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) -endif - -endif # sparc - - -### -### Borland C++ 5.5 (DOES NOT WORK - INCOMPLETE C++ IMPLEMENTATION) +### Borland C++ 5.5.1 ### ifeq ($(target),bcc) o = .obj a = .lib -CC = bcc32 -CFLAGS = -w -w-par +e = .exe +CC = bcc32 -q +CFLAGS = -w -w-aus -g1 CXXFLAGS1 = $(CFLAGS) -CXXFLAGS2 = $(CFLAGS) +CXXFLAGS2 = $(CFLAGS) -x- -xd- -RT- CFLAGS_OUTPUT = -o$@ LDFLAGS = -LDLIBS = $(DOS_LDLIBS) zlib.lib +LDLIBS = $(DOS_LDLIBS) ifneq ($(strip $(DOS_LIBDIRS)),) LIB := $(DOS_LIBDIRS);$(LIB) @@ -336,15 +359,131 @@ else CFLAGS += -O2 -d endif -LINK_EXE = $(CC) $(LDFLAGS) -e$@ $^ $(LDLIBS) +LINK_EXE = $(CXXLD) $(LDFLAGS) -e$@ $^ $(LDLIBS) endif # bcc ### -### malloc debuggers and memory checkers +### Digital Mars C++ 8.28 ### +ifeq ($(target),dmc) +o = .obj +a = .lib +e = .exe +CC = sc -mn +CFLAGS = -w- -wx +CXXFLAGS1 = $(CFLAGS) -Aa -Ab -Ae -Ar +CXXFLAGS2 = $(CFLAGS) -Aa -Ab +CFLAGS_OUTPUT = -o$@ +LDFLAGS = +LDLIBS = $(DOS_LDLIBS) + +ifneq ($(strip $(DOS_LIBDIRS)),) +LIB := $(DOS_LIBDIRS);$(LIB) +endif +export LIB + +ifeq ($(DEBUG),1) + CFLAGS += -o- -g -s +else + CFLAGS += -o +endif + +LINK_EXE = $(CXXLD) $(LDFLAGS) -o$@ $^ $(LDLIBS) + +endif # dmc + + +### +### Visual C++ 6 (aka Microsoft C/C++ Compiler 12.00) +### + +ifeq ($(target),vc6) +o = .obj +a = .lib +e = .exe +CC = cl -nologo +CFLAGS = -W4 -WX +CXXFLAGS1 = $(CFLAGS) -EHac -GR +CXXFLAGS2 = $(CFLAGS) +LDFLAGS = +LINK_LDFLAGS = /link /map:$T.map + +ifneq ($(strip $(DOS_LIBDIRS)),) +LIB := $(DOS_LIBDIRS);$(LIB) +endif +export LIB + +ifeq (1,2) + # statically link libc.lib + CC += -ML + LDLIBS = $(u)_s.lib setargv.obj +else + # link against msvcrt.dll + CC += -MD + LDLIBS = $(DOS_LDLIBS) setargv.obj +endif +ifeq ($(DEBUG),1) + CFLAGS += -Od -ZI + LINK_LDFLAGS += /debug +else + CFLAGS += -O2 -GF + LINK_LDFLAGS += /release +endif +RESOURCES = upx.res + +##LINK_LDFLAGS += /verbose +LINK_EXE = $(CXXLD) $(LDFLAGS) -Fe$@ $^ $(LDLIBS) $(LINK_LDFLAGS) + +endif # vc6 + + +### +### Watcom C++ 11.0c +### + +ifeq ($(target),wcc) +o = .obj +a = .lib +e = .exe +CC = wcl386 -zq -bt=nt -mf -5r +CFLAGS = -zc -w5 -we +CXXFLAGS1 = $(CFLAGS) -xs -xr +CXXFLAGS2 = $(CFLAGS) +CFLAGS_OUTPUT = -fo=$@ +LDFLAGS = -k0x100000 -fm +LDLIBS = $(DOS_LDLIBS) + +INCLUDES:=$(strip $(subst /,\\,$(INCLUDES))) +ifeq (1,2) + WCL386:=$(INCLUDES) + export WCL386 + INCLUDES:= +endif + +ifneq ($(strip $(DOS_LIBDIRS)),) +LIB := $(DOS_LIBDIRS);$(LIB) +endif +export LIB + +ifeq ($(DEBUG),1) + CFLAGS += +else + # note: it seems that the optimizer is generating bad code with `-ox' + CFLAGS += -olr +endif + +LINK_EXE = $(CXXLD) $(LDFLAGS) -fe=$@ $^ $(LDLIBS) + +endif # wcc + + +# /*********************************************************************** +# // malloc debuggers and memory checkers +# ************************************************************************/ + ifeq (1,2) LDLIBS += -lefence endif @@ -367,17 +506,44 @@ ifeq (1,2) endif -### -### extra flags -### +# /*********************************************************************** +# // finish settings +# ************************************************************************/ +# C++ defaults +ifeq ($(strip $(CXX)),) + ifeq ($(strip $(CC)),gcc) + CXX = g++ + else + CXX = $(CC) + endif +endif +ifeq ($(strip $(CXXLD)),) + CXXLD = $(CXX) +endif +ifeq ($(strip $(CXXFLAGS_OUTPUT)),) + CXXFLAGS_OUTPUT = $(CFLAGS_OUTPUT) +endif + + +# extra flags +DEFS += $(EXTRA_DEFS) CFLAGS += $(EXTRA_CFLAGS) +CFLAGS_W += $(EXTRA_CFLAGS_W) +CFLAGS_M += $(EXTRA_CFLAGS_M) +CFLAGS_O += $(EXTRA_CFLAGS_O) CXXFLAGS1 += $(EXTRA_CXXFLAGS1) CXXFLAGS2 += $(EXTRA_CXXFLAGS2) LDFLAGS += $(EXTRA_LDFLAGS) LDLIBS += $(EXTRA_LDLIBS) +# To better deal with asynchronous exceptions we compile all source +# files with exception handling and RTTI enabled - the size overhead +# is negligible. +CXXFLAGS2 = $(CXXFLAGS1) + + # /*********************************************************************** # // main targets # ************************************************************************/ @@ -386,7 +552,7 @@ all: $(upx_exe) .PHONY: all unupx mostlyclean clean distclean maintainer-clean untabify tags -$(upx_exe): $(OBJECTS) $(LIBS) +$(upx_exe): $(OBJECTS) $(LIBS) $(RESOURCES) $(LINK_EXE) $(STUBEDIT_EXE) $(STUBIFY_EXE) @@ -404,9 +570,9 @@ mostlyclean: -rm -f *.d *.err *.i *.log *.map *~ gdb-trans* clean: mostlyclean - -rm -f *.a *.lib *.o *.obj tags TAGS ID + -rm -f *.a *.lib *.o *.obj *.res *.tds tags TAGS ID -rm -f *.idb *.pdb - -rm -f upx upx.exe upx_nrv upx_nrv.exe upx_ucl upx_ucl.exe + -rm -f upx upx.exe upx.ttp upx_nrv upx_nrv.exe upx_nrv.ttp upx_ucl upx_ucl.exe upx_ucl.ttp -rm -rf .deps distclean: clean @@ -429,36 +595,25 @@ ID: # // rules # ************************************************************************/ -.c$o: +%$o : %.c $(CC) $(DEFS) $(INCLUDES) $(CFLAGS) $(CFLAGS_OUTPUT) -c $< -.cpp$o: - $(CXX) $(DEFS) $(INCLUDES) $(CXXFLAGS1) $(CXXFLAGS_OUTPUT) -c $< - -$(OBJECTS1): %$o : %.cpp +%$o : %.cpp $(CXX) $(DEFS) $(INCLUDES) $(CXXFLAGS1) $(CXXFLAGS_OUTPUT) -c $< +ifneq ($(strip $(OBJECTS2)),) $(OBJECTS2): %$o : %.cpp $(CXX) $(DEFS) $(INCLUDES) $(CXXFLAGS2) $(CXXFLAGS_OUTPUT) -c $< - -ifneq ($(strip $(OBJECTS3)),) -$(OBJECTS3): %$o : %.c - $(CC) $(DEFS) $(INCLUDES) $(CFLAGS) $(CFLAGS_OUTPUT) -c $< endif +%.res : %.rc + rc -l 0x409 -fo$@ $< + # /*********************************************************************** # // dependencies # ************************************************************************/ -ifeq ($(strip $(wildcard .deps)),) - DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) -else - DEP_FILES := $(wildcard .deps/*.pp) - ifneq ($(strip $(DEP_FILES)),) - include $(DEP_FILES) - endif -endif - +include $(srcdir)/Makefile.dep # vi:nowrap diff --git a/src/Makefile.dep b/src/Makefile.dep new file mode 100644 index 00000000..7d12a5f1 --- /dev/null +++ b/src/Makefile.dep @@ -0,0 +1,16 @@ + +# /*********************************************************************** +# // automated dependencies +# ************************************************************************/ + +CFLAGS += -Wp,-MMD,.deps/$(*F).pp + +ifeq ($(strip $(wildcard .deps)),) + DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) +else + DEP_FILES := $(wildcard .deps/*.pp) + ifneq ($(strip $(DEP_FILES)),) + include $(DEP_FILES) + endif +endif + diff --git a/src/Makefile.inc b/src/Makefile.inc index a8a76086..49ff77c8 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -1,11 +1,12 @@ UDIR := $($(U)DIR) +ifneq ($(strip $(wildcard $(UDIR)/include)),) # { include DEFS += -DWITH_$(U) - -ifneq ($(strip $(wildcard $(UDIR)/include)),) INCLUDES += -I$(UDIR)/include -endif +ifneq ($(strip $(wildcard $(UDIR)/build/$(target)/src/.libs)),) +LIBDIRS += $(UDIR)/build/$(target)/src/.libs +endif ifneq ($(strip $(wildcard $(UDIR)/src/.libs)),) LIBDIRS += $(UDIR)/src/.libs endif @@ -35,3 +36,4 @@ LIBDIRS := $(LIBDIRS) LDLIBS := $(LDLIBS) DOS_LDLIBS := $(DOS_LDLIBS) +endif # } include diff --git a/src/bele.h b/src/bele.h index ef1cabb2..f8b39bb0 100644 --- a/src/bele.h +++ b/src/bele.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -34,18 +34,18 @@ // access memory in BigEndian and LittleEndian byte order **************************************************************************/ -inline unsigned short get_be16(const void *bb) +inline unsigned get_be16(const void *bb) { - const upx_bytep const b = reinterpret_cast(bb); + const upx_bytep b = reinterpret_cast(bb); unsigned v; v = (unsigned) b[1] << 0; v |= (unsigned) b[0] << 8; - return (unsigned short) v; + return v; } inline void set_be16(void *bb, unsigned v) { - upx_bytep const b = reinterpret_cast(bb); + upx_bytep b = reinterpret_cast(bb); b[1] = (unsigned char) (v >> 0); b[0] = (unsigned char) (v >> 8); } @@ -53,7 +53,7 @@ inline void set_be16(void *bb, unsigned v) inline unsigned get_be32(const void *bb) { - const upx_bytep const b = reinterpret_cast(bb); + const upx_bytep b = reinterpret_cast(bb); unsigned v; v = (unsigned) b[3] << 0; v |= (unsigned) b[2] << 8; @@ -64,7 +64,7 @@ inline unsigned get_be32(const void *bb) inline void set_be32(void *bb, unsigned v) { - upx_bytep const b = reinterpret_cast(bb); + upx_bytep b = reinterpret_cast(bb); b[3] = (unsigned char) (v >> 0); b[2] = (unsigned char) (v >> 8); b[1] = (unsigned char) (v >> 16); @@ -72,9 +72,9 @@ inline void set_be32(void *bb, unsigned v) } -inline unsigned short get_le16(const void *bb) +inline unsigned get_le16(const void *bb) { - const upx_bytep const b = reinterpret_cast(bb); + const upx_bytep b = reinterpret_cast(bb); unsigned v; #if defined(__i386__) v = * (const unsigned short *) b; @@ -82,12 +82,12 @@ inline unsigned short get_le16(const void *bb) v = (unsigned) b[0] << 0; v |= (unsigned) b[1] << 8; #endif - return (unsigned short) v; + return v; } inline void set_le16(void *bb, unsigned v) { - upx_bytep const b = reinterpret_cast(bb); + upx_bytep b = reinterpret_cast(bb); #if defined(__i386__) (* (unsigned short *) b) = (unsigned short) v; #else @@ -99,7 +99,7 @@ inline void set_le16(void *bb, unsigned v) inline unsigned get_le24(const void *bb) { - const upx_bytep const b = reinterpret_cast(bb); + const upx_bytep b = reinterpret_cast(bb); unsigned v; v = (unsigned) b[0] << 0; v |= (unsigned) b[1] << 8; @@ -109,7 +109,7 @@ inline unsigned get_le24(const void *bb) inline void set_le24(void *bb, unsigned v) { - upx_bytep const b = reinterpret_cast(bb); + upx_bytep b = reinterpret_cast(bb); b[0] = (unsigned char) (v >> 0); b[1] = (unsigned char) (v >> 8); b[2] = (unsigned char) (v >> 16); @@ -118,7 +118,7 @@ inline void set_le24(void *bb, unsigned v) inline unsigned get_le32(const void *bb) { - const upx_bytep const b = reinterpret_cast(bb); + const upx_bytep b = reinterpret_cast(bb); unsigned v; #if defined(__i386__) v = * (const unsigned *) b; @@ -133,7 +133,7 @@ inline unsigned get_le32(const void *bb) inline void set_le32(void *bb, unsigned v) { - upx_bytep const b = reinterpret_cast(bb); + upx_bytep b = reinterpret_cast(bb); #if defined(__i386__) (* (unsigned *) b) = v; #else @@ -163,7 +163,8 @@ public: BE16& operator |= (unsigned v) { set_be16(d, get_be16(d) | v); return *this; } operator const unsigned () const { return get_be16(d); } -}; +} +__attribute_packed; class BE32 @@ -180,7 +181,8 @@ public: BE32& operator |= (unsigned v) { set_be32(d, get_be32(d) | v); return *this; } operator const unsigned () const { return get_be32(d); } -}; +} +__attribute_packed; class LE16 @@ -197,7 +199,8 @@ public: LE16& operator |= (unsigned v) { set_le16(d, get_le16(d) | v); return *this; } operator const unsigned () const { return get_le16(d); } -}; +} +__attribute_packed; class LE32 @@ -214,7 +217,8 @@ public: LE32& operator |= (unsigned v) { set_le32(d, get_le32(d) | v); return *this; } operator const unsigned () const { return get_le32(d); } -}; +} +__attribute_packed; /************************************************************************* @@ -242,6 +246,27 @@ inline bool operator < (const LE32& v1, const LE32& v2) } +template +inline T* operator + (T* ptr, const BE16& v) { return ptr + (const unsigned) v; } +template +inline T* operator - (T* ptr, const BE16& v) { return ptr - (const unsigned) v; } + +template +inline T* operator + (T* ptr, const BE32& v) { return ptr + (const unsigned) v; } +template +inline T* operator - (T* ptr, const BE32& v) { return ptr - (const unsigned) v; } + +template +inline T* operator + (T* ptr, const LE16& v) { return ptr + (const unsigned) v; } +template +inline T* operator - (T* ptr, const LE16& v) { return ptr - (const unsigned) v; } + +template +inline T* operator + (T* ptr, const LE32& v) { return ptr + (const unsigned) v; } +template +inline T* operator - (T* ptr, const LE32& v) { return ptr - (const unsigned) v; } + + /************************************************************************* // misc **************************************************************************/ @@ -255,10 +280,12 @@ int le32_compare(const void *e1, const void *e2); // just for testing... #if 0 && defined(__i386__) && defined(__GNUC__) - typedef unsigned short LE16_unaligned __attribute__((aligned(1))); - typedef unsigned int LE32_unaligned __attribute__((aligned(1))); +# if (__GNUC_VERSION_HEX__ >= 0x030100) + typedef unsigned short LE16_unaligned __attribute__((__packed__,__aligned__(1))); + typedef unsigned int LE32_unaligned __attribute__((__packed__,__aligned__(1))); # define LE16 LE16_unaligned # define LE32 LE32_unaligned +# endif #endif diff --git a/src/c_file.cpp b/src/c_file.cpp index ef1646c7..eb9a900c 100644 --- a/src/c_file.cpp +++ b/src/c_file.cpp @@ -1,9 +1,9 @@ -/* c_file.cpp -- file console output +/* c_file.cpp -- This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ diff --git a/src/c_init.cpp b/src/c_init.cpp index 4f34bf89..dcb44a66 100644 --- a/src/c_init.cpp +++ b/src/c_init.cpp @@ -1,9 +1,9 @@ -/* c_init.cpp -- console initialization +/* c_init.cpp -- This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ diff --git a/src/c_none.cpp b/src/c_none.cpp index 7278a958..25898ced 100644 --- a/src/c_none.cpp +++ b/src/c_none.cpp @@ -1,9 +1,9 @@ -/* c_none.cpp -- dummy console output +/* c_none.cpp -- This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ diff --git a/src/c_screen.cpp b/src/c_screen.cpp index 257f9956..7b39982b 100644 --- a/src/c_screen.cpp +++ b/src/c_screen.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -196,7 +196,7 @@ static void print0(FILE *f, const char *ss) // Note: // We use 2 passes to avoid unnecessary system calls because - // scrollUp() under Win95/98 is *extremely* slow. + // scrollUp() under Win32 is *extremely* slow. UNUSED(f); screen->getCursor(screen,&old_cx,&old_cy); diff --git a/src/compress.cpp b/src/compress.cpp index 9927e63e..800163c0 100644 --- a/src/compress.cpp +++ b/src/compress.cpp @@ -1,9 +1,9 @@ -/* compress.cpp -- interface to the compression library +/* compress.cpp -- This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,17 +21,58 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ #include "conf.h" +#include "version.h" -#if defined(WITH_UCL) && !defined(WITH_NRV) +#if 0 && defined(WITH_NRV) && defined(__i386__) +# define NRV_USE_ASM +#endif +#if 0 && defined(WITH_UCL) && defined(__i386__) +# define UCL_USE_ASM +#endif +#if defined(WITH_NRV) +# include +# include +//# include +# if !defined(NRV_VERSION) || (NRV_VERSION < 0x008000L) +# error +# endif + NRV_EXTERN_CDECL(int) nrv2b_99_compress_internal(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2d_99_compress_internal(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2e_99_compress_internal(const upx_byte *, ...); +#elif defined(WITH_UCL) # define nrv2b_99_compress_internal ucl_nrv2b_99_compress # define nrv2d_99_compress_internal ucl_nrv2d_99_compress -# if 0 && defined(__i386__) +# define nrv2e_99_compress_internal ucl_nrv2e_99_compress +#endif +#if 1 && defined(WITH_NRV) && defined(NRV_USE_ASM) +# if 1 && defined(NRV_USE_ASM) +# define nrv2b_decompress_safe_8 nrv2b_decompress_asm_safe_8 +# define nrv2b_decompress_safe_le16 nrv2b_decompress_asm_safe_le16 +# define nrv2b_decompress_safe_le32 nrv2b_decompress_asm_safe_le32 +# define nrv2d_decompress_safe_8 nrv2d_decompress_asm_safe_8 +# define nrv2d_decompress_safe_le16 nrv2d_decompress_asm_safe_le16 +# define nrv2d_decompress_safe_le32 nrv2d_decompress_asm_safe_le32 +# define nrv2e_decompress_safe_8 nrv2e_decompress_asm_safe_8 +# define nrv2e_decompress_safe_le16 nrv2e_decompress_asm_safe_le16 +# define nrv2e_decompress_safe_le32 nrv2e_decompress_asm_safe_le32 +# endif + NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_8(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_le16(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_le32(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_8(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_le16(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_le32(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_8(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_le16(const upx_byte *, ...); + NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_le32(const upx_byte *, ...); +#elif defined(WITH_UCL) +# if defined(UCL_USE_ASM) # include # define nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8 # define nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_asm_safe_le16 @@ -39,6 +80,9 @@ # define nrv2d_decompress_safe_8 ucl_nrv2d_decompress_asm_safe_8 # define nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_asm_safe_le16 # define nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_asm_safe_le32 +# define nrv2e_decompress_safe_8 ucl_nrv2e_decompress_asm_safe_8 +# define nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_asm_safe_le16 +# define nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_asm_safe_le32 # else # define nrv2b_decompress_safe_8 ucl_nrv2b_decompress_safe_8 # define nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_safe_le16 @@ -46,36 +90,12 @@ # define nrv2d_decompress_safe_8 ucl_nrv2d_decompress_safe_8 # define nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_safe_le16 # define nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_safe_le32 +# define nrv2e_decompress_safe_8 ucl_nrv2e_decompress_safe_8 +# define nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_safe_le16 +# define nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_safe_le32 # endif -#endif - -#if defined(WITH_NRV) -# include -# include -# if !defined(NRV_VERSION) || (NRV_VERSION < 0x007300L) -# error -# endif -# if 1 && defined(__i386__) -# define nrv2b_decompress_safe_8 nrv2b_decompress_asm_safe_8 -# define nrv2b_decompress_safe_le16 nrv2b_decompress_asm_safe_le16 -# define nrv2d_decompress_safe_8 nrv2d_decompress_asm_safe_8 -# define nrv2d_decompress_safe_le16 nrv2d_decompress_asm_safe_le16 -# if (NRV_VERSION < 0x008000L) -# define nrv2b_decompress_safe_le32 nrv2b_decompress_asm_safe -# define nrv2d_decompress_safe_le32 nrv2d_decompress_asm_safe -# else -# define nrv2b_decompress_safe_le32 nrv2b_decompress_asm_safe_le32 -# define nrv2d_decompress_safe_le32 nrv2d_decompress_asm_safe_le32 -# endif -# endif - NRV_EXTERN_CDECL(int) nrv2b_99_compress_internal(...); - NRV_EXTERN_CDECL(int) nrv2d_99_compress_internal(...); - NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_8(...); - NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_le16(...); - NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_le32(...); - NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_8(...); - NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_le16(...); - NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_le32(...); +#else +# error #endif #if 0 && defined(WITH_ZLIB) && defined(M_ZLIB) @@ -87,14 +107,11 @@ // **************************************************************************/ -unsigned upx_adler32(unsigned adler, const void *buf, unsigned len) +unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) { - if (buf == NULL) - { - assert(adler == 0); - assert(len == 0); - return 1; - } + if (len == 0) + return adler; + assert(buf != NULL); #if defined(WITH_NRV) return nrv_adler32(adler, (const nrv_byte *)buf, len); #elif defined(WITH_UCL) @@ -103,14 +120,28 @@ unsigned upx_adler32(unsigned adler, const void *buf, unsigned len) } -unsigned upx_adler32(const void *buf, unsigned len) +#if (UPX_VERSION_HEX >= 0x019000) +unsigned upx_adler32(unsigned adler, const void *buf, unsigned len) { - //unsigned adler = upx_adler32(0, NULL, 0); - unsigned adler = 1; - assert(buf != NULL); - adler = upx_adler32(adler, buf, len); - return adler; + return upx_adler32(buf, len, adler); } +#endif /* UPX_VERSION_HEX */ + + + +#if 0 // NOT USED +unsigned upx_crc32(const void *buf, unsigned len, unsigned crc) +{ + if (len == 0) + return crc; + assert(buf != NULL); +#if defined(WITH_NRV) + return nrv_crc32(crc, (const nrv_byte *)buf, len); +#elif defined(WITH_UCL) + return ucl_crc32(crc, (const ucl_byte *)buf, len); +#endif +} +#endif /************************************************************************* @@ -136,14 +167,14 @@ int upx_compress ( const upx_byte *src, upx_uint src_len, result = result_buffer; // assume no info available - fill in worst case results - //result[0] = 1; // min_offset_found - NOT USED + //result[0] = 1; // min_offset_found - NOT USED result[1] = src_len - 1; // max_offset_found - //result[2] = 2; // min_match_found - NOT USED + //result[2] = 2; // min_match_found - NOT USED result[3] = src_len - 1; // max_match_found - //result[4] = 1; // min_run_found - NOT USED + //result[4] = 1; // min_run_found - NOT USED result[5] = src_len; // max_run_found result[6] = 1; // first_offset_found - //result[7] = 999999; // same_match_offsets_found - NOT USED + //result[7] = 999999; // same_match_offsets_found - NOT USED #if 0 && defined(WITH_ZLIB) && defined(M_ZLIB) if (method == M_ZLIB) @@ -162,18 +193,22 @@ int upx_compress ( const upx_byte *src, upx_uint src_len, // prepare bit-buffer settings conf.bb_endian = 0; conf.bb_size = 0; - if (method == M_NRV2B_LE32 || method == M_NRV2D_LE32) - conf.bb_size = 32; - else if (method == M_NRV2B_8 || method == M_NRV2D_8) - conf.bb_size = 8; - else if (method == M_NRV2B_LE16 || method == M_NRV2D_LE16) - conf.bb_size = 16; + if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) + { + int n = (method - M_NRV2B_LE32) % 3; + if (n == 0) + conf.bb_size = 32; + else if (n == 1) + conf.bb_size = 8; + else + conf.bb_size = 16; + } else throwInternalError("unknown compression method"); #if 1 && defined(WITH_NRV) if (level == 1 && conf.bb_size == 32 && - conf.max_offset == UPX_UINT_MAX && conf.max_match == UPX_UINT_MAX) + conf.max_offset >= src_len && conf.max_match >= src_len) { if (method == M_NRV2B_LE32) { @@ -191,6 +226,16 @@ int upx_compress ( const upx_byte *src, upx_uint src_len, #endif r = nrv2d_1_16_compress(src, src_len, dst, dst_len, wrkmem); } +#if 0 + else if (method == M_NRV2E_LE32) + { + upx_byte wrkmem[NRV2E_1_16_MEM_COMPRESS]; +#if defined(__UPX_CHECKER) + memset(wrkmem,0,NRV2E_1_16_MEM_COMPRESS); +#endif + r = nrv2e_1_16_compress(src, src_len, dst, dst_len, wrkmem); + } +#endif else throwInternalError("unknown compression method"); return r; @@ -203,12 +248,12 @@ int upx_compress ( const upx_byte *src, upx_uint src_len, else if (level == 4 && conf.max_offset == UPX_UINT_MAX) conf.max_offset = 32*1024-1; #if defined(WITH_NRV) - else if (level <= 7 && conf.max_offset == UPX_UINT_MAX) - conf.max_offset = 1024*1024-1; + else if (level <= 6 && conf.max_offset == UPX_UINT_MAX) + conf.max_offset = 1*1024*1024-1; else if (level <= 8 && conf.max_offset == UPX_UINT_MAX) - conf.max_offset = 2048*1024-1; + conf.max_offset = 2*1024*1024-1; else if (level <= 10 && conf.max_offset == UPX_UINT_MAX) - conf.max_offset = 4096*1024-1; + conf.max_offset = 4*1024*1024-1; #endif if M_IS_NRV2B(method) @@ -217,6 +262,11 @@ int upx_compress ( const upx_byte *src, upx_uint src_len, else if M_IS_NRV2D(method) r = nrv2d_99_compress_internal(src, src_len, dst, dst_len, cb, level, &conf, result); +#if 0 + else if M_IS_NRV2E(method) + r = nrv2e_99_compress_internal(src, src_len, dst, dst_len, + cb, level, &conf, result); +#endif else throwInternalError("unknown compression method"); @@ -248,20 +298,42 @@ int upx_decompress ( const upx_byte *src, upx_uint src_len, } #endif - if (method == M_NRV2B_LE32) - r = nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL); - else if (method == M_NRV2B_8) + switch (method) + { + case M_NRV2B_8: r = nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL); - else if (method == M_NRV2B_LE16) + break; + case M_NRV2B_LE16: r = nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL); - else if (method == M_NRV2D_LE32) - r = nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL); - else if (method == M_NRV2D_8) + break; + case M_NRV2B_LE32: + r = nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2D_8: r = nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL); - else if (method == M_NRV2D_LE16) + break; + case M_NRV2D_LE16: r = nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL); - else + break; + case M_NRV2D_LE32: + r = nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL); + break; +#if 0 + case M_NRV2E_8: + r = nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2E_LE16: + r = nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2E_LE32: + r = nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL); + break; +#endif + default: throwInternalError("unknown decompression method"); + break; + } + return r; } @@ -270,29 +342,55 @@ int upx_decompress ( const upx_byte *src, upx_uint src_len, // **************************************************************************/ +#if (UPX_VERSION_HEX >= 0x019000) + int upx_test_overlap ( const upx_byte *buf, upx_uint src_off, upx_uint src_len, upx_uint *dst_len, int method ) { int r = UPX_E_ERROR; - if (method == M_NRV2B_LE32) - r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); - else if (method == M_NRV2B_8) + switch (method) + { + case M_NRV2B_8: r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL); - else if (method == M_NRV2B_LE16) + break; + case M_NRV2B_LE16: r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); - else if (method == M_NRV2D_LE32) - r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); - else if (method == M_NRV2D_8) + break; + case M_NRV2B_LE32: + r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2D_8: r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL); - else if (method == M_NRV2D_LE16) + break; + case M_NRV2D_LE16: r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); - else + break; + case M_NRV2D_LE32: + r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); + break; +#if 0 + case M_NRV2E_8: + r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2E_LE16: + r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2E_LE32: + r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); + break; +#endif + default: throwInternalError("unknown decompression method"); + break; + } + return r; } +#endif /* UPX_VERSION_HEX */ + /* vi:ts=4:et:nowrap diff --git a/src/conf.h b/src/conf.h index 36e6e1a0..80933990 100644 --- a/src/conf.h +++ b/src/conf.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -58,24 +58,6 @@ #undef unix -#if defined(WITH_UCL) -# include -# include -# if !defined(UPX_UINT_MAX) -# define UPX_UINT_MAX UCL_UINT_MAX -# define upx_uint ucl_uint -# define upx_voidp ucl_voidp -# define upx_uintp ucl_uintp -# define upx_byte ucl_byte -# define upx_bytep ucl_bytep -# define upx_bool ucl_bool -# define upx_progress_callback_t ucl_progress_callback_t -# define UPX_E_OK UCL_E_OK -# define UPX_E_ERROR UCL_E_ERROR -# define UPX_E_OUT_OF_MEMORY UCL_E_OUT_OF_MEMORY -# define __UPX_ENTRY __UCL_ENTRY -# endif -#endif #if defined(WITH_NRV) # include # if !defined(UPX_UINT_MAX) @@ -92,6 +74,30 @@ # define UPX_E_OUT_OF_MEMORY NRV_E_OUT_OF_MEMORY # define __UPX_ENTRY __NRV_ENTRY # endif +# if 1 && defined(__i386__) && !defined(__BORLANDC__) && !defined(__DMC__) +# define NRV_USE_ASM +# endif +#endif +#if defined(WITH_UCL) +# include +# include +# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010100L) +# error "please upgrade your UCL installation" +# endif +# if !defined(UPX_UINT_MAX) +# define UPX_UINT_MAX UCL_UINT_MAX +# define upx_uint ucl_uint +# define upx_voidp ucl_voidp +# define upx_uintp ucl_uintp +# define upx_byte ucl_byte +# define upx_bytep ucl_bytep +# define upx_bool ucl_bool +# define upx_progress_callback_t ucl_progress_callback_t +# define UPX_E_OK UCL_E_OK +# define UPX_E_ERROR UCL_E_ERROR +# define UPX_E_OUT_OF_MEMORY UCL_E_OUT_OF_MEMORY +# define __UPX_ENTRY __UCL_ENTRY +# endif #endif #if !defined(__UPX_CHECKER) # if defined(__UCL_CHECKER) || defined(__NRV_CHECKER) @@ -104,9 +110,6 @@ #if !defined(WITH_UCL) # error "you lose" #endif -#if !defined(UCL_VERSION) || (UCL_VERSION < 0x009200L) -# error "please upgrade your UCL installation" -#endif #ifndef WITH_ZLIB # define WITH_ZLIB 1 @@ -196,6 +199,17 @@ // portab **************************************************************************/ +#if defined(__GNUC__) && !defined(__GNUC_VERSION_HEX__) +# if !defined(__GNUC_MINOR__) +# error +# endif +# if !defined(__GNUC_PATCHLEVEL__) +# define __GNUC_PATCHLEVEL__ 0 +# endif +# define __GNUC_VERSION_HEX__ \ + (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +#endif + #if defined(NO_BOOL) typedef int bool; enum { false, true }; @@ -297,8 +311,41 @@ typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int); #define outp upx_outp -#define COMPILE_TIME_ASSERT(expr) \ - { typedef int __upx_compile_time_assert_fail[(expr) ? 1 : -1]; } +#if 0 +# define COMPILE_TIME_ASSERT(expr) \ + { typedef char __upx_compile_time_assert_fail[1 - 2 * !(expr)]; \ + switch (sizeof(__upx_compile_time_assert_fail)) { \ + case 1: case !(expr): break; \ + } } +#elif defined(__SC__) +# define COMPILE_TIME_ASSERT(expr) \ + { switch (1) { case 1: case !(expr): break; } } +#elif 0 +# define COMPILE_TIME_ASSERT(expr) \ + { typedef int __upx_compile_time_assert_fail[1 - 2 * !(expr)]; typedef int a[sizeof(__upx_compile_time_assert_fail]; } +#else +# define COMPILE_TIME_ASSERT(expr) \ + { typedef int __upx_compile_time_assert_fail[1 - 2 * !(expr)]; } +#endif + + +#undef __attribute_packed +#if defined(__GNUC__) +# if 1 && defined(__i386__) +# define __attribute_packed +# else +# define __attribute_packed __attribute__((__packed__,__aligned__(1))) +# endif +#else +# define __attribute_packed +#endif + + +#if defined(__cplusplus) +#define NOTHROW throw() +#else +#define NOTHROW +#endif /************************************************************************* @@ -316,6 +363,10 @@ typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int); # define O_BINARY 0 #endif +#if defined(__DMC__) +# undef tell +#endif + #if defined(__DJGPP__) # undef sopen # undef USE_SETMODE @@ -328,13 +379,15 @@ typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int); #undef UNUSED #if 1 +# define UNUSED(var) ((void) &(var)) +#elif 1 && defined(__GNUC__) # define UNUSED(var) { typedef int __upx_unused[sizeof(var) ? 1 : -1]; } -#elif 1 +#elif 0 # define UNUSED(var) do { } while (!sizeof(var)) #elif defined(__BORLANDC__) -# define UNUSED(var) ((void)(var)) +# define UNUSED(parm) ((void)(parm)) #else -# define UNUSED(var) (var = var) +# define UNUSED(parm) (parm = parm) #endif #define HIGH(array) ((unsigned) (sizeof(array)/sizeof((array)[0]))) @@ -379,22 +432,24 @@ inline void operator delete[](void *p) #endif -// A autoheap_array allocates memory on the heap, but automatically +// An Array allocates memory on the heap, but automatically // gets destructed when leaving scope or on exceptions. // "var" is declared as a read-only reference to a pointer // and behaves exactly like an array "var[]". #if 0 -# define autoheap_array(type, var, size) \ +# define Array(type, var, size) \ assert((int)(size) > 0); \ - vector var ## _autoheap_vec((size)); \ - type * const & var = & var ## _autoheap_vec[0] + std::vector var ## _array_vec((size)); \ + type * const & var = & var ## _array_vec[0] #else -# define autoheap_array(type, var, size) \ +# define Array(type, var, size) \ assert((int)(size) > 0); \ - MemBuffer var ## _autoheap_buf((size)*(sizeof(type))); \ - type * const & var = (type *) (unsigned char *) var ## _autoheap_buf + MemBuffer var ## _array_buf((size)*(sizeof(type))); \ + type * const & var = ((type *) var ## _array_buf.getVoidPtr()) #endif +#define ByteArray(var, size) Array(unsigned char, var, size) + /************************************************************************* // @@ -421,9 +476,13 @@ inline void operator delete[](void *p) #define M_NRV2D_LE32 5 #define M_NRV2D_8 6 #define M_NRV2D_LE16 7 +#define M_NRV2E_LE32 8 +#define M_NRV2E_8 9 +#define M_NRV2E_LE16 10 #define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16) #define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16) +#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16) /************************************************************************* @@ -530,7 +589,7 @@ struct options_t { int compress_exports; int compress_icons; int compress_resources; - signed char compress_rt[24]; // 24 == RT_LAST + signed char compress_rt[25]; // 25 == RT_LAST int strip_relocs; } w32pe; }; @@ -553,7 +612,7 @@ void e_exit(int ec); void printSetNl(int need_nl); void printClearLine(FILE *f = NULL); void printErr(const char *iname, const Throwable *e); -void printUnhandledException(const char *iname, const exception *e); +void printUnhandledException(const char *iname, const std::exception *e); #if defined(__GNUC__) void printErr(const char *iname, const char *format, ...) __attribute__((format(printf,2,3))); @@ -594,12 +653,10 @@ void show_version(int); // compress.cpp -unsigned upx_adler32(const void *buf, unsigned len); +unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1); unsigned upx_adler32(unsigned adler, const void *buf, unsigned len); -#if defined(WITH_UCL) -#define upx_compress_config_t ucl_compress_config_t -#elif defined(WITH_NRV) +#if defined(WITH_NRV) struct nrv_compress_config_t; struct nrv_compress_config_t { @@ -614,6 +671,8 @@ struct nrv_compress_config_t nrv_uint m_size; }; #define upx_compress_config_t nrv_compress_config_t +#elif defined(WITH_UCL) +#define upx_compress_config_t ucl_compress_config_t #endif int upx_compress ( const upx_byte *src, upx_uint src_len, diff --git a/src/console.h b/src/console.h index 6c9e18ff..ec5feeed 100644 --- a/src/console.h +++ b/src/console.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ diff --git a/src/except.cpp b/src/except.cpp index 2f9f1efc..689a5059 100644 --- a/src/except.cpp +++ b/src/except.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,14 +21,55 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ #include "conf.h" +/************************************************************************* +// +**************************************************************************/ + +long Throwable::counter = 0; + +Throwable::Throwable(const char *m, int e, bool w) + : super(), msg(NULL), err(e), is_warning(w) +{ + if (m) + msg = strdup(m); +#if 0 + fprintf(stderr, "construct exception: %s %ld\n", msg, counter); + counter++; +#endif +} + + +Throwable::Throwable(Throwable const &other) + : super(other), msg(NULL), err(other.err), is_warning(other.is_warning) +{ + if (other.msg) + msg = strdup(other.msg); +#if 0 + fprintf(stderr, "copy exception: %s %ld\n", msg, counter); + counter++; +#endif +} + + +Throwable::~Throwable() NOTHROW +{ +#if 0 + counter--; + fprintf(stderr, "destruct exception: %s %ld\n", msg, counter); +#endif + if (msg) + free(msg); +} + + /************************************************************************* // compression **************************************************************************/ @@ -135,18 +176,16 @@ void throwEOFException(const char *msg, int e) const char *prettyName(const char *n) { -#if defined(__GNUC__) + if (n == NULL) + return ""; while (*n >= '0' && *n <= '9') // gcc n++; -#endif -#if defined(_MSC_VER) if (strncmp(n, "class ", 6) == 0) // Visual C++ n += 6; -#endif return n; } -const char *prettyName(const type_info &ti) +const char *prettyName(const std::type_info &ti) { return prettyName(ti.name()); } diff --git a/src/except.h b/src/except.h index 45d89335..68b5b5fd 100644 --- a/src/except.h +++ b/src/except.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -32,31 +32,41 @@ #ifdef __cplusplus const char *prettyName(const char *n); -const char *prettyName(const type_info &ti); +const char *prettyName(const std::type_info &ti); /************************************************************************* // exceptions **************************************************************************/ -class Throwable : public exception +class Throwable : public std::exception { + typedef std::exception super; protected: - Throwable(const char *m = 0, int e = 0, bool w = false) - : msg(m), err(e), is_warning(w) { } + Throwable(const char *m = 0, int e = 0, bool w = false); public: - virtual ~Throwable() { } + Throwable(Throwable const &); + virtual ~Throwable() NOTHROW; const char *getMsg() const { return msg; } int getErrno() const { return err; } bool isWarning() const { return is_warning; } private: - //Throwable(const Throwable &); -private: -// void * operator new(size_t); // ... - const char *msg; + char *msg; int err; protected: bool is_warning; // can be set by subclasses + +private: + // disable assignment + Throwable& operator= (Throwable const &); + // disable dynamic allocation +#ifndef new + static void *operator new (size_t); // {} + static void *operator new[] (size_t); // {} +#endif + +private: + static long counter; // for debugging }; @@ -196,25 +206,25 @@ public: #undef NORET #if 0 && defined(__GNUC__) // (noreturn) is probably not the correct semantics for throwing exceptions -#define NORET __attribute__((noreturn)) +#define NORET __attribute__((__noreturn__)) #else #define NORET #endif void throwCantPack(const char *msg) NORET; -void throwUnknownExecutableFormat(const char *msg = 0, bool warn = false) NORET; -void throwNotCompressible(const char *msg = 0) NORET; -void throwAlreadyPacked(const char *msg = 0) NORET; -void throwAlreadyPackedByUPX(const char *msg = 0) NORET; +void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET; +void throwNotCompressible(const char *msg = NULL) NORET; +void throwAlreadyPacked(const char *msg = NULL) NORET; +void throwAlreadyPackedByUPX(const char *msg = NULL) NORET; void throwCantUnpack(const char *msg) NORET; -void throwNotPacked(const char *msg = 0) NORET; +void throwNotPacked(const char *msg = NULL) NORET; void throwFilterException() NORET; void throwBadLoader() NORET; void throwChecksumError() NORET; void throwCompressedDataViolation() NORET; void throwInternalError(const char *msg) NORET; -void throwIOException(const char *msg = 0, int e = 0) NORET; -void throwEOFException(const char *msg = 0, int e = 0) NORET; +void throwIOException(const char *msg = NULL, int e = 0) NORET; +void throwEOFException(const char *msg = NULL, int e = 0) NORET; #undef NORET diff --git a/src/file.cpp b/src/file.cpp index 6d94ee51..a783995b 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -85,6 +85,25 @@ FileBase::~FileBase() } +void FileBase::sopen() +{ + if (_shflags < 0) + _fd = ::open(_name,_flags,_mode); + else + { +#if defined(__DJGPP__) + _fd = ::open(_name,_flags | _shflags, _mode); +#elif defined(__MINT__) + _fd = ::open(_name,_flags | (_shflags & O_SHMODE), _mode); +#elif defined(SH_DENYRW) + _fd = ::sopen(_name,_flags,_shflags,_mode); +#else + assert(0); +#endif + } +} + + bool FileBase::close() { bool ok = true; @@ -213,16 +232,7 @@ void InputFile::sopen(const char *name, int flags, int shflags) _flags = flags; _shflags = shflags; _mode = 0; - if (shflags < 0) - _fd = ::open(_name,_flags); - else -#if defined(__DJGPP__) - _fd = ::open(_name,_flags | _shflags); -#elif defined(SH_DENYRW) - _fd = ::sopen(_name,_flags,_shflags); -#else - assert(0); -#endif + FileBase::sopen(); if (!isOpen()) { if (errno == ENOENT) @@ -281,16 +291,7 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode) _flags = flags; _shflags = shflags; _mode = mode; - if (shflags < 0) - _fd = ::open(_name,_flags,_mode); - else -#if defined(__DJGPP__) - _fd = ::open(_name,_flags | _shflags, _mode); -#elif defined(SH_DENYRW) - _fd = ::sopen(_name,_flags,_shflags,_mode); -#else - assert(0); -#endif + FileBase::sopen(); if (!isOpen()) { #if 0 @@ -323,7 +324,9 @@ bool OutputFile::openStdout(int flags, bool force) if (flags != 0) { assert(flags == O_BINARY); -#if defined(HAVE_SETMODE) && defined(USE_SETMODE) +#if defined(__MINT__) + __set_binmode(stdout, 1); +#elif defined(HAVE_SETMODE) && defined(USE_SETMODE) if (setmode(_fd, O_BINARY) == -1) throwIOException(_name,errno); #if defined(__DJGPP__) @@ -358,6 +361,8 @@ void OutputFile::dump(const char *name, const void *buf, int len, int flags) // **************************************************************************/ +#if 0 + MemoryOutputFile::MemoryOutputFile() : b(NULL), b_size(0), b_pos(0), bytes_written(0) { @@ -378,6 +383,9 @@ void MemoryOutputFile::write(const void *buf, int len) } +#endif /* if 0 */ + + /* vi:ts=4:et */ diff --git a/src/file.h b/src/file.h index f9181e94..8a442354 100644 --- a/src/file.h +++ b/src/file.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -56,6 +56,7 @@ public: const char *getName() const { return _name; } protected: + void sopen(); virtual int read(void *buf, int len); virtual int readx(void *buf, int len); virtual void write(const void *buf, int len); @@ -89,8 +90,8 @@ public: sopen(name, flags, -1); } - virtual int read(void * buf, int len); - virtual int readx(void * buf, int len); + virtual int read(void *buf, int len); + virtual int readx(void *buf, int len); virtual void seek(off_t off, int whence); virtual off_t tell() const; @@ -144,6 +145,7 @@ protected: // **************************************************************************/ +#if 0 class MemoryOutputFile : public FileBase { typedef FileBase super; @@ -166,6 +168,7 @@ protected: unsigned b_pos; off_t bytes_written; }; +#endif /* if 0 */ #endif /* already included */ diff --git a/src/help.cpp b/src/help.cpp index 05100be8..a8b69695 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -49,7 +49,7 @@ void show_head(void) fg = con_fg(f,FG_GREEN); con_fprintf(f, " Ultimate Packer for eXecutables\n" - " Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001\n" + " Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002\n" "UPX %-12s Markus F.X.J. Oberhumer & Laszlo Molnar %20s\n\n", #if defined(__MFX_DOS) V("d"), @@ -74,7 +74,7 @@ void show_usage(void) { FILE *f = con_term; - con_fprintf(f,"Usage: %s [-123456788dlthVL] [-qvfk] [-o file] %sfile..\n", progname, + con_fprintf(f,"Usage: %s [-123456789dlthVL] [-qvfk] [-o file] %sfile..\n", progname, #if defined(__DJGPP__) || defined(__EMX__) "[@]"); #else @@ -295,7 +295,7 @@ void show_license(void) show_head(); -con_fprintf(f, + con_fprintf(f, " This program may be used freely, and you are welcome to\n" " redistribute it under certain conditions.\n" "\n" @@ -310,16 +310,15 @@ con_fprintf(f, "\n" ); int fg = con_fg(f,FG_CYAN); -con_fprintf(f, - " http://upx.tsx.org\n" - " http://www.oberhumer.com/upx/\n" - " http://wildsau.idv.uni-linz.ac.at/mfx/upx.html\n" + con_fprintf(f, + " http://upx.sourceforge.net\n" + " http://www.oberhumer.com/opensource/upx/\n" ); (void)con_fg(f,FG_ORANGE); -con_fprintf(f, + con_fprintf(f, "\n" - " Markus F.X.J. Oberhumer Laszlo Molnar\n" - " markus@oberhumer.com ml1050@cdata.tvnet.hu\n" + " Markus F.X.J. Oberhumer Laszlo Molnar\n" + " \n" ); fg = con_fg(f,fg); } @@ -334,16 +333,20 @@ void show_version(int x) FILE *f = stdout; UNUSED(x); - fprintf(f,"upx %s\n",UPX_VERSION_STRING); +#if 0 && defined(__GNUC__) + fprintf(f,"upx %s (gcc 0x%lx)\n", UPX_VERSION_STRING, __GNUC_VERSION_HEX__); +#else + fprintf(f,"upx %s\n", UPX_VERSION_STRING); +#endif #if defined(WITH_NRV) fprintf(f,"NRV data compression library %s\n", nrv_version_string()); #endif #if defined(WITH_UCL) fprintf(f,"UCL data compression library %s\n", ucl_version_string()); #endif - fprintf(f,"Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer\n"); - fprintf(f,"Copyright (C) 1996-2001 Laszlo Molnar\n"); - fprintf(f,"Copyright (C) 2000-2001 John F. Reiser\n"); + fprintf(f,"Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer\n"); + fprintf(f,"Copyright (C) 1996-2002 Laszlo Molnar\n"); + fprintf(f,"Copyright (C) 2000-2002 John F. Reiser\n"); fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname); } diff --git a/src/lefile.cpp b/src/lefile.cpp index 190f5a56..759fb05d 100644 --- a/src/lefile.cpp +++ b/src/lefile.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -32,8 +32,13 @@ #include "lefile.h" -LeFile::LeFile(InputFile *f) : fif(f) +LeFile::LeFile(InputFile *f) : + fif(f), fof(NULL), + le_offset(0), exe_offset(0) { + COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196); + COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24); + COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4); memset(&ih,0,sizeof ih); memset(&oh,0,sizeof oh); iobject_table = oobject_table = NULL; @@ -43,7 +48,6 @@ LeFile::LeFile(InputFile *f) : fif(f) ifixups = ofixups = NULL; inonres_names = ononres_names = NULL; ientries = oentries = NULL; - le_offset = exe_offset = 0; } @@ -168,6 +172,18 @@ void LeFile::writeFixups() } +unsigned LeFile::getImageSize() const +{ + unsigned n = 0; + if (ih.memory_pages > 0) + { + n = (ih.memory_pages - 1) * ih.memory_page_size; + n += ih.bytes_on_last_page; + } + return n; +} + + void LeFile::readImage() { soimage = pages*mps; @@ -295,7 +311,8 @@ void LeFile::writeFile(OutputFile *f, bool le) void LeFile::countFixups(unsigned *counts) const { - memset(counts,0,sizeof(unsigned)*(objects+2)); + const unsigned o = objects; + memset(counts,0,sizeof(unsigned)*(o+2)); // counts[0..objects-1] - # of 32-bit offset relocations in for that objects // counts[objects] - # of selector fixups // counts[objects+1] - # of self-relative fixups @@ -311,7 +328,7 @@ void LeFile::countFixups(unsigned *counts) const switch (*fix) { case 2: // selector fixup - counts[objects] += 9; + counts[o] += 9; fix += 5; break; case 0x12: // alias selector @@ -320,7 +337,7 @@ void LeFile::countFixups(unsigned *counts) const fix += (fix[1] & 0x10) ? 9 : 7; break; case 6: // 16:32 pointer - counts[objects] += 9; + counts[o] += 9; case 7: // 32-bit offset counts[fix[4]-1] += 4; fix += (fix[1] & 0x10) ? 9 : 7; @@ -332,15 +349,15 @@ void LeFile::countFixups(unsigned *counts) const fix += ll*2; break; case 8: // 32-bit self relative fixup - counts[objects+1] += 4; + counts[o+1] += 4; fix += (fix[1] & 0x10) ? 9 : 7; break; default: throwCantPack("unsupported fixup record"); } } - counts[objects]++; // extra space for 'ret' - counts[objects+1] += 4; // extra space for 0xFFFFFFFF + counts[o]++; // extra space for 'ret' + counts[o+1] += 4; // extra space for 0xFFFFFFFF } diff --git a/src/lefile.h b/src/lefile.h index 773573da..bbc3b485 100644 --- a/src/lefile.h +++ b/src/lefile.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -117,7 +117,8 @@ protected: LE16 device_id; LE16 ddk_version; #endif - }; + } + __attribute_packed; struct le_object_table_entry_t { @@ -127,15 +128,17 @@ protected: LE32 pagemap_index; LE32 npages; LE32 reserved; - }; + } + __attribute_packed; struct le_pagemap_entry_t { - upx_byte h; - upx_byte m; - upx_byte l; - upx_byte type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed - }; + unsigned char h; + unsigned char m; + unsigned char l; + unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed + } + __attribute_packed; virtual void readObjectTable(); virtual void writeObjectTable(); @@ -178,6 +181,7 @@ protected: //virtual void decodeImage(){encodeImage();} void countFixups(unsigned *) const; + unsigned getImageSize() const; InputFile *fif; OutputFile *fof; diff --git a/src/linker.h b/src/linker.h index d8925747..b1e8a230 100644 --- a/src/linker.h +++ b/src/linker.h @@ -88,7 +88,6 @@ private: }; - #endif /* already included */ diff --git a/src/main.cpp b/src/main.cpp index be056ce5..7de4f99c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,6 +69,7 @@ void init_options(struct options_t *o) o->w32pe.compress_resources = -1; for (unsigned i = 0; i < HIGH(opt->w32pe.compress_rt); i++) opt->w32pe.compress_rt[i] = -1; + opt->w32pe.compress_rt[24] = false; // 24 == RT_MANIFEST o->w32pe.strip_relocs = -1; } @@ -183,6 +184,14 @@ static void e_optarg(const char *n) } +static void e_optval(const char *n) +{ + fflush(con_term); + fprintf(stderr,"%s: invalid value for option `%s'\n", argv0, n); + e_exit(EXIT_USAGE); +} + + #if defined(OPTIONS_VAR) void e_envopt(const char *n) { @@ -334,7 +343,7 @@ static void set_script_name(const char *n, bool allow_m) fprintf(stderr,"%s: missing script name\n",argv0); e_usage(); } - if (strlen(n) >= opt->unix.SCRIPT_MAX - 3) + if (strlen(n) >= (size_t)opt->unix.SCRIPT_MAX - 3) { fprintf(stderr,"%s: script name too long\n",argv0); e_usage(); @@ -422,10 +431,13 @@ static int do_option(int optc, const char *arg) switch (optc) { +#if 0 + // FIXME: to_stdout doesn't work because of console code mess //case 'c': case 517: opt->to_stdout = true; break; +#endif case 'd': set_cmd(CMD_DECOMPRESS); break; @@ -537,7 +549,9 @@ static int do_option(int optc, const char *arg) break; // compression settings case 520: // --small - opt->small = 1; + if (opt->small < 0) + opt->small = 0; + opt->small++; break; case 521: // --filter= getoptvar(&opt->filter, 0, 255); @@ -575,7 +589,8 @@ static int do_option(int optc, const char *arg) getoptvar(&opt->crp.max_match, 16u, ~0u); break; case 537: - getoptvar(&opt->crp.m_size, 1024u, 512*1024u); + if (getoptvar(&opt->crp.m_size, 10000u, (unsigned)999999u) != 0) + e_optval("--crp-ms="); break; // backup case 'k': @@ -720,8 +735,11 @@ static const struct mfx_option longopts[] = {"output", 0x21, 0, 'o'}, {"quiet", 0, 0, 'q'}, // quiet mode {"silent", 0, 0, 'q'}, // quiet mode +#if 0 + // FIXME: to_stdout doesn't work because of console code mess {"stdout", 0x10, 0, 517}, // write output on standard output {"to-stdout", 0x10, 0, 517}, // write output on standard output +#endif {"verbose", 0, 0, 'v'}, // verbose mode // backup options @@ -794,7 +812,7 @@ static const struct mfx_option longopts[] = // psx/exe {"no-align", 0x10, 0, 670}, - { 0, 0, 0, 0 } + { NULL, 0, NULL, 0 } }; int optc, longind; @@ -862,7 +880,7 @@ static const struct mfx_option longopts[] = {"compress-resources", 2, 0, 632}, {"strip-relocs", 2, 0, 633}, - { 0, 0, 0, 0 } + { NULL, 0, NULL, 0 } }; char *env, *p; @@ -950,14 +968,22 @@ static const struct mfx_option longopts[] = static void first_options(int argc, char **argv) { int i; + int n = argc; - for (i = 1; i < argc; i++) + for (i = 1; i < n; i++) + { + if (strcmp(argv[i],"--") == 0) + { + n = i; + break; + } if (strcmp(argv[i],"--version") == 0) do_option('V'+256, argv[i]); - for (i = 1; i < argc; i++) + } + for (i = 1; i < n; i++) if (strcmp(argv[i],"--help") == 0) do_option('h'+256, argv[i]); - for (i = 1; i < argc; i++) + for (i = 1; i < n; i++) if (strcmp(argv[i],"--no-env") == 0) do_option(519, argv[i]); } @@ -988,34 +1014,47 @@ void upx_sanity_check(void) COMPILE_TIME_ASSERT(sizeof(LE16) == 2); COMPILE_TIME_ASSERT(sizeof(LE32) == 4); +#if defined(__GNUC__) + COMPILE_TIME_ASSERT(__alignof__(BE16) == 1); + COMPILE_TIME_ASSERT(__alignof__(BE32) == 1); + COMPILE_TIME_ASSERT(__alignof__(LE16) == 1); + COMPILE_TIME_ASSERT(__alignof__(LE32) == 1); +#endif + +#if !defined(__WATCOMC__) struct align_assertion_1a_t { struct foo_t { char c1; LE16 v[4]; - } d[3]; - }; + } __attribute_packed; + foo_t d[3]; + } __attribute_packed; struct align_assertion_1b_t { struct foo_t { char c1; char v[4*2]; - } d[3]; - }; + } __attribute_packed; + foo_t d[3]; + } __attribute_packed; struct align_assertion_2a_t { struct foo_t { char c1; LE32 v[4]; - } d[3]; - }; + } __attribute_packed; + foo_t d[3]; + } __attribute_packed; struct align_assertion_2b_t { struct foo_t { char c1; char v[4*4]; - } d[3]; - }; + } __attribute_packed; + foo_t d[3]; + } __attribute_packed; + //printf("%d\n", (int) sizeof(align_assertion_1a_t)); //printf("%d\n", (int) sizeof(align_assertion_1b_t)); //printf("%d\n", (int) sizeof(align_assertion_2a_t)); @@ -1024,6 +1063,7 @@ void upx_sanity_check(void) COMPILE_TIME_ASSERT(sizeof(align_assertion_2a_t) == sizeof(align_assertion_2b_t)); COMPILE_TIME_ASSERT(sizeof(align_assertion_1a_t) == 3*9); COMPILE_TIME_ASSERT(sizeof(align_assertion_2a_t) == 3*17); +#endif COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1); assert(strlen(UPX_VERSION_STRING4) == 4); @@ -1041,7 +1081,21 @@ int main(int argc, char *argv[]) { int i; static char default_argv0[] = "upx"; - int cmdline_cmd = CMD_NONE; +// int cmdline_cmd = CMD_NONE; + +#if 0 && defined(__DJGPP__) + // LFN=n may cause problems with 2.03's _rename and mkdir under WinME + putenv("LFN=y"); +#endif +#if defined(__EMX__) + _response(&argc,&argv); + _wildcard(&argc,&argv); +#endif +#if defined(__MINT__) + __binmode(1); + __set_binmode(stdout, 0); + __set_binmode(stderr, 0); +#endif upx_sanity_check(); init_options(opt); @@ -1050,11 +1104,6 @@ int main(int argc, char *argv[]) MSS_DISABLE_LOG_OUTPUT; #endif -#if defined(__EMX__) - _response(&argc,&argv); - _wildcard(&argc,&argv); -#endif - if (!argv[0] || !argv[0][0]) argv[0] = default_argv0; argv0 = argv[0]; @@ -1062,15 +1111,15 @@ int main(int argc, char *argv[]) { char *prog = fn_basename(argv0); char *p; - bool allupper = 1; + bool allupper = true; for (p = prog; *p; p++) if (islower((unsigned char)*p)) - allupper = 0; + allupper = false; if (allupper) fn_strlwr(prog); - if (strlen(prog) > 4) + if (p - prog > 4) { - p = prog + strlen(prog) - 4; + p -= 4; if (fn_strcmp(p, ".exe") == 0 || fn_strcmp(p, ".ttp") == 0) *p = 0; } @@ -1118,7 +1167,7 @@ int main(int argc, char *argv[]) assert(i <= argc); set_term(0); - cmdline_cmd = opt->cmd; +// cmdline_cmd = opt->cmd; switch (opt->cmd) { case CMD_NONE: @@ -1178,7 +1227,7 @@ int main(int argc, char *argv[]) set_term(stdout); do_files(i,argc,argv); -#if 1 && (UPX_VERSION < 0x012000) +#if 1 && (UPX_VERSION_HEX < 0x020000) { FILE *f = stdout; int fg = con_fg(f,FG_RED); diff --git a/src/mem.cpp b/src/mem.cpp index 1d8a1b21..4de8ee22 100644 --- a/src/mem.cpp +++ b/src/mem.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ diff --git a/src/mem.h b/src/mem.h index ff0a8441..7b686810 100644 --- a/src/mem.h +++ b/src/mem.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -52,6 +52,9 @@ public: operator unsigned char * () { return ptr; } //operator const unsigned char * () const { return ptr; } + void *getVoidPtr() { return (void *) ptr; } + const void *getVoidPtr() const { return (const void *) ptr; } + private: void alloc(unsigned size, unsigned base_offset); diff --git a/src/msg.cpp b/src/msg.cpp index d6339bb0..ed90dac1 100644 --- a/src/msg.cpp +++ b/src/msg.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -146,7 +146,7 @@ void printWarn(const char *iname, const char *format, ...) } -void printUnhandledException(const char *iname, const exception *e) +void printUnhandledException(const char *iname, const std::exception *e) { if (e) printErr(iname,"unhandled exception: %s\n", prettyName(e->what())); diff --git a/src/p_djgpp2.cpp b/src/p_djgpp2.cpp index 3454f5f5..d81f5bfd 100644 --- a/src/p_djgpp2.cpp +++ b/src/p_djgpp2.cpp @@ -46,8 +46,13 @@ static const PackDjgpp2::PackDjgpp2(InputFile *f) : super(f), coff_offset(0) { - COMPILE_TIME_ASSERT(sizeof(coff_hdr) == 0xa8); + COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40); + COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8); COMPILE_TIME_ASSERT(sizeof(stubify_stub) == 2048); +#if defined(STUBIFY_STUB_ADLER32) + //printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub))); + assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32); +#endif } diff --git a/src/p_djgpp2.h b/src/p_djgpp2.h index 172fbca7..82fe40ce 100644 --- a/src/p_djgpp2.h +++ b/src/p_djgpp2.h @@ -71,7 +71,8 @@ protected: LE32 scnptr; char misc[12]; // relptr, lnnoptr, nreloc, nlnno char __[4]; // flags - }; + } + __attribute_packed; struct coff_header_t { @@ -95,8 +96,10 @@ protected: // section headers external_scnhdr_t sh[3]; - } coff_hdr; + } + __attribute_packed; + coff_header_t coff_hdr; external_scnhdr_t *text,*data,*bss; void stripDebug(); diff --git a/src/p_elf.h b/src/p_elf.h index 4ebbd8e0..b3a582f4 100644 --- a/src/p_elf.h +++ b/src/p_elf.h @@ -51,7 +51,8 @@ struct Elf_LE32_Ehdr LE16 e_shentsize; /* Section header table entry size */ LE16 e_shnum; /* Section header table entry count */ LE16 e_shstrndx; /* Section header string table index */ -}; +} +__attribute_packed; // Program segment header. @@ -77,7 +78,8 @@ struct Elf_LE32_Phdr enum { PF_X = (1 << 0) }; /* Segment is executable */ enum { PF_W = (1 << 1) }; /* Segment is writable */ enum { PF_R = (1 << 2) }; /* Segment is readable */ -}; +} +__attribute_packed; struct Elf_LE32_Dyn @@ -91,7 +93,9 @@ struct Elf_LE32_Dyn DT_STRTAB = 5, /* String table */ DT_STRSZ = 10 /* Sizeof string table */ }; -}; +} +__attribute_packed; + #endif /* already included */ diff --git a/src/p_exe.cpp b/src/p_exe.cpp index e88949a2..e5b76660 100644 --- a/src/p_exe.cpp +++ b/src/p_exe.cpp @@ -227,7 +227,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size, const upx_byte *relocs, const unsigned nrelocs, upx_byte *crel, bool *has_9a) { - upx_byte *crel_save = crel; + upx_byte * const crel_save = crel; unsigned i; unsigned seg_high = 0; #if 0 @@ -486,7 +486,10 @@ void PackExe::pack(OutputFile *fo) oh.relocs = 0; oh.firstreloc = ih.cs*0x10000 + ih.ip; } - oh.relocoffs = offsetof(exe_header_t, firstreloc); + + // g++ 3.1 does not like the following line... +// oh.relocoffs = offsetof(exe_header_t, firstreloc); + oh.relocoffs = ptr_diff(&oh.firstreloc, &oh); if (flag & SP) patch_le16(loader,lsize,"SP",ih.sp); diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index b5fbe148..60fe2742 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -404,8 +404,8 @@ void PackLinuxI386elf::unpack(OutputFile *fo) unsigned total_in = 0; unsigned total_out = 0; - unsigned c_adler = upx_adler32(0, NULL, 0); - unsigned u_adler = upx_adler32(0, NULL, 0); + unsigned c_adler = upx_adler32(NULL, 0); + unsigned u_adler = upx_adler32(NULL, 0); off_t ptload0hi=0, ptload1lo=0, ptload1sz=0; // decompress PT_LOAD diff --git a/src/p_lx_exc.cpp b/src/p_lx_exc.cpp index a061abd4..599ca8c6 100644 --- a/src/p_lx_exc.cpp +++ b/src/p_lx_exc.cpp @@ -456,9 +456,7 @@ void PackLinuxI386::patchLoaderChecksum() lp->l_version = (unsigned char) ph.version; lp->l_format = (unsigned char) ph.format; // INFO: lp->l_checksum is currently unused - unsigned adler = upx_adler32(0,NULL,0); - adler = upx_adler32(adler, ptr, lsize); - lp->l_checksum = adler; + lp->l_checksum = upx_adler32(ptr, lsize); } diff --git a/src/p_lx_exc.h b/src/p_lx_exc.h index 4903cb6a..788a17cb 100644 --- a/src/p_lx_exc.h +++ b/src/p_lx_exc.h @@ -87,17 +87,22 @@ protected: struct Elf_LE32_Ehdr ehdr; struct Elf_LE32_Phdr phdr[1]; struct PackUnix::l_info linfo; - }; + } + __attribute_packed; + struct cprElfHdr2 { struct Elf_LE32_Ehdr ehdr; struct Elf_LE32_Phdr phdr[2]; struct PackUnix::l_info linfo; - }; + } + __attribute_packed; + struct cprElfHdr3 { struct Elf_LE32_Ehdr ehdr; struct Elf_LE32_Phdr phdr[3]; struct PackUnix::l_info linfo; - }; + } + __attribute_packed; cprElfHdr3 elfout; diff --git a/src/p_lx_sep.cpp b/src/p_lx_sep.cpp index 154194a9..bc3e97d1 100644 --- a/src/p_lx_sep.cpp +++ b/src/p_lx_sep.cpp @@ -42,7 +42,8 @@ // **************************************************************************/ -#define SCRIPT_SIZE (opt->unix.SCRIPT_MAX + sizeof(l_info)) +//#define SCRIPT_SIZE (opt->unix.SCRIPT_MAX + sizeof(l_info)) +#define SCRIPT_SIZE (32 + sizeof(l_info)) const upx_byte *PackLinuxI386sep::getLoader() const { diff --git a/src/p_unix.cpp b/src/p_unix.cpp index b5eff4ee..7bf4bd11 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -314,8 +314,8 @@ void PackUnix::unpack(OutputFile *fo) } } - unsigned c_adler = upx_adler32(0, NULL, 0); - unsigned u_adler = upx_adler32(0, NULL, 0); + unsigned c_adler = upx_adler32(NULL, 0); + unsigned u_adler = upx_adler32(NULL, 0); // defaults for ph.version == 8 unsigned orig_file_size = 0; diff --git a/src/p_unix.h b/src/p_unix.h index 65198f3d..79df577d 100644 --- a/src/p_unix.h +++ b/src/p_unix.h @@ -92,19 +92,24 @@ protected: 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 unsigned l_checksum; unsigned l_magic; unsigned short l_lsize; unsigned char l_version; unsigned char l_format; - }; + } + __attribute_packed; + struct p_info { // 12-byte packed program header unsigned p_progid; unsigned p_filesize; unsigned p_blocksize; - }; + } + __attribute_packed; // do not change !!! enum { OVERHEAD = 2048 }; diff --git a/src/p_vmlinz.h b/src/p_vmlinz.h index 722dd8fd..bdfd4bd8 100644 --- a/src/p_vmlinz.h +++ b/src/p_vmlinz.h @@ -79,7 +79,8 @@ protected: // some more uninteresting fields here ... // see /usr/src/linux/Documentation/i386/zero-page.txt - }; + } + __attribute_packed; MemBuffer setup_buf; int setup_size; diff --git a/src/p_w32pe.cpp b/src/p_w32pe.cpp index 63c78039..7e0020a5 100644 --- a/src/p_w32pe.cpp +++ b/src/p_w32pe.cpp @@ -57,6 +57,27 @@ static const #define tls PackW32Pe_tls +/************************************************************************* +// +**************************************************************************/ + +#if defined(__BORLANDC__) +# undef strcpy +# define strcpy(a,b) std::strcpy((char *)(a),(const char *)(b)) +#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; +} + + /************************************************************************* // **************************************************************************/ @@ -140,7 +161,7 @@ bool PackW32Pe::testUnpackVersion(int version) const int PackW32Pe::readFileHeader() { - struct h_t + struct exe_header_t { LE16 mz; LE16 m512; @@ -149,8 +170,11 @@ int PackW32Pe::readFileHeader() LE16 relocoffs; char __[34]; LE32 nexepos; - } h; + } + __attribute_packed; + COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 64); + exe_header_t h; int ic; pe_offset = 0; @@ -283,10 +307,17 @@ class Reloc { LE32 pagestart; LE32 size; - } *rel; - LE16 *rel1; - void newRelocPos(void *p) { rel = (reloc*) p; rel1 = (LE16*) ((char*) p + sizeof (reloc)); } + } + __attribute_packed; + void newRelocPos(void *p) + { + rel = (reloc*) p; + rel1 = (LE16*) ((char*) p + sizeof (reloc)); + } + + reloc *rel; + LE16 *rel1; unsigned counts[16]; public: @@ -302,6 +333,7 @@ public: Reloc::Reloc(upx_byte *s,unsigned si) : start(s), size(si), rel(0) { + COMPILE_TIME_ASSERT(sizeof(reloc) == 8); memset(counts,0,sizeof(counts)); unsigned pos,type; while (next(pos,type)) @@ -350,7 +382,7 @@ void Reloc::finish(upx_byte *&p,unsigned &siz) prev = pos; *rel1 = 0; rel->size = ALIGN_UP(ptr_diff(rel1,rel),4); - newRelocPos(rel->size + (char*) rel); + newRelocPos((char *)rel + rel->size); rel->pagestart = (pos >> 4) &~ 0xfff; } *rel1++ = (pos << 12) + ((pos >> 4) & 0xfff); @@ -440,10 +472,13 @@ struct import_desc char _[8]; LE32 dllname; LE32 iat; // import address table -}; +} +__attribute_packed; void PackW32Pe::processImports(unsigned myimport) // pass 2 { + COMPILE_TIME_ASSERT(sizeof(import_desc) == 20); + // adjust import data for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++) { @@ -499,11 +534,12 @@ unsigned PackW32Pe::processImports() // pass 1 if (!u2->shname) return -1; return strlen(u1->shname) - strlen(u2->shname); } - }; + } + __attribute_packed; // +1 for dllnum=0 - autoheap_array(struct udll, dlls, dllnum+1); - autoheap_array(struct udll *, idlls, dllnum+1); + Array(struct udll, dlls, dllnum+1); + Array(struct udll *, idlls, dllnum+1); soimport = 1024; // safety @@ -691,10 +727,10 @@ unsigned PackW32Pe::processImports() // pass 1 #endif // do some work for the unpacker im = im_save; - for (ic = 0; ic < dllnum; ic++) + for (ic = 0; ic < dllnum; ic++, im++) { memset(im,FILLVAL,sizeof(*im)); - im++->dllname = ptr_diff(idlls[ic]->name,ibuf); // I only need this info + im->dllname = ptr_diff(idlls[ic]->name,ibuf); // I only need this info } } else @@ -723,7 +759,7 @@ unsigned PackW32Pe::processImports() // pass 1 class Export { - struct export_dir + struct export_dir_t { char _[12]; // flags, timedate, version LE32 name; @@ -733,9 +769,10 @@ class Export LE32 addrtable; LE32 nameptrtable; LE32 ordinaltable; - }; + } + __attribute_packed; - export_dir edir; + export_dir_t edir; char *ename; char *functionptrs; char *ordinals; @@ -760,6 +797,7 @@ private: Export::Export(char *_base) : base(_base), iv(_base) { + COMPILE_TIME_ASSERT(sizeof(export_dir_t) == 40); ename = functionptrs = ordinals = 0; names = 0; memset(&edir,0,sizeof(edir)); @@ -778,8 +816,8 @@ Export::~Export() void Export::convert(unsigned eoffs,unsigned esize) { - memcpy(&edir,base + eoffs,sizeof(export_dir)); - size = sizeof(export_dir); + memcpy(&edir,base + eoffs,sizeof(export_dir_t)); + size = sizeof(export_dir_t); iv.add(eoffs,size); unsigned len = strlen(base + edir.name) + 1; @@ -914,10 +952,13 @@ struct tls LE32 tlsindex; // VA tls index LE32 callbacks; // VA tls callbacks char _[8]; // zero init, characteristics -}; +} +__attribute_packed; void PackW32Pe::processTls(Interval *iv) // pass 1 { + COMPILE_TIME_ASSERT(sizeof(tls) == 24); + if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4)) == 0) return; @@ -1000,7 +1041,8 @@ class Resource { LE32 tnl; // Type | Name | Language id - depending on level LE32 child; - }; + } + __attribute_packed; struct res_dir { char _[12]; // flags, timedate, version @@ -1011,13 +1053,15 @@ class Resource res_dir_entry entries[1]; // it's usually safe to assume that every res_dir contains // at least one res_dir_entry - check() complains otherwise - }; + } + __attribute_packed; struct res_data { LE32 offset; LE32 size; char _[8]; // codepage, reserved - }; + } + __attribute_packed; // struct upx_rnode { @@ -1083,6 +1127,10 @@ public: void Resource::init(const upx_byte *res) { + COMPILE_TIME_ASSERT(sizeof(res_dir_entry) == 8); + COMPILE_TIME_ASSERT(sizeof(res_dir) == 16 + sizeof(res_dir_entry)); + COMPILE_TIME_ASSERT(sizeof(res_data) == 16); + start = res; root = head = current = 0; dsize = ssize = 0; @@ -1094,7 +1142,10 @@ void Resource::check(const res_dir *node,unsigned level) { int ic = node->identr + node->namedentr; if (ic == 0) - throwCantPack("unsupported resource structure"); + { + //throwCantPack("unsupported resource structure"); + throwCantPack("empty resource sections are not supported"); + } for (const res_dir_entry *rde = node->entries; --ic >= 0; rde++) if (((rde->child & 0x80000000) == 0) ^ (level == 2)) throwCantPack("unsupported resource structure"); @@ -1325,9 +1376,13 @@ void PackW32Pe::processResources(Resource *res) else if (rtype > 0 && rtype < RT_LAST) do_compress = opt->w32pe.compress_rt[rtype] ? true : false; else if (res->ntype()) // named resource type - if (0 == memcmp(res->ntype(),"\x7\x0T\x0Y\x0P\x0""E\x0L\x0I\x0""B\x0",16) - || 0 == memcmp(res->ntype(),"\x8\x0R\x0""E\x0G\x0I\x0S\x0T\x0R\x0Y\x0",18)) - do_compress = false; // typelib or registry + { + 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) { @@ -1409,7 +1464,8 @@ unsigned PackW32Pe::stripDebug(unsigned overlaystart) LE32 size; char __[4]; // rva LE32 fpos; - }; + } + __attribute_packed; const debug_dir_t *dd = (const debug_dir_t*) (ibuf + IDADDR(PEDIR_DEBUG)); for (unsigned ic = 0; ic < IDSIZE(PEDIR_DEBUG) / sizeof(debug_dir_t); ic++, dd++) @@ -2230,7 +2286,7 @@ void PackW32Pe::unpack(OutputFile *fo) extrainfo += sizeof (oh); unsigned objs = oh.objects; - autoheap_array(pe_section_t, osection, objs); + Array(pe_section_t, osection, objs); memcpy(osection,extrainfo,sizeof(pe_section_t) * objs); rvamin = osection[0].vaddr; extrainfo += sizeof(pe_section_t) * objs; diff --git a/src/p_w32pe.h b/src/p_w32pe.h index a01c3843..05a41dc2 100644 --- a/src/p_w32pe.h +++ b/src/p_w32pe.h @@ -159,8 +159,12 @@ protected: { LE32 vaddr; LE32 size; - } ddirs[16]; - } ih, oh; + } + __attribute_packed; + + struct ddirs_t ddirs[16]; + } + __attribute_packed; struct pe_section_t { @@ -171,7 +175,11 @@ protected: LE32 rawdataptr; char _[12]; LE32 flags; - } *isection; + } + __attribute_packed; + + pe_header_t ih, oh; + pe_section_t *isection; static unsigned virta2objnum (unsigned, pe_section_t *, unsigned); unsigned tryremove (unsigned, unsigned); @@ -225,13 +233,13 @@ protected: FBIG_ENDIAN = 0x8000 }; - // resource types + // predefined resource types enum { RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, RT_DIALOG, RT_STRING, - RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGE_TABLE, + RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGETABLE, RT_GROUP_CURSOR, RT_GROUP_ICON = 14, RT_VERSION = 16, RT_DLGINCLUDE, RT_PLUGPLAY = 19, RT_VXD, RT_ANICURSOR, RT_ANIICON, RT_HTML, - RT_LAST + RT_MANIFEST, RT_LAST }; }; diff --git a/src/p_wcle.cpp b/src/p_wcle.cpp index ab1954f7..108b120b 100644 --- a/src/p_wcle.cpp +++ b/src/p_wcle.cpp @@ -173,6 +173,7 @@ void PackWcle::encodeEntryTable() } //if (Opt_debug) printf("%d entries encoded.\n",n); + UNUSED(n); soentries = p - ientries + 1; oentries = ientries; @@ -276,20 +277,18 @@ void PackWcle::preprocessFixups() unsigned ic,jc; - MemBuffer counts_buf((objects+2)*sizeof(unsigned)); - unsigned *counts = (unsigned *) (unsigned char *) counts_buf; + Array(unsigned, counts, objects+2); countFixups(counts); for (ic = jc = 0; ic < objects; ic++) jc += counts[ic]; - MemBuffer rl(jc); - MemBuffer srf(counts[objects+0]+1); - MemBuffer slf(counts[objects+1]+1); + ByteArray(rl,jc); + ByteArray(srf, counts[objects+0]+1); + ByteArray(slf, counts[objects+1]+1); upx_byte *selector_fixups = srf; upx_byte *selfrel_fixups = slf; - unsigned rc = 0; upx_byte *fix = ifixups; @@ -297,7 +296,7 @@ void PackWcle::preprocessFixups() { while ((unsigned)(fix - ifixups) < get_le32(ifpage_table+ic+1)) { - const short fixp2 = get_le16(fix+2); + const signed short fixp2 = (signed short) get_le16(fix+2); unsigned value; switch (*fix) @@ -319,7 +318,7 @@ void PackWcle::preprocessFixups() fix += 5; break; case 5: // 16-bit offset - if ((unsigned)fixp2 < 4096 && IOT(fix[4]-1,my_base_address) == jc) + if ((unsigned short)fixp2 < 4096 && IOT(fix[4]-1,my_base_address) == jc) dputc('6',stdout); else throwCantPack("unsupported 16-bit offset relocation"); @@ -483,7 +482,7 @@ void PackWcle::pack(OutputFile *fo) set_le32(ifixups+sofixups,ih.init_esp_offset+IOT(ih.init_ss_object-1,my_base_address)); // old stack pointer set_le32(ifixups+sofixups+4,ih.init_eip_offset+text_vaddr); // real entry point set_le32(ifixups+sofixups+8,mps*pages); // virtual address of unpacked relocations - ifixups[sofixups+12] = (unsigned char) objects; + ifixups[sofixups+12] = (unsigned char) (unsigned) objects; sofixups += 13; // filter @@ -832,7 +831,7 @@ void PackWcle::unpack(OutputFile *fo) // copy the overlay const unsigned overlaystart = ih.data_pages_offset + exe_offset - + mps * (pages - 1) + ih.bytes_on_last_page; + + getImageSize(); const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length; checkOverlay(overlay); copyOverlay(fo, overlay, &oimage); diff --git a/src/packer.cpp b/src/packer.cpp index a97ffb52..72606a63 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -458,7 +458,7 @@ void Packer::handleStub(InputFile *fif, OutputFile *fo, long size) { // copy stub from exe info("Copying original stub: %ld bytes", size); - autoheap_array(char, stub, size); + ByteArray(stub, size); fif->seek(0,SEEK_SET); fif->readx(stub,size); fo->write(stub,size); @@ -566,7 +566,7 @@ void Packer::initPackHeader() ph.format = getFormat(); ph.method = -1; ph.level = -1; - ph.u_adler = ph.c_adler = ph.saved_u_adler = ph.saved_c_adler = upx_adler32(0,NULL,0); + ph.u_adler = ph.c_adler = ph.saved_u_adler = ph.saved_c_adler = upx_adler32(NULL,0); ph.buf_offset = -1; ph.u_file_size = file_size; } @@ -1160,7 +1160,7 @@ void Packer::compressWithFilters(Filter *parm_ft, // copy filters, add a 0 int nfilters = 0; bool zero_seen = false; - autoheap_array(int, filters, raw_nfilters + 2); + Array(int, filters, raw_nfilters + 2); for (f = raw_filters; *f >= 0; f++) { if (*f == 0) diff --git a/src/s_djgpp2.cpp b/src/s_djgpp2.cpp index fc79f6b4..94d06a39 100644 --- a/src/s_djgpp2.cpp +++ b/src/s_djgpp2.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -65,6 +65,7 @@ struct screen_data_t int rows; int cursor_x; int cursor_y; + int scroll_counter; unsigned char attr; unsigned char init_attr; unsigned char empty_attr; @@ -312,7 +313,7 @@ static int init(screen_t *this, int fd) return -1; #if 1 && defined(__DJGPP__) - /* check for Windows NT/2000 */ + /* check for Windows NT/2000/XP */ if (_get_dos_version(1) == 0x0532) return -1; #endif @@ -419,6 +420,7 @@ static int scrollUp(screen_t *this, int lines) for (y = sr - lines; y < sr; y++) clearLine(this,y); + this->data->scroll_counter += lines; return lines; } @@ -456,10 +458,17 @@ static int scrollDown(screen_t *this, int lines) #endif } + this->data->scroll_counter -= lines; return lines; } +static int getScrollCounter(const screen_t *this) +{ + return this->data->scroll_counter; +} + + static int s_kbhit(screen_t *this) { UNUSED(this); @@ -531,6 +540,7 @@ static const screen_t driver = updateLineN, scrollUp, scrollDown, + getScrollCounter, s_kbhit, intro, (struct screen_data_t *) 0 diff --git a/src/s_object.cpp b/src/s_object.cpp index 45eee5f0..5c9a10f8 100644 --- a/src/s_object.cpp +++ b/src/s_object.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ diff --git a/src/s_vcsa.cpp b/src/s_vcsa.cpp index 9dcd30ed..7ec73b9e 100644 --- a/src/s_vcsa.cpp +++ b/src/s_vcsa.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -63,6 +63,7 @@ struct screen_data_t int rows; int cursor_x; int cursor_y; + int scroll_counter; unsigned char attr; unsigned char init_attr; unsigned char map[256]; @@ -324,7 +325,7 @@ static int init(screen_t *this, int fd) #if defined(MINOR) && defined(MAJOR) && defined(TTY_MAJOR) if (MAJOR(st.st_rdev) == TTY_MAJOR) { - char vc_name[32]; + char vc_name[64]; unsigned char vc_data[4]; int i; int attr; @@ -332,6 +333,11 @@ static int init(screen_t *this, int fd) sprintf(vc_name, "/dev/vcsa%d", (int) MINOR(st.st_rdev)); this->data->fd = open(vc_name, O_RDWR); + if (this->data->fd == -1) + { + sprintf(vc_name, "/dev/vcc/a%d", (int) MINOR(st.st_rdev)); + this->data->fd = open(vc_name, O_RDWR); + } if (this->data->fd != -1) { if (read(this->data->fd, vc_data, 4) == 4) @@ -446,6 +452,7 @@ static int scrollUp(screen_t *this, int lines) for (y = sr - lines; y < sr; y++) clearLine(this,y); + this->data->scroll_counter += lines; return lines; } @@ -483,10 +490,17 @@ static int scrollDown(screen_t *this, int lines) #endif } + this->data->scroll_counter -= lines; return lines; } +static int getScrollCounter(const screen_t *this) +{ + return this->data->scroll_counter; +} + + static int getCursorShape(const screen_t *this) { UNUSED(this); @@ -580,6 +594,7 @@ static const screen_t driver = updateLineN, scrollUp, scrollDown, + getScrollCounter, kbhit, intro, (struct screen_data_t *) 0 diff --git a/src/s_win32.cpp b/src/s_win32.cpp index da37e8a9..133e5948 100644 --- a/src/s_win32.cpp +++ b/src/s_win32.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -62,6 +62,7 @@ struct screen_data_t int rows; int cursor_x; int cursor_y; + int scroll_counter; WORD attr; WORD init_attr; @@ -311,8 +312,10 @@ static int init(screen_t *this, int fd) #else this->data->cols = csbi->dwSize.X; this->data->rows = csbi->dwSize.Y; +#if 0 if (csbi->srWindow.Left != 0) return -1; +#endif #endif this->data->cursor_x = csbi->dwCursorPosition.X; @@ -413,12 +416,21 @@ static int do_scroll(screen_t *this, int lines, int way) static int scrollUp(screen_t *this, int lines) { - return do_scroll(this, lines, 0); + lines = do_scroll(this, lines, 0); + this->data->scroll_counter += lines; + return lines; } static int scrollDown(screen_t *this, int lines) { - return do_scroll(this, lines, 1); + lines = do_scroll(this, lines, 1); + this->data->scroll_counter -= lines; + return lines; +} + +static int getScrollCounter(const screen_t *this) +{ + return this->data->scroll_counter; } @@ -426,7 +438,11 @@ static int s_kbhit(screen_t *this) { #if defined(HAVE_CONIO_H) UNUSED(this); +# if defined(__BORLANDC__) + return kbhit(); +# else return _kbhit(); +# endif #else UNUSED(this); return 0; @@ -483,6 +499,7 @@ static const screen_t driver = updateLineN, scrollUp, scrollDown, + getScrollCounter, s_kbhit, intro, (struct screen_data_t *) 0 diff --git a/src/screen.h b/src/screen.h index d3b79088..84e942a6 100644 --- a/src/screen.h +++ b/src/screen.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -79,6 +79,7 @@ struct screen_t int (*scrollUp)(screen_t *s, int); int (*scrollDown)(screen_t *s, int); + int (*getScrollCounter)(const screen_t *s); int (*kbhit)(screen_t *s); @@ -120,6 +121,8 @@ static void LOG(const char *format, ...) if (!logfile) logfile = fopen("screen.log", "wt"); + if (!logfile) + return; va_start(args,format); vfprintf(logfile,format,args); diff --git a/src/stdcxx.cpp b/src/stdcxx.cpp index 249072a6..a086060b 100644 --- a/src/stdcxx.cpp +++ b/src/stdcxx.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -33,7 +33,7 @@ #ifdef WANT_STL -#if defined(__DJGPP__) || defined(__MINGW32__) || defined(__sparc__) +#if defined(__GNUC__) // provide missing oom_handler void (*__malloc_alloc_template<0>::__malloc_alloc_oom_handler)() = 0; # if !defined(__USE_MALLOC) diff --git a/src/stdcxx.h b/src/stdcxx.h index aa2e53f3..44325fcd 100644 --- a/src/stdcxx.h +++ b/src/stdcxx.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -32,16 +32,56 @@ #ifdef __cplusplus +//#define NOTHROW throw() + + /************************************************************************* -// exceptions, RTTI +// exceptions & RTTI **************************************************************************/ +#if defined(__DMC__) + +#include +#include + +namespace std { +typedef ::Type_info type_info; +class exception +{ +public: + exception() NOTHROW { } + virtual ~exception() NOTHROW { } + virtual const char* what() const NOTHROW { return "exception"; } +}; +class bad_alloc : public exception +{ +public: + bad_alloc() NOTHROW { } + virtual ~bad_alloc() NOTHROW { } + virtual const char* what() const NOTHROW { return "bad_alloc"; } +}; +}; + +#elif defined(__WATCOMC__) + +#define std + #include //#include - #include #include +class bad_alloc { }; + +#else + +#include +//#include +#include +#include + +#endif + /************************************************************************* // STL @@ -52,7 +92,7 @@ #if defined(__linux__) # define _NOTHREADS #endif -#if defined(__DJGPP__) || defined(__MINGW32__) || defined(__sparc__) +#if defined(__GNUC__) # define __THROW_BAD_ALLOC throw bad_alloc() # define __USE_MALLOC # define enable upx_stl_enable @@ -71,8 +111,6 @@ #endif /* WANT_STL */ -using namespace std; - #endif /* __cplusplus */ #endif /* already included */ diff --git a/src/tailor.h b/src/tailor.h index 143d42fe..074ac03e 100644 --- a/src/tailor.h +++ b/src/tailor.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -41,6 +41,8 @@ # define __MFX_WIN # elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) # define __MFX_WIN +# elif defined(__CYGWIN__) || defined(__MINGW32__) +# define __MFX_WIN # elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__) # define __MFX_WIN # elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS) @@ -122,13 +124,18 @@ # define HAVE_MODE_T 1 # define HAVE_CHMOD 1 # define HAVE_UTIME 1 -#elif defined(__GNUC__) && defined(__MFX_TOS) +#elif defined(__MINT__) +# undef HAVE_SETMODE # define TIME_WITH_SYS_TIME 1 # define HAVE_UNISTD_H 1 # define HAVE_UTIME_H 1 # define HAVE_CHMOD 1 +# define HAVE_CHOWN 1 # define HAVE_UTIME 1 #elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x551) +# error "need Borland C 5.5.1 or newer" +# endif # define __UPX_CDECL __cdecl # define SIGTYPEENTRY __cdecl # define HAVE_CONIO_H 1 @@ -140,6 +147,16 @@ # define HAVE_UTIME 1 # define HAVE_VSNPRINTF 1 # define vsnprintf _vsnprintf +#elif defined(__DMC__) +# define __UPX_CDECL __cdecl +# define SIGTYPEENTRY __cdecl +# define HAVE_IO_H 1 +# define HAVE_MALLOC_H 1 +# define HAVE_UNISTD_H 1 +# define HAVE_UTIME_H 1 +# define HAVE_MODE_T 1 +# define HAVE_CHMOD 1 +# define HAVE_UTIME 1 #elif defined(_MSC_VER) # define __UPX_CDECL __cdecl # define SIGTYPEENTRY __cdecl @@ -154,16 +171,27 @@ # define HAVE_VSNPRINTF 1 # define vsnprintf _vsnprintf //# pragma warning(once: 4097 4710) -# pragma warning(disable: 4097 4710) -# pragma warning(disable: 4511 4512) +//# pragma warning(disable: 4097 4511 4512 4710) +# pragma warning(disable: 4097) // W3: typedef-name 'A' used as synonym for class-name 'B' +# pragma warning(disable: 4511) // W3: 'class': copy constructor could not be generated +# pragma warning(disable: 4512) // W4: 'class': assignment operator could not be generated +# pragma warning(disable: 4710) // W4: 'function': function not inlined # endif #elif defined(__WATCOMC__) +# if (__WATCOMC__ < 1100) +# error "need Watcom C 11.0c or newer" +# define NO_BOOL 1 +# endif # define __UPX_CDECL __cdecl # define HAVE_IO_H 1 # define HAVE_SYS_UTIME_H 1 # define HAVE_CHMOD 1 # define HAVE_UTIME 1 -# define NO_BOOL 1 +# define HAVE_VSNPRINTF 1 +# define vsnprintf _vsnprintf +# if defined(__cplusplus) +# pragma warning 656 9 // w5: define this function inside its class definition (may improve code quality) +# endif #endif #if defined(__MFX_DOS) diff --git a/src/ui.cpp b/src/ui.cpp index ec346ab2..842d5320 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,15 +21,15 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ #include "conf.h" #include "file.h" -#include "screen.h" #include "ui.h" +#include "screen.h" #include "packer.h" @@ -47,7 +47,7 @@ enum { }; -struct UiPacker::State +struct UiPacker__State { int mode; @@ -116,7 +116,7 @@ static void init_global_constants(void) done = true; #if 1 && defined(__DJGPP__) - /* check for Windows NT/2000 */ + /* check for Windows NT/2000/XP */ if (_get_dos_version(1) == 0x0532) return; #endif @@ -144,16 +144,18 @@ static const char *mkline(unsigned long fu_len, unsigned long fc_len, { static char buf[2000]; char r[7+1]; + char fn[13+1]; const char *f; unsigned ratio = get_ratio(fu_len, fc_len); - upx_snprintf(r,sizeof(r),"%3d.%02d%%", ratio / 10000, (ratio % 10000) / 100); + upx_snprintf(r, sizeof(r), "%3d.%02d%%", ratio / 10000, (ratio % 10000) / 100); if (decompress) f = "%10ld <-%10ld %7s %13s %s"; else f = "%10ld ->%10ld %7s %13s %s"; - upx_snprintf(buf,sizeof(buf),f, - fu_len, fc_len, r, center_string(format_name,13), filename); + center_string(fn, sizeof(fn), format_name); + assert(strlen(fn) == 13); + upx_snprintf(buf, sizeof(buf), f, fu_len, fc_len, r, fn, filename); UNUSED(u_len); UNUSED(c_len); return buf; } @@ -170,12 +172,12 @@ UiPacker::UiPacker(const Packer *p_) : clear_cb(); - s = new State; + s = new UiPacker__State; memset(s,0,sizeof(*s)); s->msg_buf[0] = '\r'; #if defined(UI_USE_SCREEN) - // ugly hack + // FIXME - ugly hack s->screen = sobject_get_screen(); #endif @@ -185,7 +187,7 @@ UiPacker::UiPacker(const Packer *p_) : s->mode = M_INFO; else if (opt->verbose == 1 || opt->no_progress) s->mode = M_MSG; - else if (!s->screen) + else if (s->screen == NULL) s->mode = M_CB_TERM; else s->mode = M_CB_SCREEN; @@ -203,6 +205,18 @@ UiPacker::~UiPacker() // start callback **************************************************************************/ +void UiPacker::printInfo(int nl) +{ +#if 1 + char method_name[32+1]; + set_method_name(method_name, sizeof(method_name), p->ph.method, p->ph.level); + con_fprintf(stdout, "Compressing %s [%s, %s]%s", p->fi->getName(), p->getName(), method_name, nl ? "\n" : ""); +#else + con_fprintf(stdout, "Compressing %s [%s]%s", p->fi->getName(), p->getName(), nl ? "\n" : ""); +#endif +} + + void UiPacker::startCallback(unsigned u_len, unsigned step, int pass, int total_passes) { @@ -230,7 +244,7 @@ void UiPacker::startCallback(unsigned u_len, unsigned step, { if (pass <= 1) { - con_fprintf(stdout,"Compressing %s [%s]",p->fi->getName(),p->getName()); + printInfo(0); fflush(stdout); printSetNl(2); } @@ -274,18 +288,18 @@ void UiPacker::startCallback(unsigned u_len, unsigned step, #if defined(UI_USE_SCREEN) if (s->mode == M_CB_SCREEN) { - s->screen->getCursor(s->screen,&s->s_cx,&s->s_cy); - s->s_fg = s->screen->getFg(s->screen); - s->s_bg = s->screen->getBg(s->screen); - - // FIXME: this message can be longer than one line. - // must adapt endCallback() for this case. - con_fprintf(stdout,"Compressing %s [%s]\n",p->fi->getName(),p->getName()); - s->screen->getCursor(s->screen,&s->b_cx,&s->b_cy); - if (s->b_cy == s->s_cy) - s->scroll_up++; - if (s->screen->hideCursor) - s->cursor_shape = s->screen->hideCursor(s->screen); + if (pass <= 1) + { + if (s->screen->hideCursor) + s->cursor_shape = s->screen->hideCursor(s->screen); + s->s_fg = s->screen->getFg(s->screen); + s->s_bg = s->screen->getBg(s->screen); + s->screen->getCursor(s->screen,&s->s_cx,&s->s_cy); + s->scroll_up = s->screen->getScrollCounter(s->screen); + printInfo(1); + s->screen->getCursor(s->screen,&s->b_cx,&s->b_cy); + s->scroll_up = s->screen->getScrollCounter(s->screen) - s->scroll_up; + } } #endif /* UI_USE_SCREEN */ } @@ -330,23 +344,26 @@ void UiPacker::endCallback() #if defined(UI_USE_SCREEN) if (s->mode == M_CB_SCREEN) { -#if 0 - if (s->scroll_up) - s->screen->scrollDown(screen,s->scroll_up); + if (done) + { + int cx, cy, sy; + assert(s->s_cx == 0 && s->b_cx == 0); + s->screen->getCursor(s->screen, &cx, &cy); + sy = UPX_MAX(0, s->s_cy - s->scroll_up); + while (cy >= sy) + s->screen->clearLine(s->screen, cy--); + s->screen->setCursor(s->screen, s->s_cx, sy); + s->screen->setFg(s->screen,s->s_fg); + s->screen->setBg(s->screen,s->s_bg); + if (s->cursor_shape > 0) + s->screen->setCursorShape(s->screen,s->cursor_shape); + } else - s->screen->clearLine(s->screen,s->s_cy+1); - s->screen->clearLine(s->screen,s->s_cy); - s->screen->setCursor(s->screen,s->s_cx,s->s_cy); -#else - assert(s->s_cx == 0 && s->b_cx == 0); - s->screen->clearLine(s->screen,s->b_cy-1); - s->screen->clearLine(s->screen,s->b_cy); - s->screen->setCursor(s->screen,s->b_cx,s->b_cy-1); -#endif - s->screen->setFg(s->screen,s->s_fg); - s->screen->setBg(s->screen,s->s_bg); - if (s->cursor_shape > 0) - s->screen->setCursorShape(s->screen,s->cursor_shape); + { + // not needed: +// s->screen->clearLine(s->screen, s->b_cy); +// s->screen->setCursor(s->screen, s->b_cx, s->b_cy); + } } #endif /* UI_USE_SCREEN */ @@ -362,14 +379,14 @@ void UiPacker::endCallback() // the callback **************************************************************************/ -void __UPX_ENTRY UiPacker::callback(upx_uint isize, upx_uint osize, int state, void * user) +void __UPX_ENTRY UiPacker::callback(upx_uint isize, upx_uint osize, int state, void *user) { - //printf("%6d %6d %d\n", is, os, state); + //printf("%6d %6d %d\n", isize, osize, state); if (state != -1 && state != 3) return; if (user) { UiPacker *uip = reinterpret_cast(user); - uip->doCallback(isize,osize); + uip->doCallback(isize, osize); } } diff --git a/src/ui.h b/src/ui.h index e2b7c4d0..542c1cf7 100644 --- a/src/ui.h +++ b/src/ui.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -43,10 +43,12 @@ class CMainDlg; // **************************************************************************/ +struct UiPacker__State; + class UiPacker { public: - UiPacker(const Packer *p); + UiPacker(const Packer *p_); public: virtual ~UiPacker(); @@ -91,14 +93,14 @@ public: static void uiFooter(const char *n); protected: + virtual void printInfo(int nl=0); const Packer *p; // callback cb_t cb; // internal state - struct State; - struct State *s; + UiPacker__State *s; // totals static long total_files; diff --git a/src/unupx.h b/src/unupx.h index fd45ec2b..25676bf6 100644 --- a/src/unupx.h +++ b/src/unupx.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ diff --git a/src/upx.rc b/src/upx.rc new file mode 100644 index 00000000..a4594492 --- /dev/null +++ b/src/upx.rc @@ -0,0 +1,59 @@ +#include +#include "version.h" + +#define VERSION_MAJOR ((UPX_VERSION_HEX >> 16) & 0xff) +#define VERSION_MINOR ((UPX_VERSION_HEX >> 8) & 0xff) +#define VERSION_MICRO ((UPX_VERSION_HEX >> 0) & 0xff) +#define VERSION_STRING UPX_VERSION_STRING + +#if 0 +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif +#endif + + +//---------------------------------------------------------------------------## +// Icons +//---------------------------------------------------------------------------## + + +//---------------------------------------------------------------------------## +// Version +//---------------------------------------------------------------------------## + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_MICRO,0 + PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_MICRO,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The UPX Team http://upx.sf.net\0" + VALUE "FileDescription", "UPX executable packer\0" + VALUE "FileVersion", VERSION_STRING "\0" + VALUE "InternalName", "upx.exe\0" + VALUE "LegalCopyright", "© 1996-2002 Markus F.X.J. Oberhumer\0" + VALUE "OriginalFilename", "upx.exe\0" + VALUE "ProductName", "UPX\0" + VALUE "ProductVersion", VERSION_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +// vi:ts=4:et diff --git a/src/util.cpp b/src/util.cpp index e2188f2b..350129c5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -69,15 +69,16 @@ int le32_compare(const void *e1, const void *e2) int find(const void *b, int blen, const void *what, int wlen) { - if (b == NULL || what == NULL || wlen <= 0) + if (b == NULL || blen <= 0 || what == NULL || wlen <= 0) return -1; int i; const unsigned char *base = (const unsigned char *) b; unsigned char firstc = * (const unsigned char *) what; - for (i = 0; i <= blen - wlen; i++, base++) - if (*base == firstc && memcmp(base,what,wlen) == 0) + blen -= wlen; + for (i = 0; i <= blen; i++, base++) + if (*base == firstc && memcmp(base, what, wlen) == 0) return i; return -1; @@ -87,35 +88,93 @@ int find(const void *b, int blen, const void *what, int wlen) int find_be16(const void *b, int blen, unsigned what) { unsigned char w[2]; - set_be16(w,what); - return find(b,blen,w,2); + set_be16(w, what); + return find(b, blen, w, 2); } int find_be32(const void *b, int blen, unsigned what) { unsigned char w[4]; - set_be32(w,what); - return find(b,blen,w,4); + set_be32(w, what); + return find(b, blen, w, 4); } int find_le16(const void *b, int blen, unsigned what) { unsigned char w[2]; - set_le16(w,what); - return find(b,blen,w,2); + set_le16(w, what); + return find(b, blen, w, 2); } int find_le32(const void *b, int blen, unsigned what) { unsigned char w[4]; - set_le32(w,what); - return find(b,blen,w,4); + set_le32(w, what); + return find(b, blen, w, 4); } +/************************************************************************* +// find util +**************************************************************************/ + +#if (UPX_VERSION_HEX < 0x019000) + +upx_bytep pfind(const void *b, int blen, const void *what, int wlen) +{ + if (b == NULL || blen <= 0 || what == NULL || wlen <= 0) + return NULL; + + int i; + const upx_bytep base = (const upx_bytep) b; + unsigned char firstc = * (const upx_bytep) what; + + blen -= wlen; + for (i = 0; i <= blen; i++, base++) + if (*base == firstc && memcmp(base, what, wlen) == 0) + return const_cast(base); + + return NULL; +} + + +upx_bytep pfind_be16(const void *b, int blen, unsigned what) +{ + unsigned char w[2]; + set_be16(w,what); + return pfind(b,blen,w,2); +} + + +upx_bytep pfind_be32(const void *b, int blen, unsigned what) +{ + unsigned char w[4]; + set_be32(w,what); + return pfind(b,blen,w,4); +} + + +upx_bytep pfind_le16(const void *b, int blen, unsigned what) +{ + unsigned char w[2]; + set_le16(w,what); + return pfind(b,blen,w,2); +} + + +upx_bytep pfind_le32(const void *b, int blen, unsigned what) +{ + unsigned char w[4]; + set_le32(w,what); + return pfind(b,blen,w,4); +} + +#endif /* UPX_VERSION_HEX */ + + /************************************************************************* // string util **************************************************************************/ @@ -318,15 +377,37 @@ void time2str(char *s, const time_t *t) // misc. **************************************************************************/ -char *center_string(const char *name, size_t s) +bool set_method_name(char *buf, size_t size, int method, int level) { - static char buf[256+1]; - size_t l = strlen(name); - assert(l <= s && l < sizeof(buf)); - memset(buf,' ',s); - memcpy(buf+(s-l)/2,name,l); - buf[s] = 0; - return buf; + bool r = true; + const char *alg; + if (M_IS_NRV2B(method)) + alg = "NRV2B"; + else if (M_IS_NRV2D(method)) + alg = "NRV2D"; + else if (M_IS_NRV2E(method)) + alg = "NRV2E"; + else + { + alg = "???"; + r = false; + } + if (level > 0) + upx_snprintf(buf, size, "%s/%d", alg, level); + else + upx_snprintf(buf, size, "%s", alg); + return r; +} + + +void center_string(char *buf, size_t size, const char *s) +{ + size_t l = strlen(s); + size_t len = size - 1; + assert(l < size); + memset(buf, ' ', len); + memcpy(buf+(len-l)/2, s, l); + buf[len] = 0; } @@ -449,15 +530,20 @@ bool isafile(int fd) // return compression ratio, where 100% == 1000*1000 == 1e6 **************************************************************************/ -unsigned get_ratio (unsigned u_len, unsigned c_len) +unsigned get_ratio(unsigned u_len, unsigned c_len) { -#if defined(__GNUC__) +#if (ULONG_MAX <= 0xffffffffL) +# if defined(__GNUC__) || defined(__DMC__) const unsigned long long n = 1000000; -#elif defined(_MSC_VER) +# elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__WATCOMC__) const unsigned __int64 n = 1000000; +# else +# error "need a 64-bit integer type" +# endif #else -#error + const unsigned long n = 1000000; #endif + COMPILE_TIME_ASSERT(sizeof(n) >= 8); if (u_len <= 0) return (unsigned) n; return (unsigned) ((c_len * n) / u_len) + 5; @@ -509,7 +595,7 @@ int _is_executable(const char *, int , const char *) return 0; } -//FIXME: something wants to link in ctime.o +// FIXME: something wants to link in ctime.o time_t mktime(struct tm *) { return 0; diff --git a/src/util.h b/src/util.h index 926c3e98..953bcc2a 100644 --- a/src/util.h +++ b/src/util.h @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -49,7 +49,8 @@ bool makebakname(char *ofilename, const char *ifilename, bool force=true); bool isafile(int fd); unsigned get_ratio(unsigned u_len, unsigned c_len); -char *center_string(const char *name, size_t s); +bool set_method_name(char *buf, size_t size, int method, int level); +void center_string(char *buf, size_t size, const char *s); int find(const void *b, int blen, const void *what, int wlen); @@ -58,6 +59,14 @@ int find_be32(const void *b, int blen, unsigned what); int find_le16(const void *b, int blen, unsigned what); int find_le32(const void *b, int blen, unsigned what); +#if (UPX_VERSION_HEX < 0x019000) +upx_bytep pfind(const void *b, int blen, const void *what, int wlen); +upx_bytep pfind_be16(const void *b, int blen, unsigned what); +upx_bytep pfind_be32(const void *b, int blen, unsigned what); +upx_bytep pfind_le16(const void *b, int blen, unsigned what); +upx_bytep pfind_le32(const void *b, int blen, unsigned what); +#endif + inline ptrdiff_t ptr_diff(const void *p1, const void *p2) { diff --git a/src/version.h b/src/version.h index f0085b8e..417c5037 100644 --- a/src/version.h +++ b/src/version.h @@ -1,4 +1,4 @@ -#define UPX_VERSION 0x019001 /* 01.90.01 */ +#define UPX_VERSION_HEX 0x019001 /* 01.90.01 */ #define UPX_VERSION_STRING "1.90.1" #define UPX_VERSION_STRING4 "1.90" #define UPX_VERSION_DATE "Jul 16th 2002" diff --git a/src/work.cpp b/src/work.cpp index 8f0cd1b7..d759e8d3 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -31,6 +31,7 @@ #include "packmast.h" #include "packer.h" #include "ui.h" +#include "version.h" #if defined(__DJGPP__) @@ -129,6 +130,10 @@ void do_one_file(const char *iname, char *oname) else flags |= O_EXCL; int shmode = SH_DENYWR; +#if defined(__MINT__) + flags |= O_TRUNC; + shmode = O_DENYRW; +#endif #if defined(__DJGPP__) || defined(_MSC_VER) // we can avoid the chmod() call below int omode = st.st_mode; @@ -146,7 +151,11 @@ void do_one_file(const char *iname, char *oname) } // handle command +#if (UPX_VERSION_HEX >= 0x019000) PackMaster pm(&fi, opt); +#else + PackMaster pm(&fi); +#endif if (opt->cmd == CMD_COMPRESS) pm.pack(&fo); else if (opt->cmd == CMD_DECOMPRESS) @@ -275,21 +284,23 @@ void do_files(int i, int argc, char *argv[]) unlink_ofile(oname); printErr(iname,&e); e_exit(EXIT_ERROR); - } catch (const std::bad_alloc &e) { + } catch (const std::bad_alloc &) { unlink_ofile(oname); printErr(iname,"out of memory"); e_exit(EXIT_ERROR); - } catch (const std::bad_alloc *e) { + } catch (std::bad_alloc *e) { unlink_ofile(oname); printErr(iname,"out of memory"); + delete e; e_exit(EXIT_ERROR); - } catch (const exception &e) { + } catch (const std::exception &e) { unlink_ofile(oname); printUnhandledException(iname,&e); e_exit(EXIT_ERROR); - } catch (const exception *e) { + } catch (std::exception *e) { unlink_ofile(oname); printUnhandledException(iname,e); + delete e; e_exit(EXIT_ERROR); } catch (...) { unlink_ofile(oname);