Compare commits

..

146 Commits

Author SHA1 Message Date
Markus F.X.J. Oberhumer 33cdcb0e82 all: prepare for release 2023-01-30 11:18:06 +01:00
Markus F.X.J. Oberhumer ec870a5aeb submodules: update for new versions 2023-01-30 11:10:36 +01:00
Markus F.X.J. Oberhumer 0653bb5a72 src: some xspan cleanups 2023-01-30 11:03:11 +01:00
Markus F.X.J. Oberhumer 43b6ff29e3 all: bump tentative release date 2023-01-29 15:39:35 +01:00
Markus F.X.J. Oberhumer a444a8a704 src: pefile: fix overly tricky canUnpack0 logic 2023-01-29 12:40:00 +01:00
Markus F.X.J. Oberhumer 3fa18c1799 src: clang-format pefile 2023-01-29 12:34:05 +01:00
Markus F.X.J. Oberhumer 19147963b9 src: pefile: try to work-around a scan-build warning 2023-01-29 12:21:15 +01:00
Markus F.X.J. Oberhumer 5056215a1f all: more assorted cleanups 2023-01-29 11:39:57 +01:00
Markus F.X.J. Oberhumer 340b7614e2 submodules: update for new versions 2023-01-26 18:49:14 +01:00
Markus F.X.J. Oberhumer 8a1bd67a20 src: more valgrind integration 2023-01-26 08:50:30 +01:00
Markus F.X.J. Oberhumer a094df7b55 all: more cleanups; NFCI 2023-01-24 21:52:10 +01:00
Markus F.X.J. Oberhumer cc893dfc11 CI: add zigcc and scan-build 2023-01-22 22:07:35 +01:00
Markus F.X.J. Oberhumer 8ef17da082 all: cleanups 2023-01-22 18:44:31 +01:00
Markus F.X.J. Oberhumer 7993e619cd src: even more outstanding util/xspan renaming; NFC 2023-01-21 19:15:38 +01:00
Markus F.X.J. Oberhumer 1ab8d5fb3f src: remove currently unused submodules 2023-01-21 18:57:23 +01:00
Markus F.X.J. Oberhumer 213ac3ac73 all: better support for clang Static Analyzer (scan-build) 2023-01-19 19:17:26 +01:00
Markus F.X.J. Oberhumer 0a8876443a submodules: update for new versions 2023-01-19 19:16:11 +01:00
Markus F.X.J. Oberhumer f37a3bb9bb src: new ACC version 2023-01-19 06:26:06 +01:00
Markus F.X.J. Oberhumer 2632342f44 all: remove currently unused submodules 2023-01-19 03:32:49 +01:00
Markus F.X.J. Oberhumer 8efcf6f099 src: move console files into a subdir; NFC 2023-01-18 14:19:15 +01:00
Markus F.X.J. Oberhumer 58343fc78d src: more outstanding util/xspan renaming; NFC 2023-01-18 10:11:29 +01:00
Markus F.X.J. Oberhumer 6c41a4c9c8 src: move compress files into a subdir; clang-format some more files; NFC 2023-01-18 09:28:12 +01:00
Markus F.X.J. Oberhumer 334be287fc CI: add minimal-ci 2023-01-17 23:43:24 +01:00
Markus F.X.J. Oberhumer aa050e0001 cmake: compile compression libs with -O2 even in Debug mode 2023-01-16 09:47:39 +01:00
Markus F.X.J. Oberhumer cc994326a0 all: cleanups 2023-01-15 13:49:27 +01:00
Markus F.X.J. Oberhumer 58de07629e submodules: add vendor/rangeless 2023-01-15 03:23:22 +01:00
Markus F.X.J. Oberhumer 9f830e0c41 all: add zstd compression library 2023-01-13 22:25:15 +01:00
Markus F.X.J. Oberhumer c52d302f07 submodules: add vendor/zstd 2023-01-13 22:25:15 +01:00
Markus F.X.J. Oberhumer 44049ecf30 all: enable WITH_VALGRIND by default 2023-01-13 22:25:15 +01:00
Markus F.X.J. Oberhumer e1b5904196 submodules: add vendor/valgrind 2023-01-13 22:25:15 +01:00
Markus F.X.J. Oberhumer 88e692791a submodules: update for new version 2023-01-13 13:02:38 +01:00
Markus F.X.J. Oberhumer f00667ad7d all: minor cleanups, update some comments 2023-01-13 05:37:28 +01:00
Markus F.X.J. Oberhumer 696d0eec64 misc: update podman images 2023-01-06 01:48:32 +01:00
Markus F.X.J. Oberhumer 513b00a30e cmake: update for MSVC_IDE 2023-01-05 14:26:17 +01:00
Markus F.X.J. Oberhumer 0cb0dbf6d8 src: cleanup conf.h 2023-01-05 14:26:12 +01:00
Markus F.X.J. Oberhumer 9f00515da4 CI: fix windows build 2023-01-05 02:29:12 +01:00
Markus F.X.J. Oberhumer 72f31787f6 submodules: update for new versions 2023-01-05 02:02:31 +01:00
Markus F.X.J. Oberhumer cd686cb1d9 src: add boost-pfr 2023-01-05 00:57:05 +01:00
Markus F.X.J. Oberhumer d9657e9831 cmake and make: minor updates 2023-01-05 00:57:01 +01:00
Markus F.X.J. Oberhumer 72f3e9b25a all: require C++17 2023-01-03 15:11:11 +01:00
John Reiser 811b15a5b3 Fix crash with TLS init in i386 dll
https://github.com/upx/upx/issues/643
	modified:   .github/travis_testsuite_1-expected_sha256sums.sh
	modified:   src/stub/i386-win32.pe.h
	modified:   src/stub/src/i386-win32.pe.S
	modified:   src/stub/tmp/i386-win32.pe.bin.dump
2023-01-12 18:35:04 -08:00
John Reiser ab00825f37 i386 shared library TLS init
https://github.com/upx/upx/issues/643
	modified:   .github/travis_testsuite_1-expected_sha256sums.sh
	modified:   src/p_w32pe.cpp
	modified:   src/stub/i386-win32.pe.h
	modified:   src/stub/src/i386-win32.pe.S
	modified:   src/stub/tmp/i386-win32.pe.bin.dump
2023-01-12 14:34:06 -08:00
John Reiser e86d9179aa Sync testsuite
modified:   .github/travis_testsuite_1-expected_sha256sums.sh
	modified:   src/p_lx_elf.cpp
2023-01-09 10:51:47 -08:00
John Reiser 26d8e9c4c5 amd64-linux revamp for compressing shared libraries
Major changes: p_lx_elf.cpp and stub/src/amd64-linux.elf-so*.
(Includes run-time infrastructure for multiple de-compressors.)
	modified:   linker.cpp
	modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
	modified:   p_unix.cpp
	modified:   p_unix.h
	modified:   stub/Makefile
	modified:   stub/src/amd64-darwin.dylib-entry.S
	modified:   stub/src/amd64-darwin.macho-entry.S
	new file:   stub/src/amd64-expand.S
	modified:   stub/src/amd64-linux.elf-entry.S
	new file:   stub/src/amd64-linux.elf-so_entry.S
	new file:   stub/src/amd64-linux.elf-so_fold.S
	new file:   stub/src/amd64-linux.elf-so_fold.lds
	new file:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/amd64-linux.shlib-init.S
	modified:   stub/src/amd64-win64.pep.S
	modified:   stub/src/arch/amd64/nrv2b_d.S
	modified:   stub/src/arch/amd64/nrv2d_d.S
	modified:   stub/src/arch/amd64/nrv2e_d.S
           plus many generated stub/*.h and stub/tmp/*.bin.dump
2023-01-09 09:39:25 -08:00
John Reiser 5f3ebc8a7f clang-format
modified:   linker.cpp
2023-01-09 09:33:34 -08:00
John Reiser 425b1b44bc Initialize output_capacity for loader
modified:   pefile.cpp
2023-01-09 09:20:43 -08:00
John Reiser 39442e6282 initLoader() 4th parameter allows larger output size
modified:   packer.cpp
	modified:   packer.h
2023-01-05 15:28:12 -08:00
John Reiser 99575e1010 ElfLinker::output_capacity
modified:   linker.cpp
	modified:   linker.h
2023-01-05 15:25:34 -08:00
John Reiser 64aa7540e2 Sync copyright year 2023
modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
	modified:   p_unix.cpp
	modified:   p_unix.h
2023-01-02 08:28:41 -08:00
Markus F.X.J. Oberhumer 3ff5dbd179 testsuite: update testsuite caused by version year change 2023-01-01 19:56:14 +01:00
Markus F.X.J. Oberhumer e25d04fb12 all: bump version date 2023-01-01 19:53:28 +01:00
Markus F.X.J. Oberhumer dd1d5a92d2 all: welcome 2023 2023-01-01 19:49:30 +01:00
Markus F.X.J. Oberhumer c6e0aad40b make: move extra builds to "build/extra/" subdirectories 2023-01-01 19:43:57 +01:00
Markus F.X.J. Oberhumer 99b795ceaa cmake: update for MinGW 2023-01-01 13:54:39 +01:00
Markus F.X.J. Oberhumer 33dc60df26 all: minor cleanups 2022-12-31 21:08:58 +01:00
John Reiser 619aeb54ff Pesky "upx -t" mode
https://github.com/upx/upx/issues/599
	modified:   p_lx_elf.cpp
2022-12-30 10:29:25 -08:00
John Reiser 77ba43328b Use my_page_size, which is 0x4000 (16KiB) on arm64
https://github.com/upx/upx/issues/628
	modified:   p_mach.cpp
2022-12-31 20:55:34 +01:00
John Reiser 01a30752c7 Mach-O: allow 256 ncmds and 32768 sizeofcmds
https://github.com/upx/upx/issues/642
	modified:   p_mach.cpp
	modified:   stub/src/i386-darwin.macho-upxmain.c
	modified:   stub/src/powerpc-darwin.macho-upxmain.c
2022-12-29 14:02:42 -08:00
John Reiser e56b748435 WIP fixing "upx -t" of shared library
modified:   p_lx_elf.cpp
2022-12-23 11:23:41 -08:00
Markus F.X.J. Oberhumer bb4cbdff44 src: fix m68k-atari build, prepare for std::atomic, port John's MemBuffer debug 2022-12-22 16:06:25 +01:00
Markus F.X.J. Oberhumer 0b47e474a7 make: update src/Makefile 2022-12-22 15:52:50 +01:00
Markus F.X.J. Oberhumer 8e85680eb4 all: minor updates 2022-12-21 22:09:05 +01:00
John Reiser fefce0d5c4 Cleanup "PT_LOAD gap recovery" during upx -d
https://github.com/upx/upx/issues/635
	modified:   p_lx_elf.cpp
2022-12-21 06:53:37 -08:00
Markus F.X.J. Oberhumer 0ac3cb2329 CI: update CI 2022-12-21 10:08:21 +01:00
Markus F.X.J. Oberhumer 708ab1dcd7 src: p_xxx_enum.h: trailing commas in enums are allowed since C++11 2022-12-20 23:34:36 +01:00
Markus F.X.J. Oberhumer 9b87ddb621 CI: run test-suite; remove obsolete scripts 2022-12-20 23:33:58 +01:00
Markus F.X.J. Oberhumer 5dc4eb4b03 CI: also test linux gcc-m32 builds 2022-12-20 12:10:39 +01:00
Markus F.X.J. Oberhumer a203c72281 make: update Makefile 2022-12-20 11:40:48 +01:00
Markus F.X.J. Oberhumer 6cf85cee6e src: minor compatibility fix 2022-12-20 11:40:22 +01:00
Markus F.X.J. Oberhumer 1eb6a40fdd src: restore lseek() error check in file.cpp 2022-12-20 11:51:31 +01:00
John Reiser 1bed77e4d3 'sizeof' returns size_t, which on i386 is not as wide as off_t
https://github.com/upx/upx/issues/629
https://github.com/upx/upx/issues/635
	modified:   p_lx_elf.cpp
2022-12-20 07:21:02 -08:00
John Reiser f2a68023fa MSVC error C4146: unary minus operator applied to unsigned type, result still unsigned
modified:   p_lx_elf.cpp
2022-12-19 16:14:48 -08:00
John Reiser 8ccffc40e3 A real typo that caused an error in "upx -d" de-compressing
modified:   p_lx_elf.cpp
	modified:   ../.github/travis_testsuite_1-expected_sha256sums.sh
2022-12-19 15:45:27 -08:00
John Reiser dd8c1d0441 clang alignment
modified:   p_lx_elf.cpp
2022-12-19 14:31:26 -08:00
John Reiser f9f28ff176 More work on "upx -d" de-compression
https://github.com/upx/upx/issues/629
https://github.com/upx/upx/issues/635
	modified:   p_elf_enum.h
	modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
	modified:   p_unix.cpp
2022-12-19 13:49:43 -08:00
John Reiser 3649041195 Return value of FileBase::seek(, SEEK_CUR) was not FileBase::tell()
modified:   file.cpp
2022-12-19 13:37:24 -08:00
Markus F.X.J. Oberhumer c23c7a9379 all: minor updates 2022-12-15 16:20:22 +01:00
Markus F.X.J. Oberhumer 9934e33b99 src: pacify a clang scan-build warning in p_mach.cpp 2022-12-12 21:27:34 +01:00
Markus F.X.J. Oberhumer 9e75fdda66 src: pacify a -Wcast-align warning 2022-12-12 20:07:27 +01:00
Markus F.X.J. Oberhumer d873a26f41 all: clang-format-15.0.6 2022-12-12 19:25:31 +01:00
Markus F.X.J. Oberhumer 91aa5b55ab all: upgrade to upx-stubtools v20221212 2022-12-12 19:25:28 +01:00
Markus F.X.J. Oberhumer 3f460a76ce src: fix typo in options.cpp 2022-12-12 05:38:51 +01:00
Markus F.X.J. Oberhumer 7256ea3b32 make: update Makefile 2022-12-12 05:32:04 +01:00
John Reiser 4cdf77e16f Stupid MSVC 14.2, 14.3; obtuse clang 14.0.5 (and MemBuffer vs alignment)
MSVC: cannot say "if (0)" to get "check symtax+semantics, but do not emit code"
clang+MemBuffer: must fight too much to get pointer to wider-than-char
	modified:   src/p_lx_elf.cpp
2022-12-11 14:41:38 -08:00
John Reiser d89813e911 Implement de-compress of --android-shlib
64-bit (arm64, aarch64) only for now.  NYI: 32-bit (armv7).
(Also: implied catch-up with all changes by Markus in the meantime.)
https://github.com/upx/upx/issues/599

	modified:   src/p_lx_elf.cpp
	modified:   src/p_lx_elf.h
2022-12-11 13:46:44 -08:00
Markus F.X.J. Oberhumer 7c57b10cae all: minor cleanups 2022-12-02 16:46:16 +01:00
Markus F.X.J. Oberhumer 8d1a98e03b misc: update podman images, add build-all script 2022-11-27 23:50:22 +01:00
Markus F.X.J. Oberhumer 65a2da4b40 src: more clang-format 2022-11-27 22:03:20 +01:00
Markus F.X.J. Oberhumer 02f6786b2a src: new ACC version 2022-11-27 21:56:30 +01:00
Markus F.X.J. Oberhumer 9da4f7a6dc src: clang-format more files; cleanups; NFCI 2022-11-27 12:34:15 +01:00
John Reiser 510505a85c p_tmt: more sanity of input, cleanup MemBuffer usage
https://github.com/upx/upx/issues/632
	modified:   src/p_tmt.cpp
2022-11-24 10:28:03 -08:00
Markus F.X.J. Oberhumer 741cb3a136 misc: update podman images 2022-11-26 19:12:26 +01:00
Markus F.X.J. Oberhumer 9f5d67e27c src: clang-format various packers 2022-11-26 17:45:25 +01:00
Markus F.X.J. Oberhumer 93c6496ba8 src: add a xspan check to p_tmt.cpp and clang-format 2022-11-24 09:11:25 +01:00
John Reiser 779b648c5f invert_pt_dynamic: fix thinko; PackLinuxElf64help1 insist on ELF
https://github.com/upx/upx/issues/631
	modified:   src/p_lx_elf.cpp
2022-11-23 19:49:28 -08:00
Markus F.X.J. Oberhumer 9d5e06232d testsuite: update checksums caused by version bump 2022-11-22 21:36:32 +01:00
Markus F.X.J. Oberhumer b221c44466 src: re-add non-working PackMachPPC32 to PackMaster 2022-11-22 21:24:33 +01:00
Markus F.X.J. Oberhumer 665296f7cf src/util: minor xspan improvements 2022-11-22 21:21:26 +01:00
Markus F.X.J. Oberhumer 39778d5f47 cmake: default to relaxed options when building from source tarball 2022-11-22 20:54:12 +01:00
Markus F.X.J. Oberhumer 0af9bbb623 all: post-release version bump 2022-11-22 20:51:56 +01:00
Markus F.X.J. Oberhumer fdec47a83d all: prepare for release 2022-11-16 23:15:38 +01:00
Markus F.X.J. Oberhumer 7ff913bbd2 src: remove non-working PackMachPPC32 from PackMaster 2022-11-16 22:24:39 +01:00
Markus F.X.J. Oberhumer 94775bef9f src: remove non-working PackMachPPC64 from PackMaster; see issue #626 2022-11-16 20:41:31 +01:00
Markus F.X.J. Oberhumer 3cf102334f src: add option '--force-overwrite' 2022-11-16 12:52:53 +01:00
Markus F.X.J. Oberhumer 627e733a30 src: minor compress_lzma.cpp cleanups 2022-11-15 11:59:22 +01:00
Markus F.X.J. Oberhumer d31b80da5b cmake: improve tests 2022-11-14 13:21:07 +01:00
Markus F.X.J. Oberhumer eb231b65f3 src: clang-format compress_*.cpp; minor cleanup 2022-11-14 11:35:13 +01:00
Markus F.X.J. Oberhumer 59e3b1f98d all: cosmetic cleanups in NEWS and doc/Makefile 2022-11-11 05:32:59 +01:00
Markus F.X.J. Oberhumer 8b174bb272 submodules: update for new version 2022-11-10 17:34:02 +01:00
John Reiser 4199a44bef armeb stub: b_method as arg5 is 32-bit unsigned
https://github.com/upx/upx/issues/618
	modified:   src/stub/src/arch/arm/v4a/lzma_d.S

	modified:   .github/travis_testsuite_1-expected_sha256sums.sh
        also src/stub/arm*-linux*.h, src/stub/tmp/*.bin.dump
2022-11-10 08:04:35 -08:00
Markus F.X.J. Oberhumer 777392c0fe src: add some compress doctest checks 2022-11-10 16:26:36 +01:00
Markus F.X.J. Oberhumer ede1fec5e7 submodules: update for new version 2022-11-10 16:25:33 +01:00
Markus F.X.J. Oberhumer 16de3e78a5 src: try to fix canUnpack() confusion - see packer.h 2022-11-10 06:00:53 +01:00
Markus F.X.J. Oberhumer d7508d8c09 src: pefile.cpp: replace "membuffer + x - y" with "membuffer + (x - y)"
This is needed because "membuffer + x" is now bounds-checked, and
the temporary addition would trigger an exception.
2022-11-10 00:40:41 +01:00
John Reiser 2a136c1c1d End users wish to avoid "double packing".
https://github.com/upx/upx/issues/622
	modified:   src/p_lx_elf.cpp
2022-11-09 15:39:16 -08:00
Markus F.X.J. Oberhumer 2578102be9 src: misc cleanups 2022-11-09 22:15:11 +01:00
Markus F.X.J. Oberhumer dadee7acfb doc: update NEWS to mention a user visible change 2022-11-09 21:47:28 +01:00
Markus F.X.J. Oberhumer 28f0bb4e11 src: fix pefile.cpp otls allocation not accounting for alignment. Closes #621. 2022-11-09 19:29:16 +01:00
Markus F.X.J. Oberhumer 824c8a8efb src: introduce raw_index_bytes() 2022-11-08 23:05:34 +01:00
John Reiser 37f27a1262 "gcc -Werror=format-security" is small-minded
... and does not perform constant propagation
	modified:   src/p_vmlinx.cpp
2022-11-08 13:36:28 -08:00
Markus F.X.J. Oberhumer 2b8a7a492a src/util: fix compilation when not using xspan 2022-11-08 20:38:52 +01:00
Markus F.X.J. Oberhumer db56bbb11b src/util: forward memset() in xspan_fwd.h 2022-11-08 20:34:44 +01:00
John Reiser 82d26f04a4 p_vmlinx was too eager
https://github.com/upx/upx/issues/622
	modified:   src/p_vmlinx.cpp
2022-11-08 10:30:48 -08:00
Markus F.X.J. Oberhumer 5045f7eb42 submodules: update for new versions 2022-11-08 17:33:56 +01:00
Markus F.X.J. Oberhumer 82a6ccac4d misc: add misc/cross-compile-upx-with-podman 2022-11-08 03:54:30 +01:00
Markus F.X.J. Oberhumer 2d74298001 make: update Makefiles 2022-11-08 03:52:43 +01:00
Markus F.X.J. Oberhumer ce21254ed2 all: misc cleanups 2022-11-06 08:35:00 +01:00
Markus F.X.J. Oberhumer 874250fe49 submodules: update for new versions 2022-11-06 08:34:06 +01:00
John Reiser c8a3acbba8 Static executable with 4 PT_LOAD has only ELF headers in first PT_LOAD
https://github.com/upx/upx/issues/615
2022-11-02 10:03:25 -07:00
Markus F.X.J. Oberhumer 81e11987a2 all: add UPX_VERSION_GIT_DESCRIBE 2022-11-02 10:35:40 +01:00
Markus F.X.J. Oberhumer 668cefec2f src: mention UPX_CONFIG_DISABLE_GITREV build config 2022-11-02 02:52:20 +01:00
Markus F.X.J. Oberhumer 212bc04257 cmake: run tests sequentially 2022-11-02 02:50:02 +01:00
Markus F.X.J. Oberhumer db401fd05e cmake: improve "make test" 2022-10-31 18:53:38 +01:00
Markus F.X.J. Oberhumer bebe72481c testsuite: update checksums 2022-10-29 19:16:57 +02:00
John Reiser 2b9e83256d SELinux execmod requires no PROT_EXEC when PROT_WRITE
modified:   src/stub/src/amd64-linux.elf-main.c

	modified:   src/stub/amd64-linux.elf-fold.h
	modified:   src/stub/arm64-linux.elf-fold.h
	modified:   src/stub/powerpc64-linux.elf-fold.h
	modified:   src/stub/powerpc64le-linux.elf-fold.h
	modified:   src/stub/tmp/amd64-linux.elf-fold.map
	modified:   src/stub/tmp/arm64-linux.elf-fold.map
	modified:   src/stub/tmp/powerpc64-linux.elf-fold.map
	modified:   src/stub/tmp/powerpc64le-linux.elf-fold.map
2022-10-28 13:04:17 -07:00
Markus F.X.J. Oberhumer 5763518cce misc: add misc/rebuild-stubs-with-podman to add upx-4.0.0 2022-10-28 20:03:30 +02:00
Markus F.X.J. Oberhumer 3e4c5bab72 testsuite: update checksums caused by version bump 2022-10-28 17:30:56 +02:00
Markus F.X.J. Oberhumer bce109ab54 all: post-release version bump 2022-10-28 17:10:52 +02:00
Markus F.X.J. Oberhumer 69ca635c4c all: prepare for 4.0.0 release 2022-10-28 10:38:03 +02:00
Markus F.X.J. Oberhumer e0bf460993 src: rename membuffer "Uncompression" to "Decompression" 2022-10-28 10:34:31 +02:00
Markus F.X.J. Oberhumer 29762a8a96 CI: small update 2022-10-28 07:51:00 +02:00
Markus F.X.J. Oberhumer c7ef08dc2d testsuite: update 2022-10-27 22:35:45 +02:00
John Reiser 50a6698715 Each PROT_WRITE segment has implicit .bss on end of last page (64-bit only for now);
Also  workaround kernel bug invoking the escape hatch on arm64 (aarch64).
https://github.com/upx/upx/issues/611
2022-10-27 11:01:37 -07:00
Markus F.X.J. Oberhumer 7dd2cdea1e src: deprecate util/bptr.h 2022-10-27 17:52:15 +02:00
Markus F.X.J. Oberhumer af87f7f2bf doc: add missing NEWS entries 2022-10-27 18:10:29 +02:00
Markus F.X.J. Oberhumer 295889023f all: set next version back to 4.0.0, bump tentative release date, update
docs
2022-10-27 17:36:02 +02:00
506 changed files with 53901 additions and 59583 deletions
+34 -18
View File
@@ -1,28 +1,44 @@
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike # "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
# #
# for clang-format-10.0.1 from https://github.com/upx/upx-stubtools/releases # for clang-format-15.0.6 from https://github.com/upx/upx-stubtools/releases
--- ---
BasedOnStyle: LLVM BasedOnStyle: LLVM
AccessModifierOffset: -4
#AlignConsecutiveAssignments: true
AlwaysBreakTemplateDeclarations: true
ColumnLimit: 100 ColumnLimit: 100
IndentWidth: 4 IndentWidth: 4
---
Language: Cpp
AccessModifierOffset: -4
AlwaysBreakTemplateDeclarations: true
AttributeMacros:
- __acc_cdecl
- __acc_cdecl_atexit
- __acc_cdecl_qsort
- __acc_cdecl_sighandler
- __acc_forceinline
- __acc_noinline
- __acc_static_noinline
- __acc_static_forceinline
- forceinline
- noinline
EmptyLineBeforeAccessModifier: Leave
SortIncludes: false SortIncludes: false
SpaceAfterCStyleCast: true SpaceAfterCStyleCast: true
Standard: Cpp03 Standard: Cpp03
StatementMacros: [ StatementMacros:
ACCCHK_ASSERT, - ACCCHK_ASSERT
ACCCHK_ASSERT_IS_SIGNED_T, - ACCCHK_ASSERT_IS_SIGNED_T
ACCCHK_ASSERT_IS_UNSIGNED_T, - ACCCHK_ASSERT_IS_UNSIGNED_T
ACCCHK_ASSERT_SIGN_T, - ACCCHK_ASSERT_SIGN_T
ACC_COMPILE_TIME_ASSERT, - ACC_BLOCK_BEGIN
ACC_COMPILE_TIME_ASSERT_HEADER, - ACC_COMPILE_TIME_ASSERT
ACC_CXX_DISABLE_NEW_DELETE, - ACC_COMPILE_TIME_ASSERT_HEADER
ACC_CXX_TRIGGER_FUNCTION, - ACC_CXX_DISABLE_NEW_DELETE
ACC_CXX_TRIGGER_FUNCTION_IMPL, - ACC_CXX_TRIGGER_FUNCTION
CLANG_FORMAT_DUMMY_STATEMENT, - ACC_CXX_TRIGGER_FUNCTION_IMPL
COMPILE_TIME_ASSERT, - CLANG_FORMAT_DUMMY_STATEMENT
COMPILE_TIME_ASSERT_ALIGNED1, - COMPILE_TIME_ASSERT
] - COMPILE_TIME_ASSERT_ALIGNED1
WhitespaceSensitiveMacros:
- ACC_PP_MACRO_EXPAND
- ACC_PP_STRINGIZE
... ...
-93
View File
@@ -1,93 +0,0 @@
#! /bin/bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# ...lots of outdated/unneeded stuff from the old Travis/Circle/AppVeyor CI days...
if [[ $TRAVIS_OS_NAME == osx ]]; then
argv0=$0; argv0abs=$(greadlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
else
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
fi
source "$argv0dir/travis_init.sh" || exit 1
# create dirs
cd / || exit 1
mkbuilddirs $upx_BUILDDIR $ucl_BUILDDIR $upx_testsuite_BUILDDIR $zlib_BUILDDIR
cd / && cd "$upx_SRCDIR" || exit 1
echo
print_settings
echo
echo "$CC --version"; $CC --version
echo "$CXX --version"; $CXX --version
echo
# check whitespace
if [[ $TRAVIS_OS_NAME == linux ]]; then
cd / && cd $upx_SRCDIR || exit 1
echo "Checking source code for whitespace violations..."
bash ./misc/scripts/check_whitespace.sh || exit 1
echo " Passed."
fi # linux
set -x
#
# rebuild UPX stubs (needs upx-stubtools)
#
if [[ $BM_X =~ (^|\+)rebuild-stubs($|\+) ]]; then
if [[ -f "$HOME/local/bin/bin-upx/upx-stubtools-check-version" ]]; then
bin_upx=$(readlink -en -- "$HOME/local/bin/bin-upx")
elif [[ -f "$HOME/.local/bin/bin-upx/upx-stubtools-check-version" ]]; then
bin_upx=$(readlink -en -- "$HOME/.local/bin/bin-upx")
else
bin_upx=$(readlink -en -- "$upx_SRCDIR/../deps/bin-upx-20210104")
fi
cd / && cd "$upx_SRCDIR" || exit 1
extra_subdirs=()
extra_subdirs+=( src/stub/src/arch/amd64 )
extra_subdirs+=( src/stub/src/arch/arm/v4a )
extra_subdirs+=( src/stub/src/arch/arm/v4t )
extra_subdirs+=( src/stub/src/arch/arm64/v8 )
extra_subdirs+=( src/stub/src/arch/i386 )
extra_subdirs+=( src/stub/src/arch/m68k/m68000 )
extra_subdirs+=( src/stub/src/arch/m68k/m68020 )
extra_subdirs+=( src/stub/src/arch/mips/r3000 )
extra_subdirs+=( src/stub/src/arch/powerpc/32 )
extra_subdirs+=( src/stub/src/arch/powerpc/64 )
extra_subdirs+=( src/stub/src/arch/powerpc/64le )
make -C src/stub maintainer-clean
for d in ${extra_subdirs[@]}; do
make -C $d -f Makefile.extra maintainer-clean
git status $d || true
done
git status src/stub/src || true
git status || true
failed=0
for d in ${extra_subdirs[@]}; do
PATH="$bin_upx:$PATH" make -C $d -f Makefile.extra || failed=1
done
PATH="$bin_upx:$PATH" make -C src/stub all || failed=1
if [[ $failed != 0 ]]; then
echo "UPX-ERROR: FATAL: rebuild-stubs failed"
exit 1
fi
if ! git diff --quiet; then
git status || true
git diff || true
echo "UPX-ERROR: FATAL: rebuild-stubs git status mismatch. See log file."
exit 1
fi
git status
if [[ $BM_X == rebuild-stubs ]]; then
echo "X=rebuild-stubs done. Exiting."
exit 0
fi
unset bin_upx extra_subdirs d failed
fi
exit 1
-273
View File
@@ -1,273 +0,0 @@
## vim:set ts=4 sw=4 et:
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# ...lots of outdated/unneeded stuff from the old Travis/Circle/AppVeyor CI days...
#set -x # debug
umask 022
export GIT_PAGER=
# rename short variables to more readable Build-Matrix BM_ names
# C is COMPILER
# B is BUILD_OPTIONS
# T is TESTSUITE_OPTIONS
# X is EXTRA_OPTIONS
BM_CROSS=$CROSS; BM_C=$C; BM_B=$B; BM_T=$T; BM_X=$X
unset CROSS C B T X
[[ -z $BM_C ]] && BM_C=gcc
[[ -z $BM_B ]] && BM_B=release
# just in case, unset variable for passing extra UPX options
export UPX=
# un-export some vars
declare +x UPX_AUTOMATIC_BUILDS_SSL_KEY UPX_AUTOMATIC_BUILDS_SSL_IV
# compatibility wrappers
if [[ $TRAVIS_OS_NAME == osx ]]; then
# use GNU coreutils ("brew install coreutils")
chmod() {
gchmod "$@"
}
date() {
gdate "$@"
}
readlink() {
greadlink "$@"
}
sha256sum() {
gsha256sum "$@"
}
fi
if [[ -n $APPVEYOR_JOB_ID ]]; then
openssl() {
/usr/bin/openssl "$@"
}
sort() {
/usr/bin/sort "$@"
}
fi
# set CC and CXX from BM_C and BM_CROSS
if [[ -z $CC_OVERRIDE ]]; then
CC=false CXX=false SCAN_BUILD=false
AR=ar SIZE=size
if [[ -n $APPVEYOR_JOB_ID ]]; then
BUILD_LOCAL_UCL=1
BUILD_LOCAL_ZLIB=1
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
export upx_EXTRA_LDFLAGS="-static-libgcc -static-libstdc++"
fi
upx_exeext=.exe
# dir c:\cygwin
case $BM_C in
gcc-m32 | gcc-4.9-m32)
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
gcc-m64 | gcc-4.9-m64)
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
msvc | msvc-*)
AR="link -lib"; CC="cl"; CXX="cl" ;; # standard system compiler
esac
fi # APPVEYOR_JOB_ID
if [[ -n $BM_CROSS ]]; then
BUILD_LOCAL_UCL=1
BUILD_LOCAL_ZLIB=1
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
export upx_EXTRA_LDFLAGS="-static-libgcc -static-libstdc++"
fi
cat /etc/os-release || true
if grep -E -q '^PRETTY_NAME="?Ubuntu .*12\.04' /etc/os-release; then
case $BM_CROSS-$BM_C in
arm-linux-gnueabi-gcc | arm-linux-gnueabi-gcc-4.6)
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabi"
x=arm-linux-gnueabi; AR="$x-ar"; CC="$x-gcc"; CXX="$x-g++" ;;
arm-linux-gnueabihf-gcc | arm-linux-gnueabihf-gcc-4.6)
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabihf"
x=arm-linux-gnueabihf; AR="$x-ar"; CC="$x-gcc"; CXX="$x-g++" ;;
i[36]86-w64-mingw32-gcc | i[36]86-w64-mingw32-gcc-4.6)
upx_exeext=.exe
[[ -z $upx_wine ]] && upx_wine="wine"
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
x86_64-w64-mingw32-gcc | x86_64-w64-mingw32-gcc-4.6)
upx_exeext=.exe
[[ -z $upx_wine ]] && upx_wine="wine"
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
esac
elif grep -E -q '^PRETTY_NAME="?Ubuntu 16\.04' /etc/os-release; then
case $BM_CROSS-$BM_C in
aarch64-linux-gnu-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-aarch64 -L /usr/aarch64-linux-gnu"
x=aarch64-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
arm-linux-gnueabi-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabi"
x=arm-linux-gnueabi; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
arm-linux-gnueabihf-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabihf"
x=arm-linux-gnueabihf; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
i[36]86-w64-mingw32-gcc-5)
upx_exeext=.exe
[[ -z $upx_wine ]] && upx_wine="wine"
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
mips-linux-gnu-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-mips -L /usr/mips-linux-gnu"
x=mips-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
mipsel-linux-gnu-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-mipsel -L /usr/mipsel-linux-gnu"
x=mipsel-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
powerpc-linux-gnu-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc -L /usr/powerpc-linux-gnu"
x=powerpc-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
powerpc64-linux-gnu-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc64 -L /usr/powerpc64-linux-gnu"
x=powerpc64-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
powerpc64le-linux-gnu-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc64le -L /usr/powerpc64le-linux-gnu"
x=powerpc64le-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
s390x-linux-gnu-gcc-5)
[[ -z $upx_qemu ]] && upx_qemu="qemu-s390x -L /usr/s390x-linux-gnu"
x=s390x-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
x86_64-w64-mingw32-gcc-5)
upx_exeext=.exe
[[ -z $upx_wine ]] && upx_wine="wine"
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
esac
elif grep -E -q '^PRETTY_NAME="?Ubuntu 20\.04' /etc/os-release; then
case $BM_CROSS-$BM_C in
x86_64-w64-mingw32-gcc-9)
export upx_EXTRA_CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1"
export upx_EXTRA_LDFLAGS="-static"
upx_exeext=.exe
[[ -z $upx_wine ]] && upx_wine="wine64"
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
esac
fi
fi # BM_CROSS
if [[ $CC == "false" ]]; then # generic
if [[ -z $BM_CROSS ]]; then
if [[ $TRAVIS_OS_NAME == osx ]]; then
case $BM_C in
clang | clang-m?? | clang-[6789][0-9][0-9]-m?? | clang-1[0-1][0-9][0-9]-m??)
CC="clang"; CXX="clang++" ;; # standard system compiler
esac
else
case $BM_C in
clang | clang-m?? | clang-3.4-m??)
CC="clang"; CXX="clang++" ;; # standard system compiler
clang-[3456].[0-9]-m??)
v=${BM_C:6:3}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
clang-[789]-m??)
v=${BM_C:6:1}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
clang-1[0-9]-m??)
v=${BM_C:6:2}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
gcc | gcc-m?? | gcc-mx32)
CC="gcc"; CXX="g++" ;; # standard system compiler
gcc-[34].[0-9]-m?? | gcc-[34].[0-9]-mx32)
v=${BM_C:4:3}; CC="gcc-$v"; CXX="g++-$v" ;;
gcc-[56789]-m?? | gcc-[56789]-mx32)
v=${BM_C:4:1}; CC="gcc-$v"; CXX="g++-$v" ;;
gcc-1[0-9]-m?? | gcc-1[0-9]-mx32)
v=${BM_C:4:2}; CC="gcc-$v"; CXX="g++-$v" ;;
esac
fi
fi
fi # generic
case $BM_C in
clang*-m32) CC="$CC -m32"; CXX="$CXX -m32" ;;
clang*-m64) CC="$CC -m64"; CXX="$CXX -m64" ;;
gcc*-m32) CC="$CC -m32"; CXX="$CXX -m32" ;;
gcc*-m64) CC="$CC -m64"; CXX="$CXX -m64" ;;
gcc*-mx32) CC="$CC -mx32"; CXX="$CXX -mx32"; BUILD_LOCAL_UCL=1; BUILD_LOCAL_ZLIB=1 ;;
esac
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
CC="$CC -std=gnu89"
fi
unset v x
export AR CC CXX
fi # CC_OVERRIDE
# source dirs
[[ -z $upx_SRCDIR ]] && upx_SRCDIR=$(readlink -mn -- $argv0dir/..)
[[ -z $ucl_SRCDIR ]] && ucl_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/ucl-1.03)
[[ -z $upx_testsuite_SRCDIR ]] && upx_testsuite_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/upx-testsuite)
[[ -z $zlib_SRCDIR ]] && zlib_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/zlib-1.2.11)
# build dirs
mkbuilddirs() {
local d
for d in "$@"; do
mkdir -p -v "$d" || exit 1
[[ -f "$d/.mfxnobackup" ]] || touch "$d/.mfxnobackup"
done
}
# search for an existing $toptop_builddir
if [[ -z $toptop_builddir ]]; then
for d in . ..; do
for subdir in "local" appveyor circle github gitlab travis .; do
dd=$d/build/$subdir
if [[ -d $dd ]]; then
toptop_builddir=$(readlink -en -- "$dd")
break 2
fi
done
done
unset d subdir dd
fi
[[ -z $toptop_builddir ]] && toptop_builddir=$(readlink -mn -- ./build)
[[ -z $toptop_bdir ]] && toptop_bdir=$(readlink -mn -- "$toptop_builddir/${BM_CROSS:+$BM_CROSS-}$BM_C/$BM_B")
[[ -z $upx_BUILDDIR ]] && upx_BUILDDIR=$(readlink -mn -- "$toptop_bdir/upx")
[[ -z $ucl_BUILDDIR ]] && ucl_BUILDDIR=$(readlink -mn -- "$toptop_bdir/ucl-1.03")
[[ -z $upx_testsuite_BUILDDIR ]] && upx_testsuite_BUILDDIR=$(readlink -mn -- "$toptop_bdir/upx-testsuite")
[[ -z $zlib_BUILDDIR ]] && zlib_BUILDDIR=$(readlink -mn -- "$toptop_bdir/zlib-1.2.11")
[[ -z $lcov_OUTPUTDIR ]] && lcov_OUTPUTDIR=$(readlink -mn -- "$toptop_bdir/.lcov-results")
unset toptop_builddir toptop_bdir
# ensure absolute directories
make_absolute() {
local d
while [[ $# -gt 0 ]]; do
if [[ -n ${!1} ]]; then
d=$(readlink -mn -- "${!1}")
eval $1="$d"
fi
shift
done
}
for var_prefix in ucl upx upx_testsuite zlib; do
for var_suffix in _BUILDDIR _SRCDIR; do
make_absolute ${var_prefix}${var_suffix}
done
done
make_absolute lcov_OUTPUTDIR
unset var_prefix var_suffix
print_header() {
local x="==========="; x="$x$x$x$x$x$x$x"
echo -e "\n${x}\n${1}\n${x}\n"
}
print_settings() {
local v var_prefix var_suffix
# Build Matrix
for v in TRAVIS_OS_NAME BM_CROSS BM_C BM_B BM_T; do
[[ -n ${!v} ]] && echo "${v}='${!v}'"
done
# BM_C related
for v in AR CC CXX CPPFLAGS CFLAGS CXXFLAGS LDFLAGS LIBS SCAN_BUILD; do
[[ -n ${!v} ]] && echo "${v}='${!v}'"
v=EXTRA_${v}
[[ -n ${!v} ]] && echo "${v}='${!v}'"
done
# directories and other info
for v in TRAVIS_XCODE_SDK UPX_UCLDIR lcov_OUTPUTDIR; do
[[ -n ${!v} ]] && echo "${v}='${!v}'"
done
for var_prefix in ucl upx upx_testsuite zlib; do
for var_suffix in _BUILDDIR _SRCDIR; do
v=${var_prefix}${var_suffix}
[[ -n ${!v} ]] && echo "${v}='${!v}'"
done
done
##env | LC_ALL=C sort
}
true
+147 -147
View File
@@ -46,164 +46,164 @@ b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95 a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\ expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
d8e9cb72d6d63b64b68c44a380b0f700a2c2a127bb128cf16bf003e5fe7b112f *amd64-linux.elf/upx-3.91 693102863358cc906bce946afec10dd0e15d0effc6ceb462d9beaaba25967304 *amd64-linux.elf/upx-3.91
71c2a5e4b1fd131c7d94c646394228e577e33a90620e6f04ed8ce71bf9419dd6 *amd64-linux.elf/upx-3.95 4aa9e1868d7797b50768cf1ae0ab0e93cc2eff81f3abaf36f2fdb5faf673f7b7 *amd64-linux.elf/upx-3.95
7ef188bb0071bf5ad92edc0ff2cca7798ab2f084bad5d244162bafdd4dd99a03 *amd64-win64.pe/upx-3.95.exe 996dc60b7b6aa8c4c55b4fbec9b1ad3e2f82f9986fd1cdcd2cb41ab01877d5a9 *amd64-win64.pe/upx-3.95.exe
cb458bf41edcac0b50648c15ac538048fd9e57da03c3588f0fa3e524d7e9b856 *arm-linux.elf/upx-3.95 bb6cd600a28de3abc86c618125d72231d3d4b40de0260d2da7393970859723dd *arm-linux.elf/upx-3.95
5d86c92a039dbe374ff69d1ee160eee849ed7a43aabe21a427482d4f050b98be *arm-wince.pe/upx-3.91.exe bc945bc3f64a318a00ecbfde2e4a4bac2d298f753e5a8dbdc6a972bcabfce6eb *arm-wince.pe/upx-3.91.exe
9436568081d9bb519cf0c7ad1f9497026e2e74fd29009d4829a05a742c649142 *arm64-linux.elf/upx-3.95 19bdd27706f3476dfd46e5cdde782908af5bf9d068bf337ad8a26024d51ede8f *arm64-linux.elf/upx-3.95
e68f0929566ff9a8c978c9203c07bde9bc9ecc57fb3b3664f7ce4cd84ca82d26 *armeb-linux.elf/upx-3.91 3b6e5e9eeb660859e35d9d3e005fb51a8163bfe548d8be6525660a30d1ea5c37 *armeb-linux.elf/upx-3.91
8fe7b9bcf5db78b3f5585555526ee9aa640e40e97052226431c2f4e2dcd8d26a *armeb-linux.elf/upx-3.95 2f2d916ee977e06b07429e563aeab0d052b7ba359dd61a7d767e2a7ef7fa049d *armeb-linux.elf/upx-3.95
899a2af496235848b333d49645c9b08638170fc05899b55673900e5962d70a2a *i386-dos32.djgpp2.coff/upx-3.91.exe 1e8cded938d4ee16bcc66fb5462650733a8862a1c9fab264a77a22e7958b36a7 *i386-dos32.djgpp2.coff/upx-3.91.exe
41048de2b63e0703a78c222efeca6b99225fad8e0c8758775f5fb6e63edde3e9 *i386-dos32.djgpp2.coff/upx-3.95.exe 6f439d62cdb735570c6c5e941924b6d2819024cad6c3453db020edc1e9e0d66b *i386-dos32.djgpp2.coff/upx-3.95.exe
4e7bb9e52a5f8085e9882eff1007b7f401a7fbdfc82e5342ef604e4feb4ccf15 *i386-linux.elf/upx-3.91 f6a8a76b9af29272722be6785242a9822ce6b2ca3483cd953c2c34e4d85e1cf4 *i386-linux.elf/upx-3.91
72fba7c493de49b2ee152629e9083b83d6e732c99eefc7d59641d091c64f171e *i386-linux.elf/upx-3.95 7eead732dddffdb1db5e5002babe112f8589eeb8251cb23e0b6f29dacfad3817 *i386-linux.elf/upx-3.95
38fbad083a8eaa4ed7cb379f21a5277a703baaa77d4e6d9e145d2bb4838513b5 *i386-win32.pe/upx-3.91.exe 2c41d77ae9ac810cde23a222046d05b57a272c90aa75b127e0697a586be1ce1f *i386-win32.pe/upx-3.91.exe
a27abdb7d9888b7d1e79aa90cdb6a1500e0a3abdc64ee9fbe7db7ce4423ffc79 *i386-win32.pe/upx-3.95.exe 0218c00a3686363148a2bbe7d89634d54a2d7840beeab7f5fef2f269e56d517e *i386-win32.pe/upx-3.95.exe
a8e11176946ec68f4c2e40e0a585eb70f589560117bef2a98315c454b2fe1f13 *m68k-atari.tos/upx-3.91.ttp 44034fc9a3609538d8edfbe3996aa3946b1745e537d1ea2ca14181c177b98034 *m68k-atari.tos/upx-3.91.ttp
a80d40f6ae66effe0ce9dfcbcc306e59c61118a3653eba304b6120c3cb4bd951 *mips-linux.elf/upx-3.95 55c6151325fdf1638584f0fa5ee228547445e239bb0c8f4c6f31c30945e114b1 *mips-linux.elf/upx-3.95
8aab2896c689c9b9eae5d205e8dbf3e9896989f212181f666dece91e893314e9 *mipsel-linux.elf/upx-3.91 b6905f55277b3abc8ad10eb1ca95135ce9f2a5d87c992f7de78ca8e69d8e819e *mipsel-linux.elf/upx-3.91
00dbb8a83349fff83374b5a716ae953943b003991e1808e5d773f3e2aa3176bb *mipsel-linux.elf/upx-3.95 3a5eb4b01cb334e4a30a0ebb1c7d9f85f2035e6e5989acc296beb3ff34c98152 *mipsel-linux.elf/upx-3.95
174a1e090a254cefff98bc23235a3feea9e23c3be0a4c007c44c89a999e62567 *powerpc-linux.elf/upx-3.91 df4157e8e613f62fb26b1965b1c22dc44bf18f4aec4611283afadb9889d267d4 *powerpc-linux.elf/upx-3.91
f133e103c0d02927311593f6f25ea0c4803fe648919e154a5b2a527964b6a9fb *powerpc-linux.elf/upx-3.95 054a126aa7e17c6c5b8a00f608c4bf98f252ec4ab9ca2c03aebf9c92e30bda4f *powerpc-linux.elf/upx-3.95
996c63e6717ced59c7dfd4573482ef54d2715dc04bc106e6a86e0317443cb960 *powerpc64le-linux.elf/upx-3.95 4667d37cb2474a30b184cd4d7ca8ba071650c396ebe9f1f9a39172c924676090 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\ expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
e5fce664c1ed5e4d5ced5186c5b88be8ef14b378b911e2e70bc8e7a331f8e3ff *amd64-linux.elf/upx-3.91 f3cfc0be5885525965fbd3e56f5a4083a727414978bb4c018b4b0355c5b06921 *amd64-linux.elf/upx-3.91
86437aa77c0c1c5f55ef8d15ae2ba69d9d48034330faccc025f03a2a7d54ef12 *amd64-linux.elf/upx-3.95 06f933cf1c5e42f2f00ffb6a5312fa687846b6a566d372459208f8cad34e34bb *amd64-linux.elf/upx-3.95
761629a404ac155b3f856ff6bedf66266e1c75dcf389b56aee7692f420872653 *amd64-win64.pe/upx-3.95.exe db33236e886947a74c766e632ded0249166e2e5f74a3d03cda37cc07901cd1b1 *amd64-win64.pe/upx-3.95.exe
7dc22a271fd568f2ec7db5360ae08d2ed0dc6ceb14901bf8d3a49f6a239506be *arm-linux.elf/upx-3.95 3564858c026c2b0637e3c8e41a972fabc609ccc69c7ddd0ae457dd4ba7a62008 *arm-linux.elf/upx-3.95
58259c38274532baf60932569a4006ceb762a381ac3b257e9af648af24422660 *arm-wince.pe/upx-3.91.exe dceda960aa7b15b13a06bf88d1512d52e7e460d85a81207b6b5407bdbb51ffe8 *arm-wince.pe/upx-3.91.exe
f626c4131c1b70a880e6431c41842093dad4a2fff921304727306e699c6e6ceb *arm64-linux.elf/upx-3.95 52b93b549591081ef72d19fe09d4588d7f2bc736f2ad50a32be03fb7fcd70e95 *arm64-linux.elf/upx-3.95
6f870fe4f7a92cd244bc0b209082264ffdf68d023dc1d697f5111ce5f4a168ca *armeb-linux.elf/upx-3.91 1877be1f5f5333f1ee7c77bfb020f35f5c125e7f6b661a92a6918b468c02484f *armeb-linux.elf/upx-3.91
ed554bbf0d531740a2cb408a5408b7fb67fef32173531bae21b15829e4465b92 *armeb-linux.elf/upx-3.95 a4d1f01a3dc748e92dd33e1377885ef2955c2c35fd379474c6622ce67267fac2 *armeb-linux.elf/upx-3.95
6e5b040dd59e0bf3491da6947fd3c576fd1b090b1fa7f278b147dd33b0a561a4 *i386-dos32.djgpp2.coff/upx-3.91.exe d5d3cf6ecf1a89f5871bcfef9c59794f249b9f7ca12afdf15b79d343a18ddefc *i386-dos32.djgpp2.coff/upx-3.91.exe
f27ef0ce4ca0c7557dfd4c0c3a7e5443523f82dd9f4d354fb80ad0e001ede485 *i386-dos32.djgpp2.coff/upx-3.95.exe eca16dec497e1a9f334fd4d806f035cafcd3438749d25b494e95f4935760ae4f *i386-dos32.djgpp2.coff/upx-3.95.exe
8e6d5979658e8a00b567ddd214abd5565fc4c356b3e84941038c16aff9b3fb23 *i386-linux.elf/upx-3.91 1ab8d00e13d149f6e74187eadaacd1d8cfa4777ce7489cef88fba4cbde9bcdee *i386-linux.elf/upx-3.91
7d7cc62ec7f8e71e526687cde53d5b49e5f688787c3aef533a8aa9f302e51bea *i386-linux.elf/upx-3.95 dd3169256039f7df2db15a86114818b275c03bd96c3ee828d724131b98fcc6f2 *i386-linux.elf/upx-3.95
f81ed2a88589df18a735bebc1b42d638d3eb0bebbaea70758c762348103adde1 *i386-win32.pe/upx-3.91.exe 17a97d24ebbdaa3bd8f7ec9633e38bca1754c8af2d79250aaa5472499a98e0ec *i386-win32.pe/upx-3.91.exe
d5533151370ea42679c94036b8d61239f90fd930fca5d3cedbbca9c959756294 *i386-win32.pe/upx-3.95.exe 1bb873ed8a8cbb11238f98c3f616ec6a34f4765a6021e10d9686158f382458f0 *i386-win32.pe/upx-3.95.exe
5361b1f369a4b42f9063f448bdcda31f97bd610c659d2fe3c89d3e479a84cbc9 *m68k-atari.tos/upx-3.91.ttp 13b0b57643342d0e08fe084cbf799f518b3d44ac9f39edda7db3e6b6c36386cc *m68k-atari.tos/upx-3.91.ttp
ac4233c2d342375bd2fb5cf871cfd47b58863fbcac7693937e1d15d23f09f96e *mips-linux.elf/upx-3.95 91145a85e926495a536661d4e842a7b5b259707ef6accf5f08d13adcec173f13 *mips-linux.elf/upx-3.95
9bcae27b631736ff226d45fc143c61c55b1bbb127b77b9612ad2d123dc96d45d *mipsel-linux.elf/upx-3.91 8090533000872748b70c761d5581d78fde421d66884ab238527ca41d1446c2ae *mipsel-linux.elf/upx-3.91
bf735a042c3406897f1cba6a62f8f7ea631bd15f15f21a56165decfe39323c52 *mipsel-linux.elf/upx-3.95 f82e7b166647f157c981af92eaeec63bf080609591a5d13f76f84cd49c8e7495 *mipsel-linux.elf/upx-3.95
215c0694962ab6f4ead91448722a6ddce8471abce0742e148a6626cdbdf904fa *powerpc-linux.elf/upx-3.91 ae312cc5d34fd889ed9582a928ab03c589c0caddb111aceade7e072f928c6361 *powerpc-linux.elf/upx-3.91
82857404a03d2a21c4bff152c8da78ae3cdcdb71ad0c847256c370ce510a4f1b *powerpc-linux.elf/upx-3.95 fd28cb894be895afb8aec675739b276810e7a35c5212016c3f7acde853d8c763 *powerpc-linux.elf/upx-3.95
ee860ecf8fafb5ca6a7f9c6baf316dba1c3b55553aa02f4dc254d54b32e0a61a *powerpc64le-linux.elf/upx-3.95 e299bb500c34d2f90b2b35a7186a0b24fb5ac80e56d4a2d80f9c8bd32cf2be62 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\ expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
d43e28f8724cdb76deaca6581b698bd77c06a94ea37c8cf730eb38f82ce62cce *amd64-linux.elf/upx-3.91 eea59d6755beed52bff26941d31362f28097d029d4f61a2f9065dcc63cd628fb *amd64-linux.elf/upx-3.91
05c7ced28df8fa967385aa85adb479a9d9928112cb28884e8382421ee7aed062 *amd64-linux.elf/upx-3.95 b89f4ca39165071a7a5eb107ed9b7c6c77b7c7ad90acdb2b073314571aacc23a *amd64-linux.elf/upx-3.95
405399cb91cde3dfeed89bfe14ff65301fcb9a6925ffb55bdac8c60e164fec9f *amd64-win64.pe/upx-3.95.exe 6af6bc4f2d4bdb1e7694f44ce695c54d181011b734f159018d5e2c515d14a47c *amd64-win64.pe/upx-3.95.exe
48a0983b24a0dc0e29df24ee30470ce228f4c978a3e965e27a6b12d8977807bd *arm-linux.elf/upx-3.95 9ae22ad9af331ec8c08ab22b0a8e0e0ff849512a6d11257c55fe7c423c0b7937 *arm-linux.elf/upx-3.95
9b460ce1edeb2557661526bdd0d195f5d4c7c5f261c2886fe47691ce5b2d20c5 *arm-wince.pe/upx-3.91.exe 8605ddb612a1a3e096e272cb876e7777585804fa000f338f2164437a6da3de9a *arm-wince.pe/upx-3.91.exe
391afe58edcbbedadde8c9ec4cd693c4c169bd6f6fefa9f63c41f4d7529246c9 *arm64-linux.elf/upx-3.95 2ab36b41db84e6e3002420ec397d79abed451869a7a8b703ab3b81f79c487753 *arm64-linux.elf/upx-3.95
05943cb6189f8230a6a6cc8ffb9ae9b6f3ecb1ef222181522833dc8373c77211 *armeb-linux.elf/upx-3.91 38879c80525760492a95de9bfcbce49997c5bff30bb43a6bb173b1978d21f248 *armeb-linux.elf/upx-3.91
0f1cdc18d24c03d3e56256721ba9fdddf7809eeaeefacf4f677120903c9544e4 *armeb-linux.elf/upx-3.95 72e3bf259bf1304235a7ebe600f5b37be21297b8552f2fbdf47e28e3aa19e807 *armeb-linux.elf/upx-3.95
ee2918a9bf26aebcb5547684f2d4f9c24ac516597c208a478e5bc3f36b59291e *i386-dos32.djgpp2.coff/upx-3.91.exe 3af56cb84be62f4078ae39be3370ef68061b094c62b3cbcd5d38e99e0e91df7f *i386-dos32.djgpp2.coff/upx-3.91.exe
f24770536216fa29a7d3624f6e676a54244be0a7ab1213d29d21a146639a1b83 *i386-dos32.djgpp2.coff/upx-3.95.exe 224b882b4dcebc1112ced3df1b468ea8dc58083dac4893fa0061dc50ce6abf7c *i386-dos32.djgpp2.coff/upx-3.95.exe
2ea7702d4398d03ea46502f5179b2eaa209926ad0d105e81663b3c87c2e7acb7 *i386-linux.elf/upx-3.91 59e3a1d456036bed175056978d12484a64405f356b1a1fa480866e7e31c9543b *i386-linux.elf/upx-3.91
74df9d74515b51839272c5c84572880d58ea85a16cbed5549b2af182149dad24 *i386-linux.elf/upx-3.95 9662deb5f74b23c5b63d09457442895091f4b6cfd619f7bd6ffc27ec75f08682 *i386-linux.elf/upx-3.95
11401986fe43ee57cb0170099d3a6228238e2eff8244ad81cc647420314c98ee *i386-win32.pe/upx-3.91.exe 3c585a745cd105073bb7324f2183731be84cfc4669f2bab1ef20c9bff909d2fc *i386-win32.pe/upx-3.91.exe
3ee3b313f0cf6c891c5895343ff304aa34e3017aac45022f7bbd0cfd7d80dc25 *i386-win32.pe/upx-3.95.exe fc796dad77cb6cb99bcb5700c3ff0a7b185c1fe8b129a293dd0e45d0903b13e6 *i386-win32.pe/upx-3.95.exe
e9659acb2dc14f60e8f3d71b6024ec9c768ee11233ec9dad5e1bd252cd259381 *m68k-atari.tos/upx-3.91.ttp da41cb691775b8b0ef969954ea272262ed77e83b57257b2ba0ba19427a2ab991 *m68k-atari.tos/upx-3.91.ttp
0796aa39c6a069f5c940ee07442c22d864fdca7f6fe083d51debabab077c413f *mips-linux.elf/upx-3.95 ea6ff916a226e39a5e67b2118fc3ceb0dbc69d8d473051a5df19af14e03ae25e *mips-linux.elf/upx-3.95
98d370c61692de7249aa51f3befc3ebefa705f172a1ebf0dd092ea07b9776158 *mipsel-linux.elf/upx-3.91 0cbc8eaecb2aa7dcc2e9d7b11ba0c0e26193f1328a35107cf1069a8c5f9e63be *mipsel-linux.elf/upx-3.91
7bb3afac05c13ef34721facf4c81621791a45a40cceab2cc1bb7306a747c5df5 *mipsel-linux.elf/upx-3.95 7b112c59fccf3e5f3d4ec253fdb25761e47705a1c5d3a0103249b1747bbbe7d9 *mipsel-linux.elf/upx-3.95
eb292cd7c95fcd597431a8e6c9f13f0b64bbda3423611a43ceeca418a3979554 *powerpc-linux.elf/upx-3.91 de8354fbeaf0623f3d08c3945dcdb5a8f0c078fe3e8082a13767979e841e6677 *powerpc-linux.elf/upx-3.91
6a45c2734fc2aa82a0e2b9331c545e1bb04d02797c59ab00a8250d052603b8a2 *powerpc-linux.elf/upx-3.95 403c26bc1dda0cbf23032bc5ec5ac42ed8537a640a077c4332446227c8a3eb7b *powerpc-linux.elf/upx-3.95
9c6dc09daf5901983625e8f9f2f45f66a10fcf9841ae3e9788bb3ae075db5307 *powerpc64le-linux.elf/upx-3.95 093a7fdbb555c8aea8728b4d6240ed3b723ee9007c5f6ea40a8daf2d1eb63f54 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t140_compress_lzma_2_no_filter="\ expected_sha256sums__t140_compress_lzma_2_no_filter="\
8f08ea0a86c3f49c7b2a90aca17b5739a91e39ef6542365e7395d1325fdcfc2b *amd64-linux.elf/upx-3.91 6dd472386ff2a9683d75fe4cc8d0d40be223681f4d7305a51a7aacf25501e60f *amd64-linux.elf/upx-3.91
9f7c9d0432baaf21977ca4bd827f7cdf7c39296f77e122689cc57945856e7b39 *amd64-linux.elf/upx-3.95 4bbb96b109ae2b8b43b957bc66c3cdc2cfcf3a692377153ef912d09a495c876c *amd64-linux.elf/upx-3.95
86e277047c1b8c1884bf5ceb4f628410b011fae761e8cf7031f0b8b3058adac6 *amd64-win64.pe/upx-3.95.exe 510fc860ac393abcfdbb547e999c12a6c6e928ead026607a6879fa7ca1e2d568 *amd64-win64.pe/upx-3.95.exe
80a8f4d0df27d32d8f20bfd838f6c876026f84d6c54bb5c1a920340031eb22e8 *arm-linux.elf/upx-3.95 a54c0e5b61257154c56f076460f64efbb4216c913c846073d0a695ac3c0ddffd *arm-linux.elf/upx-3.95
c059993735be23726fd74a5d0c5165f4c6581cc90513b2a6f82cb0f8d113ca6a *arm-wince.pe/upx-3.91.exe 9182294f2e31db89b138294cbbc6f6d03ea39a00565adf0e052ed3d21491e1b5 *arm-wince.pe/upx-3.91.exe
3b8298af00f656d071187fc219bbb9a131a412f7489dc7a164fa7c6a78c96c85 *arm64-linux.elf/upx-3.95 fde8face710b6a479a96d7d2d40a29ac8894d5483403e33acbf4a5d6f9cdb29d *arm64-linux.elf/upx-3.95
83d0c4dc17bbb9391d904c85c6382fee5b8f76baf664f14c8f7c3c0b31bc8079 *armeb-linux.elf/upx-3.91 0a92af3f6034487034ea062bc44c93bba74219fa5fdcbb34d1643a95f7daa9ed *armeb-linux.elf/upx-3.91
f939c8365f00d486573f9b969d42d1b43e49fc8c5f59b3a72eb229482de3938e *armeb-linux.elf/upx-3.95 2c11ec89ad145e9f82c3cbbd63ed1e1eca2b0d3c3081fce3e0500ed33c05a623 *armeb-linux.elf/upx-3.95
467cead4f4418d1a581ac61cac5526afdbb6ebe8887749c3b8b25a45bb686e22 *i386-dos32.djgpp2.coff/upx-3.91.exe 13cbcb06079492a21b7440b981250f84ff2be48a69daa168d95cee798f8fbf77 *i386-dos32.djgpp2.coff/upx-3.91.exe
c35eb28139afcea4b03e7fabf993e9927486b53e0ca20d78e61a274358934ad3 *i386-dos32.djgpp2.coff/upx-3.95.exe adfdcd033340a7b14945c9a60da036e25d44c8b1ee0811ac0a4ef1cbca423cc5 *i386-dos32.djgpp2.coff/upx-3.95.exe
6898de07c4d250dfdd9be431a59562e87f49e2c69112d034352d1ec62c6e99dd *i386-linux.elf/upx-3.91 e5fff5b965da26349311c0513d09086600c3b466f1d53e42d6e35d6b4656168e *i386-linux.elf/upx-3.91
400f08c53c7b3d81e99c85f9aa86443616d884a366627f61dce3f1d0c46c67ba *i386-linux.elf/upx-3.95 cf8df3858bbb1c92a06e57ce1b971e11bbf280954f2fc1dc7e5b5a4641d72819 *i386-linux.elf/upx-3.95
2530b702024091f71405e5a8b4b0ebc235a8e12bcb66867590d1a6741c905b9d *i386-win32.pe/upx-3.91.exe ddc4952ef008b7f31e69bf53310d6f03b36a959ebb1cd3c3985d560efcbd4296 *i386-win32.pe/upx-3.91.exe
2a854af2416d459b7bdf8345cae374800cf471d9e945a170fa38046221e7b462 *i386-win32.pe/upx-3.95.exe 99b0b637b562798a440ba605d44e34cf7d4ff995b04dc2e54ebee288ed5180b4 *i386-win32.pe/upx-3.95.exe
74ac6483e4a98a4173330ad43203f04354af0bc1ce046e6c94e5759d68ce992f *m68k-atari.tos/upx-3.91.ttp 89a5de403a012256afefff0f88e1cff4696dee611946e326ad15416dbdba7d13 *m68k-atari.tos/upx-3.91.ttp
118fd0c794402cf96c4c97533c2a3292afdc87632bac6a25978f0baae248e375 *mips-linux.elf/upx-3.95 eac695bc19163050c5bee9271393156a195bfef9c3c76f5aaf3aaef00f5602eb *mips-linux.elf/upx-3.95
4b26db733fab84d8032dd4c6cc345f3da50ac3fe581706b1676ebe19d099c693 *mipsel-linux.elf/upx-3.91 b1331b88421cdf8ef73f8ef1a2c86045fc56a495c08d06d83018c88f5f3934de *mipsel-linux.elf/upx-3.91
a016e09a4aa299dd176a6e5eccde98db8781c509e7605504c316a77bf55fe1a1 *mipsel-linux.elf/upx-3.95 9644118e26647d489e811ebe3bfd320e2976dbe26621e994fe979b0f9d175818 *mipsel-linux.elf/upx-3.95
db75012b5177ef021fb9365c3828aba39ea7feff0783e737a4625c0066de8ef1 *powerpc-linux.elf/upx-3.91 64a4a31815e4bf43e2ea866faa494c69a4209ed53055f16562d0d2d6ba7fd927 *powerpc-linux.elf/upx-3.91
168931dfcecc39019fa86eb2e27dfc2e8239160c3b826b76fd53f39f13f986da *powerpc-linux.elf/upx-3.95 dec559bf9cbd4d1745e8f3bf2cedf016a72f443d037f75eab0d2baab191f0ae1 *powerpc-linux.elf/upx-3.95
e58fb39928d60ec18add81e3dcc62b5a82cfa8c9c19f89ade0a7388ac88342f5 *powerpc64le-linux.elf/upx-3.95 f10b8afa319b1056a82f24dd52d13003c5cf005fc3cc3481dad1e58ef33e973f *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t150_compress_ucl_2_all_filters="\ expected_sha256sums__t150_compress_ucl_2_all_filters="\
c329512f59d065b20698c49ff7d710c7bb0cf099b8a4b8fe5ecd1121a12eb175 *amd64-linux.elf/upx-3.91 2e89a5b8192957b066d5a5ee39e47663518f49c1e7811f6806e21d938201d5b6 *amd64-linux.elf/upx-3.91
8cf09664da89c51453e23c4ac76e8d619814dbd576580f408ebf95078dc67474 *amd64-linux.elf/upx-3.95 d1cfdda4b93d697211c052f3d85cd745e533261f05cc06c2869a8561c07b4f57 *amd64-linux.elf/upx-3.95
8af657df3b6a0f7d586f38960a592827921a914f923db4ab87fbb93094f1096d *amd64-win64.pe/upx-3.95.exe c7381363e31af6789111f58ca590b0d751956c322684efa1914f1d918ecc23ce *amd64-win64.pe/upx-3.95.exe
055f5fd681f872e2e308a59402196bb3f33fdb0ef34ddee4031f7d676e6ac364 *arm-linux.elf/upx-3.95 4dc8ba75edd4b1c3d890c9deeb033d9abf08fb65054eddb4f34138d34503c21d *arm-linux.elf/upx-3.95
eae07f1e169d0b89ec80fac5f61ce41af9c697d48ddb45495806f9e3103dd0ac *arm-wince.pe/upx-3.91.exe 36f744d6dca6ecb8c60ee456859ac6a1ac241d12ababa20a5e2d0d79551d53aa *arm-wince.pe/upx-3.91.exe
b1bfa0d71d8dfd3edd772d1d92f76695155ba9cbcdc572c68efa8cd6e500b0b6 *arm64-linux.elf/upx-3.95 72d3de2abdc3985c790d833a9535054683e2b3feaa6b96778e55ea8f448846a3 *arm64-linux.elf/upx-3.95
12af497fbc9d06199fa623744a31778ee78fe142e5958162f0e683809ca58435 *armeb-linux.elf/upx-3.91 233d4f130995bb7155064ce6f651b9f6ac61268c8698ccc90a8ea3b2e297cb39 *armeb-linux.elf/upx-3.91
b497a7fb0b12fb75a4444f0c137e174fe059b973f5f2425b1eedb04855dfb130 *armeb-linux.elf/upx-3.95 a107428a7675181974a8efc359d39da74510098d8307347865f7bcdd707e28ad *armeb-linux.elf/upx-3.95
1c7d4abe5aa21da343399e2cff642f04bf0904bbac2df97d5e10b2e9087806fd *i386-dos32.djgpp2.coff/upx-3.91.exe bd57c1e3844310c2a864384f2b83a5781933a5beb05a5eb748a6094e37621166 *i386-dos32.djgpp2.coff/upx-3.91.exe
70ae2c3a58b22dbf1aefb145705c00855be241e6b2cc45fe18cd90bf93fa3802 *i386-dos32.djgpp2.coff/upx-3.95.exe 1a13debece417ada4e18d5ec02efa7ef1c354ddfa4674b5717e0aa6bc90c16e3 *i386-dos32.djgpp2.coff/upx-3.95.exe
f332cba5e96fa04377a127c2c7f45822ccf1f12dd990fca5bf73499902082c3b *i386-linux.elf/upx-3.91 f7b56af17d3d8402310387d1e82f90fa670dfa058feb3fe413ac81c01a1efbb1 *i386-linux.elf/upx-3.91
15f1238bd48835d850c4eb9bb51515738d69237b6c81bd7148aefb0a0e4556e6 *i386-linux.elf/upx-3.95 fe9162fbfe8f4eb1c9f286df68107c08f25592d2edaaf5707540c81f709e29ac *i386-linux.elf/upx-3.95
1c00860e202116b199fa76b4b508f27d7ec28510d8287557d04688c93be4e624 *i386-win32.pe/upx-3.91.exe aaa267d824bd0520c016edcc1a6642d4898030760879e1da883b8211cf071350 *i386-win32.pe/upx-3.91.exe
12e1ac68a55bae0c2f82149b133e21224e37168e9915ef97bd40d38455723a53 *i386-win32.pe/upx-3.95.exe d178699c0ed805829e457987ea5da21f4e37cf1eb74529235d9b1275bf3122f6 *i386-win32.pe/upx-3.95.exe
ae43a71d76b0bc2f1af2e9b5ec90d6cc0337dbd603d124dfac8c68893bd8fb5f *m68k-atari.tos/upx-3.91.ttp 8376ba3954c4fd9cd5e5e8e38923759db005a4048c3d86dc76476e9f3d92a07d *m68k-atari.tos/upx-3.91.ttp
e0c0dd0e41b3d0f059d373bbc81c35fdb843657d496614fd090aa2d89ed5da27 *mips-linux.elf/upx-3.95 65a0227127b7952a42216c79a8431d1bbe7f04c9efdc81f72095d095a969cb80 *mips-linux.elf/upx-3.95
558780a870830f5fbb14f5cd00db576fa37c8fcd72f7f22491ca2279aaf85757 *mipsel-linux.elf/upx-3.91 c2bd45b55980bfbc5e568a640643772e3e82bc02cd2c7559cb1c57fc0809d01e *mipsel-linux.elf/upx-3.91
7d85974f25e3daa3f21c11496683bee6c22d1c6086f29ed5b410637cb9c66f2e *mipsel-linux.elf/upx-3.95 74e25daba42baeaaffadab00bacca56b1de5f151a00160592077288a678f41f2 *mipsel-linux.elf/upx-3.95
cb3c36ee3ade39e4cb1c2d5bb20548f1f4560bf1853c315b5c2b3fca533c75ec *powerpc-linux.elf/upx-3.91 904310944bec344897fc6b7a61dfe8ee639d136c555a950c736059cbc6cac8be *powerpc-linux.elf/upx-3.91
faaf09644ef9eb51a5f48a34971bb6ab363cb85fb79fdba8ad9eb1aecd7d5a7e *powerpc-linux.elf/upx-3.95 5304a95cdcdbdcb76cfac2b93e254f601fb73f68be0a44ed282096aec8d55ae8 *powerpc-linux.elf/upx-3.95
c714496c2027d81cd16431cc27dc105761aae98d71099cecae84bd1d269e9dba *powerpc64le-linux.elf/upx-3.95 7ebd0be91bc9f60e22304103b3543b16a0fd128aa22f11474e31aecc97703e43 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t160_compress_all_methods_1_no_filter="\ expected_sha256sums__t160_compress_all_methods_1_no_filter="\
08a685a5869892597aa82264e8796a6d0e663f61426b683cfb47a51c5f4e1f37 *amd64-linux.elf/upx-3.91 4d8069614af5721c7878daf10ee1d30a6bffc5446532963e2ff0e6cb6f1feecd *amd64-linux.elf/upx-3.91
ea0ef4eed5ecfa14f5e713bae4a7559adcd8dc5bf26a6bc035d771063cf325eb *amd64-linux.elf/upx-3.95 f1971902f7d8f840fdc70ad9edbf5587db556ba046947f5ee7b4130e9ba7de5a *amd64-linux.elf/upx-3.95
d5cbc1908d75808afffaa503584588aa33ef3ce36692273c0d7ae628fe649fc6 *amd64-win64.pe/upx-3.95.exe 0198a6cfd468f7ec7cd32294333400a4c97bf1cac32602594681db8f08c87700 *amd64-win64.pe/upx-3.95.exe
a90a668fb46aa1ae1ebe875383930f016ea3ca9985f8a6d0d09bcef179cee7ab *arm-linux.elf/upx-3.95 d46340dcd209cce0f1d65d6a50754ea3246cdbba730199765b2c2ac40957bd55 *arm-linux.elf/upx-3.95
ad3d1c557d82f8d4d54a462b5e720705b51df064141b0fd3f81d54de685f51d6 *arm-wince.pe/upx-3.91.exe aa03361a7dae633d5b6c8b4164726c99bfc28fcf4f1ac8ebea6fc44e90c03244 *arm-wince.pe/upx-3.91.exe
1b2f673515ca9b67c7af0a9381d4e2b7f23b709e97ae969cf1dedcfda8b254ef *arm64-linux.elf/upx-3.95 aa0a3dda3e2f073eb36d6614c02f4af79590876a23437623ea6c231be8e070fa *arm64-linux.elf/upx-3.95
ef2ce0aace6ea8c6994232c93b73d2b0fda6ccc2b108bfca6a0f4d4dbacc36d0 *armeb-linux.elf/upx-3.91 578547a4d527655c7fd661148dfcf0f7dc9585dfb08063c13b116364a881bf15 *armeb-linux.elf/upx-3.91
2bfdc5e22932b32d405611d51940d7a79b851e3776b8cdb05db5112a195cc624 *armeb-linux.elf/upx-3.95 0034809b31b0105631b0e4c0a4378cfd26a80dfca2016228e8084f410025f091 *armeb-linux.elf/upx-3.95
a9b09a6118386855e0b326e337f72c8dd369b3cadfb4e1d35a08c197a71ec0f6 *i386-dos32.djgpp2.coff/upx-3.91.exe 55b9b578a97a7b8637a9041a222269f2563a4e1f75c329c533f83432c8f9652c *i386-dos32.djgpp2.coff/upx-3.91.exe
4cedba26f462707805fef1810d720e09b25040f97344444d93c0af36923e8089 *i386-dos32.djgpp2.coff/upx-3.95.exe 98a9f601d095f910c68bbf35ff50f19e3e851ef5dae78fc0e9ef4462dd8a314d *i386-dos32.djgpp2.coff/upx-3.95.exe
7fdf110134d120d6cec0aea13c1a7b861770cecb4f516cd1ab595a4d3d26936f *i386-linux.elf/upx-3.91 45f714365212b31419986016b5b730ca77523036469e28242543bfde4dc44678 *i386-linux.elf/upx-3.91
deb15af9198da2d8e2d95b5f5e64bd8639cb97d4cfe2484eabdcd6385288b964 *i386-linux.elf/upx-3.95 e45f6ae7ad7b9e719e5080bfbd04e7c961242473bb8f1574cb625bc8a1abd201 *i386-linux.elf/upx-3.95
40fcff57d7859f37d349b907a4564bf3e9ba7223cc163e770f8353a8bfa51c73 *i386-win32.pe/upx-3.91.exe 0b5d940059fc6f2a3d5664eadd0781399210c306be99411beeb8f6f02ea85762 *i386-win32.pe/upx-3.91.exe
fae3dc1dc8eac23f6e610a1e01c20d4779026511a091672f7c150c402ae1c552 *i386-win32.pe/upx-3.95.exe 0f5b50dfe0db34ae07f113871a39c64624f964ed16dc8d49922e6a891c17a3bd *i386-win32.pe/upx-3.95.exe
f9663e80b6d0f69cc916ae137f6df9cd8c10bfff9c1562959efd32e91b02e1a8 *m68k-atari.tos/upx-3.91.ttp 56fd999694feb66cdc2272daf86bb91b3c66b857867f3e0c071f3e70624760f4 *m68k-atari.tos/upx-3.91.ttp
50b71e6090c7964bb704849584c7c75d8ee5aaa5bfab26482d3879bc01d17841 *mips-linux.elf/upx-3.95 2d8d2e02bedad8ba1e7d69a89888b173b9be48ee154e2461c205ba4eae6ececa *mips-linux.elf/upx-3.95
cb7d16ae50a2eb464c1f864f1b9052cc66f52545b82d636e48b2105e797e31f7 *mipsel-linux.elf/upx-3.91 c478c21ecabe91910cf861ebc6b6d38deeb31545e5ae44eaf826dafb477bbfba *mipsel-linux.elf/upx-3.91
a1052f7425c434ce0f92dbb292d6511c8af1698a2e88352f7a463711ef8115c6 *mipsel-linux.elf/upx-3.95 4d66e1b32ca6b1d399616de5643ee5d1c54a7bf1eca761055570450f56efe4f9 *mipsel-linux.elf/upx-3.95
5fcc6323a8cd37d83e9a9136d7d2511a3e5c59216ceab50d4f386a2ae1a6c842 *powerpc-linux.elf/upx-3.91 72c85b48afb30cc191483af41f797a397225cfaaa44e2eaf7a9d59d9033335e1 *powerpc-linux.elf/upx-3.91
a905cb39a96982ab08e2663be690cd400bd54646b50ee50790de51b322d09830 *powerpc-linux.elf/upx-3.95 c0ed0c72fd6a6e0bfb4444b8c358018246f80cbc732388a22bd2492fd9fdc59c *powerpc-linux.elf/upx-3.95
071b42a5ae7bf3d25f01e436473433470b97311ac2aff834884a0d3d240d0291 *powerpc64le-linux.elf/upx-3.95 070f4c2ca60717abedda0ab4030d546cca8a75b9872038a414e2946b8d8f93e7 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\ expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
c5ed17847125467790aa635c926075768925ab88c3a6baa57b3bf2877c6b9001 *amd64-linux.elf/upx-3.91 223bcdc5f11daa4d0258090e967d4e0b5986d764d6b21fcfadba7212676396f2 *amd64-linux.elf/upx-3.91
a17594fae504de512492ef822675cf6faac74e48c7803ac119626148ea9adb89 *amd64-linux.elf/upx-3.95 a3e5f1a20bd9db4ae920c5c7e7f1707a63fa3f557f9db50b5e1004b706e3a52c *amd64-linux.elf/upx-3.95
1ea4c9aedd3591f62cd6902986c1df39d3ef7fc624abc78bde61300e87627d20 *amd64-win64.pe/upx-3.95.exe 355011427a4d433ccef5060e4cbebc59b0ecc38a430566cdb684330388ea0812 *amd64-win64.pe/upx-3.95.exe
319e96fc0a6dbaa3aa7214100176957d4d0e84b7d0ee849a1f60c34ba5a22947 *arm-linux.elf/upx-3.95 1e0a8363b539953181dc95283a1e3100bacce961f49e875c8f430b18d0e6672d *arm-linux.elf/upx-3.95
a3f2144754b44700b4aacb39ab5f5b818fda7caa0a934090eeacee7dafb6ba7b *arm-wince.pe/upx-3.91.exe e281362e2172468d20ea2c7171c847f47e01a63d912cafacf977236655708521 *arm-wince.pe/upx-3.91.exe
5cb0a03d3305ddd5bc77990538b49ce3f14dcd03ad76d272d45005aa86dd5f7d *arm64-linux.elf/upx-3.95 7f3497c67e816b3f2af6642f09ba809166f8a0a65f52936cfb2e3d9756d7bd44 *arm64-linux.elf/upx-3.95
f5061f76060445a72edb898e9919400e81423bde6dad566a5bb5bdf1407ef6dc *armeb-linux.elf/upx-3.91 7d9d52959a64c5dd19ea343c8c2bdd4d70fd0644d13c62924760407515fd74ba *armeb-linux.elf/upx-3.91
337e4776b2f1afec7eb6d54c34d68f166af63ce5b4e2fb7ac48eeb5b83582c28 *armeb-linux.elf/upx-3.95 e05ad251ec24e2f788de71c4c8cf7c8880a8eb7d8a516ca8d6ab94c715c2f77d *armeb-linux.elf/upx-3.95
46223cc5aea67b275cc5621eec79f97d4f543edecfdac37a0f2407583f881fc9 *i386-dos32.djgpp2.coff/upx-3.91.exe 00a030d8967c5145b955eba17d84edd44b21c93b570f80a44e894a10a3ebf99f *i386-dos32.djgpp2.coff/upx-3.91.exe
228c9007c5395fc9eef93a23d781e7daab01efa1ee86a4d4f6a46b9b7f7aeb8b *i386-dos32.djgpp2.coff/upx-3.95.exe b4b0e3c774dbf3940af777d28e1ba7c62bfedaa710e3376e81259218779eae56 *i386-dos32.djgpp2.coff/upx-3.95.exe
089693d8059d8580ea3bf326d038ffb51f258721833ad96c05f20c321ab8df13 *i386-linux.elf/upx-3.91 f903265140b193e672c4dd2bc28e68b9f822d73517f0b339fc715ad781a49fab *i386-linux.elf/upx-3.91
d4995b5b5c46eef7f8f1673c629f427d19b5dbda495c2b3f157acf4046b72123 *i386-linux.elf/upx-3.95 6253062e41c4619bb3aeb807665a2925b1f01095d000c614c443b81d44112a1d *i386-linux.elf/upx-3.95
dd70e8fde421a35692f26147c3eba392f57adb332d0e5025fa0039a2673c10cb *i386-win32.pe/upx-3.91.exe 7664ed4ce00b962a21ca5654993c4c4cb2ec1afcf9dc921cd90862f8412572cc *i386-win32.pe/upx-3.91.exe
3fa365f39199afc7a259ba8ad8ae50cd026ef3f0a37d3fd570d42cba8bc5e0e7 *i386-win32.pe/upx-3.95.exe 6ef354d0b2dffc71c32fc33f3f89b0b8ae7035e43e8a684a12d6ce2c53caf706 *i386-win32.pe/upx-3.95.exe
1b2f9a97731805dafef6961656bd29d7e983320a5626fe88ba987bf267bef32a *m68k-atari.tos/upx-3.91.ttp 5890050fe690bb93bf70693f1bef0e6ea708029836c7d8aa57de02b6aefe4239 *m68k-atari.tos/upx-3.91.ttp
21febba6606d89c4a0f72a7f07f55d90268da48b97c65d23647c021c2e26b7c4 *mips-linux.elf/upx-3.95 2bce2082ae39dedcc21a1a6c83e954073b368e9172ee0c7f2a3f13b3447a7898 *mips-linux.elf/upx-3.95
7a0892428e07493578d59f16adc0e6f5959f3d5a437e818375ff9fbf8ba42d2f *mipsel-linux.elf/upx-3.91 d5b88d291a8a2141d9d9f07a6a21e11522e510c6520ba0c36ebf94d089962607 *mipsel-linux.elf/upx-3.91
ecf7d97388e48f2ad27a06ab8f4027e165e5a34f577f7b4fec3928a946557d60 *mipsel-linux.elf/upx-3.95 ff42d564999e02346c86d4156266f423edd55b3887aadf76d81a8c355e3b175d *mipsel-linux.elf/upx-3.95
171393e34d004f04040067080b4b48d08030708bd30bcea593f554ed13b4ddb8 *powerpc-linux.elf/upx-3.91 f33205ad8252524d8c48d18cdb03bba507e29c9cc931f94327a5a46480f70843 *powerpc-linux.elf/upx-3.91
0b97ff1ed48d19e64120cd4fac5f4e76da6ea6f3ec1fda5cada11aa2142d045a *powerpc-linux.elf/upx-3.95 011683a891e30ea346efe9ba5c1488fb50f143e4090bd2be07537c696d6167db *powerpc-linux.elf/upx-3.95
0c825675a076c7b9f73ae0292527e3d569b5c0b33298b9f48b7bdd3084115c69 *powerpc64le-linux.elf/upx-3.95 9d919460b0ceec4b880cdf14850fea8096d6796c2457467b3cc9b2ce954cc6de *powerpc64le-linux.elf/upx-3.95
" "
########## end .sha256sums.recreate ########## end .sha256sums.recreate
+33 -30
View File
@@ -1,40 +1,29 @@
#! /bin/bash #! /bin/bash
## vim:set ts=4 sw=4 et: ## vim:set ts=4 sw=4 et:
set -e; set -o pipefail set -e; set -o pipefail
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# very first version of the upx-testsuite
#
if [[ $TRAVIS_OS_NAME == osx ]]; then
argv0=$0; argv0abs=$(greadlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
else
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs") argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
fi
source "$argv0dir/travis_init.sh" || exit 1
if [[ $BM_T =~ (^|\+)SKIP($|\+) ]]; then # very first version of the upx-testsuite; requires:
echo "UPX testsuite SKIPPED." # $upx_exe
exit 0 # $upx_testsuite_SRCDIR
fi # $upx_testsuite_BUILDDIR (optional)
if [[ $BM_X == rebuild-stubs ]]; then # $BM_T (optional)
exit 0
fi
# convenience # convenience
[[ -z $upx_testsuite_BUILDDIR ]] && upx_testsuite_BUILDDIR=./tmp-upx-testsuite
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe") [[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe")
# create dirs # make dirs absolute
cd / || exit 1 upx_testsuite_SRCDIR=$(readlink -en -- "$upx_testsuite_SRCDIR")
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
echo 'invalid or missing $upx_testsuite_SRCDIR:' echo 'invalid or missing $upx_testsuite_SRCDIR:'
echo ' please git clone https://github.com/upx/upx-testsuite' echo ' please git clone https://github.com/upx/upx-testsuite'
echo ' and set (export) the envvar upx_testsuite_SRCDIR to the local file path' echo ' and set (export) the envvar upx_testsuite_SRCDIR to the local file path'
exit 1 exit 1
fi fi
mkbuilddirs "$upx_testsuite_BUILDDIR" mkdir -p "$upx_testsuite_BUILDDIR"
upx_testsuite_BUILDDIR=$(readlink -en -- "$upx_testsuite_BUILDDIR")
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1 cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
# /*********************************************************************** # /***********************************************************************
@@ -42,7 +31,8 @@ cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
# ************************************************************************/ # ************************************************************************/
testsuite_header() { testsuite_header() {
print_header "$1" local x='==========='; x="$x$x$x$x$x$x$x"
echo -e "\n${x}\n${1}\n${x}\n"
} }
testsuite_split_f() { testsuite_split_f() {
@@ -147,8 +137,6 @@ if [[ $BM_T =~ (^|\+)ALLOW_FAIL($|\+) ]]; then
set +e set +e
fi fi
[[ -z $upx_exe && -f $upx_BUILDDIR/upx.out ]] && upx_exe=$upx_BUILDDIR/upx.out
[[ -z $upx_exe && -f $upx_BUILDDIR/upx.exe ]] && upx_exe=$upx_BUILDDIR/upx.exe
if [[ -z $upx_exe ]]; then exit 1; fi if [[ -z $upx_exe ]]; then exit 1; fi
upx_run=$upx_exe upx_run=$upx_exe
if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then
@@ -169,10 +157,6 @@ if [[ $BM_T =~ (^|\+)valgrind($|\+) ]]; then
upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe" upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe"
fi fi
if [[ $BM_B =~ (^|\+)coverage($|\+) ]]; then
(cd / && cd "$upx_BUILDDIR" && lcov -d . --zerocounters)
fi
export UPX="--prefer-ucl --no-color --no-progress" export UPX="--prefer-ucl --no-color --no-progress"
export UPX_DEBUG_DISABLE_GITREV_WARNING=1 export UPX_DEBUG_DISABLE_GITREV_WARNING=1
export UPX_DEBUG_DOCTEST_VERBOSE=0 export UPX_DEBUG_DOCTEST_VERBOSE=0
@@ -182,7 +166,7 @@ if ! $upx_run --version-short; then echo "UPX-ERROR: FATAL: upx --version-sho
if ! $upx_run -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi if ! $upx_run -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
if ! $upx_run --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi if ! $upx_run --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
rm -rf ./testsuite_1 rm -rf ./testsuite_1
mkbuilddirs testsuite_1 mkdir testsuite_1
cd testsuite_1 || exit 1 cd testsuite_1 || exit 1
# /*********************************************************************** # /***********************************************************************
@@ -223,33 +207,52 @@ testsuite_check_sha $testdir
# // test UPX and not the compression libraries # // test UPX and not the compression libraries
# ************************************************************************/ # ************************************************************************/
case $UPX_TESTSUITE_FAST in
[0-7]) ;;
*) UPX_TESTSUITE_FAST=999 ;;
esac
if [[ $UPX_TESTSUITE_FAST -ge 1 ]]; then
testdir=t110_compress_ucl_nrv2b_3_no_filter testdir=t110_compress_ucl_nrv2b_3_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --nrv2b -3 --no-filter time testsuite_run_compress --nrv2b -3 --no-filter
fi
if [[ $UPX_TESTSUITE_FAST -ge 2 ]]; then
testdir=t120_compress_ucl_nrv2d_3_no_filter testdir=t120_compress_ucl_nrv2d_3_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --nrv2d -3 --no-filter time testsuite_run_compress --nrv2d -3 --no-filter
fi
if [[ $UPX_TESTSUITE_FAST -ge 3 ]]; then
testdir=t130_compress_ucl_nrv2e_3_no_filter testdir=t130_compress_ucl_nrv2e_3_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --nrv2e -3 --no-filter time testsuite_run_compress --nrv2e -3 --no-filter
fi
if [[ $UPX_TESTSUITE_FAST -ge 4 ]]; then
testdir=t140_compress_lzma_2_no_filter testdir=t140_compress_lzma_2_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --lzma -2 --no-filter time testsuite_run_compress --lzma -2 --no-filter
fi
if [[ $UPX_TESTSUITE_FAST -ge 5 ]]; then
testdir=t150_compress_ucl_2_all_filters testdir=t150_compress_ucl_2_all_filters
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress -2 --all-filters time testsuite_run_compress -2 --all-filters
fi
if [[ $UPX_TESTSUITE_FAST -ge 6 ]]; then
testdir=t160_compress_all_methods_1_no_filter testdir=t160_compress_all_methods_1_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --all-methods -1 --no-filter time testsuite_run_compress --all-methods -1 --no-filter
fi
if [[ $UPX_TESTSUITE_FAST -ge 7 ]]; then
testdir=t170_compress_all_methods_no_lzma_5_no_filter testdir=t170_compress_all_methods_no_lzma_5_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --all-methods --no-lzma -5 --no-filter time testsuite_run_compress --all-methods --no-lzma -5 --no-filter
fi
# /*********************************************************************** # /***********************************************************************
# // summary # // summary
+242 -76
View File
@@ -1,5 +1,4 @@
# Support for GitHub Actions -- https://github.com/features/actions # Support for GitHub Actions -- https://github.com/features/actions
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# note: GitHub Actions runner images are frequently updated, and # note: GitHub Actions runner images are frequently updated, and
# unfortunately this sometimes breaks builds in mysterious ways... # unfortunately this sometimes breaks builds in mysterious ways...
@@ -7,16 +6,10 @@
name: 'CI' name: 'CI'
on: on: [push, workflow_dispatch]
push:
branches:
- '*'
- '!appveyor*'
- '!gitlab*'
- '!travis*'
workflow_dispatch:
env: env:
DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose UPX_CMAKE_BUILD_FLAGS: --verbose
jobs: jobs:
@@ -27,27 +20,30 @@ jobs:
- name: 'Install extra packages' - name: 'Install extra packages'
run: | run: |
uname -a; pwd; id; umask uname -a; pwd; id; umask
cd ..; mkdir -p deps; cd deps; mkdir packages mkdir ../deps; cd ../deps; mkdir packages
# for ubuntu-22.04: install python2 # for ubuntu-22.04: install python2-minimal
##export DEBIAN_FRONTEND=noninteractive ##sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal
##sudo apt-get install -y --no-install-recommends python2-minimal
# manually install compat libs from Ubuntu 16.04 # manually install compat libs from Ubuntu 16.04
wget -q 'http://mirror.enzu.com/ubuntu/pool/main/g/gmp/libgmp10_6.1.0+dfsg-2_amd64.deb' wget -q 'http://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb'
wget -q 'http://mirror.enzu.com/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.4-1_amd64.deb' for f in ./*.deb; do dpkg -x $f ./packages; done
for f in *.deb; do dpkg -x $f ./packages; done
sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/
rm -rf ./*.deb ./packages
sudo ldconfig sudo ldconfig
wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20210104/bin-upx-20210104.tar.xz | tar -xJ wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
with: { submodules: true } with: { submodules: true }
- name: 'Rebuild and verify stubs' - name: 'Rebuild and verify stubs'
run: | run: |
env C=gcc X=rebuild-stubs TRAVIS_OS_NAME=linux bash ./.github/travis_build.sh export PATH="$(readlink -en ../deps/bin-upx-20221212):$PATH"
make -C src/stub maintainer-clean extra-clean
git status || true
make -C src/stub extra-all all
if ! git diff --quiet; then git diff; exit 1; fi
- name: 'Check source code formatting' - name: 'Check source code formatting'
run: | run: |
bash ./misc/scripts/check_whitespace_git.sh bash ./misc/scripts/check_whitespace_git.sh
env UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20210104/clang-format-10.0.1" make -C src clang-format UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20221212/clang-format-15.0.6" make -C src clang-format
if ! git diff --quiet; then git diff; exit 1; fi if ! git diff --quiet; then git diff; exit 1; fi
job-linux-cmake: job-linux-cmake:
@@ -58,25 +54,45 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { os: ubuntu-20.04 } - { os: ubuntu-22.04, use_m32: true }
- { os: ubuntu-22.04 } - { os: ubuntu-20.04, use_m32: false }
steps: steps:
- name: 'Install extra 32-bit and Windows packages'
if: ${{ matrix.use_m32 }}
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
with: { submodules: true } with: { submodules: true }
- name: 'Build cmake debug-gcc' - name: 'Check out test suite'
run: 'make build/debug-gcc' run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
- name: 'Build cmake release-gcc' - name: 'Build cmake extra/gcc/debug'
run: 'make build/release-gcc' run: 'make build/extra/gcc/debug'
- name: 'Build cmake debug-clang' - name: 'Build cmake extra/gcc/release'
run: 'make build/debug-clang' run: 'make build/extra/gcc/release'
- name: 'Build cmake release-clang' - name: 'Build cmake extra/clang/debug'
run: 'make build/release-clang' run: 'make build/extra/clang/debug'
- name: 'Build cmake extra/clang/release'
run: 'make build/extra/clang/release'
- name: 'Build cmake extra/gcc-m32/debug'
if: ${{ matrix.use_m32 }}
run: 'make build/extra/gcc-m32/debug'
- name: 'Build cmake extra/gcc-m32/release'
if: ${{ matrix.use_m32 }}
run: 'make build/extra/gcc-m32/release'
- name: 'Build cmake extra/cross-windows-mingw32/release'
if: ${{ matrix.use_m32 }}
run: 'make build/extra/cross-windows-mingw32/release'
- name: 'Build cmake extra/cross-windows-mingw64/release'
if: ${{ matrix.use_m32 }}
run: 'make build/extra/cross-windows-mingw64/release'
- name: 'Make artifact' - name: 'Make artifact'
run: | run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }} N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
mkdir -p "tmp/artifact/$N" mkdir -p "tmp/artifact/$N"
(cd build && cp -ai --parents */upx "../tmp/artifact/$N") (cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N") (cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
@@ -87,10 +103,20 @@ jobs:
path: tmp/artifact path: tmp/artifact
- name: 'Run basic tests' - name: 'Run basic tests'
run: | run: |
make -C build/debug-gcc test make -C build/extra/gcc/debug test
make -C build/release-gcc test make -C build/extra/gcc/release test
make -C build/debug-clang test make -C build/extra/clang/debug test
make -C build/release-clang test make -C build/extra/clang/release test
- name: 'Run basic tests 32-bit'
if: ${{ matrix.use_m32 }}
run: |
make -C build/extra/gcc-m32/debug test
make -C build/extra/gcc-m32/release test
- name: 'Run test suite build/extra/gcc/release'
run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
env -C build/extra/gcc/release upx_exe=./upx bash "$testsuite_1"
job-macos-cmake: job-macos-cmake:
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
@@ -100,28 +126,43 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10' } - { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true }
# { os: macos-12, gcc: gcc-11, gxx: 'g++-11' } # disable gcc - XCode 14.0 ld bug - { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true }
- { os: macos-12 }
steps: steps:
- name: 'Install brew packages'
if: ${{ matrix.testsuite }}
run: |
brew update
brew install coreutils
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
with: { submodules: true } with: { submodules: true }
- name: 'Build cmake debug-gcc' - name: 'Check out test suite'
if: ${{ matrix.testsuite }}
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
- name: 'Build cmake extra/clang/debug'
run: 'make build/extra/clang/debug'
- name: 'Build cmake extra/clang/release'
run: 'make build/extra/clang/release'
- name: 'Build cmake extra/gcc/debug'
if: ${{ matrix.gcc != '' }} if: ${{ matrix.gcc != '' }}
run: 'make build/debug-gcc CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}' run: 'make build/extra/gcc/debug CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
- name: 'Build cmake release-gcc' - name: 'Build cmake extra/gcc/release'
if: ${{ matrix.gcc != '' }} if: ${{ matrix.gcc != '' }}
run: 'make build/release-gcc CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}' run: 'make build/extra/gcc/release CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
- name: 'Build cmake debug-clang' - name: 'Build cmake xtarget/cross-darwin-arm64/debug'
run: 'make build/debug-clang' run: |
- name: 'Build cmake release-clang' CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \
run: 'make build/release-clang' make UPX_XTARGET=cross-darwin-arm64 xtarget/debug
- name: 'Build cmake xtarget/cross-darwin-arm64/release'
run: |
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \
make UPX_XTARGET=cross-darwin-arm64 xtarget/release
- name: 'Make artifact' - name: 'Make artifact'
run: | run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }} N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
mkdir -p "tmp/artifact/$N" mkdir -p "tmp/artifact/$N"
(cd build && rsync -R -a */upx "../tmp/artifact/$N/") (cd build && rsync -R -a */*/*/upx "../tmp/artifact/$N/")
(cd tmp/artifact && gtar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N") (cd tmp/artifact && gtar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
@@ -132,8 +173,15 @@ jobs:
path: tmp/artifact path: tmp/artifact
- name: 'Run basic tests' - name: 'Run basic tests'
run: | run: |
make -C build/debug-clang test make -C build/extra/clang/debug test
make -C build/release-clang test make -C build/extra/clang/release test
- name: 'Run test suite build/extra/clang/release'
if: ${{ matrix.testsuite }}
run: |
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
env -C build/extra/clang/release upx_exe=./upx bash "$testsuite_1"
job-windows-cmake: job-windows-cmake:
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
@@ -143,8 +191,9 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# windows-2019 used to work but got broken with the 20220821.1 # windows-2019 used to work but got broken with the 20220821.1 runner-image
# runner-image update; disable for now # update; we cannot download that image for inspection, and debugging the
# remote image is painful, so disable for now
# see https://github.com/actions/runner-images.git # see https://github.com/actions/runner-images.git
####- { os: windows-2019 } ####- { os: windows-2019 }
- { os: windows-2022 } - { os: windows-2022 }
@@ -152,8 +201,10 @@ jobs:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
with: { submodules: true } with: { submodules: true }
- name: 'Check out test suite'
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
- name: 'Inspect runner-image settings' - name: 'Inspect runner-image settings'
# see https://github.com/actions/runner-images.git # debug remote image; also see https://github.com/actions/runner-images.git
if: ${{ false }} if: ${{ false }}
run: | run: |
Get-Command bash; Get-Command cmake; Get-Command make Get-Command bash; Get-Command cmake; Get-Command make
@@ -180,71 +231,81 @@ jobs:
run: | run: |
cmake --build build/debug --config Debug --target RUN_TESTS cmake --build build/debug --config Debug --target RUN_TESTS
cmake --build build/release --config Release --target RUN_TESTS cmake --build build/release --config Release --target RUN_TESTS
- name: 'Run test suite build/release'
shell: bash
run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
env -C build/release/Release upx_exe=./upx bash "$testsuite_1"
job-windows-toolchains: job-windows-toolchains:
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ matrix.name }} name: ${{ format('windows {0}', matrix.name) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
C: ${{ matrix.C }} C: ${{ matrix.C }}
B: release B: release
H: 'd:\a\upx' H: 'd:\a\upx\upx'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { name: amd64-win64-msvc-14.2, os: windows-2019, C: msvc-14.2-x64, A: x64 } - { name: amd64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64 }
- { name: amd64-win64-msvc-14.3, os: windows-2022, C: msvc-14.3-x64, A: x64 } - { name: amd64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64 }
- { name: i386-win32-msvc-14.2, os: windows-2019, C: msvc-14.2-x86, A: x86 } - { name: arm64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64_arm64 }
- { name: i386-win32-msvc-14.3, os: windows-2022, C: msvc-14.3-x86, A: x86 } - { name: arm64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64_arm64 }
- { name: i386-win32-vs2019, os: windows-2019, C: msvc-14.2-x86, arch: amd64_x86 }
- { name: i386-win32-vs2022, os: windows-2022, C: msvc-14.3-x86, arch: amd64_x86 }
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
with: { submodules: true } with: { submodules: true }
- name: 'Prepare sources' - name: 'Prepare sources and Check out test suite'
shell: cmd shell: bash
run: | run: |
where bash & where cat & where chmod & where cmp & where cp & where curl & where date & where file & where git & where gzip & where mkdir & where mv & where openssl & where readlink & where rm & where rmdir & where sed & where sha256sum & where sort & where ssh & where ssh-add & where ssh-agent & where ssh-keyscan & where tar & where touch
git config --global core.autocrlf input git config --global core.autocrlf input
git --version & bash --version git --version && bash --version
cd %H% git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
md build build\%C% deps mkdir -p -v build/$C/$B/{ucl,upx,zlib,zstd}
cd deps
git clone --depth=1 https://github.com/upx/upx-testsuite
- name: 'Set up Developer Command Prompt' - name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
with: with:
arch: ${{ matrix.A }} arch: ${{ matrix.arch }}
- name: 'Build' - name: 'Build'
shell: cmd shell: cmd
run: | run: |
@REM setup directories following the VPATH build in travis_build.sh @REM setup directories
where cl & where link where cl & where link
set BDIR=%H%\build\%C%\%B% set BDIR=%H%\build\%C%\%B%
md %BDIR% %BDIR%\ucl %BDIR%\upx %BDIR%\upx-testsuite %BDIR%\zlib
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
@REM ===== build UCL ===== @REM ===== build UCL =====
cd %BDIR%\ucl cd %BDIR%\ucl
set s=%H%\upx\vendor\ucl set s=%H%\vendor\ucl
cl -MT -J -O2 -W4 %DEFS% -I%s%\include -I%s% -c %s%\src\*.c cl -MT -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
link -lib -out:ucl.lib *.obj link -lib -out:ucl.lib *.obj
@REM ===== build zlib ===== @REM ===== build zlib =====
cd %BDIR%\zlib cd %BDIR%\zlib
cl -MT -J -O2 -W3 %DEFS% -c %H%\upx\vendor\zlib\*.c cl -MT -J -O2 -W3 -WX %DEFS% -c %H%\vendor\zlib\*.c
link -lib -out:zlib.lib *.obj link -lib -out:zlib.lib *.obj
@REM ===== build zstd =====
@rem cd %BDIR%\zstd
@rem set s=%H%\vendor\zstd\lib
@rem cl -MT -J -O2 -W4 -WX -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM %DEFS% -c %s%\common\*.c %s%\compress\*.c %s%\decompress\*.c
@rem link -lib -out:zstd.lib *.obj
@REM ===== build UPX ===== @REM ===== build UPX =====
cd %BDIR%\upx cd %BDIR%\upx
set s=%H%\upx\src set s=%H%\src
cat .GITREV.txt cat .GITREV.txt
set /p GITREV=<.GITREV.txt set /p GITREV=<.GITREV.txt
cl -MT -EHsc -J -O2 -W4 -WX -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% -I%H%\upx\vendor -Feupx.exe %s%\*.cpp %s%\util\*.cpp %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib /link setargv.obj set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp
cl -MT -std:c++17 -Zc:__cplusplus -EHsc -J -O2 -W4 -WX -DUPX_VERSION_GITREV="""%GITREV%""" -DWITH_ZSTD=0 %DEFS% -I%H%\vendor -I%H%\vendor\boost-pfr\include -Feupx.exe %sources% %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib /link setargv.obj
- name: 'Make artifact' - name: 'Make artifact'
shell: bash shell: bash
run: | run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.name }} N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-${{ matrix.name }}
mkdir -p "tmp/artifact/$N/$B" mkdir -p "tmp/artifact/$N/$B"
cp -ai ../build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B" cp -ai build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B"
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
@@ -253,6 +314,7 @@ jobs:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
- name: 'Run basic tests' - name: 'Run basic tests'
if: ${{ matrix.arch != 'amd64_arm64' }}
run: | run: |
$ErrorActionPreference = 'stop' $ErrorActionPreference = 'stop'
$ErrorView = 'NormalView' $ErrorView = 'NormalView'
@@ -265,7 +327,111 @@ jobs:
.\upx.exe -t upx_packed.exe .\upx.exe -t upx_packed.exe
.\upx_packed.exe --version .\upx_packed.exe --version
- name: 'Run test suite' - name: 'Run test suite'
if: ${{ matrix.arch != 'amd64_arm64' }}
shell: bash
run: | run: |
bash ./.github/travis_testsuite_1.sh export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1"
job-linux-zigcc:
if: ${{ true }}
needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }}
runs-on: ubuntu-latest
##container: alpine:3.17 # older versions such as alpine:3.12 also work; no-container also works
strategy:
fail-fast: false
matrix:
include:
- { zig_target: aarch64-linux-musl }
- { zig_target: aarch64-macos.11-none }
- { zig_target: aarch64-macos.12-none }
- { zig_target: aarch64-macos.13-none }
- { zig_target: aarch64-windows-gnu }
- { zig_target: i386-linux-musl }
- { zig_target: i386-windows-gnu }
- { zig_target: x86_64-linux-musl }
- { zig_target: x86_64-linux-musl, zig_pic: -fPIE }
- { zig_target: x86_64-macos.11-none }
- { zig_target: x86_64-macos.12-none }
- { zig_target: x86_64-macos.13-none }
- { zig_target: x86_64-windows-gnu }
env:
# 2023-01-30
ZIG_DIST_VERSION: 0.11.0-dev.1491+2b27bc2c6
# for zig-cc wrapper scripts (see below):
ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING
ZIG_FLAGS: ${{ matrix.zig_flags }}
ZIG_PIC: ${{ matrix.zig_pic }}
ZIG_TARGET: ${{ matrix.zig_target }}
steps:
- name: 'Install Alpine Linux container packages'
if: ${{ job.container }}
shell: sh
run: |
apk update && apk upgrade && apk add bash cmake file git make tar xz
# set PATH like in Ubuntu
echo "PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }}
shell: bash
run: |
# GitHub Actions magic: set "UPX_GITREV_SHORT" environment value for use in steps below
rev=$(git rev-parse --short=7 HEAD)
echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV
# update ZIG_TARGET (i386 => x86)
ZIG_TARGET=${ZIG_TARGET/i386-/x86-}
echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV
# install zig; note that ~/.local/bin is included in the default $PATH on Ubuntu
mkdir -p -v ~/.local/bin
cd ~/.local/bin
ZIG_DIST_NAME=zig-linux-x86_64-${ZIG_DIST_VERSION}
wget -q 'https://ziglang.org/builds/'${ZIG_DIST_NAME}.tar.xz
ls -l ${ZIG_DIST_NAME}.tar.xz
tar -xoJf ${ZIG_DIST_NAME}.tar.xz
rm ${ZIG_DIST_NAME}.tar.xz
ln -s -v ${ZIG_DIST_NAME}/zig zig
#echo "PATH=$PATH" && which zig
echo -n 'zig version: '; zig version
# create wrapper scripts (needed for CMake)
echo -e '#!/bin/sh\nexec zig ar "$@"' > zig-ar
echo -e '#!/bin/sh\nexec zig cc -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CFLAGS "$@"' > zig-cc
echo -e '#!/bin/sh\nexec zig c++ -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CXXFLAGS "$@"' > zig-cxx
echo -e '#!/bin/sh\nexec zig ranlib "$@"' > zig-ranlib
chmod +x zig-ar zig-cc zig-cxx zig-ranlib
ls -la; head zig-ar zig-cc zig-cxx zig-ranlib
- name: ${{ format('Build Release with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
run: |
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/release
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release
cmake ../../../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_AR=$HOME/.local/bin/zig-ar -DCMAKE_C_COMPILER=zig-cc -DCMAKE_CXX_COMPILER=zig-cxx -DCMAKE_RANLIB=$HOME/.local/bin/zig-ranlib $EXTRA_CMAKE_CONFIG_FLAGS_RELEASE
cmake --build . --config Release --parallel --verbose
file ./upx*
- name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
run: |
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/debug
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/debug
cmake ../../../.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_AR=$HOME/.local/bin/zig-ar -DCMAKE_C_COMPILER=zig-cc -DCMAKE_CXX_COMPILER=zig-cxx -DCMAKE_RANLIB=$HOME/.local/bin/zig-ranlib $EXTRA_CMAKE_CONFIG_FLAGS_DEBUG
cmake --build . --config Debug --parallel --verbose
file ./upx*
- name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }}
shell: bash
run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-zigcc-${{ matrix.zig_target }}${ZIG_PIC}
mkdir -p "tmp/artifact/$N"
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
# GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: tmp/artifact
# vim:set ts=2 sw=2 et: # vim:set ts=2 sw=2 et:
+8 -6
View File
@@ -1,8 +1,8 @@
# see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues # see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues
# see https://github.com/actions/stale # see https://github.com/actions/stale
# Automatically closing issues is far from perfect, but then we only have # Automatically closing issues is far from perfect, but then we only
# limited resources and this approach favors issues that people # have limited resources and this approach favors issues that people
# actually care about. # actually care about.
# #
# also see: # also see:
@@ -10,10 +10,10 @@
# Abandoned Issues and Pull Request". # Abandoned Issues and Pull Request".
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf # https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
name: 'Close inactive issues' name: 'GitHub - Close inactive issues'
on: on:
schedule: schedule:
- cron: "30 6 * * 4" - cron: '30 6 * * 4'
workflow_dispatch: workflow_dispatch:
jobs: jobs:
close-issues: close-issues:
@@ -23,9 +23,11 @@ jobs:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v6 - uses: actions/stale@v7
with: with:
# operations-per-run: 300 operations-per-run: 300
exempt-all-milestones: true
exempt-issue-labels: 'blocker,enhancement,regression'
days-before-stale: 60 days-before-stale: 60
days-before-close: 30 days-before-close: 30
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.' stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.'
+6 -6
View File
@@ -1,11 +1,11 @@
name: "CodeQL" name: 'Static Analyzer - CodeQL'
on: on:
push: # push:
branches: [ "devel", "devel4", "devel5", "master" ] # branches: [ 'devel', 'devel4', 'devel5', 'master' ]
pull_request: # pull_request:
# The branches below must be a subset of the branches above # # The branches below must be a subset of the branches above
branches: [ "devel", "devel4", "devel5" ] # branches: [ 'devel', 'devel4', 'devel5' ]
schedule: schedule:
- cron: '20 1 * * 3' - cron: '20 1 * * 3'
workflow_dispatch: workflow_dispatch:
+29
View File
@@ -0,0 +1,29 @@
# minimal GitHub CI building UPX with clang and gcc in an Alpine Linux container
name: 'CI - Minimal CI with Alpine Linux'
on: { workflow_dispatch: }
jobs:
job-alpine-cmake:
strategy: {matrix: {container: ['alpine:3.12','alpine:3.17','alpine:edge']}}
name: ${{ format('container {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Install packages {0}', matrix.container) }}
run: 'apk update && apk upgrade && apk add bash clang cmake g++ git make'
- name: ${{ format('Check out code upx-{0}', github.ref_name) }}
run: |
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx
git -C upx submodule update --init
echo "artifact_name=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-minimal-ci-${{ matrix.container }}" | sed 's/[:,; ]/-/g' >> $GITHUB_ENV
- { name: 'Build clang', run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"' }
- { name: 'Build gcc', run: 'make -C upx UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static"' }
- { name: 'Strip release binaries', run: 'strip -p --strip-unneeded upx/build/*/*/release/upx' }
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: 'upx*/build/*/*/*/upx'
- { name: 'Run basic tests clang', run: 'make -C upx/build/xtarget/clang-static/release test' }
- { name: 'Run basic tests gcc', run: 'make -C upx/build/xtarget/gcc-static/release test' }
+1 -1
View File
@@ -1,4 +1,4 @@
name: 'Close pull requests' name: 'GitHub - Close pull requests'
on: on:
#pull_request: #pull_request:
workflow_dispatch: workflow_dispatch:
+22
View File
@@ -0,0 +1,22 @@
name: 'Static Analyzer - scan-build'
on:
schedule:
- cron: '40 1 * * 3'
workflow_dispatch:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
container: 'alpine:edge'
steps:
- name: 'Install packages'
run: 'apk update && apk upgrade && apk add bash clang clang-analyzer cmake g++ git make'
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Perform scan-build Analysis Debug'
run: 'make build/extra/scan-build/debug'
- name: 'Perform scan-build Analysis Release'
run: 'make build/extra/scan-build/release'
+1 -8
View File
@@ -5,11 +5,10 @@
/maint* /maint*
/vendor* /vendor*
.depend
GNUmakefile GNUmakefile
MMakefile MMakefile
Makevars.local* Makevars.local*
tmp-testsuite* tmp*
*.a *.a
*.d *.d
@@ -30,20 +29,14 @@ doc/*.ps
doc/*.tex doc/*.tex
src/stub/**/.*-stamp src/stub/**/.*-stamp
src/stub/**/MMakefile
src/stub/tmp*/*.bin src/stub/tmp*/*.bin
src/stub/tmp*/*.bin.bindump src/stub/tmp*/*.bin.bindump
src/stub/tmp*/*.bin.disasm src/stub/tmp*/*.bin.disasm
src/stub/tmp*/*.d
src/stub/tmp*/*.o
src/stub/tmp*/*.o.disasm src/stub/tmp*/*.o.disasm
src/stub/tmp*/mips.r3000-*.[is] src/stub/tmp*/mips.r3000-*.[is]
src/stub/tmp*/mipsel.r3000-*.[is] src/stub/tmp*/mipsel.r3000-*.[is]
src/stub/src/**/tmp*/* src/stub/src/**/tmp*/*
src/stub/tools/armpe/armpe_tester.exe
src/stub/tools/armpe/armpe_tester.out
src/stub/tools/sstrip/amd64-linux-sstrip src/stub/tools/sstrip/amd64-linux-sstrip
src/stub/tools/sstrip/i386-linux-sstrip src/stub/tools/sstrip/i386-linux-sstrip
src/stub/tools/sstrip/sstrip src/stub/tools/sstrip/sstrip
+5
View File
@@ -13,6 +13,11 @@
url = https://github.com/upx/upx-vendor-ucl.git url = https://github.com/upx/upx-vendor-ucl.git
branch = upx-vendor branch = upx-vendor
shallow = true shallow = true
[submodule "vendor/valgrind"]
path = vendor/valgrind
url = https://github.com/upx/upx-vendor-valgrind.git
branch = upx-vendor
shallow = true
[submodule "vendor/zlib"] [submodule "vendor/zlib"]
path = vendor/zlib path = vendor/zlib
url = https://github.com/upx/upx-vendor-zlib.git url = https://github.com/upx/upx-vendor-zlib.git
+178 -63
View File
@@ -1,9 +1,22 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR) cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
# config options # compilation config options
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info.") if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options.") # permissive config defaults when building from source code tarball
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option.") option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." ON)
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." ON)
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." ON)
else()
# strict config defaults for devel builds
message(STATUS "===== UPX info: strict config defaults enabled")
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." OFF)
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." OFF)
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." OFF)
endif()
# test config options (see below)
# NOTE: self-pack test can only work if the host executable format is supported by UPX!
option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself" OFF)
#*********************************************************************** #***********************************************************************
# init # init
@@ -11,24 +24,27 @@ option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option."
# Disallow in-source builds. Note that you will still have to manually # Disallow in-source builds. Note that you will still have to manually
# clean up a few files if you accidentally try an in-source build. # clean up a few files if you accidentally try an in-source build.
if(NOT MSVC_IDE)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
if(",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_BINARY_DIR},")
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.") message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
endif() endif()
endif()
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# determine git revision # determine git revision
set(GITREV_SHORT "") set(GITREV_SHORT "")
set(GITREV_PLUS "") set(GITREV_PLUS "")
set(GIT_DESCRIBE "")
find_package(Git) find_package(Git)
if(GIT_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV) if(Git_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
execute_process( execute_process(
RESULT_VARIABLE result
COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD
ERROR_QUIET RESULT_VARIABLE result ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE GITREV_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE GITREV_SHORT
) )
string(LENGTH "${GITREV_SHORT}" l) string(LENGTH "${GITREV_SHORT}" l)
if(${result} EQUAL 0 AND ${l} EQUAL 12) if(${result} EQUAL 0 AND ${l} EQUAL 12)
@@ -39,17 +55,31 @@ if(GIT_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
else() else()
set(GITREV_SHORT "") set(GITREV_SHORT "")
endif() endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --match "v*.*.*" --tags --dirty
RESULT_VARIABLE result ERROR_QUIET
OUTPUT_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(GIT_DESCRIBE MATCHES "^v?([0-9]+\\.[0-9]+\\.[0-9]+)-([0-9]+)-g(.+)$")
set(GIT_DESCRIBE "${CMAKE_MATCH_1}-devel.${CMAKE_MATCH_2}+git-${CMAKE_MATCH_3}")
endif()
endif() endif()
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") # extra check if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") # extra check
set(GITREV_SHORT "") set(GITREV_SHORT "")
endif() endif()
if(GITREV_SHORT) if(GITREV_SHORT)
message(STATUS "UPX_VERSION_GITREV = \"${GITREV_SHORT}${GITREV_PLUS}\"") message(STATUS "UPX_VERSION_GITREV = \"${GITREV_SHORT}${GITREV_PLUS}\"")
if(GIT_DESCRIBE)
message(STATUS "UPX_VERSION_GIT_DESCRIBE = \"${GIT_DESCRIBE}\"")
endif()
elseif(UPX_CONFIG_DISABLE_GITREV)
message(STATUS "UPX_VERSION_GITREV: disabled")
else() else()
message(STATUS "UPX_VERSION_GITREV: not set") message(STATUS "UPX_VERSION_GITREV: not set")
endif() endif()
project(upx VERSION 4.0.0 LANGUAGES C CXX) # CMake init
project(upx VERSION 4.0.2 LANGUAGES C CXX)
# set default build type to "Release" # set default build type to "Release"
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
@@ -70,6 +100,9 @@ endif()
# targets and compilation flags # targets and compilation flags
#*********************************************************************** #***********************************************************************
#find_package(Threads) # multithreading is currently not used; maybe in UPX version 5
set(UPX_CONFIG_DISABLE_ZSTD ON) # zstd is currently not used; maybe in UPX version 5
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c") file(GLOB ucl_SOURCES "vendor/ucl/src/*.c")
list(SORT ucl_SOURCES) list(SORT ucl_SOURCES)
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES}) add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
@@ -80,12 +113,26 @@ list(SORT zlib_SOURCES)
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES}) add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
file(GLOB upx_SOURCES "src/*.cpp" "src/util/*.cpp") if(NOT UPX_CONFIG_DISABLE_ZSTD)
file(GLOB zstd_SOURCES "vendor/zstd/lib/*/*.c")
list(SORT zstd_SOURCES)
add_library(upx_vendor_zstd STATIC ${zstd_SOURCES})
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
endif()
file(GLOB upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
list(SORT upx_SOURCES) list(SORT upx_SOURCES)
add_executable(upx ${upx_SOURCES}) add_executable(upx ${upx_SOURCES})
set_property(TARGET upx PROPERTY CXX_STANDARD 14) set_property(TARGET upx PROPERTY CXX_STANDARD 17)
target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib) target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib)
if(NOT MSVC)
# rather strict default compilation warnings
set(warn_strict
-Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations
-Wpointer-arith -Wshadow -Wvla -Wwrite-strings
)
endif()
if(UPX_CONFIG_DISABLE_WERROR) if(UPX_CONFIG_DISABLE_WERROR)
set(warn_Werror "") set(warn_Werror "")
set(warn_WX "") set(warn_WX "")
@@ -108,25 +155,54 @@ if(MSVC)
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS) add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
# set __cplusplus according to selected C++ standard; use new preprocessor
add_definitions(-Zc:__cplusplus -Zc:preprocessor)
else() else()
# protect against security threats caused by misguided compiler "optimizations" # protect against security threats caused by misguided compiler "optimizations"
if (CMAKE_C_COMPILER_ID STREQUAL "GNU") if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
add_definitions(-fno-delete-null-pointer-checks) add_definitions(-fno-delete-null-pointer-checks -fno-lifetime-dse)
endif() endif()
add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char) add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char)
# disable overambitious auto-vectorization until this actually gains something # disable overambitious auto-vectorization until this actually gains something
add_definitions(-fno-tree-vectorize) add_definitions(-fno-tree-vectorize)
endif() endif()
# compile a target with -O2 in Debug build
function(upx_compile_target_debug_with_O2 t)
if(MSVC)
# msvc uses some Debug compile options like -RTC1 that are incompatible with -O2
else()
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
endif()
endfunction()
function(upx_sanitize_target t)
if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC)
if(CMAKE_C_PLATFORM_ID MATCHES "^MinGW" OR MINGW OR CYGWIN)
# avoid link errors with current MinGW-w64 versions
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
else()
# default sanitizer for Debug builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
# default sanitizer for Release builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
endif()
endif()
endfunction()
set(t upx_vendor_ucl) set(t upx_vendor_ucl)
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl) target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t})
if(MSVC) if(MSVC)
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX}) target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
else() else()
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
endif() endif()
set(t upx_vendor_zlib) set(t upx_vendor_zlib)
upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t})
if(MSVC) if(MSVC)
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX}) target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX})
else() else()
@@ -135,100 +211,139 @@ else()
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla -Wno-strict-prototypes ${warn_Werror}) target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla -Wno-strict-prototypes ${warn_Werror})
endif() endif()
if(NOT UPX_CONFIG_DISABLE_ZSTD)
set(t upx_vendor_zstd)
upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t})
target_compile_options(${t} PRIVATE -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM)
if(MSVC)
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
else()
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
endif()
endif()
set(t upx) set(t upx)
target_include_directories(${t} PRIVATE vendor) target_include_directories(${t} PRIVATE vendor vendor/boost-pfr/include)
target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>) target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
if(GITREV_SHORT) if(GITREV_SHORT)
target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}") target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}")
if(GIT_DESCRIBE)
target_compile_definitions(${t} PRIVATE UPX_VERSION_GIT_DESCRIBE="${GIT_DESCRIBE}")
endif() endif()
if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC)
# default sanitizer for Debug builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
# default sanitizer for Release builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
endif() endif()
#upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t})
if(MSVC) if(MSVC)
target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX}) target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX})
else() else()
target_compile_options(${t} PRIVATE target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
-Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith endif()
-Wshadow -Wvla -Wwrite-strings ${warn_Werror} if(NOT UPX_CONFIG_DISABLE_ZSTD)
) target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
target_link_libraries(upx upx_vendor_zstd)
endif() endif()
#*********************************************************************** #***********************************************************************
# "ctest"
# "make test" # "make test"
# "ninja test"
#*********************************************************************** #***********************************************************************
if(NOT CMAKE_CROSSCOMPILING) if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
include(CTest) include(CTest)
set(exe ${CMAKE_EXECUTABLE_SUFFIX}) if(NOT CMAKE_CROSSCOMPILING)
set(upx_self_exe "$<TARGET_FILE:upx>")
add_test(NAME upx-test-cleanup COMMAND rm -f ./upx.packed${exe} ./upx.unpacked${exe})
add_test(NAME upx-version COMMAND upx --version) add_test(NAME upx-version COMMAND upx --version)
add_test(NAME upx-help COMMAND upx --help) add_test(NAME upx-help COMMAND upx --help)
add_test(NAME upx-self-pack COMMAND upx -3 ${upx_self_exe} -o upx.packed${exe}) endif()
add_test(NAME upx-list COMMAND upx -l upx.packed${exe}) if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
add_test(NAME upx-fileinfo COMMAND upx --fileinfo upx.packed${exe}) # NOTE: these tests can only work if the host executable format is supported by UPX!
add_test(NAME upx-test COMMAND upx -t upx.packed${exe}) function(upx_add_test)
add_test(NAME upx-unpack COMMAND upx -d upx.packed${exe} -o upx.unpacked${exe}) set(name ${ARGV0})
add_test(NAME upx-run-unpacked COMMAND ./upx.unpacked${exe} --version) list(REMOVE_AT ARGV 0)
add_test(NAME upx-run-packed COMMAND ./upx.packed${exe} --version) add_test(NAME ${name} COMMAND ${ARGV})
set_tests_properties(${name} PROPERTIES RUN_SERIAL TRUE) # run these tests sequentially
endfunction()
set(exe ${CMAKE_EXECUTABLE_SUFFIX})
set(upx_self_exe "$<TARGET_FILE:upx>")
set(fo "--force-overwrite")
upx_add_test(upx-self-pack upx -3 ${upx_self_exe} ${fo} -o upx-packed${exe})
upx_add_test(upx-self-pack-n2b upx -3 --nrv2b ${upx_self_exe} ${fo} -o upx-packed-n2b${exe})
upx_add_test(upx-self-pack-n2d upx -3 --nrv2d ${upx_self_exe} ${fo} -o upx-packed-n2d${exe})
upx_add_test(upx-self-pack-n2e upx -3 --nrv2e ${upx_self_exe} ${fo} -o upx-packed-n2e${exe})
upx_add_test(upx-self-pack-lzma upx -3 --lzma ${upx_self_exe} ${fo} -o upx-packed-lzma${exe})
upx_add_test(upx-list upx -l upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe})
upx_add_test(upx-run-unpacked ./upx-unpacked${exe} --version-short)
upx_add_test(upx-run-packed ./upx-packed${exe} --version-short)
endif() endif()
# TODO: could add some more explicit test programs; but then, the integrated endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
# "doctest" is quite convenient and already covers a number of basic
# checks - and more complex cases better should be handled by an
# external test suite.
#*********************************************************************** #***********************************************************************
# "cmake --install ."
# "make install" # "make install"
# "ninja install"
#*********************************************************************** #***********************************************************************
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
# installation prefix and directories # installation prefix and directories
if(NOT CMAKE_INSTALL_PREFIX) if(NOT CMAKE_INSTALL_PREFIX)
message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.") #message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.")
message(WARNING "WARNING: CMAKE_INSTALL_PREFIX is not defined.")
endif() endif()
if(CMAKE_INSTALL_PREFIX)
include(GNUInstallDirs) include(GNUInstallDirs)
endif()
if(DEFINED CMAKE_INSTALL_FULL_BINDIR) if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR)
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}") install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
install(FILES install(FILES
COPYING LICENSE NEWS README doc/upx-doc.html doc/upx-doc.txt COPYING LICENSE NEWS README THANKS doc/upx-doc.html doc/upx-doc.txt
DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}" DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}"
) )
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1") install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1")
endif() endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
#*********************************************************************** #***********************************************************************
# finally print some info about the build configuration # finally print some info about the build configuration
#*********************************************************************** #***********************************************************************
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/src/CMakeLists.extra.txt") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/src/CMakeLists.extra.txt") include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
endif() endif()
function(print_var v) function(print_var)
foreach(v ${ARGV})
if(${v}) if(${v})
message(STATUS "${v} = ${${v}}") message(STATUS "${v} = ${${v}}")
endif() endif()
endforeach()
endfunction() endfunction()
print_var(CMAKE_BUILD_TYPE) if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
print_var(CMAKE_CONFIGURATION_TYPES) print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION)
print_var(CMAKE_INSTALL_PREFIX) print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_CROSSCOMPILING)
print_var(CMAKE_CROSSCOMPILING) print_var(CMAKE_C_COMPILER_ID CMAKE_C_COMPILER_VERSION CMAKE_C_COMPILER_ARCHITECTURE_ID CMAKE_C_PLATFORM_ID CMAKE_C_COMPILER_ABI)
print_var(CMAKE_C_COMPILER_ID) print_var(CMAKE_CXX_COMPILER_ID CMAKE_CXX_COMPILER_VERSION CMAKE_CXX_COMPILER_ARCHITECTURE_ID CMAKE_CXX_PLATFORM_ID CMAKE_CXX_COMPILER_ABI)
print_var(CMAKE_C_COMPILER_VERSION) endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO
print_var(CMAKE_C_COMPILER_ARCHITECTURE_ID) print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE)
print_var(CMAKE_C_PLATFORM_ID)
print_var(CMAKE_C_COMPILER_ABI)
print_var(CMAKE_CXX_COMPILER_ID)
print_var(CMAKE_CXX_COMPILER_VERSION)
print_var(CMAKE_CXX_COMPILER_ARCHITECTURE_ID)
print_var(CMAKE_CXX_PLATFORM_ID)
print_var(CMAKE_CXX_COMPILER_ABI)
if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release)$") if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release)$")
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"") message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
endif() endif()
if(NOT UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK)
# extra sanity checks to detect incompatible C vs CXX settings
if(NOT ",${CMAKE_C_PLATFORM_ID}," STREQUAL ",${CMAKE_CXX_PLATFORM_ID},")
message(FATAL_ERROR "ERROR: CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID mismatch")
endif()
if(NOT ",${CMAKE_C_COMPILER_ABI}," STREQUAL ",${CMAKE_CXX_COMPILER_ABI},")
message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI mismatch")
endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
# vim:set ft=cmake ts=4 sw=4 tw=0 et: # vim:set ft=cmake ts=4 sw=4 tw=0 et:
+151 -50
View File
@@ -2,41 +2,33 @@
# UPX top-level Makefile - needs GNU make and CMake >= 3.13 # UPX top-level Makefile - needs GNU make and CMake >= 3.13
# #
# NOTE: if you only have CMake 3.10 then you can invoke cmake manually like this: # INFO: this Makefile is just a convenience wrapper for calling CMake
# NOTE: if you only have an older CMake 3.x then you can invoke cmake manually like this:
# mkdir -p build/release # mkdir -p build/release
# cd build/release # cd build/release
# cmake ../.. # cmake ../..
# cmake --build . # make -j (or use "cmake --build . --parallel")
CMAKE = cmake CMAKE = cmake
UPX_CMAKE_BUILD_FLAGS += --parallel UPX_CMAKE_BUILD_FLAGS += --parallel
ifneq ($(VERBOSE),) ifneq ($(VERBOSE),)
UPX_CMAKE_BUILD_FLAGS += --verbose UPX_CMAKE_BUILD_FLAGS += --verbose
endif endif
# enable this if you prefer Ninja for the actual builds:
# check git submodules #UPX_CMAKE_CONFIG_FLAGS += -G Ninja
ifeq ($(wildcard ./vendor/doctest/doctest/.),)
$(error ERROR: missing git submodule; run 'git submodule update --init')
endif
ifeq ($(wildcard ./vendor/lzma-sdk/C/.),)
$(error ERROR: missing git submodule; run 'git submodule update --init')
endif
ifeq ($(wildcard ./vendor/ucl/include/.),)
$(error ERROR: missing git submodule; run 'git submodule update --init')
endif
ifeq ($(wildcard ./vendor/zlib/crc32.c),)
$(error ERROR: missing git submodule; run 'git submodule update --init')
endif
#*********************************************************************** #***********************************************************************
# default # default
#*********************************************************************** #***********************************************************************
__check_cache = $(if $(wildcard $1/CMakeCache.txt),@true,) run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
run_config = $(call __check_cache,$1) $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2 run_cmake_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
run_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2 # avoid re-running run_cmake_config if CMakeCache.txt already exists
run_config = $(if $(wildcard $1/CMakeCache.txt),,$(call run_cmake_config,$1,$2))
run_build = $(call run_cmake_build,$1,$2)
default: build/release .DEFAULT_GOAL = build/release
build/debug: PHONY build/debug: PHONY
$(call run_config,$@,Debug) $(call run_config,$@,Debug)
@@ -46,40 +38,149 @@ build/release: PHONY
$(call run_config,$@,Release) $(call run_config,$@,Release)
$(call run_build,$@,Release) $(call run_build,$@,Release)
# shortcuts
all: build/debug build/release
debug: build/debug
release: build/release
.PHONY: PHONY
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
.SUFFIXES:
# END of Makefile; extra stuff follows
#*********************************************************************** #***********************************************************************
# some pre-defined build configurations # extra builds: some pre-defined build configurations
#*********************************************************************** #***********************************************************************
# force building with gcc/g++ define run_config_and_build
build/%-gcc: export CC=gcc $(call run_config,$1,$2)
build/%-gcc: export CXX=g++ $(call run_build,$1,$2)
build/debug-gcc: PHONY endef
$(call run_config,$@,Debug)
$(call run_build,$@,Debug)
build/release-gcc: PHONY
$(call run_config,$@,Release)
$(call run_build,$@,Release)
# force building with clang/clang++ # force building with clang/clang++
build/%-clang: export CC=clang build/extra/clang/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/%-clang: export CXX=clang++ build/extra/clang/release: PHONY; $(call run_config_and_build,$@,Release)
build/debug-clang: PHONY build/extra/clang/%: export CC = clang
$(call run_config,$@,Debug) build/extra/clang/%: export CXX = clang++
$(call run_build,$@,Debug)
build/release-clang: PHONY
$(call run_config,$@,Release)
$(call run_build,$@,Release)
# cross compiler: Windows mingw-w64 # force building with clang/clang++ -m32
build/%-cross-mingw64: export CC=x86_64-w64-mingw32-gcc build/extra/clang-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/%-cross-mingw64: export CXX=x86_64-w64-mingw32-g++ build/extra/clang-m32/release: PHONY; $(call run_config_and_build,$@,Release)
# disable sanitize to avoid link errors on GitHub CI build/extra/clang-m32/%: export CC = clang -m32
build/%-cross-mingw64: UPX_CMAKE_CONFIG_FLAGS += -DUPX_CONFIG_DISABLE_SANITIZE=1 build/extra/clang-m32/%: export CXX = clang++ -m32
build/debug-cross-mingw64: PHONY
$(call run_config,$@,Debug)
$(call run_build,$@,Debug)
build/release-cross-mingw64: PHONY
$(call run_config,$@,Release)
$(call run_build,$@,Release)
.PHONY: default PHONY # force building with clang/clang++ -mx32
build/extra/clang-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-mx32/%: export CC = clang -mx32
build/extra/clang-mx32/%: export CXX = clang++ -mx32
# force building with clang/clang++ -m64
build/extra/clang-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-m64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-m64/%: export CC = clang -m64
build/extra/clang-m64/%: export CXX = clang++ -m64
# force building with gcc/g++
build/extra/gcc/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc/%: export CC = gcc
build/extra/gcc/%: export CXX = g++
# force building with gcc/g++ -m32
build/extra/gcc-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-m32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-m32/%: export CC = gcc -m32
build/extra/gcc-m32/%: export CXX = g++ -m32
# force building with gcc/g++ -mx32
build/extra/gcc-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-mx32/%: export CC = gcc -mx32
build/extra/gcc-mx32/%: export CXX = g++ -mx32
# force building with gcc/g++ -m64
build/extra/gcc-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-m64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-m64/%: export CC = gcc -m64
build/extra/gcc-m64/%: export CXX = g++ -m64
# force building with clang Static Analyzer (scan-build)
build/extra/scan-build/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/scan-build/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/scan-build/%: CMAKE := scan-build $(CMAKE)
build/extra/scan-build/%: export CCC_CC ?= clang
build/extra/scan-build/%: export CCC_CXX ?= clang++
# cross compiler: Linux glibc aarch64-linux-gnu
build/extra/cross-linux-aarch64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-linux-aarch64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-linux-aarch64/%: export CC = aarch64-linux-gnu-gcc
build/extra/cross-linux-aarch64/%: export CXX = aarch64-linux-gnu-g++
# cross compiler: Linux glibc arm-linux-gnueabihf
build/extra/cross-linux-arm/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-linux-arm/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-linux-arm/%: export CC = arm-linux-gnueabihf-gcc
build/extra/cross-linux-arm/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi
# cross compiler: Windows x86 win32 MinGW
build/extra/cross-windows-mingw32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-windows-mingw32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-windows-mingw32/%: export CC = i686-w64-mingw32-gcc
build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++
# cross compiler: Windows x64 win64 MinGW
build/extra/cross-windows-mingw64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-windows-mingw64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-windows-mingw64/%: export CC = x86_64-w64-mingw32-gcc
build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++
# cross compiler: macOS arm64
build/extra/cross-darwin-arm64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-darwin-arm64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-darwin-arm64/%: export CC = clang -target arm64-apple-darwin
build/extra/cross-darwin-arm64/%: export CXX = clang++ -target arm64-apple-darwin
# cross compiler: macOS x86_64
build/extra/cross-darwin-x86_64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-darwin-x86_64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-darwin-x86_64/%: export CC = clang -target x86_64-apple-darwin
build/extra/cross-darwin-x86_64/%: export CXX = clang++ -target x86_64-apple-darwin
#***********************************************************************
# advanced: generic extra target
#***********************************************************************
# usage:
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags"
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags" xtarget/debug
ifneq ($(UPX_XTARGET),)
ifneq ($(CC),)
ifneq ($(CXX),)
UPX_XTARGET := $(UPX_XTARGET)
build/xtarget/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/xtarget/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release)
build/xtarget/$(UPX_XTARGET)/%: export CC
build/xtarget/$(UPX_XTARGET)/%: export CXX
# shortcuts
xtarget/debug: build/xtarget/$(UPX_XTARGET)/debug
xtarget/release: build/xtarget/$(UPX_XTARGET)/release
# set new default
.DEFAULT_GOAL = xtarget/release
endif
endif
endif
#***********************************************************************
# check git submodules
#***********************************************************************
SUBMODULES = doctest lzma-sdk ucl valgrind zlib
dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\
$(error ERROR: missing git submodule $m; run 'git submodule update --init')))
+14 -5
View File
@@ -2,15 +2,22 @@
User visible changes for UPX User visible changes for UPX
================================================================== ==================================================================
Changes in 3.99 (27 Oct 2022): Changes in 4.0.2 (30 Jan 2023):
* NOTE: this is a pre-release with known regressions for some ELF formats; * bug fixes - see https://github.com/upx/upx/milestone/9
please help testing and reporting bugs, and see our GitHub Actions CI
page for up-to-date pre-built binaries ("Artifacts") Changes in 4.0.1 (16 Nov 2022):
https://github.com/upx/upx/actions/workflows/ci.yml * bug fixes - see https://github.com/upx/upx/milestone/8
Changes in 4.0.0 (28 Oct 2022):
* Switch to semantic versioning
* SECURITY NOTES: emphasize the security context in the docs * SECURITY NOTES: emphasize the security context in the docs
* Support easy building from source code with CMake * Support easy building from source code with CMake
* Support easy rebuilding the stubs from source with Podman/Docker
* Add integrated doctest C++ testing framework
* Add support for EFI files (PE x86; Kornel Pal) * Add support for EFI files (PE x86; Kornel Pal)
* win32/pe and win64/pe: set correct SizeOfHeaders in the PE header
* bug fixes - see https://github.com/upx/upx/milestone/6 * bug fixes - see https://github.com/upx/upx/milestone/6
* bug fixes - see https://github.com/upx/upx/milestone/7
Changes in 3.96 (23 Jan 2020): Changes in 3.96 (23 Jan 2020):
* bug fixes - see https://github.com/upx/upx/milestone/5 * bug fixes - see https://github.com/upx/upx/milestone/5
@@ -364,6 +371,8 @@ Changes in 0.99 (25 Feb 2000)
* dos/com and dos/sys: fixed a bad decompressor problem * dos/com and dos/sys: fixed a bad decompressor problem
* linux/386: the counter for the progress indicator was off by one * linux/386: the counter for the progress indicator was off by one
==================================================================
Changes in 0.94 (06 Dec 1999) Changes in 0.94 (06 Dec 1999)
* win32/pe: the stub now calls ExitProcess in case of import errors * win32/pe: the stub now calls ExitProcess in case of import errors
* under DOS and Windows, the environment variable UPX now accepts * under DOS and Windows, the environment variable UPX now accepts
+13 -15
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
@@ -68,9 +68,11 @@ NEWS and BUGS also contain various tidbits of information.
THE FUTURE THE FUTURE
========== ==========
- Stay up-to-date with ongoing OS and executable format changes. - Stay up-to-date with ongoing OS and executable format changes
- RISC-V 64 for Linux. - RISC-V 64 for Linux
- ARM64 for Windows (help wanted)
- We will *NOT* add any sort of protection and/or encryption. - We will *NOT* add any sort of protection and/or encryption.
This only gives people a false feeling of security because This only gives people a false feeling of security because
@@ -83,24 +85,20 @@ THE FUTURE
COPYRIGHT COPYRIGHT
========= =========
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2000-2022 John F. Reiser Copyright (C) 2000-2023 John F. Reiser
This program may be used freely, and you are welcome to UPX is distributed with full source code under the terms of the
redistribute it under certain conditions. GNU General Public License v2+; either under the pure GPLv2+ (see
the file COPYING), or (at your option) under the GPLv+2 with special
exceptions and restrictions granting the free usage for all binaries
including commercial programs (see the file LICENSE).
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
UPX is distributed with full source code under the terms of the
GNU General Public License v2+;
either under the pure GPLv2+ (see the file COPYING),
or (at your option) under the GPLv+2 with special exceptions and
restrictions granting the free usage for commercial
programs (see the file LICENSE).
You should have received a copy of the UPX License Agreements along You should have received a copy of the UPX License Agreements along
with this program; see the files COPYING and LICENSE. If not, with this program; see the files COPYING and LICENSE. If not,
visit the UPX home page. visit the UPX home page.
+2 -1
View File
@@ -44,7 +44,8 @@ Short overview
Tools needed to build/modify the UPX sources Tools needed to build/modify the UPX sources
-------------------------------------------- --------------------------------------------
- A C++ compiler that supports C++ 14: clang, gcc or msvc - A C++ compiler that supports C++ 17: clang-5, gcc-8 or msvc-2019 16.11
(older or other compilers may work but are unsupported, use at your own risk)
- GNU make - GNU make
+2 -2
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
@@ -55,6 +55,6 @@ Salvador Eduardo Tropea
for beta testing for beta testing
Stefan Widmann Stefan Widmann
for the win32/pe TLS callback support for the win32/pe TLS callback support
The WINE project (http://www.winehq.com/) The WINE project (https://www.winehq.com/)
for lots of useful information found in their PE loader sources for lots of useful information found in their PE loader sources
Natascha Natascha
+1
View File
@@ -1,3 +1,4 @@
-std=gnu++17
-Ivendor -Ivendor
-fno-strict-aliasing -fno-strict-aliasing
-fno-strict-overflow -fno-strict-overflow
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
+24 -35
View File
@@ -1,21 +1,8 @@
# #
# UPX doc Makefile - needs GNU make # UPX doc Makefile - needs GNU make, pod2html, pod2man and pod2text
# #
MAKEFLAGS += -rR BUILT_SOURCES = upx.1 upx-doc.html upx-doc.txt
.SUFFIXES:
SHELL = /bin/sh
# internal make variables
comma := ,
empty :=
space := $(empty) $(empty)
tab := $(empty) $(empty)
# /***********************************************************************
# //
# ************************************************************************/
top_srcdir ?= .. top_srcdir ?= ..
@@ -23,28 +10,31 @@ PACKAGE = upx
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h) VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h) VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
# internal make variables
comma := ,
empty :=
space := $(empty) $(empty)
tab := $(empty) $(empty)
RTRIM := sed -e 's/[ $(tab)]*$$//' RTRIM := sed -e 's/[ $(tab)]*$$//'
DETAB2 := sed -e 's/$(tab)/ /g' DETAB2 := sed -e 's/$(tab)/ /g'
BUILT_SOURCES = upx.1 upx-doc.html upx-doc.txt #***********************************************************************
# targets
#***********************************************************************
.DEFAULT_GOAL = all
### all: $(BUILT_SOURCES) PHONY
### targets
###
all: $(BUILT_SOURCES) mostlyclean clean distclean maintainer-clean: PHONY
rm -f $(BUILT_SOURCES) ./pod2htm*
mostlyclean clean distclean maintainer-clean: #***********************************************************************
rm -f $(BUILT_SOURCES) pod2htm* # rules
#***********************************************************************
.PHONY: all mostlyclean clean distclean maintainer-clean
###
### rules
###
.SUFFIXES:
.SUFFIXES: .1 .html .man .pod .ps .tex .txt .SUFFIXES: .1 .html .man .pod .ps .tex .txt
%.1 : %.pod %.1 : %.pod
@@ -53,7 +43,7 @@ mostlyclean clean distclean maintainer-clean:
%-doc.html : %.pod %-doc.html : %.pod
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@ pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
@rm -f pod2htm* @rm -f ./pod2htm*
test -s $@ test -s $@
%.man : %.1 %.man : %.1
@@ -72,11 +62,10 @@ mostlyclean clean distclean maintainer-clean:
pod2text < $< | $(RTRIM) > $@ pod2text < $< | $(RTRIM) > $@
test -s $@ test -s $@
#***********************************************************************
### # dependencies
### dependencies #***********************************************************************
###
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST) $(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
.DELETE_ON_ERROR: $(BUILT_SOURCES) .DELETE_ON_ERROR: $(BUILT_SOURCES)
.PHONY: PHONY
+1 -1
View File
@@ -1,5 +1,5 @@
Decompressing ELF Directly to Memory on Linux/x86 Decompressing ELF Directly to Memory on Linux/x86
Copyright (C) 2000-2022 John F. Reiser jreiser@BitWagon.com Copyright (C) 2000-2023 John F. Reiser jreiser@BitWagon.com
References: References:
<elf.h> definitions for the ELF file format <elf.h> definitions for the ELF file format
+6 -8
View File
@@ -22,7 +22,7 @@
<h1 id="ABSTRACT">ABSTRACT</h1> <h1 id="ABSTRACT">ABSTRACT</h1>
<pre><code> The Ultimate Packer for eXecutables <pre><code> The Ultimate Packer for eXecutables
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar &amp; John Reiser Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar &amp; John Reiser
https://upx.github.io</code></pre> https://upx.github.io</code></pre>
<p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p> <p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p>
@@ -785,20 +785,18 @@ Jens Medoch &lt;jssg@users.sourceforge.net&gt;</code></pre>
<h1 id="COPYRIGHT">COPYRIGHT</h1> <h1 id="COPYRIGHT">COPYRIGHT</h1>
<p>Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer</p> <p>Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer</p>
<p>Copyright (C) 1996-2022 Laszlo Molnar</p> <p>Copyright (C) 1996-2023 Laszlo Molnar</p>
<p>Copyright (C) 2000-2022 John F. Reiser</p> <p>Copyright (C) 2000-2023 John F. Reiser</p>
<p>Copyright (C) 2002-2022 Jens Medoch</p> <p>Copyright (C) 2002-2023 Jens Medoch</p>
<p>This program may be used freely, and you are welcome to redistribute it under certain conditions.</p> <p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p>
<p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p> <p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>
<p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for commercial programs (see the file LICENSE).</p>
<p>You should have received a copy of the UPX License Agreements along with this program; see the files COPYING and LICENSE. If not, visit the UPX home page.</p> <p>You should have received a copy of the UPX License Agreements along with this program; see the files COPYING and LICENSE. If not, visit the UPX home page.</p>
+10 -13
View File
@@ -6,7 +6,7 @@ SYNOPSIS
ABSTRACT ABSTRACT
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
UPX is a portable, extendable, high-performance executable packer for UPX is a portable, extendable, high-performance executable packer for
@@ -818,27 +818,24 @@ AUTHORS
Jens Medoch <jssg@users.sourceforge.net> Jens Medoch <jssg@users.sourceforge.net>
COPYRIGHT COPYRIGHT
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2000-2022 John F. Reiser Copyright (C) 2000-2023 John F. Reiser
Copyright (C) 2002-2022 Jens Medoch Copyright (C) 2002-2023 Jens Medoch
This program may be used freely, and you are welcome to redistribute it UPX is distributed with full source code under the terms of the GNU
under certain conditions. General Public License v2+; either under the pure GPLv2+ (see the file
COPYING), or (at your option) under the GPLv+2 with special exceptions
and restrictions granting the free usage for all binaries including
commercial programs (see the file LICENSE).
This program is distributed in the hope that it will be useful, but This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
UPX is distributed with full source code under the terms of the GNU
General Public License v2+; either under the pure GPLv2+ (see the file
COPYING), or (at your option) under the GPLv+2 with special exceptions
and restrictions granting the free usage for commercial programs (see
the file LICENSE).
You should have received a copy of the UPX License Agreements along with You should have received a copy of the UPX License Agreements along with
this program; see the files COPYING and LICENSE. If not, visit the UPX this program; see the files COPYING and LICENSE. If not, visit the UPX
home page. home page.
+11 -15
View File
@@ -133,7 +133,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "UPX 1" .IX Title "UPX 1"
.TH UPX 1 "2022-10-27" "upx 3.99" " " .TH UPX 1 "2023-01-30" "upx 4.0.2" " "
.\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents. .\" way too many mistakes in technical documents.
.if n .ad l .if n .ad l
@@ -147,7 +147,7 @@ upx \- compress or expand executable files
.IX Header "ABSTRACT" .IX Header "ABSTRACT"
.Vb 3 .Vb 3
\& The Ultimate Packer for eXecutables \& The Ultimate Packer for eXecutables
\& Copyright (c) 1996\-2022 Markus Oberhumer, Laszlo Molnar & John Reiser \& Copyright (c) 1996\-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
\& https://upx.github.io \& https://upx.github.io
.Ve .Ve
.PP .PP
@@ -1019,28 +1019,24 @@ Please report all bugs immediately to the authors.
.Ve .Ve
.SH "COPYRIGHT" .SH "COPYRIGHT"
.IX Header "COPYRIGHT" .IX Header "COPYRIGHT"
Copyright (C) 1996\-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996\-2023 Markus Franz Xaver Johannes Oberhumer
.PP .PP
Copyright (C) 1996\-2022 Laszlo Molnar Copyright (C) 1996\-2023 Laszlo Molnar
.PP .PP
Copyright (C) 2000\-2022 John F. Reiser Copyright (C) 2000\-2023 John F. Reiser
.PP .PP
Copyright (C) 2002\-2022 Jens Medoch Copyright (C) 2002\-2023 Jens Medoch
.PP .PP
This program may be used freely, and you are welcome to \&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the
redistribute it under certain conditions. \&\s-1GNU\s0 General Public License v2+; either under the pure GPLv2+ (see
the file \s-1COPYING\s0), or (at your option) under the GPLv+2 with special
exceptions and restrictions granting the free usage for all binaries
including commercial programs (see the file \s-1LICENSE\s0).
.PP .PP
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but \s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of but \s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of
\&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 \&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0
.PP .PP
\&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the
\&\s-1GNU\s0 General Public License v2+;
either under the pure GPLv2+ (see the file \s-1COPYING\s0),
or (at your option) under the GPLv+2 with special exceptions and
restrictions granting the free usage for commercial
programs (see the file \s-1LICENSE\s0).
.PP
You should have received a copy of the \s-1UPX\s0 License Agreements along You should have received a copy of the \s-1UPX\s0 License Agreements along
with this program; see the files \s-1COPYING\s0 and \s-1LICENSE.\s0 If not, with this program; see the files \s-1COPYING\s0 and \s-1LICENSE.\s0 If not,
visit the \s-1UPX\s0 home page. visit the \s-1UPX\s0 home page.
+10 -14
View File
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
=head1 ABSTRACT =head1 ABSTRACT
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
@@ -932,28 +932,24 @@ Please report all bugs immediately to the authors.
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2000-2022 John F. Reiser Copyright (C) 2000-2023 John F. Reiser
Copyright (C) 2002-2022 Jens Medoch Copyright (C) 2002-2023 Jens Medoch
This program may be used freely, and you are welcome to B<UPX> is distributed with full source code under the terms of the
redistribute it under certain conditions. GNU General Public License v2+; either under the pure GPLv2+ (see
the file COPYING), or (at your option) under the GPLv+2 with special
exceptions and restrictions granting the free usage for all binaries
including commercial programs (see the file LICENSE).
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
B<UPX> is distributed with full source code under the terms of the
GNU General Public License v2+;
either under the pure GPLv2+ (see the file COPYING),
or (at your option) under the GPLv+2 with special exceptions and
restrictions granting the free usage for commercial
programs (see the file LICENSE).
You should have received a copy of the UPX License Agreements along You should have received a copy of the UPX License Agreements along
with this program; see the files COPYING and LICENSE. If not, with this program; see the files COPYING and LICENSE. If not,
visit the UPX home page. visit the UPX home page.
+17
View File
@@ -0,0 +1,17 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# create the image from Dockerfile
# using a rootless Podman container
# NOTE: this image is based on rebuild-stubs-with-podman/upx-stubtools-20221212-v4,
# so you have to create that image first
# WARNING: we install many packages, so the resulting image needs A LOT of disk space!
image=upx-cross-compile-20230115-v2
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
podman image list "$image"
podman image tree "$image"
+53
View File
@@ -0,0 +1,53 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# run an interactive shell in the image
# using a rootless Podman container
image=upx-cross-compile-20230115-v2
flags=( -ti --read-only --rm )
flags+=( --cap-drop=all ) # drop all capabilities
flags+=( --network=none ) # no network needed
flags+=( -e TERM="$TERM" ) # pass $TERM
if [[ 1 == 1 ]]; then
# run as user upx 2000:2000
flags+=( --user 2000 )
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" )
flags+=( -w /home/upx/src/upx ) # set working directory
else
# run as user root 0:0
# ONLY FOR DEBUGGING THE IMAGE
# map container user/group 0 to current host user/group
flags+=( --user 0 )
fi
podman run "${flags[@]}" "$image" bash -l
# now we can cross-compile UPX for Windows:
# cd /home/upx/src/upx
# rm -rf ./build/extra/cross-windows-mingw64/release
# make build/extra/cross-windows-mingw64/release
# and we can run the clang Static Analyzer (scan-build)
# cd /home/upx/src/upx
# rm -rf ./build/extra/scan-build/release
# make build/extra/scan-build/release
# and lots of other cross-compilers are installed; see "ls /usr/bin/*g++*"
# and finally see misc/cross-compile-upx-with-podman/build-all-inside-container.sh
# after running that script we can do cool things like:
# cd /home/upx/src/upx/build/cross-compile-upx-with-podman/alpha-linux-gnu/debug
# qemu-alpha -L /usr/alpha-linux-gnu upx --version
# cd /home/upx/src/upx/build/cross-compile-upx-with-podman/hppa-linux-gnu/debug
# qemu-hppa -L /usr/hppa-linux-gnu upx --version
# (similar for many other architectures/builds)
@@ -0,0 +1,54 @@
# NOTE: this image is based on rebuild-stubs-with-podman/upx-stubtools-20221212-v4,
# so you have to create that image first
# WARNING: we install many packages, so the resulting image needs A LOT of disk space!
FROM localhost/upx-stubtools-20221212-v4
ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-20230115-v2
ARG DEBIAN_FRONTEND=noninteractive
USER root
# Ubuntu 22.04
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y \
# Linux glibc cross compilers
g++-aarch64-linux-gnu \
g++-alpha-linux-gnu \
g++-arm-linux-gnueabi \
g++-arm-linux-gnueabihf \
g++-hppa-linux-gnu \
g++-i686-linux-gnu \
g++-m68k-linux-gnu \
g++-mips-linux-gnu \
g++-mipsel-linux-gnu \
g++-mips64-linux-gnuabi64 \
g++-mips64el-linux-gnuabi64 \
g++-powerpc-linux-gnu \
g++-powerpc64-linux-gnu \
g++-powerpc64le-linux-gnu \
g++-riscv64-linux-gnu \
g++-s390x-linux-gnu \
g++-sh4-linux-gnu \
g++-sparc64-linux-gnu \
# Linux glibc cross compilers - ILP32 on 64-bit CPUs
g++-x86-64-linux-gnux32 \
# Windows cross compilers
g++-mingw-w64-i686 \
g++-mingw-w64-x86-64 \
&& true
RUN apt-get install -y \
# clang-14 and tools
clang-14 clang-format-14 clang-tidy-14 clang-tools-14 lldb-14 llvm-14 \
# QEMU and Wine
qemu-system qemu-user wine wine32 \
# misc
gdb lsb-release valgrind \
&& true
RUN cd /usr/bin \
# create unversioned clang symlinks in /usr/local/bin
&& for f in clang*-14 llvm-*-14 scan-*-14; do ln -s -v ../../bin/$f /usr/local/bin/${f%-14}; done \
&& ln -s -v ../../bin/obj2yaml-14 /usr/local/bin/llvm-obj2yaml \
&& ln -s -v ../../bin/yaml2obj-14 /usr/local/bin/llvm-yaml2obj \
&& true
# switch back to default user upx 2000:2000
USER upx
@@ -0,0 +1,93 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# build UPX for 21 targets; must be run inside the container!
# using a rootless Podman container
# simple sanity check that we are indeed running inside the container
if [[ $UPX_CONTAINER_IMAGE_NAME != upx-cross-compile-* ]]; then
echo "$argv0: NOTE: please run this script *inside* the container"
exit 1
fi
# go to upx top-level directory
cd "$argv0dir/../.." || exit 1
pwd
[[ -f src/version.h ]] || exit 1 # sanity check
function run_config_and_build {
# requires: AR CC CXX RANLIB
local toolchain=$1
local cmake_config_flags build_type bdir
# cmake flags
cmake_config_flags=
case $toolchain in
# these old architectures do not support sanitize
alpha-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
hppa-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
# avoid link errors with current MinGW-w64 versions
i686-w64-mingw32) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
x86_64-w64-mingw32) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
# avoid warnings about arm libstdc++ ABI change in gcc-7
arm-linux-*) CXX="$CXX -Wno-psabi" ;;
esac
if [[ 1 == 1 ]]; then
# prefer building with Ninja (ninja-build)
cmake_config_flags="$cmake_config_flags -G Ninja -DUPX_CONFIG_CMAKE_DISABLE_INSTALL=ON"
fi
# for all build types
for build_type in Debug Release; do
bdir=build/cross-compile-upx-with-podman/$toolchain/${build_type,,}
mkdir -p $bdir
# run_config
if [[ ! -f $bdir/CMakeCache.txt ]]; then
cmake -S . -B $bdir -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_AR=$AR -DCMAKE_RANLIB=$RANLIB $cmake_config_flags
fi
# run_build
cmake --build $bdir --config $build_type --parallel
done
}
# see Dockerfile for packages
for package in \
g++-aarch64-linux-gnu \
g++-alpha-linux-gnu \
g++-arm-linux-gnueabi \
g++-arm-linux-gnueabihf \
g++-hppa-linux-gnu \
g++-i686-linux-gnu \
g++-m68k-linux-gnu \
g++-mips-linux-gnu \
g++-mipsel-linux-gnu \
g++-mips64-linux-gnuabi64 \
g++-mips64el-linux-gnuabi64 \
g++-powerpc-linux-gnu \
g++-powerpc64-linux-gnu \
g++-powerpc64le-linux-gnu \
g++-riscv64-linux-gnu \
g++-s390x-linux-gnu \
g++-sh4-linux-gnu \
g++-sparc64-linux-gnu \
g++-x86-64-linux-gnux32 \
g++-mingw-w64-i686 \
g++-mingw-w64-x86-64
do
# setup toolchain and environment variables
toolchain=$package
toolchain=${toolchain/-x86-64/-x86_64}
toolchain=${toolchain/g++-/}
case $toolchain in
mingw-w64-i686) toolchain=i686-w64-mingw32 ;;
mingw-w64-x86_64) toolchain=x86_64-w64-mingw32 ;;
esac
echo "========== $toolchain"
export AR=/usr/bin/${toolchain}-ar
export CC=/usr/bin/${toolchain}-gcc
export CXX=/usr/bin/${toolchain}-g++
export RANLIB=/usr/bin/${toolchain}-ranlib
ls -l $AR $CC $CXX $RANLIB
run_config_and_build $toolchain
unset AR CC CXX RANLIB
done
@@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# create the image from Dockerfile # create the image from Dockerfile
# using a rootless Podman container # using a rootless Podman container
image=upx-stubtools-20210104-v5 image=upx-stubtools-20221212-v4
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
@@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# run an interactive shell in the image # run an interactive shell in the image
# using a rootless Podman container # using a rootless Podman container
image=upx-stubtools-20210104-v5 image=upx-stubtools-20221212-v4
flags=( -ti --read-only --rm ) flags=( -ti --read-only --rm )
flags+=( --cap-drop=all ) # drop all capabilities flags+=( --cap-drop=all ) # drop all capabilities
@@ -15,14 +15,14 @@ flags+=( -e TERM="$TERM" ) # pass $TERM
if [[ 1 == 1 ]]; then if [[ 1 == 1 ]]; then
# run as user upx 2000:2000 # run as user upx 2000:2000
flags+=( --user 2000 ) flags+=( --user 2000 )
# map container user 0 to subuid-user 1, and map container user 2000 to current host user # map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
flags+=( --uidmap=0:1:1 --uidmap=2000:0:1 ) flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
# map container group 0 to subgid-group 1, and map container group 2000 to current host group # map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
flags+=( --gidmap=0:1:1 --gidmap=2000:0:1 ) flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx # NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs! # INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" ) flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" )
flags+=( -w /home/upx/src/upx ) # working directory flags+=( -w /home/upx/src/upx ) # set working directory
else else
# run as user root 0:0 # run as user root 0:0
# ONLY FOR DEBUGGING THE IMAGE # ONLY FOR DEBUGGING THE IMAGE
@@ -37,10 +37,40 @@ podman run "${flags[@]}" "$image" bash -l
# # make sure that git is clean: # # make sure that git is clean:
# git status . # git status .
# # remove stub files and make sure that they got deleted: # # remove stub files and make sure that they got deleted:
# make maintainer-clean # make maintainer-clean extra-clean
# git status . # git status .
# # rebuild # # rebuild
# make all # make extra-all all
# # make sure that the stub files did rebuild correctly: # # make sure that the stub files did rebuild correctly:
# git status . # git status .
# git diff . # git diff .
# we can also build UPX in the container:
# cd /home/upx/src/upx
# rm -rf ./build/extra/gcc/release
# make build/extra/gcc/release
# # run tests
# ./build/extra/gcc/release/upx --version
# make -C build/extra/gcc/release test
# and we can also build UPX with -m32:
# cd /home/upx/src/upx
# rm -rf ./build/extra/gcc-m32/release
# make build/extra/gcc-m32/release
# # run tests
# ./build/extra/gcc-m32/release/upx --version
# make -C build/extra/gcc-m32/release test
# and we can also build UPX with -mx32: (NOTE: needs CONFIG_X86_X32_ABI on host kernel!)
# cd /home/upx/src/upx
# rm -rf ./build/extra/gcc-mx32/release
# make build/extra/gcc-mx32/release
# # run tests (needs CONFIG_X86_X32_ABI on host kernel)
# ./build/extra/gcc-mx32/release/upx --version
# make -C build/extra/gcc-mx32/release test
# and we can also rebuild the UPX docs the container:
# cd /home/upx/src/upx/doc
# make clean all
# git status .
# git diff .
+22 -30
View File
@@ -1,4 +1,5 @@
FROM docker.io/library/ubuntu:22.04 FROM docker.io/library/ubuntu:22.04
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20221212-v4
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8 ENV LANG=C.UTF-8
@@ -9,19 +10,20 @@ RUN dpkg --add-architecture i386 \
aria2 ca-certificates git less libmpc3 libncurses5 make \ aria2 ca-certificates git less libmpc3 libncurses5 make \
ncurses-term perl-base python2-minimal wget xz-utils \ ncurses-term perl-base python2-minimal wget xz-utils \
libc6:i386 zlib1g:i386 \ libc6:i386 zlib1g:i386 \
# the following packages are not required for rebuilding the stubs, # the following packages are not required for rebuilding the stubs, but
# but they do make the image more convenient and also allow building # they do make the image much more convenient and also allow building
# the full UPX binary inside the container via CMake: # the full UPX binary inside the container via CMake:
bzip2 cmake elfutils file g++ libzstd-dev lzop ninja-build patch \ 7zip bfs bzip2 cmake curl elfutils fd-find file fzf g++ gdb gojq htop hyperfine \
patchelf pax-utils rsync unzip vim zip zlib1g-dev zsh zstd \ jq libzstd-dev lsb-release lzip lzop ninja-build p7zip patch patchelf pax-utils \
ripgrep rsync screen universal-ctags unzip vim zip zlib1g-dev zsh zstd \
# extra packages for compiling with "gcc -m32" and and "gcc -mx32":
gcc-multilib g++-multilib \
&& true && true
# manually install compat libs from Ubuntu 16.04 # manually install compat libs from Ubuntu 16.04; REQUIRED
RUN cd /root \ RUN cd /root \
&& aria2c --checksum=sha-256=2605f43f8047fc972855bb909f1dd7af761bbfd35ae559ad689b0d55a4236d69 \ && aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \
'http://mirror.enzu.com/ubuntu/pool/main/g/gmp/libgmp10_6.1.0+dfsg-2_amd64.deb' \ 'http://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb' \
&& aria2c --checksum=sha-256=3973a97387bbe0e8a775995c22861d8478edee2a594e8117970f635de25b2c8a \
'http://mirror.enzu.com/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.4-1_amd64.deb' \
&& mkdir packages \ && mkdir packages \
&& for f in ./*.deb; do dpkg -x $f ./packages; done \ && for f in ./*.deb; do dpkg -x $f ./packages; done \
&& mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ \ && mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ \
@@ -29,38 +31,28 @@ RUN cd /root \
&& ldconfig \ && ldconfig \
&& true && true
# install upx-stubtools into /usr/local/bin/bin-upx-20210104 # install upx-stubtools into /usr/local/bin/bin-upx-20221212; REQUIRED
RUN cd /root \ RUN cd /root \
&& aria2c --checksum=sha-256=abcd8337cc656fe68d7bbb2ffe0f1e5ddce618688aa0e18c1ebcc40072843884 \ && aria2c --checksum=sha-256=509e06639118a79d8e79489a400e134c6d3ca36bad2c6ec29648d7c1e5b81afa \
'https://github.com/upx/upx-stubtools/releases/download/v20210104/bin-upx-20210104.tar.xz' \ 'https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz' \
&& cd /usr/local/bin \ && cd /usr/local/bin \
&& tar -xoaf /root/bin-upx-20210104.tar.xz \ && tar -xoaf /root/bin-upx-20221212.tar.xz \
&& rm /root/bin-upx-20210104.tar.xz \ && rm /root/bin-upx-20221212.tar.xz \
&& true && true
# install previous UPX versions into /usr/local/bin # install official UPX release binaries into /usr/local/bin; not required but convenient for testing
RUN cd /root \ RUN cd /root \
&& wget -q https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \ && wget -q https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \
&& wget -q https://github.com/upx/upx/releases/download/v3.92/upx-3.92-amd64_linux.tar.xz \ && for v in 3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2; do wget -q https://github.com/upx/upx/releases/download/v${v}/upx-${v}-amd64_linux.tar.xz; done \
&& wget -q https://github.com/upx/upx/releases/download/v3.93/upx-3.93-amd64_linux.tar.xz \
&& wget -q https://github.com/upx/upx/releases/download/v3.94/upx-3.94-amd64_linux.tar.xz \
&& wget -q https://github.com/upx/upx/releases/download/v3.95/upx-3.95-amd64_linux.tar.xz \
&& wget -q https://github.com/upx/upx/releases/download/v3.96/upx-3.96-amd64_linux.tar.xz \
&& for f in ./upx-*.tar.*; do tar -xoaf $f; done \ && for f in ./upx-*.tar.*; do tar -xoaf $f; done \
&& rm ./upx-*.tar.* \ && for v in 3.91 3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2; do d=upx-${v}-amd64_linux; ./$d/upx -qq -d $d/upx -o /usr/local/bin/upx-${v}; done \
&& d=upx-3.91-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.91 \ && rm -r ./upx-*.tar.* ./upx-*linux \
&& d=upx-3.92-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.92 \
&& d=upx-3.93-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.93 \
&& d=upx-3.94-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.94 \
&& d=upx-3.95-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.95 \
&& d=upx-3.96-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.96 \
&& rm -rf ./upx-*linux \
&& true && true
# create default user upx 2000:2000 # create default user upx 2000:2000
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \ RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
&& mkdir -p /home/upx/.local/bin /home/upx/src/upx \ && mkdir -p /home/upx/.cache/zig /home/upx/.local/bin /home/upx/src/upx \
&& ln -s /usr/local/bin/bin-upx-20210104 /home/upx/.local/bin/bin-upx \ && ln -s /usr/local/bin/bin-upx-20221212 /home/upx/.local/bin/bin-upx \
&& chown -R upx:upx /home/upx \ && chown -R upx:upx /home/upx \
&& true && true
USER upx USER upx
+5 -5
View File
@@ -4,22 +4,22 @@ set -e; set -o pipefail
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike # "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
# NOTE: we are using clang-format-10.0.1 from upx-stubtools # NOTE: we are using clang-format-15.0.6 from upx-stubtools
# see https://github.com/upx/upx-stubtools/releases # see https://github.com/upx/upx-stubtools/releases
# NOTE: we use .clang-format config from upx.git/.clang-format # NOTE: we use .clang-format config from upx.git/.clang-format
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-10.0.1" UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-15.0.6"
fi fi
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-10.0.1" UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-15.0.6"
fi fi
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-10.0.1" UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-15.0.6"
fi fi
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
echo "ERROR: $0: cannot find clang-format-10.0.1" echo "ERROR: $0: cannot find clang-format-15.0.6"
echo "ERROR: $0: please visit https://github.com/upx/upx-stubtools" echo "ERROR: $0: please visit https://github.com/upx/upx-stubtools"
exit 1 exit 1
fi fi
+32 -29
View File
@@ -21,19 +21,22 @@ endif
# redirect to top-level CMake build # redirect to top-level CMake build
# #
default: debug .DEFAULT_GOAL = build/debug
all: debug release
debug: $(top_srcdir)/build/debug/upx
release: $(top_srcdir)/build/release/upx
$(top_srcdir)/build/debug/upx: build/debug: $(top_srcdir)/build/debug/upx
build/release: $(top_srcdir)/build/release/upx
# shortcuts
all: build/debug build/release
debug: build/debug
release: build/release
$(top_srcdir)/build/debug/upx: PHONY
$(MAKE) -C $(top_srcdir) build/debug $(MAKE) -C $(top_srcdir) build/debug
$(top_srcdir)/build/release/upx: $(top_srcdir)/build/release/upx: PHONY
$(MAKE) -C $(top_srcdir) build/release $(MAKE) -C $(top_srcdir) build/release
.PHONY: default all debug release .PHONY: PHONY
.PHONY: $(top_srcdir)/build/debug/upx .NOTPARALLEL:
.PHONY: $(top_srcdir)/build/release/upx
# #
# "make run-testsuite" # "make run-testsuite"
@@ -54,15 +57,18 @@ endif
# run the UPX testsuite # run the UPX testsuite
# The expected (old) checksums are in $(top_srcdir)/.github/travis_testsuite_1-expected_sha256sums.sh # The expected (old) checksums are in $(top_srcdir)/.github/travis_testsuite_1-expected_sha256sums.sh
# The actual (new) checksums are in tmp-testsuite/testsuite_1/.sha256sums.recreate # The actual (new) checksums are in ./tmp-testsuite/testsuite_1/.sha256sums.recreate
ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),) ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
ifneq ($(wildcard $(top_srcdir)/.github/travis_testsuite_1.sh),) ifneq ($(wildcard $(top_srcdir)/.github/travis_testsuite_1.sh),)
run-testsuite: export upx_exe := $(top_srcdir)/build/release/upx run-testsuite: run-testsuite-release
run-testsuite: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR) run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
run-testsuite: export upx_testsuite_BUILDDIR := ./tmp-testsuite run-testsuite-%: export upx_testsuite_BUILDDIR := ./tmp-testsuite
run-testsuite: $(top_srcdir)/build/release/upx run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx
run-testsuite-debug: PHONY $(top_srcdir)/build/debug/upx
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx
run-testsuite-release: PHONY $(top_srcdir)/build/release/upx
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
.PHONY: run-testsuite
endif endif
endif endif
@@ -72,18 +78,16 @@ endif
# automatically format some C++ source code files # automatically format some C++ source code files
ifeq ($(shell uname),Linux) ifeq ($(shell uname),Linux)
CLANG_FORMAT_FILES += bele.h bele_policy.h # Markus loves clang-format, but John hates it; find a compromise
CLANG_FORMAT_FILES += except.cpp except.h CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h help.cpp
CLANG_FORMAT_FILES += file.cpp file.h CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmli%
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h CLANG_FORMAT_EXCLUDE_FILES += packer_c.cpp packer_f.cpp
CLANG_FORMAT_FILES += main.cpp options.cpp options.h packer.cpp packer.h CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.cpp
CLANG_FORMAT_FILES += p_tos.cpp p_tos.h CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
CLANG_FORMAT_FILES += ui.cpp ui.h work.cpp clang-format: PHONY $(CLANG_FORMAT_FILES)
CLANG_FORMAT_FILES += $(wildcard util/[a-ln-z]*.[ch]* util/mem*.[ch]*) @echo "running upx-clang-format"
clang-format: @$(top_srcdir)/misc/scripts/upx-clang-format -i $(CLANG_FORMAT_FILES)
$(top_srcdir)/misc/scripts/upx-clang-format -i $(addprefix $(top_srcdir)/src/,$(sort $(CLANG_FORMAT_FILES)))
.PHONY: clang-format
endif endif
# #
@@ -96,8 +100,7 @@ CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
ifneq ($(wildcard $(top_srcdir)/.git/.),) ifneq ($(wildcard $(top_srcdir)/.git/.),)
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir) CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
endif endif
check-whitespace : ; $(CHECK_WHITESPACE) check-whitespace : PHONY ; $(CHECK_WHITESPACE)
endif endif
.PHONY: check-whitespace
# vim:set ts=8 sw=8 noet: # vim:set ts=8 sw=8 noet:
+37 -38
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -38,35 +38,35 @@
// core - NE // core - NE
**************************************************************************/ **************************************************************************/
__acc_static_forceinline unsigned get_ne16(const void *p) { static forceinline unsigned get_ne16(const void *p) {
upx_uint16_t v = 0; upx_uint16_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
__acc_static_forceinline unsigned get_ne32(const void *p) { static forceinline unsigned get_ne32(const void *p) {
upx_uint32_t v = 0; upx_uint32_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
__acc_static_forceinline upx_uint64_t get_ne64(const void *p) { static forceinline upx_uint64_t get_ne64(const void *p) {
upx_uint64_t v = 0; upx_uint64_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
__acc_static_forceinline void set_ne16(void *p, unsigned vv) { static forceinline void set_ne16(void *p, unsigned vv) {
upx_uint16_t v = (upx_uint16_t) (vv & 0xffff); upx_uint16_t v = (upx_uint16_t) (vv & 0xffff);
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
__acc_static_forceinline void set_ne32(void *p, unsigned vv) { static forceinline void set_ne32(void *p, unsigned vv) {
upx_uint32_t v = vv; upx_uint32_t v = vv;
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
__acc_static_forceinline void set_ne64(void *p, upx_uint64_t vv) { static forceinline void set_ne64(void *p, upx_uint64_t vv) {
upx_uint64_t v = vv; upx_uint64_t v = vv;
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
@@ -79,36 +79,31 @@ __acc_static_forceinline void set_ne64(void *p, upx_uint64_t vv) {
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
__acc_static_forceinline unsigned bswap16(unsigned v) { // unfortunately *not* constexpr with MSVC
return (unsigned) _byteswap_ulong(v << 16); static forceinline unsigned bswap16(unsigned v) { return (unsigned) _byteswap_ulong(v << 16); }
} static forceinline unsigned bswap32(unsigned v) { return (unsigned) _byteswap_ulong(v); }
__acc_static_forceinline unsigned bswap32(unsigned v) { return (unsigned) _byteswap_ulong(v); } static forceinline upx_uint64_t bswap64(upx_uint64_t v) { return _byteswap_uint64(v); }
__acc_static_forceinline upx_uint64_t bswap64(upx_uint64_t v) { return _byteswap_uint64(v); }
#else #else
__acc_static_forceinline constexpr unsigned bswap16(unsigned v) { static forceinline constexpr unsigned bswap16(unsigned v) {
// return __builtin_bswap16((upx_uint16_t) (v & 0xffff)); // return __builtin_bswap16((upx_uint16_t) (v & 0xffff));
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48); // return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
return __builtin_bswap32(v << 16); return __builtin_bswap32(v << 16);
} }
__acc_static_forceinline constexpr unsigned bswap32(unsigned v) { static forceinline constexpr unsigned bswap32(unsigned v) {
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32); // return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32);
return __builtin_bswap32(v); return __builtin_bswap32(v);
} }
__acc_static_forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) { static forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) { return __builtin_bswap64(v); }
return __builtin_bswap64(v);
}
#endif #endif
__acc_static_forceinline constexpr unsigned no_bswap16(unsigned v) { static forceinline constexpr unsigned no_bswap16(unsigned v) {
return v & 0xffff; // needed so that this is equivalent to bswap16() above return v & 0xffff; // needed so that this is equivalent to bswap16() above
} }
static forceinline constexpr unsigned no_bswap32(unsigned v) { return v; }
__acc_static_forceinline constexpr unsigned no_bswap32(unsigned v) { return v; } static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v; }
__acc_static_forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v; }
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
#define ne16_to_be16(v) no_bswap16(v) #define ne16_to_be16(v) no_bswap16(v)
@@ -175,24 +170,27 @@ inline unsigned get_le26(const void *p) { return get_le32(p) & 0x03ffffff; }
inline void set_le26(void *p, unsigned v) { inline void set_le26(void *p, unsigned v) {
// preserve the top 6 bits // preserve the top 6 bits
// set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff)); #if 0
set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
#else
// optimized version, saving a runtime bswap32 // optimized version, saving a runtime bswap32
set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) | set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
(ne32_to_le32(v) & ne32_to_le32(0x03ffffff))); (ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
#endif
} }
/************************************************************************* /*************************************************************************
// get signed values // get signed values
**************************************************************************/ **************************************************************************/
__acc_static_forceinline int sign_extend(unsigned v, unsigned bits) { static forceinline int sign_extend(unsigned v, unsigned bits) {
const unsigned sign_bit = 1u << (bits - 1); const unsigned sign_bit = 1u << (bits - 1);
v &= sign_bit | (sign_bit - 1); v &= sign_bit | (sign_bit - 1);
v |= 0 - (v & sign_bit); v |= 0 - (v & sign_bit);
return ACC_ICAST(int, v); return ACC_ICAST(int, v);
} }
__acc_static_forceinline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) { static forceinline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) {
const upx_uint64_t sign_bit = 1ull << (bits - 1); const upx_uint64_t sign_bit = 1ull << (bits - 1);
v &= sign_bit | (sign_bit - 1); v &= sign_bit | (sign_bit - 1);
v |= 0 - (v & sign_bit); v |= 0 - (v & sign_bit);
@@ -251,6 +249,7 @@ inline upx_int64_t get_le64_signed(const void *p) {
**************************************************************************/ **************************************************************************/
struct alignas(1) BE16 { struct alignas(1) BE16 {
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
unsigned char d[2]; unsigned char d[2];
BE16 &operator=(unsigned v) { BE16 &operator=(unsigned v) {
@@ -300,6 +299,7 @@ struct alignas(1) BE16 {
}; };
struct alignas(1) BE32 { struct alignas(1) BE32 {
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
unsigned char d[4]; unsigned char d[4];
BE32 &operator=(unsigned v) { BE32 &operator=(unsigned v) {
@@ -349,6 +349,7 @@ struct alignas(1) BE32 {
}; };
struct alignas(1) BE64 { struct alignas(1) BE64 {
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
unsigned char d[8]; unsigned char d[8];
BE64 &operator=(upx_uint64_t v) { BE64 &operator=(upx_uint64_t v) {
@@ -398,6 +399,7 @@ struct alignas(1) BE64 {
}; };
struct alignas(1) LE16 { struct alignas(1) LE16 {
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
unsigned char d[2]; unsigned char d[2];
LE16 &operator=(unsigned v) { LE16 &operator=(unsigned v) {
@@ -447,6 +449,7 @@ struct alignas(1) LE16 {
}; };
struct alignas(1) LE32 { struct alignas(1) LE32 {
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
unsigned char d[4]; unsigned char d[4];
LE32 &operator=(unsigned v) { LE32 &operator=(unsigned v) {
@@ -496,6 +499,7 @@ struct alignas(1) LE32 {
}; };
struct alignas(1) LE64 { struct alignas(1) LE64 {
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
unsigned char d[8]; unsigned char d[8];
LE64 &operator=(upx_uint64_t v) { LE64 &operator=(upx_uint64_t v) {
@@ -567,7 +571,6 @@ template <class T>
inline T *operator-(T *ptr, const BE16 &v) { inline T *operator-(T *ptr, const BE16 &v) {
return ptr - unsigned(v); return ptr - unsigned(v);
} }
template <class T> template <class T>
inline T *operator+(T *ptr, const BE32 &v) { inline T *operator+(T *ptr, const BE32 &v) {
return ptr + unsigned(v); return ptr + unsigned(v);
@@ -576,13 +579,6 @@ template <class T>
inline T *operator-(T *ptr, const BE32 &v) { inline T *operator-(T *ptr, const BE32 &v) {
return ptr - unsigned(v); return ptr - unsigned(v);
} }
// these are not implemented on purpose and will cause link-time errors
template <class T>
T *operator+(T *ptr, const BE64 &v);
template <class T>
T *operator-(T *ptr, const BE64 &v);
template <class T> template <class T>
inline T *operator+(T *ptr, const LE16 &v) { inline T *operator+(T *ptr, const LE16 &v) {
return ptr + unsigned(v); return ptr + unsigned(v);
@@ -591,7 +587,6 @@ template <class T>
inline T *operator-(T *ptr, const LE16 &v) { inline T *operator-(T *ptr, const LE16 &v) {
return ptr - unsigned(v); return ptr - unsigned(v);
} }
template <class T> template <class T>
inline T *operator+(T *ptr, const LE32 &v) { inline T *operator+(T *ptr, const LE32 &v) {
return ptr + unsigned(v); return ptr + unsigned(v);
@@ -601,11 +596,15 @@ inline T *operator-(T *ptr, const LE32 &v) {
return ptr - unsigned(v); return ptr - unsigned(v);
} }
// these are not implemented on purpose and will cause link-time errors // these are not implemented on purpose and will cause errors
template <class T> template <class T>
T *operator+(T *ptr, const LE64 &v); T *operator+(T *ptr, const BE64 &v) DELETED_FUNCTION;
template <class T> template <class T>
T *operator-(T *ptr, const LE64 &v); T *operator-(T *ptr, const BE64 &v) DELETED_FUNCTION;
template <class T>
T *operator+(T *ptr, const LE64 &v) DELETED_FUNCTION;
template <class T>
T *operator-(T *ptr, const LE64 &v) DELETED_FUNCTION;
/************************************************************************* /*************************************************************************
// global overloads // global overloads
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -2,8 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -21,8 +20,8 @@
If not, write to the Free Software Foundation, Inc., If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar Markus F.X.J. Oberhumer
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com>
*/ */
#include "../conf.h" #include "../conf.h"
@@ -35,6 +34,7 @@ int upx_doctest_check(int argc, char **argv) {
#if defined(DOCTEST_CONFIG_DISABLE) #if defined(DOCTEST_CONFIG_DISABLE)
UNUSED(argc); UNUSED(argc);
UNUSED(argv); UNUSED(argv);
return 0;
#else #else
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE"); const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE");
if (e && e[0] && strcmp(e, "0") != 0) if (e && e[0] && strcmp(e, "0") != 0)
@@ -72,8 +72,8 @@ int upx_doctest_check(int argc, char **argv) {
return 1; return 1;
if (context.shouldExit()) if (context.shouldExit())
return 2; return 2;
#endif // DOCTEST_CONFIG_DISABLE
return 0; return 0;
#endif // DOCTEST_CONFIG_DISABLE
} }
int upx_doctest_check() { return upx_doctest_check(0, nullptr); } int upx_doctest_check() { return upx_doctest_check(0, nullptr); }
@@ -98,6 +98,9 @@ ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304)
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull) ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull)
#endif #endif
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("a") == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", "")) ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", "")) ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a")) ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a"))
@@ -119,6 +122,20 @@ ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz")) ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz")) ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
#if 0 // does not work with MSVC
#if '\0' - 1 < 0
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 127)
#else
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255)
#endif
#if L'\0' - 1 < 0
ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 < 0)
#else
ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 > 0)
#endif
#endif
/************************************************************************* /*************************************************************************
// upx_compiler_sanity_check() // upx_compiler_sanity_check()
// assert a sane architecture and compiler // assert a sane architecture and compiler
@@ -129,6 +146,17 @@ namespace {
template <class T> template <class T>
struct TestBELE { struct TestBELE {
__acc_static_noinline bool test(void) { __acc_static_noinline bool test(void) {
// POD checks
{
COMPILE_TIME_ASSERT(std::is_standard_layout<T>::value)
COMPILE_TIME_ASSERT(std::is_trivial<T>::value)
// extra checks, these are probably implied by std::is_trivial:
COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<T>::value)
COMPILE_TIME_ASSERT(std::is_trivially_copyable<T>::value)
COMPILE_TIME_ASSERT(std::is_trivially_default_constructible<T>::value)
}
// alignment checks
{
COMPILE_TIME_ASSERT_ALIGNED1(T) COMPILE_TIME_ASSERT_ALIGNED1(T)
struct alignas(1) test1_t { struct alignas(1) test1_t {
char a; char a;
@@ -138,17 +166,20 @@ struct TestBELE {
char a; char a;
T b[3]; T b[3];
}; };
test1_t t1[7];
UNUSED(t1);
test2_t t2[7];
UNUSED(t2);
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
COMPILE_TIME_ASSERT_ALIGNED1(test1_t) COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
test1_t t1[7];
test2_t t2[7];
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T)) COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T))
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3 * sizeof(T)) COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3 * sizeof(T))
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T)) COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
UNUSED(t1);
UNUSED(t2);
}
#if 1 #if 1
// arithmetic checks
{
T allbits; T allbits;
allbits = 0; allbits = 0;
allbits += 1; allbits += 1;
@@ -185,6 +216,7 @@ struct TestBELE {
assert(v2 == 0); assert(v2 == 0);
if ((v1 ^ v2) != 1) if ((v1 ^ v2) != 1)
return false; return false;
}
#endif #endif
return true; return true;
} }
@@ -321,6 +353,20 @@ void upx_compiler_sanity_check(void) {
assert(get_le26(d) == 0x03020304); assert(get_le26(d) == 0x03020304);
assert(dd == ne32_to_le32(0xf7020304)); assert(dd == ne32_to_le32(0xf7020304));
} }
{
upx_uint16_t a;
upx_uint32_t b;
upx_uint64_t c;
set_ne16(&a, 0x04030201); // ignore upper bits
set_ne32(&b, 0x04030201);
set_ne64(&c, 0x0807060504030201ull);
assert(a == 0x0201);
assert(b == 0x04030201);
assert(c == 0x0807060504030201ull);
assert(get_ne16(&a) == 0x0201);
assert(get_ne32(&b) == 0x04030201);
assert(get_ne64(&c) == 0x0807060504030201ull);
}
#endif #endif
union { union {
short v_short; short v_short;
+12 -5
View File
@@ -2,8 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -21,8 +20,8 @@
If not, write to the Free Software Foundation, Inc., If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar Markus F.X.J. Oberhumer
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com>
*/ */
/************************************************************************* /*************************************************************************
@@ -33,11 +32,19 @@
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING) #if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
#define DOCTEST_CONFIG_NO_MULTITHREADING #define DOCTEST_CONFIG_NO_MULTITHREADING
#endif #endif
#if defined(__MSDOS__) && defined(__DJGPP__) #if defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__)
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS #define DOCTEST_CONFIG_NO_POSIX_SIGNALS
#elif defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
#define DOCTEST_CONFIG_COLORS_NONE
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
#pragma GCC diagnostic ignored "-Wshadow"
#endif #endif
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS #define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
#if defined(__clang__) && defined(__FAST_MATH__) && defined(__INTEL_LLVM_COMPILER)
// warning: comparison with NaN always evaluates to false in fast floating point modes
#pragma clang diagnostic ignored "-Wtautological-constant-compare"
#endif
#include <doctest/doctest/parts/doctest.cpp> #include <doctest/doctest/parts/doctest.cpp>
#endif #endif
+791
View File
@@ -0,0 +1,791 @@
/* xspan -- a minimally invasive checked memory smart pointer
This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
*/
// lots of tests (and probably quite a number of redundant tests)
#include "../conf.h"
/*************************************************************************
// raw_bytes
**************************************************************************/
TEST_CASE("raw_bytes ptr") {
upx_uint16_t *ptr = nullptr;
CHECK_NOTHROW(raw_bytes(ptr, 0));
CHECK_THROWS(raw_bytes(ptr, 1));
CHECK_THROWS(raw_index_bytes(ptr, 0, 0));
CHECK_THROWS(raw_index_bytes(ptr, 1, 0));
CHECK_THROWS(raw_index_bytes(ptr, 0, 1));
upx_uint16_t buf[4];
ptr = buf;
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 1, 1), ptr) == 2u);
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 4, 0), ptr) == 8u);
}
TEST_CASE("raw_bytes bounded array") {
upx_uint16_t buf[4];
CHECK_NOTHROW(raw_bytes(buf, 8));
CHECK_THROWS(raw_bytes(buf, 9));
CHECK_NOTHROW(raw_index_bytes(buf, 4, 0));
CHECK_THROWS(raw_index_bytes(buf, 4, 1));
CHECK_NOTHROW(raw_index_bytes(buf, 3, 2));
CHECK_THROWS(raw_index_bytes(buf, 3, 3));
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 1, 1), buf) == 2u);
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 4, 0), buf) == 8u);
}
/*************************************************************************
// basic xspan
**************************************************************************/
TEST_CASE("basic xspan usage") {
char buf[4] = {0, 1, 2, 3};
SUBCASE("XSPAN_x") {
XSPAN_0(char) a0 = nullptr;
XSPAN_0(char) b0 = buf;
XSPAN_P(char) bp = buf;
XSPAN_0(char) c0 = XSPAN_0_MAKE(char, buf);
XSPAN_P(char) cp = XSPAN_P_MAKE(char, buf);
XSPAN_S(char) cs = XSPAN_S_MAKE(char, buf, sizeof(buf));
XSPAN_0(const char) const x0 = XSPAN_0_MAKE(const char, buf);
XSPAN_P(const char) const xp = XSPAN_P_MAKE(const char, buf);
XSPAN_S(const char) const xs = XSPAN_S_MAKE(const char, buf, sizeof(buf));
XSPAN_P(const char) const yp = xs;
XSPAN_0(const char) const z0p = yp;
XSPAN_0(const char) const z0s = xs;
CHECK((a0 == nullptr));
CHECK(c0 == b0);
CHECK(cp == bp);
CHECK(cs == bp);
CHECK(x0 == z0p);
CHECK(xp == z0s);
CHECK_NOTHROW(raw_bytes(a0, 0));
CHECK_THROWS(raw_bytes(a0, 1));
CHECK_THROWS(raw_index_bytes(a0, 0, 0));
CHECK(raw_bytes(c0, 4) == buf);
CHECK(raw_index_bytes(c0, 1, 3) == buf + 1);
CHECK(raw_bytes(cp, 4) == buf);
CHECK(raw_index_bytes(cp, 1, 3) == buf + 1);
CHECK(raw_bytes(cs, 4) == buf);
CHECK(raw_index_bytes(cs, 1, 3) == buf + 1);
#if WITH_XSPAN >= 2
CHECK_THROWS(raw_bytes(cs, 5));
CHECK_THROWS(raw_index_bytes(cs, 1, 4));
#endif
}
SUBCASE("XSPAN_x_VAR") {
XSPAN_0_VAR(char, a0, nullptr);
XSPAN_0_VAR(char, b0, buf);
XSPAN_P_VAR(char, bp, buf);
XSPAN_0_VAR(char, c0, buf, sizeof(buf));
XSPAN_P_VAR(char, cp, buf, sizeof(buf));
XSPAN_S_VAR(char, cs, buf, sizeof(buf));
XSPAN_0_VAR(char, d0, buf + 1, sizeof(buf), buf);
XSPAN_P_VAR(char, dp, buf + 1, sizeof(buf), buf);
XSPAN_S_VAR(char, ds, buf + 1, sizeof(buf), buf);
XSPAN_0_VAR(const char, const x0, buf, sizeof(buf));
XSPAN_P_VAR(const char, const xp, buf, sizeof(buf));
XSPAN_S_VAR(const char, const xs, buf, sizeof(buf));
XSPAN_P_VAR(const char, const yp, xs);
XSPAN_0_VAR(const char, const z0p, yp);
XSPAN_0_VAR(const char, const z0s, xs);
CHECK((a0 == nullptr));
CHECK(c0 == b0);
CHECK(cp == bp);
CHECK(cs == bp);
CHECK(d0 == dp);
CHECK(d0 == ds);
CHECK(x0 == z0p);
CHECK(xp == z0s);
CHECK_NOTHROW(raw_bytes(a0, 0));
CHECK_THROWS(raw_bytes(a0, 1));
CHECK_THROWS(raw_index_bytes(a0, 0, 0));
CHECK(raw_bytes(c0, 4) == buf);
CHECK(raw_index_bytes(c0, 1, 3) == buf + 1);
CHECK(raw_bytes(cp, 4) == buf);
CHECK(raw_index_bytes(cp, 1, 3) == buf + 1);
CHECK(raw_bytes(cs, 4) == buf);
CHECK(raw_index_bytes(cs, 1, 3) == buf + 1);
#if WITH_XSPAN >= 2
CHECK_THROWS(raw_bytes(cs, 5));
CHECK_THROWS(raw_index_bytes(cs, 1, 4));
#endif
}
SUBCASE("xspan in class") {
struct MyType {
XSPAN_0(char) s0;
XSPAN_P(char) sp;
XSPAN_S(char) ss;
#if __cplusplus >= 201103L
XSPAN_0(char) x0 = nullptr;
#endif
#if WITH_XSPAN >= 2
// much nicer syntax when using fully checked xspan:
MyType(char *b, size_t n, bool) : s0(b, n), sp(b, n), ss(b, n) {}
#endif
MyType(char *b, size_t n)
: s0(XSPAN_0_MAKE(char, b, n)), sp(XSPAN_P_MAKE(char, b, n)),
ss(XSPAN_S_MAKE(char, b, n)) {
UNUSED(n);
}
};
MyType x(buf, sizeof(buf));
MyType y = MyType(buf, sizeof(buf));
CHECK(x.s0 == y.sp);
}
}
/*************************************************************************
//
**************************************************************************/
#if (WITH_XSPAN >= 2) && DEBUG
TEST_CASE("PtrOrSpanOrNull") {
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
char *base_buf = real_buf + 2;
char *const my_null = nullptr;
typedef PtrOrSpanOrNull<char> Span0;
// basic nullptr
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = my_null);
CHECK_NOTHROW(Span0(base_buf, 4, base_buf).assign(my_null));
// basic range checking
CHECK_NOTHROW(Span0(base_buf, 4, base_buf));
CHECK_NOTHROW(Span0(base_buf, 0, base_buf));
CHECK_NOTHROW(Span0(base_buf, 0, base_buf) - 0);
CHECK_THROWS(Span0(base_buf, 0, base_buf) + 1);
CHECK_THROWS(Span0(base_buf, 0, base_buf) - 1);
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) + 4);
CHECK_THROWS(Span0(base_buf, 4, base_buf) + 5);
CHECK_THROWS(Span0(base_buf - 1, 4, base_buf));
CHECK_THROWS(Span0(base_buf + 1, 0, base_buf));
// basic same base
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 3, base_buf));
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 1, base_buf));
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 5, base_buf));
CHECK_THROWS(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 3, base_buf + 1));
Span0 a1(nullptr);
assert(a1 == nullptr);
assert(a1.raw_ptr() == nullptr);
assert(a1.raw_base() == nullptr);
assert(a1.raw_size_in_bytes() == 0u);
CHECK_THROWS(*a1);
CHECK_THROWS(a1[0]);
Span0 a2 = nullptr;
assert(a2 == nullptr);
assert(a2.raw_ptr() == nullptr);
assert(a2.raw_base() == nullptr);
assert(a2.raw_size_in_bytes() == 0u);
CHECK_THROWS(*a2);
CHECK_THROWS(a2[0]);
Span0 base0(nullptr, 4, base_buf);
assert(base0.raw_ptr() == nullptr);
assert(base0.raw_base() == base_buf);
assert(base0.raw_size_in_bytes() == 4u);
CHECK_THROWS(*base0); // nullptr
CHECK_THROWS(base0[0]); // nullptr
CHECK_THROWS(base0 + 1); // nullptr
Span0 base4(base_buf, 4);
assert(base4.raw_ptr() == base_buf);
assert(base4.raw_base() == base_buf);
assert(base4.raw_size_in_bytes() == 4u);
a1 = base_buf;
a1 = base0;
assert(a1 == nullptr);
assert(a1.raw_ptr() == nullptr);
assert(a1.raw_base() == base_buf);
assert(a1.raw_size_in_bytes() == 4u);
a1 = base4;
assert(a1 == base_buf);
assert(a1.raw_ptr() == base_buf);
assert(a1.raw_base() == base_buf);
assert(a1.raw_size_in_bytes() == 4u);
a1 = base_buf;
assert(a1 != nullptr);
a1 = base_buf + 1;
CHECK(*a1++ == 1);
CHECK(*++a1 == 3);
CHECK(*a1 == 3);
a1 = base_buf + 4; // at the end of buffer
CHECK_THROWS(*a1);
CHECK_THROWS(a1 = base_buf + 5); // range error
assert(a1 == base_buf + 4);
CHECK(a1[-4] == 0);
CHECK_THROWS(a1[-5]); // range error
a1 = base_buf;
CHECK(*a1 == 0);
Span0 new_base4(base_buf + 2, 4);
CHECK_THROWS(a1 = new_base4); // not same base
a2 = new_base4;
CHECK_THROWS(a2 = base4); // not same base
Span0 s0_no_base(nullptr);
Span0 s0_with_base(nullptr, 4, base_buf);
s0_no_base = nullptr;
s0_with_base = nullptr;
s0_with_base = s0_no_base;
assert(s0_no_base.raw_base() == nullptr);
assert(s0_with_base.raw_base() == base_buf);
s0_no_base = s0_with_base;
assert(s0_no_base.raw_base() == base_buf);
assert(s0_no_base.raw_ptr() == nullptr);
assert(s0_with_base.raw_ptr() == nullptr);
s0_no_base = my_null;
s0_with_base = my_null;
}
/*************************************************************************
//
**************************************************************************/
TEST_CASE("PtrOrSpan") {
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
char *base_buf = real_buf + 2;
char *const my_null = nullptr;
typedef PtrOrSpan<char> SpanP;
// basic nullptr
CHECK_THROWS(SpanP(base_buf, 4, base_buf) = my_null);
CHECK_THROWS(SpanP(base_buf, 4, base_buf).assign(my_null));
// basic range checking
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf));
CHECK_NOTHROW(SpanP(base_buf, 0, base_buf));
CHECK_NOTHROW(SpanP(base_buf, 0, base_buf) - 0);
CHECK_THROWS(SpanP(base_buf, 0, base_buf) + 1);
CHECK_THROWS(SpanP(base_buf, 0, base_buf) - 1);
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) + 4);
CHECK_THROWS(SpanP(base_buf, 4, base_buf) + 5);
CHECK_THROWS(SpanP(base_buf - 1, 4, base_buf));
CHECK_THROWS(SpanP(base_buf + 1, 0, base_buf));
// basic same base
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 3, base_buf));
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 1, base_buf));
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 5, base_buf));
CHECK_THROWS(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 3, base_buf + 1));
SpanP x1(base_buf, 0);
assert(x1 != nullptr);
assert(x1.raw_ptr() == base_buf);
assert(x1.raw_base() == base_buf);
assert(x1.raw_size_in_bytes() == 0u);
CHECK_THROWS(*x1);
CHECK_THROWS(x1[0]);
SpanP a2 = base_buf;
assert(a2 != nullptr);
assert(a2.raw_ptr() == base_buf);
assert(a2.raw_base() == nullptr);
assert(a2.raw_size_in_bytes() == 0u);
CHECK(*a2 == 0);
CHECK(a2[1] == 1);
SpanP base0(base_buf, 4, base_buf);
assert(base0.raw_ptr() == base_buf);
assert(base0.raw_base() == base_buf);
assert(base0.raw_size_in_bytes() == 4u);
SpanP base4(base_buf, 4);
assert(base4.raw_ptr() == base_buf);
assert(base4.raw_base() == base_buf);
assert(base4.raw_size_in_bytes() == 4u);
SpanP a1(base_buf, 4);
a1 = base_buf;
a1 = base0;
assert(a1 == base0);
assert(a1 != nullptr);
assert(a1.raw_ptr() == base0.raw_ptr());
assert(a1.raw_base() == base_buf);
assert(a1.raw_size_in_bytes() == 4u);
a1 = base4;
assert(a1 == base_buf);
assert(a1.raw_ptr() == base_buf);
assert(a1.raw_base() == base_buf);
assert(a1.raw_size_in_bytes() == 4u);
a1 = base_buf;
a1 = base_buf + 1;
CHECK(*a1++ == 1);
CHECK(*++a1 == 3);
CHECK(*a1 == 3);
a1 = base_buf + 4; // at the end of buffer
CHECK_THROWS(*a1);
CHECK_THROWS(a1 = base_buf + 5); // range error
assert(a1 == base_buf + 4);
CHECK(a1[-4] == 0);
CHECK_THROWS(a1[-5]); // range error
a1 = base_buf;
CHECK(*a1 == 0);
SpanP new_base4(base_buf + 2, 4);
CHECK_THROWS(a1 = new_base4); // not same base
a2 = new_base4;
CHECK_THROWS(a2 = base4); // not same base
SpanP sp_no_base(base_buf);
SpanP sp_with_base(base_buf, 4, base_buf);
assert(sp_no_base.raw_base() == nullptr);
assert(sp_with_base.raw_base() == base_buf);
CHECK_THROWS(sp_no_base = my_null); // nullptr assignment
CHECK_THROWS(sp_with_base = my_null); // nullptr assignment
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
typedef PtrOrSpanOrNull<char> Span0;
Span0 s0_no_base(nullptr);
Span0 s0_with_base(nullptr, 4, base_buf);
CHECK_THROWS(sp_no_base = s0_no_base); // nullptr assignment
CHECK_THROWS(sp_no_base = s0_with_base); // nullptr assignment
CHECK_THROWS(sp_with_base = s0_no_base); // nullptr assignment
CHECK_THROWS(sp_with_base = s0_with_base); // nullptr assignment
#endif
}
/*************************************************************************
//
**************************************************************************/
TEST_CASE("Span") {
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
char *base_buf = real_buf + 2;
char *const my_null = nullptr;
typedef Span<char> SpanS;
// basic nullptr
CHECK_THROWS(SpanS(base_buf, 4, base_buf) = my_null);
CHECK_THROWS(SpanS(base_buf, 4, base_buf).assign(my_null));
// basic range checking
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf));
CHECK_NOTHROW(SpanS(base_buf, 0, base_buf));
CHECK_NOTHROW(SpanS(base_buf, 0, base_buf) - 0);
CHECK_THROWS(SpanS(base_buf, 0, base_buf) + 1);
CHECK_THROWS(SpanS(base_buf, 0, base_buf) - 1);
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) + 4);
CHECK_THROWS(SpanS(base_buf, 4, base_buf) + 5);
CHECK_THROWS(SpanS(base_buf - 1, 4, base_buf));
CHECK_THROWS(SpanS(base_buf + 1, 0, base_buf));
// basic same base
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 3, base_buf));
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 1, base_buf));
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 5, base_buf));
CHECK_THROWS(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 3, base_buf + 1));
SpanS x1(base_buf, 0);
assert(x1 != nullptr);
assert(x1.raw_ptr() == base_buf);
assert(x1.raw_base() == base_buf);
assert(x1.raw_size_in_bytes() == 0u);
CHECK_THROWS(*x1);
CHECK_THROWS(x1[0]);
SpanS a2(base_buf, 4);
assert(a2 != nullptr);
assert(a2.raw_ptr() == base_buf);
assert(a2.raw_base() == base_buf);
assert(a2.raw_size_in_bytes() == 4u);
CHECK(*a2 == 0);
CHECK(a2[1] == 1);
SpanS base0(base_buf, 4, base_buf);
assert(base0.raw_ptr() == base_buf);
assert(base0.raw_base() == base_buf);
assert(base0.raw_size_in_bytes() == 4u);
SpanS base4(base_buf, 4);
assert(base4.raw_ptr() == base_buf);
assert(base4.raw_base() == base_buf);
assert(base4.raw_size_in_bytes() == 4u);
SpanS a1(base_buf, 4);
a1 = base_buf;
a1 = base0;
assert(a1 == base0);
assert(a1 != nullptr);
assert(a1.raw_ptr() == base0.raw_ptr());
assert(a1.raw_base() == base_buf);
assert(a1.raw_size_in_bytes() == 4u);
a1 = base4;
assert(a1 == base_buf);
assert(a1.raw_ptr() == base_buf);
assert(a1.raw_base() == base_buf);
assert(a1.raw_size_in_bytes() == 4u);
a1 = base_buf;
a1 = base_buf + 1;
CHECK(*a1++ == 1);
CHECK(*++a1 == 3);
CHECK(*a1 == 3);
a1 = base_buf + 4; // at the end of buffer
CHECK_THROWS(*a1);
CHECK_THROWS(a1 = base_buf + 5); // range error
assert(a1 == base_buf + 4);
CHECK(a1[-4] == 0);
CHECK_THROWS(a1[-5]); // range error
a1 = base_buf;
CHECK(*a1 == 0);
SpanS new_base4(base_buf + 2, 4);
CHECK_THROWS(a1 = new_base4); // not same base
CHECK_THROWS(a2 = new_base4); // not same base
SpanS ss_with_base(base_buf, 4, base_buf);
assert(ss_with_base.raw_base() == base_buf);
CHECK_THROWS(ss_with_base = my_null); // nullptr assignment
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
{
typedef PtrOrSpanOrNull<char> Span0;
// v0 nullptr, b0 base, b1 base + 1
const Span0 v0_v0(nullptr);
const Span0 v0_b0(nullptr, 4, base_buf);
const Span0 v0_b1(nullptr, 3, base_buf + 1);
const Span0 b0_v0(base_buf);
const Span0 b0_b0(base_buf, 4, base_buf);
CHECK_THROWS(XSPAN_0_MAKE(char, base_buf, 3, base_buf + 1)); // b0_b1
const Span0 b1_v0(base_buf + 1);
const Span0 b1_b0(base_buf + 1, 4, base_buf);
const Span0 b1_b1(base_buf + 1, 3, base_buf + 1);
CHECK_THROWS(ss_with_base = v0_v0); // nullptr assignment
CHECK_THROWS(ss_with_base = v0_b0); // nullptr assignment
CHECK_THROWS(ss_with_base = v0_b1); // nullptr assignment
CHECK_NOTHROW(ss_with_base = b0_v0);
CHECK_NOTHROW(ss_with_base = b0_b0);
CHECK_NOTHROW(ss_with_base = b1_v0);
CHECK_NOTHROW(ss_with_base = b1_b0);
CHECK_THROWS(ss_with_base = b1_b1); // different base
CHECK_THROWS(XSPAN_S_MAKE(char, v0_v0));
CHECK_THROWS(XSPAN_S_MAKE(char, v0_b0));
CHECK_THROWS(XSPAN_S_MAKE(char, v0_b1));
CHECK_THROWS(XSPAN_S_MAKE(char, b0_v0));
CHECK_NOTHROW(XSPAN_S_MAKE(char, b0_b0));
CHECK_THROWS(XSPAN_S_MAKE(char, b1_v0));
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b0));
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b1));
//
CHECK((XSPAN_S_MAKE(char, b0_b0).raw_base() == base_buf));
CHECK((XSPAN_S_MAKE(char, b1_b0).raw_base() == base_buf));
CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
}
{
typedef PtrOrSpan<char> SpanP;
// v0 nullptr, b0 base, b1 base + 1
const SpanP b0_v0(base_buf);
const SpanP b0_b0(base_buf, 4, base_buf);
CHECK_THROWS(XSPAN_P_MAKE(char, base_buf, 3, base_buf + 1)); // b0_b1
const SpanP b1_v0(base_buf + 1);
const SpanP b1_b0(base_buf + 1, 4, base_buf);
const SpanP b1_b1(base_buf + 1, 3, base_buf + 1);
CHECK_NOTHROW(ss_with_base = b0_v0);
CHECK_NOTHROW(ss_with_base = b0_b0);
CHECK_NOTHROW(ss_with_base = b1_v0);
CHECK_NOTHROW(ss_with_base = b1_b0);
CHECK_THROWS(ss_with_base = b1_b1); // different base
CHECK_THROWS(XSPAN_S_MAKE(char, b0_v0));
CHECK_NOTHROW(XSPAN_S_MAKE(char, b0_b0));
CHECK_THROWS(XSPAN_S_MAKE(char, b1_v0));
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b0));
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b1));
//
CHECK((XSPAN_S_MAKE(char, b0_b0).raw_base() == base_buf));
CHECK((XSPAN_S_MAKE(char, b1_b0).raw_base() == base_buf));
CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
}
#endif
}
/*************************************************************************
//
**************************************************************************/
TEST_CASE("Span void ptr") {
static char a[4] = {0, 1, 2, 3};
XSPAN_0(void) a0(a, 4);
XSPAN_P(void) ap(a, 4);
XSPAN_S(void) as(a, 4);
XSPAN_0(const void) c0(a, 4);
XSPAN_P(const void) cp(a, 4);
XSPAN_S(const void) cs(a, 4);
static const char b[4] = {0, 1, 2, 3};
XSPAN_0(const void) b0(b, 4);
XSPAN_P(const void) bp(b, 4);
XSPAN_S(const void) bs(b, 4);
}
TEST_CASE("Span deref/array/arrow") {
static char real_a[2 + 4 + 2] = {126, 127, 0, 1, 2, 3, 124, 125};
static char *a = real_a + 2;
XSPAN_0(char) a0(a, 4);
XSPAN_P(char) ap(a, 4);
XSPAN_S(char) as(a, 4);
CHECK_THROWS(a0[4]);
CHECK_THROWS(a0[-1]);
CHECK_THROWS(a0[-2]);
a0 += 2;
CHECK(*a0 == 2);
CHECK(a0[-1] == 1);
CHECK(a0[0] == 2);
CHECK(a0[1] == 3);
ap += 2;
CHECK(*ap == 2);
CHECK(ap[-1] == 1);
CHECK(ap[0] == 2);
CHECK(ap[1] == 3);
as += 2;
CHECK(*as == 2);
CHECK(as[-1] == 1);
CHECK(as[0] == 2);
CHECK(as[1] == 3);
}
TEST_CASE("Span subspan") {
static char buf[4] = {0, 1, 2, 3};
XSPAN_S(char) as(buf, 4);
CHECK(as.subspan(1, 1)[0] == 1);
CHECK((as + 1).subspan(1, 1)[0] == 2);
CHECK((as + 2).subspan(0, -2)[0] == 0);
CHECK_THROWS(as.subspan(1, 0)[0]);
CHECK_THROWS(as.subspan(1, 1)[-1]);
}
TEST_CASE("Span constness") {
static char buf[4] = {0, 1, 2, 3};
XSPAN_0(char) b0(buf, 4);
XSPAN_P(char) bp(buf, 4);
XSPAN_S(char) bs(buf, 4);
XSPAN_0(char) s0(b0);
XSPAN_P(char) sp(bp);
XSPAN_S(char) ss(bs);
XSPAN_0(const char) b0c(buf, 4);
XSPAN_P(const char) bpc(buf, 4);
XSPAN_S(const char) bsc(buf, 4);
XSPAN_0(const char) s0c(b0c);
XSPAN_P(const char) spc(bpc);
XSPAN_S(const char) ssc(bsc);
XSPAN_0(const char) x0c(b0);
XSPAN_P(const char) xpc(bp);
XSPAN_S(const char) xsc(bs);
CHECK(ptr_diff_bytes(b0, buf) == 0);
CHECK(ptr_diff_bytes(bp, buf) == 0);
CHECK(ptr_diff_bytes(bs, buf) == 0);
CHECK(ptr_diff_bytes(s0, buf) == 0);
CHECK(ptr_diff_bytes(sp, buf) == 0);
CHECK(ptr_diff_bytes(bs, buf) == 0);
//
CHECK(ptr_diff_bytes(s0, bp) == 0);
CHECK(ptr_diff_bytes(s0, sp) == 0);
CHECK(ptr_diff_bytes(s0, ss) == 0);
//
CHECK(ptr_diff_bytes(s0c, b0c) == 0);
CHECK(ptr_diff_bytes(spc, bpc) == 0);
CHECK(ptr_diff_bytes(ssc, bsc) == 0);
}
/*************************************************************************
//
**************************************************************************/
#if !defined(DOCTEST_CONFIG_DISABLE)
namespace {
int my_memcmp_v1(XSPAN_P(const void) a, XSPAN_0(const void) b, size_t n) {
if (b == nullptr)
return -2;
XSPAN_0(const void) x(a);
return memcmp(x, b, n);
}
int my_memcmp_v2(XSPAN_P(const char) a, XSPAN_0(const char) b, size_t n) {
if (a == b)
return 0;
if (b == nullptr)
return -2;
a += 1;
b -= 1;
XSPAN_0(const char) x(a);
XSPAN_0(const char) y = b;
return memcmp(x, y, n);
}
} // namespace
#endif
TEST_CASE("PtrOrSpan") {
static const char buf[4] = {0, 1, 2, 3};
CHECK(my_memcmp_v1(buf, nullptr, 4) == -2);
CHECK(my_memcmp_v2(buf + 4, buf + 4, 999) == 0);
CHECK(my_memcmp_v2(buf, buf + 2, 3) == 0);
}
/*************************************************************************
//
**************************************************************************/
TEST_CASE("PtrOrSpan char") {
char real_buf[2 + 8 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 6, 7, 124, 125};
char *buf = real_buf + 2;
XSPAN_P(char) a(buf, XSpanSizeInBytes(8));
XSPAN_P(char) b = a.subspan(0, 7);
XSPAN_P(char) c = (b + 1).subspan(0, 6);
a += 1;
CHECK(*a == 1);
*a++ += 1;
*b++ = 1;
CHECK(a == buf + 2);
CHECK(b == buf + 1);
CHECK(c == buf + 1);
CHECK(*b == 2);
CHECK(*c == 2);
CHECK(a.raw_size_in_bytes() == 8u);
CHECK(b.raw_size_in_bytes() == 7u);
CHECK(c.raw_size_in_bytes() == 6u);
CHECK(a.raw_base() == buf);
CHECK(b.raw_base() == buf);
CHECK(c.raw_base() == buf + 1);
#ifdef UPX_VERSION_HEX
CHECK(get_le32(a) != 0);
#endif
++c;
c++;
#ifdef UPX_VERSION_HEX
CHECK(get_le32(c) != 0);
#endif
++c;
#ifdef UPX_VERSION_HEX
CHECK_THROWS(get_le32(c));
#endif
++b;
b++;
b += 4;
CHECK(b.raw_ptr() == buf + 7);
CHECK_THROWS(*b);
CHECK(a.raw_size_in_bytes() == 8u);
a = b;
CHECK(a.raw_size_in_bytes() == 8u);
CHECK(a.raw_ptr() == buf + 7);
a++;
CHECK_THROWS(*a);
CHECK_THROWS(raw_bytes(a, 1));
a = b;
CHECK_THROWS(a = c);
*a = 0;
a = buf;
#ifdef UPX_VERSION_HEX
CHECK(upx_safe_strlen(a) == 7u);
#endif
}
TEST_CASE("PtrOrSpan int") {
int buf[8] = {0, 1, 2, 3, 4, 5, 6, 7};
XSPAN_P(int) a(buf, XSpanCount(8));
CHECK(a.raw_size_in_bytes() == 8 * sizeof(int));
XSPAN_P(int) b = a.subspan(0, 7);
CHECK(b.raw_size_in_bytes() == 7 * sizeof(int));
XSPAN_P(int) c = (b + 1).subspan(0, 6);
CHECK(c.raw_size_in_bytes() == 6 * sizeof(int));
a += 1;
CHECK(*a == 1);
CHECK(*a++ == 1);
CHECK(*++a == 3);
CHECK(--*a == 2);
CHECK(*a-- == 2);
CHECK(*b == 0);
CHECK(*c == 1);
a = buf + 7;
#ifdef UPX_VERSION_HEX
CHECK(get_le32(a) == ne32_to_le32(7));
#endif
a++;
#ifdef UPX_VERSION_HEX
CHECK_THROWS(get_le32(a));
#endif
CHECK_THROWS(raw_bytes(a, 1));
}
/*************************************************************************
// codegen
**************************************************************************/
namespace {
template <class T>
__acc_static_noinline int foo(T p) {
unsigned r = 0;
r += *p++;
r += *++p;
p += 3;
r += *p;
return r;
}
template <class T>
XSPAN_0(T)
make_span_0(T *ptr, size_t count) {
return PtrOrSpanOrNull<T>(ptr, count);
}
template <class T>
XSPAN_P(T)
make_span_p(T *ptr, size_t count) {
return PtrOrSpan<T>(ptr, count);
}
template <class T>
XSPAN_S(T)
make_span_s(T *ptr, size_t count) {
return Span<T>(ptr, count);
}
} // namespace
TEST_CASE("Span codegen") {
char buf[8] = {0, 1, 2, 3, 4, 5, 6, 7};
CHECK(foo(buf) == 0 + 2 + 5);
CHECK(foo(make_span_0(buf, 8)) == 0 + 2 + 5);
CHECK(foo(make_span_p(buf, 8)) == 0 + 2 + 5);
CHECK(foo(make_span_s(buf, 8)) == 0 + 2 + 5);
}
#endif // WITH_XSPAN >= 2
/* vim:set ts=4 sw=4 et: */
+44 -54
View File
@@ -2,8 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -21,22 +20,19 @@
If not, write to the Free Software Foundation, Inc., If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar Markus F.X.J. Oberhumer
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com>
*/ */
#include "../conf.h"
#include "conf.h"
#include "compress.h" #include "compress.h"
#include "util/membuffer.h" #include "../util/membuffer.h"
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) {
{
if (len == 0) if (len == 0)
return adler; return adler;
assert(buf != nullptr); assert(buf != nullptr);
@@ -47,8 +43,7 @@ unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
#endif #endif
} }
#if 0 // UNUSED
#if 0 /* UNUSED */
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc) unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
{ {
if (len == 0) if (len == 0)
@@ -60,24 +55,20 @@ unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
return upx_zlib_crc32(buf, len, crc); return upx_zlib_crc32(buf, len, crc);
#endif #endif
} }
#endif /* UNUSED */ #endif // UNUSED
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int upx_compress( const upx_bytep src, unsigned src_len, int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_bytep dst, unsigned* dst_len, upx_callback_p cb, int method, int level, const upx_compress_config_t *cconf,
upx_callback_p cb, upx_compress_result_t *cresult) {
int method, int level,
const upx_compress_config_t *cconf,
upx_compress_result_t *cresult )
{
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
upx_compress_result_t cresult_buffer; upx_compress_result_t cresult_buffer;
assert(method > 0); assert(level > 0); assert(method > 0);
assert(level > 0);
#if 1 #if 1
// set available bytes in dst // set available bytes in dst
@@ -94,60 +85,57 @@ int upx_compress( const upx_bytep src, unsigned src_len,
cresult = &cresult_buffer; cresult = &cresult_buffer;
memset(cresult, 0, sizeof(*cresult)); memset(cresult, 0, sizeof(*cresult));
#if 1 #if 1
// debug // debugging aid
cresult->method = method; cresult->debug.method = method;
cresult->level = level; cresult->debug.level = level;
cresult->u_len = src_len; cresult->debug.u_len = src_len;
cresult->c_len = 0; cresult->debug.c_len = 0;
#endif #endif
if __acc_cte(0) { if (__acc_cte(false)) {
} }
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
r = upx_lzma_compress(src, src_len, dst, dst_len, r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
cb, method, level, cconf, cresult);
#endif #endif
#if (WITH_NRV) #if (WITH_NRV)
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl) else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
r = upx_nrv_compress(src, src_len, dst, dst_len, r = upx_nrv_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
cb, method, level, cconf, cresult);
#endif #endif
#if (WITH_UCL) #if (WITH_UCL)
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
r = upx_ucl_compress(src, src_len, dst, dst_len, r = upx_ucl_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
cb, method, level, cconf, cresult); #endif
#if (WITH_ZSTD)
else if (M_IS_ZSTD(method))
r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
#endif #endif
else { else {
throwInternalError("unknown compression method"); throwInternalError("unknown compression method");
} }
#if 1 #if 1
// debug // debugging aid
cresult->c_len = *dst_len; cresult->debug.c_len = *dst_len;
#endif #endif
return r; return r;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int upx_decompress(const upx_bytep src, unsigned src_len, int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_bytep dst, unsigned* dst_len, int method, const upx_compress_result_t *cresult) {
int method,
const upx_compress_result_t *cresult )
{
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
assert(*dst_len > 0); assert(*dst_len > 0);
assert(src_len < *dst_len); // must be compressed assert(src_len < *dst_len); // must be compressed
if (cresult && cresult->method == 0) if (cresult && cresult->debug.method == 0)
cresult = nullptr; cresult = nullptr;
if __acc_cte(0) { if (__acc_cte(false)) {
} }
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
@@ -164,6 +152,10 @@ int upx_decompress(const upx_bytep src, unsigned src_len,
#if (WITH_ZLIB) #if (WITH_ZLIB)
else if (M_IS_DEFLATE(method)) else if (M_IS_DEFLATE(method))
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult); r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
#endif
#if (WITH_ZSTD)
else if (M_IS_ZSTD(method))
r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult);
#endif #endif
else { else {
throwInternalError("unknown decompression method"); throwInternalError("unknown decompression method");
@@ -172,21 +164,15 @@ int upx_decompress(const upx_bytep src, unsigned src_len,
return r; return r;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int upx_test_overlap( const upx_bytep buf, int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off, unsigned src_len,
const upx_bytep tbuf, unsigned *dst_len, int method, const upx_compress_result_t *cresult) {
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method,
const upx_compress_result_t *cresult )
{
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
if (cresult && cresult->method == 0) if (cresult && cresult->debug.method == 0)
cresult = nullptr; cresult = nullptr;
assert(*dst_len > 0); assert(*dst_len > 0);
@@ -194,7 +180,7 @@ int upx_test_overlap( const upx_bytep buf,
unsigned overlap_overhead = src_off + src_len - *dst_len; unsigned overlap_overhead = src_off + src_len - *dst_len;
assert((int) overlap_overhead > 0); assert((int) overlap_overhead > 0);
if __acc_cte(0) { if (__acc_cte(false)) {
} }
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
@@ -207,6 +193,10 @@ int upx_test_overlap( const upx_bytep buf,
#if (WITH_UCL) #if (WITH_UCL)
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult); r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif
#if (WITH_ZSTD)
else if (M_IS_ZSTD(method))
r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif #endif
else { else {
throwInternalError("unknown decompression method"); throwInternalError("unknown decompression method");
+50 -8
View File
@@ -2,8 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -21,19 +20,40 @@
If not, write to the Free Software Foundation, Inc., If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar Markus F.X.J. Oberhumer
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com>
*/ */
#pragma once
#ifndef __UPX_COMPRESS_H #ifndef UPX_COMPRESS_H__
#define __UPX_COMPRESS_H 1 #define UPX_COMPRESS_H__ 1
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#if (WITH_BZIP2)
int upx_bzip2_init(void);
const char *upx_bzip2_version_string(void);
int upx_bzip2_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
int method, int level,
const upx_compress_config_t *cconf,
upx_compress_result_t *cresult );
int upx_bzip2_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult );
int upx_bzip2_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method,
const upx_compress_result_t *cresult );
#endif
#if (WITH_LZMA) #if (WITH_LZMA)
int upx_lzma_init(void); int upx_lzma_init(void);
const char *upx_lzma_version_string(void); const char *upx_lzma_version_string(void);
@@ -126,6 +146,28 @@ unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
#endif #endif
#if (WITH_ZSTD)
int upx_zstd_init(void);
const char *upx_zstd_version_string(void);
int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
int method, int level,
const upx_compress_config_t *cconf,
upx_compress_result_t *cresult );
int upx_zstd_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult );
int upx_zstd_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method,
const upx_compress_result_t *cresult );
#endif
#endif /* already included */ #endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
@@ -2,8 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -21,14 +20,13 @@
If not, write to the Free Software Foundation, Inc., If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar Markus F.X.J. Oberhumer
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com>
*/ */
#include "../conf.h"
#include "conf.h"
#include "compress.h" #include "compress.h"
#include "util/membuffer.h" #include "../util/membuffer.h"
#if (ACC_CC_CLANG) #if (ACC_CC_CLANG)
#pragma clang diagnostic ignored "-Wshadow" #pragma clang diagnostic ignored "-Wshadow"
@@ -42,13 +40,8 @@
#if (ACC_CC_MSC && (_MSC_VER < 1900)) #if (ACC_CC_MSC && (_MSC_VER < 1900))
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant #pragma warning(disable : 4127) // warning C4127: conditional expression is constant
#endif #endif
#if (ACC_CC_INTELC_GNUC)
# pragma warning(error: 424) // #424: extra ";" ignored
#endif
void lzma_compress_config_t::reset() {
void lzma_compress_config_t::reset()
{
pos_bits.reset(); pos_bits.reset();
lit_pos_bits.reset(); lit_pos_bits.reset();
lit_context_bits.reset(); lit_context_bits.reset();
@@ -60,7 +53,6 @@ void lzma_compress_config_t::reset()
max_num_probs = 0; max_num_probs = 0;
} }
// INFO: the LZMA SDK is covered by a permissive license which allows // INFO: the LZMA SDK is covered by a permissive license which allows
// using unmodified LZMA source code in UPX and the UPX stubs. // using unmodified LZMA source code in UPX and the UPX stubs.
// See SPECIAL EXCEPTION below. // See SPECIAL EXCEPTION below.
@@ -97,21 +89,18 @@ void lzma_compress_config_t::reset()
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code, // SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
// while you keep LZMA SDK code unmodified. // while you keep LZMA SDK code unmodified.
/************************************************************************* /*************************************************************************
// compress defaults // compress defaults
**************************************************************************/ **************************************************************************/
static int prepare(lzma_compress_result_t *res, static bool prepare_result(lzma_compress_result_t *res, unsigned src_len, int method, int level,
unsigned src_len, int method, int level, const lzma_compress_config_t *lcconf) {
const lzma_compress_config_t *lcconf)
{
// setup defaults // setup defaults
res->pos_bits = 2; // 0 .. 4 res->pos_bits = 2; // 0 .. 4
res->lit_pos_bits = 0; // 0 .. 4 res->lit_pos_bits = 0; // 0 .. 4
res->lit_context_bits = 3; // 0 .. 8 res->lit_context_bits = 3; // 0 .. 8
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30 res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
res->fast_mode = 2; res->fast_mode = 2; // 0 .. 2
res->num_fast_bytes = 64; // 5 .. 273 res->num_fast_bytes = 64; // 5 .. 273
res->match_finder_cycles = 0; res->match_finder_cycles = 0;
// UPX overrides // UPX overrides
@@ -135,8 +124,7 @@ static int prepare(lzma_compress_result_t *res,
#endif #endif
// TODO: tune these settings according to level // TODO: tune these settings according to level
switch (level) switch (level) {
{
case 1: case 1:
res->dict_size = 256 * 1024; res->dict_size = 256 * 1024;
res->fast_mode = 0; res->fast_mode = 0;
@@ -169,8 +157,7 @@ static int prepare(lzma_compress_result_t *res,
} }
// cconf overrides // cconf overrides
if (lcconf) if (lcconf) {
{
oassign(res->pos_bits, lcconf->pos_bits); oassign(res->pos_bits, lcconf->pos_bits);
oassign(res->lit_pos_bits, lcconf->lit_pos_bits); oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
oassign(res->lit_context_bits, lcconf->lit_context_bits); oassign(res->lit_context_bits, lcconf->lit_context_bits);
@@ -183,21 +170,16 @@ static int prepare(lzma_compress_result_t *res,
res->dict_size = src_len; res->dict_size = src_len;
// limit num_probs // limit num_probs
if (lcconf && lcconf->max_num_probs) if (lcconf && lcconf->max_num_probs) {
{ for (;;) {
for (;;)
{
unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits)); unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
if (n <= lcconf->max_num_probs) if (n <= lcconf->max_num_probs)
break; break;
if (res->lit_pos_bits > res->lit_context_bits) if (res->lit_pos_bits > res->lit_context_bits) {
{
if (res->lit_pos_bits == 0) if (res->lit_pos_bits == 0)
goto error; goto error;
res->lit_pos_bits -= 1; res->lit_pos_bits -= 1;
} } else {
else
{
if (res->lit_context_bits == 0) if (res->lit_context_bits == 0)
goto error; goto error;
res->lit_context_bits -= 1; res->lit_context_bits -= 1;
@@ -212,14 +194,14 @@ static int prepare(lzma_compress_result_t *res,
lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes); lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes);
res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits)); res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs); // printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
return 0; // res->lit_context_bits, res->dict_size, res->num_probs);
return true;
error: error:
return -1; return false;
} }
/************************************************************************* /*************************************************************************
// compress - cruft because of pseudo-COM layer // compress - cruft because of pseudo-COM layer
**************************************************************************/ **************************************************************************/
@@ -238,69 +220,80 @@ error:
namespace MyLzma { namespace MyLzma {
struct InStream: public ISequentialInStream, public CMyUnknownImp struct InStream final : public ISequentialInStream, public CMyUnknownImp {
{
virtual ~InStream() {} virtual ~InStream() {}
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
const Byte *b_buf; size_t b_size; size_t b_pos; const Byte *b_buf = nullptr;
size_t b_size;
size_t b_pos;
void Init(const Byte *data, size_t size) { void Init(const Byte *data, size_t size) {
b_buf = data; b_size = size; b_pos = 0; b_buf = data;
b_size = size;
b_pos = 0;
} }
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override; STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override;
}; };
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize) {
{
size_t remain = b_size - b_pos; size_t remain = b_size - b_pos;
if (size > remain) size = (UInt32) remain; if (size > remain)
size = (UInt32) remain;
memmove(data, b_buf + b_pos, size); memmove(data, b_buf + b_pos, size);
b_pos += size; b_pos += size;
if (processedSize != nullptr) *processedSize = size; if (processedSize != nullptr)
*processedSize = size;
return S_OK; return S_OK;
} }
struct OutStream : public ISequentialOutStream, public CMyUnknownImp struct OutStream final : public ISequentialOutStream, public CMyUnknownImp {
{
virtual ~OutStream() {} virtual ~OutStream() {}
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
Byte *b_buf; size_t b_size; size_t b_pos; bool overflow; Byte *b_buf = nullptr;
size_t b_size;
size_t b_pos;
bool overflow;
void Init(Byte *data, size_t size) { void Init(Byte *data, size_t size) {
b_buf = data; b_size = size; b_pos = 0; overflow = false; b_buf = data;
b_size = size;
b_pos = 0;
overflow = false;
} }
HRESULT WriteByte(Byte c) { HRESULT WriteByte(Byte c) {
if (b_pos >= b_size) { overflow = true; return E_FAIL; } if (b_pos >= b_size) {
overflow = true;
return E_FAIL;
}
b_buf[b_pos++] = c; b_buf[b_pos++] = c;
return S_OK; return S_OK;
} }
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override; STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override;
}; };
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) {
{
size_t remain = b_size - b_pos; size_t remain = b_size - b_pos;
if (size > remain) size = (UInt32) remain, overflow = true; if (size > remain)
size = (UInt32) remain, overflow = true;
memmove(b_buf + b_pos, data, size); memmove(b_buf + b_pos, data, size);
b_pos += size; b_pos += size;
if (processedSize != nullptr) *processedSize = size; if (processedSize != nullptr)
*processedSize = size;
return overflow ? E_FAIL : S_OK; return overflow ? E_FAIL : S_OK;
} }
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp struct ProgressInfo final : public ICompressProgressInfo, public CMyUnknownImp {
{
virtual ~ProgressInfo() {} virtual ~ProgressInfo() {}
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override; STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
upx_callback_p cb; upx_callback_p cb = nullptr;
}; };
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
{
if (cb && cb->nprogress) if (cb && cb->nprogress)
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize); cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
return S_OK; return S_OK;
} }
} // namespace } // namespace MyLzma
#include <lzma-sdk/C/Common/Alloc.cpp> #include <lzma-sdk/C/Common/Alloc.cpp>
#include <lzma-sdk/C/Common/CRC.cpp> #include <lzma-sdk/C/Common/CRC.cpp>
@@ -314,29 +307,27 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp> #include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
#undef RC_NORMALIZE #undef RC_NORMALIZE
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
int upx_lzma_compress ( const upx_bytep src, unsigned src_len, upx_callback_p cb, int method, int level,
upx_bytep dst, unsigned* dst_len, const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
upx_callback_p cb,
int method, int level,
const upx_compress_config_t *cconf_parm,
upx_compress_result_t *cresult )
{
assert(M_IS_LZMA(method)); assert(M_IS_LZMA(method));
assert(level > 0); assert(cresult != nullptr); assert(level > 0);
assert(cresult != nullptr);
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
HRESULT rh; HRESULT rh;
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr; const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
lzma_compress_result_t *res = &cresult->result_lzma; lzma_compress_result_t *const res = &cresult->result_lzma;
MyLzma::InStream is; is.AddRef(); MyLzma::InStream is;
MyLzma::OutStream os; os.AddRef(); is.AddRef();
is.Init(src, src_len); is.Init(src, src_len);
MyLzma::OutStream os;
os.AddRef();
os.Init(dst, *dst_len); os.Init(dst, *dst_len);
MyLzma::ProgressInfo progress;
MyLzma::ProgressInfo progress; progress.AddRef(); progress.AddRef();
progress.cb = cb; progress.cb = cb; // progress.Init()
NCompress::NLZMA::CEncoder enc; NCompress::NLZMA::CEncoder enc;
const PROPID propIDs[8] = { const PROPID propIDs[8] = {
@@ -351,13 +342,10 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
}; };
PROPVARIANT pr[8]; PROPVARIANT pr[8];
const unsigned nprops = 8; const unsigned nprops = 8;
static const wchar_t matchfinder[] = L"BT4"; if (!prepare_result(res, src_len, method, level, lcconf))
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
pr[7].vt = VT_BSTR; pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
if (prepare(res, src_len, method, level, lcconf) != 0)
goto error; goto error;
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
pr[7].vt = VT_BSTR;
pr[0].uintVal = res->pos_bits; pr[0].uintVal = res->pos_bits;
pr[1].uintVal = res->lit_pos_bits; pr[1].uintVal = res->lit_pos_bits;
pr[2].uintVal = res->lit_context_bits; pr[2].uintVal = res->lit_context_bits;
@@ -365,11 +353,14 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
pr[4].uintVal = res->fast_mode; pr[4].uintVal = res->fast_mode;
pr[5].uintVal = res->num_fast_bytes; pr[5].uintVal = res->num_fast_bytes;
pr[6].uintVal = res->match_finder_cycles; pr[6].uintVal = res->match_finder_cycles;
static const wchar_t matchfinder[] = L"BT4";
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
try { try {
if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK) if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK)
goto error; goto error;
// encode properties in LZMA-style (5 bytes)
if (enc.WriteCoderProperties(&os) != S_OK) if (enc.WriteCoderProperties(&os) != S_OK)
goto error; goto error;
if (os.overflow) { if (os.overflow) {
@@ -378,12 +369,15 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
goto error; goto error;
} }
assert(os.b_pos == 5); assert(os.b_pos == 5);
// reset and encode properties in UPX-style (2 bytes)
os.b_pos = 0; os.b_pos = 0;
// extra stuff in first byte: 5 high bits convenience for stub decompressor // UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
unsigned t = res->lit_context_bits + res->lit_pos_bits; unsigned t = res->lit_context_bits + res->lit_pos_bits;
os.WriteByte(Byte((t << 3) | res->pos_bits)); os.WriteByte(Byte((t << 3) | res->pos_bits));
os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits))); os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits)));
// compress
rh = enc.Code(&is, &os, nullptr, nullptr, &progress); rh = enc.Code(&is, &os, nullptr, nullptr, &progress);
} catch (...) { } catch (...) {
@@ -394,26 +388,24 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
assert(os.b_pos <= *dst_len); assert(os.b_pos <= *dst_len);
if (rh == E_OUTOFMEMORY) if (rh == E_OUTOFMEMORY)
r = UPX_E_OUT_OF_MEMORY; r = UPX_E_OUT_OF_MEMORY;
else if (os.overflow) else if (os.overflow) {
{
assert(os.b_pos == *dst_len); assert(os.b_pos == *dst_len);
// r = UPX_E_OUTPUT_OVERRUN; // r = UPX_E_OUTPUT_OVERRUN;
r = UPX_E_NOT_COMPRESSIBLE; r = UPX_E_NOT_COMPRESSIBLE;
} } else if (rh == S_OK) {
else if (rh == S_OK)
{
assert(is.b_pos == src_len); assert(is.b_pos == src_len);
r = UPX_E_OK; r = UPX_E_OK;
} }
error: error:
*dst_len = (unsigned) os.b_pos; *dst_len = (unsigned) os.b_pos;
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len); // printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits,
// res->lit_pos_bits,
// res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
// printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount); // printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
return r; return r;
} }
/************************************************************************* /*************************************************************************
// decompress // decompress
**************************************************************************/ **************************************************************************/
@@ -425,60 +417,67 @@ error:
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h> #include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h>
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c> #include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c>
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len, int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_bytep dst, unsigned* dst_len, int method, const upx_compress_result_t *cresult) {
int method,
const upx_compress_result_t *cresult )
{
assert(M_IS_LZMA(method)); assert(M_IS_LZMA(method));
// see res->num_probs above // see res->num_probs above
COMPILE_TIME_ASSERT(sizeof(CProb) == 2) COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846) COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768) COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
CLzmaDecoderState s; memset(&s, 0, sizeof(s)); CLzmaDecoderState s;
memset(&s, 0, sizeof(s));
SizeT src_out = 0, dst_out = 0; SizeT src_out = 0, dst_out = 0;
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
int rh; int rh;
if (src_len < 3) // decode UPX-style properties (2 bytes)
if (src_len < 3) {
r = UPX_E_INPUT_OVERRUN;
goto error; goto error;
}
s.Properties.pb = src[0] & 7; s.Properties.pb = src[0] & 7;
s.Properties.lp = (src[1] >> 4); s.Properties.lp = (src[1] >> 4);
s.Properties.lc = src[1] & 15; s.Properties.lc = src[1] & 15;
if (s.Properties.pb >= 5) goto error; if (s.Properties.pb >= 5)
if (s.Properties.lp >= 5) goto error; goto error;
if (s.Properties.lc >= 9) goto error; if (s.Properties.lp >= 5)
// extra goto error;
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error; if (s.Properties.lc >= 9)
src += 2; src_len -= 2; goto error;
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp)
goto error;
src += 2;
src_len -= 2;
if (cresult) if (cresult) {
{ assert(cresult->debug.method == method);
assert(cresult->method == method);
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb); assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp); assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc); assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties)); assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
const lzma_compress_result_t *res = &cresult->result_lzma; const lzma_compress_result_t *res = &cresult->result_lzma;
// printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
// res->lit_context_bits, res->dict_size, res->num_probs);
UNUSED(res); UNUSED(res);
//printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
} }
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties)); s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
if (!s.Probs) if (!s.Probs) {
{
r = UPX_E_OUT_OF_MEMORY; r = UPX_E_OUT_OF_MEMORY;
goto error; goto error;
} }
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out); rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
assert(src_out <= src_len); assert(src_out <= src_len);
assert(dst_out <= *dst_len); assert(dst_out <= *dst_len);
if (rh == 0) if (rh == 0) {
{
r = UPX_E_OK; r = UPX_E_OK;
if (src_out != src_len) if (src_out != src_len)
r = UPX_E_INPUT_NOT_CONSUMED; r = UPX_E_INPUT_NOT_CONSUMED;
} } else if (rh == LZMA_RESULT_INPUT_OVERRUN)
r = UPX_E_INPUT_OVERRUN;
else if (rh == LZMA_RESULT_OUTPUT_OVERRUN)
r = UPX_E_OUTPUT_OVERRUN;
error: error:
*dst_len = dst_out; *dst_len = dst_out;
@@ -486,24 +485,20 @@ error:
return r; return r;
} }
/************************************************************************* /*************************************************************************
// test_overlap - see <ucl/ucl.h> for semantics // test_overlap - see <ucl/ucl.h> for semantics
**************************************************************************/ **************************************************************************/
int upx_lzma_test_overlap ( const upx_bytep buf, int upx_lzma_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
const upx_bytep tbuf, unsigned src_len, unsigned *dst_len, int method,
unsigned src_off, unsigned src_len, const upx_compress_result_t *cresult) {
unsigned* dst_len,
int method,
const upx_compress_result_t *cresult )
{
assert(M_IS_LZMA(method)); assert(M_IS_LZMA(method));
MemBuffer b(src_off + src_len); MemBuffer b(src_off + src_len);
memcpy(b + src_off, buf + src_off, src_len); memcpy(b + src_off, buf + src_off, src_len);
unsigned saved_dst_len = *dst_len; unsigned saved_dst_len = *dst_len;
int r = upx_lzma_decompress(b + src_off, src_len, b, dst_len, method, cresult); int r = upx_lzma_decompress(raw_index_bytes(b, src_off, src_len), src_len,
raw_bytes(b, *dst_len), dst_len, method, cresult);
if (r != UPX_E_OK) if (r != UPX_E_OK)
return r; return r;
if (*dst_len != saved_dst_len) if (*dst_len != saved_dst_len)
@@ -516,25 +511,34 @@ int upx_lzma_test_overlap ( const upx_bytep buf,
return UPX_E_OK; return UPX_E_OK;
} }
/************************************************************************* /*************************************************************************
// misc // misc
**************************************************************************/ **************************************************************************/
int upx_lzma_init(void) int upx_lzma_init(void) { return 0; }
{
return 0;
}
const char *upx_lzma_version_string(void) const char *upx_lzma_version_string(void) { return "4.43"; }
{
#if (WITH_LZMA == 0x443)
return "4.43";
#else
# error "unknown WITH_LZMA version"
return nullptr;
#endif
}
/*************************************************************************
// doctest checks
**************************************************************************/
TEST_CASE("upx_lzma_decompress") {
typedef const upx_byte C;
C *c_data;
upx_byte d_buf[16];
unsigned d_len;
int r;
c_data = (C *) "\x1a\x03\x00\x7f\xed\x3c\x00\x00\x00";
d_len = 16;
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
CHECK((r == 0 && d_len == 16));
r = upx_lzma_decompress(c_data, 8, d_buf, &d_len, M_LZMA, nullptr);
CHECK(r == UPX_E_INPUT_OVERRUN);
d_len = 15;
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN);
}
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+367
View File
@@ -0,0 +1,367 @@
/* compress_ucl.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
*/
#include "../conf.h"
#include "compress.h"
/*************************************************************************
//
**************************************************************************/
static int convert_errno_from_ucl(int r) {
switch (r) {
case UCL_E_OK:
return UPX_E_OK;
case UCL_E_ERROR:
return UPX_E_ERROR;
case UCL_E_OUT_OF_MEMORY:
return UPX_E_OUT_OF_MEMORY;
case UCL_E_NOT_COMPRESSIBLE:
return UPX_E_NOT_COMPRESSIBLE;
case UCL_E_INPUT_OVERRUN:
return UPX_E_INPUT_OVERRUN;
case UCL_E_OUTPUT_OVERRUN:
return UPX_E_OUTPUT_OVERRUN;
case UCL_E_LOOKBEHIND_OVERRUN:
return UPX_E_LOOKBEHIND_OVERRUN;
case UCL_E_EOF_NOT_FOUND:
return UPX_E_EOF_NOT_FOUND;
case UCL_E_INPUT_NOT_CONSUMED:
return UPX_E_INPUT_NOT_CONSUMED;
case UCL_E_INVALID_ARGUMENT:
return UPX_E_INVALID_ARGUMENT;
// UCL extra:
case UCL_E_OVERLAP_OVERRUN:
return UPX_E_ERROR;
}
return UPX_E_ERROR;
}
extern "C" {
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
if (state != -1 && state != 3)
return;
upx_callback_p cb = (upx_callback_p) user;
if (cb && cb->nprogress)
cb->nprogress(cb, a, b);
}
}
/*************************************************************************
//
**************************************************************************/
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
int r;
assert(level > 0);
assert(cresult != nullptr);
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
ucl_progress_callback_t cb;
cb.callback = nullptr;
cb.user = nullptr;
if (cb_parm && cb_parm->nprogress) {
cb.callback = wrap_nprogress_ucl;
cb.user = cb_parm;
}
ucl_compress_config_t cconf;
cconf.reset();
if (cconf_parm) {
// cconf = cconf_parm->conf_ucl; // struct copy
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf));
}
ucl_uint *const res = cresult->result_ucl.result;
// assume no info available - fill in worst case results
// res[0] = 1; // min_offset_found - NOT USED
res[1] = src_len - 1; // max_offset_found
// res[2] = 2; // min_match_found - NOT USED
res[3] = src_len - 1; // max_match_found
// res[4] = 1; // min_run_found - NOT USED
res[5] = src_len; // max_run_found
res[6] = 1; // first_offset_found
// res[7] = 999999; // same_match_offsets_found - NOT USED
// prepare bit-buffer settings
cconf.bb_endian = 0;
cconf.bb_size = 0;
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) {
static const unsigned char sizes[3] = {32, 8, 16};
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
} else {
throwInternalError("unknown compression method");
return UPX_E_ERROR;
}
// optimize compression parms
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
cconf.max_offset = 8 * 1024 - 1;
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
cconf.max_offset = 32 * 1024 - 1;
if M_IS_NRV2B (method)
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
else if M_IS_NRV2D (method)
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
else if M_IS_NRV2E (method)
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
else {
throwInternalError("unknown compression method");
return UPX_E_ERROR;
}
// make sure first_offset_found is set
if (res[6] == 0)
res[6] = 1;
return convert_errno_from_ucl(r);
}
/*************************************************************************
//
**************************************************************************/
int upx_ucl_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
int method, const upx_compress_result_t *cresult) {
int r;
switch (method) {
case M_NRV2B_8:
r = ucl_nrv2b_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
break;
case M_NRV2B_LE16:
r = ucl_nrv2b_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
break;
case M_NRV2B_LE32:
r = ucl_nrv2b_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
break;
case M_NRV2D_8:
r = ucl_nrv2d_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
break;
case M_NRV2D_LE16:
r = ucl_nrv2d_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
break;
case M_NRV2D_LE32:
r = ucl_nrv2d_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
break;
case M_NRV2E_8:
r = ucl_nrv2e_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
break;
case M_NRV2E_LE16:
r = ucl_nrv2e_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
break;
case M_NRV2E_LE32:
r = ucl_nrv2e_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
break;
default:
throwInternalError("unknown decompression method");
return UPX_E_ERROR;
}
UNUSED(cresult);
return convert_errno_from_ucl(r);
}
/*************************************************************************
//
**************************************************************************/
int upx_ucl_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
unsigned src_len, unsigned *dst_len, int method,
const upx_compress_result_t *cresult) {
int r;
UNUSED(tbuf); // not needed for UCL
switch (method) {
case M_NRV2B_8:
r = ucl_nrv2b_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
break;
case M_NRV2B_LE16:
r = ucl_nrv2b_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
break;
case M_NRV2B_LE32:
r = ucl_nrv2b_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
break;
case M_NRV2D_8:
r = ucl_nrv2d_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
break;
case M_NRV2D_LE16:
r = ucl_nrv2d_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
break;
case M_NRV2D_LE32:
r = ucl_nrv2d_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
break;
case M_NRV2E_8:
r = ucl_nrv2e_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
break;
case M_NRV2E_LE16:
r = ucl_nrv2e_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
break;
case M_NRV2E_LE32:
r = ucl_nrv2e_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
break;
default:
throwInternalError("unknown decompression method");
return UPX_E_ERROR;
}
UNUSED(cresult);
return convert_errno_from_ucl(r);
}
/*************************************************************************
// misc
**************************************************************************/
extern "C" {
static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return calloc(1, n); }
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
}
int upx_ucl_init(void) {
if (ucl_init() != UCL_E_OK)
return -1;
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
return -2;
ucl_set_malloc_hooks(my_malloc, my_free);
return 0;
}
const char *upx_ucl_version_string(void) { return ucl_version_string(); }
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler) {
return ucl_adler32(adler, (const ucl_bytep) buf, len);
}
#if 0 // UNUSED
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc) {
return ucl_crc32(crc, (const ucl_bytep) buf, len);
}
#endif
/*************************************************************************
// doctest checks
**************************************************************************/
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
#include "../util/membuffer.h"
static bool check_ucl(const int method, const unsigned expected_c_len) {
const unsigned u_len = 16384;
const unsigned c_extra = 4096;
MemBuffer u_buf, c_buf, d_buf;
unsigned c_len, d_len;
upx_compress_result_t cresult;
int r;
const int level = 3; // don't waste time
u_buf.alloc(u_len);
memset(u_buf, 0, u_len);
c_buf.allocForCompression(u_len, c_extra);
d_buf.allocForDecompression(u_len);
c_len = c_buf.getSize() - c_extra;
r = upx_ucl_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
&c_len, nullptr, method, level, NULL_cconf, &cresult);
if (r != 0 || c_len != expected_c_len)
return false;
d_len = d_buf.getSize();
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
return false;
d_len = u_len - 1;
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r == 0)
return false;
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
// unsigned x_len = d_len;
// r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
return true;
}
TEST_CASE("compress_ucl") {
CHECK(check_ucl(M_NRV2B_8, 34));
CHECK(check_ucl(M_NRV2B_LE16, 34));
CHECK(check_ucl(M_NRV2B_LE32, 34));
CHECK(check_ucl(M_NRV2D_8, 32));
CHECK(check_ucl(M_NRV2D_LE16, 32));
CHECK(check_ucl(M_NRV2D_LE32, 34));
CHECK(check_ucl(M_NRV2E_8, 32));
CHECK(check_ucl(M_NRV2E_LE16, 32));
CHECK(check_ucl(M_NRV2E_LE32, 34));
}
#endif // DEBUG
TEST_CASE("upx_ucl_decompress") {
typedef const upx_byte C;
C *c_data;
upx_byte d_buf[16];
unsigned d_len;
int r;
c_data = (C *) "\x92\xff\x10\x00\x00\x00\x00\x00\x48\xff";
d_len = 16;
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
CHECK((r == 0 && d_len == 16));
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2B_8, nullptr);
CHECK(r == UPX_E_INPUT_OVERRUN);
d_len = 15;
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN);
c_data = (C *) "\x92\xff\x10\x92\x49\x24\x92\xa0\xff";
d_len = 16;
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
CHECK((r == 0 && d_len == 16));
r = upx_ucl_decompress(c_data, 8, d_buf, &d_len, M_NRV2D_8, nullptr);
CHECK(r == UPX_E_INPUT_OVERRUN);
d_len = 15;
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN);
c_data = (C *) "\x90\xff\xb0\x92\x49\x24\x92\xa0\xff";
d_len = 16;
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
CHECK((r == 0 && d_len == 16));
r = upx_ucl_decompress(c_data, 8, d_buf, &d_len, M_NRV2E_8, nullptr);
CHECK(r == UPX_E_INPUT_OVERRUN);
d_len = 15;
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN);
}
/* vim:set ts=4 sw=4 et: */
@@ -2,8 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -21,20 +20,17 @@
If not, write to the Free Software Foundation, Inc., If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar Markus F.X.J. Oberhumer
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com>
*/ */
#include "../conf.h"
#include "conf.h"
#include "compress.h" #include "compress.h"
#include "util/membuffer.h" #include "../util/membuffer.h"
#include <zlib/zlib.h> #include <zlib/zlib.h>
#include <zlib/deflate.h> #include <zlib/deflate.h>
void zlib_compress_config_t::reset() {
void zlib_compress_config_t::reset()
{
mem_clear(this, sizeof(*this)); mem_clear(this, sizeof(*this));
mem_level.reset(); mem_level.reset();
@@ -42,37 +38,49 @@ void zlib_compress_config_t::reset()
strategy.reset(); strategy.reset();
} }
static int convert_errno_from_zlib(int zr) {
static int convert_errno_from_zlib(int zr) switch (zr) {
{ case Z_OK:
switch (zr) return UPX_E_OK;
{ // positive values
case Z_OK: return UPX_E_OK; case Z_STREAM_END:
case Z_DATA_ERROR: return UPX_E_ERROR; return UPX_E_ERROR;
case Z_NEED_DICT: return UPX_E_ERROR; case Z_NEED_DICT:
return UPX_E_ERROR;
// negative values
case Z_ERRNO:
return UPX_E_ERROR;
case Z_STREAM_ERROR:
return UPX_E_ERROR;
case Z_DATA_ERROR:
return UPX_E_ERROR;
case Z_MEM_ERROR:
return UPX_E_OUT_OF_MEMORY;
case Z_BUF_ERROR:
return UPX_E_OUTPUT_OVERRUN;
case Z_VERSION_ERROR:
return UPX_E_ERROR;
case -7: // UPX extra
return UPX_E_INPUT_OVERRUN;
} }
return UPX_E_ERROR; return UPX_E_ERROR;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int upx_zlib_compress ( const upx_bytep src, unsigned src_len, int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_bytep dst, unsigned* dst_len, upx_callback_p cb_parm, int method, int level,
upx_callback_p cb_parm, const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
int method, int level,
const upx_compress_config_t *cconf_parm,
upx_compress_result_t *cresult )
{
assert(method == M_DEFLATE); assert(method == M_DEFLATE);
assert(level > 0); assert(cresult != nullptr); assert(level > 0);
assert(cresult != nullptr);
UNUSED(cb_parm); UNUSED(cb_parm);
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
int zr; int zr;
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr; const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
zlib_compress_result_t *res = &cresult->result_zlib; zlib_compress_result_t *const res = &cresult->result_zlib;
if (level == 10) if (level == 10)
level = 9; level = 9;
@@ -81,8 +89,7 @@ int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
zlib_compress_config_t::window_bits_t window_bits; zlib_compress_config_t::window_bits_t window_bits;
zlib_compress_config_t::strategy_t strategy; zlib_compress_config_t::strategy_t strategy;
// cconf overrides // cconf overrides
if (lcconf) if (lcconf) {
{
oassign(mem_level, lcconf->mem_level); oassign(mem_level, lcconf->mem_level);
oassign(window_bits, lcconf->window_bits); oassign(window_bits, lcconf->window_bits);
oassign(strategy, lcconf->strategy); oassign(strategy, lcconf->strategy);
@@ -99,8 +106,7 @@ int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
s.avail_out = *dst_len; s.avail_out = *dst_len;
s.total_in = s.total_out = 0; s.total_in = s.total_out = 0;
zr = (int)deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits, zr = (int) deflateInit2(&s, level, Z_DEFLATED, 0 - (int) window_bits, mem_level, strategy);
mem_level, strategy);
if (zr != Z_OK) if (zr != Z_OK)
goto error; goto error;
assert(s.state->level == level); assert(s.state->level == level);
@@ -118,8 +124,7 @@ error:
if (r == UPX_E_OK) if (r == UPX_E_OK)
r = UPX_E_ERROR; r = UPX_E_ERROR;
done: done:
if (r == UPX_E_OK) if (r == UPX_E_OK) {
{
if (s.avail_in != 0 || s.total_in != src_len) if (s.avail_in != 0 || s.total_in != src_len)
r = UPX_E_ERROR; r = UPX_E_ERROR;
} }
@@ -129,16 +134,12 @@ done:
return r; return r;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len, int upx_zlib_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_bytep dst, unsigned* dst_len, int method, const upx_compress_result_t *cresult) {
int method,
const upx_compress_result_t *cresult )
{
assert(method == M_DEFLATE); assert(method == M_DEFLATE);
UNUSED(method); UNUSED(method);
UNUSED(cresult); UNUSED(cresult);
@@ -158,8 +159,11 @@ int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
if (zr != Z_OK) if (zr != Z_OK)
goto error; goto error;
zr = inflate(&s, Z_FINISH); zr = inflate(&s, Z_FINISH);
if (zr != Z_STREAM_END) if (zr != Z_STREAM_END) {
if (zr == Z_BUF_ERROR && s.avail_in == 0)
zr = -7; // UPX extra
goto error; goto error;
}
zr = inflateEnd(&s); zr = inflateEnd(&s);
if (zr != Z_OK) if (zr != Z_OK)
goto error; goto error;
@@ -171,8 +175,7 @@ error:
if (r == UPX_E_OK) if (r == UPX_E_OK)
r = UPX_E_ERROR; r = UPX_E_ERROR;
done: done:
if (r == UPX_E_OK) if (r == UPX_E_OK) {
{
if (s.avail_in != 0 || s.total_in != src_len) if (s.avail_in != 0 || s.total_in != src_len)
r = UPX_E_INPUT_NOT_CONSUMED; r = UPX_E_INPUT_NOT_CONSUMED;
} }
@@ -182,24 +185,20 @@ done:
return r; return r;
} }
/************************************************************************* /*************************************************************************
// test_overlap - see <ucl/ucl.h> for semantics // test_overlap - see <ucl/ucl.h> for semantics
**************************************************************************/ **************************************************************************/
int upx_zlib_test_overlap ( const upx_bytep buf, int upx_zlib_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
const upx_bytep tbuf, unsigned src_len, unsigned *dst_len, int method,
unsigned src_off, unsigned src_len, const upx_compress_result_t *cresult) {
unsigned* dst_len,
int method,
const upx_compress_result_t *cresult )
{
assert(method == M_DEFLATE); assert(method == M_DEFLATE);
MemBuffer b(src_off + src_len); MemBuffer b(src_off + src_len);
memcpy(b + src_off, buf + src_off, src_len); memcpy(b + src_off, buf + src_off, src_len);
unsigned saved_dst_len = *dst_len; unsigned saved_dst_len = *dst_len;
int r = upx_zlib_decompress(b + src_off, src_len, b, dst_len, method, cresult); int r = upx_zlib_decompress(raw_index_bytes(b, src_off, src_len), src_len,
raw_bytes(b, *dst_len), dst_len, method, cresult);
if (r != UPX_E_OK) if (r != UPX_E_OK)
return r; return r;
if (*dst_len != saved_dst_len) if (*dst_len != saved_dst_len)
@@ -212,44 +211,35 @@ int upx_zlib_test_overlap ( const upx_bytep buf,
return UPX_E_OK; return UPX_E_OK;
} }
/************************************************************************* /*************************************************************************
// misc // misc
**************************************************************************/ **************************************************************************/
int upx_zlib_init(void) int upx_zlib_init(void) {
{
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0) if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
return -2; return -2;
return 0; return 0;
} }
const char *upx_zlib_version_string(void) const char *upx_zlib_version_string(void) { return zlibVersion(); }
{
return zlibVersion();
}
#if 0 /* UNUSED */ #if 0 // UNUSED
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler) unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler) {
{
return adler32(adler, (const Bytef *) buf, len); return adler32(adler, (const Bytef *) buf, len);
} }
#endif #endif
#if 0 /* UNUSED */ #if 0 // UNUSED
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) {
{
return crc32(crc, (const Bytef *) buf, len); return crc32(crc, (const Bytef *) buf, len);
} }
#endif #endif
/************************************************************************* /*************************************************************************
// Debug checks // doctest checks
**************************************************************************/ **************************************************************************/
#if DEBUG && 1 #if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
#include "util/membuffer.h"
static bool check_zlib(const int method, const int level, const unsigned expected_c_len) { static bool check_zlib(const int method, const int level, const unsigned expected_c_len) {
const unsigned u_len = 16384; const unsigned u_len = 16384;
@@ -262,16 +252,25 @@ static bool check_zlib(const int method, const int level, const unsigned expecte
u_buf.alloc(u_len); u_buf.alloc(u_len);
memset(u_buf, 0, u_len); memset(u_buf, 0, u_len);
c_buf.allocForCompression(u_len, c_extra); c_buf.allocForCompression(u_len, c_extra);
d_buf.allocForUncompression(u_len); d_buf.allocForDecompression(u_len);
c_len = c_buf.getSize() - c_extra; c_len = c_buf.getSize() - c_extra;
r = upx_zlib_compress(u_buf, u_len, c_buf + c_extra, &c_len, nullptr, method, level, NULL_cconf, &cresult); r = upx_zlib_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
if (r != 0 || c_len != expected_c_len) return false; &c_len, nullptr, method, level, NULL_cconf, &cresult);
if (r != 0 || c_len != expected_c_len)
return false;
d_len = d_buf.getSize(); d_len = d_buf.getSize();
r = upx_zlib_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr); r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
if (r != 0 || d_len != u_len) return false; &d_len, method, nullptr);
if (memcmp(u_buf, d_buf, u_len) != 0) return false; if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
return false;
d_len = u_len - 1;
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r == 0)
return false;
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here // TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
// unsigned x_len = d_len; // unsigned x_len = d_len;
@@ -287,5 +286,22 @@ TEST_CASE("compress_zlib") {
#endif // DEBUG #endif // DEBUG
TEST_CASE("upx_zlib_decompress") {
typedef const upx_byte C;
C *c_data;
upx_byte d_buf[16];
unsigned d_len;
int r;
c_data = (C *) "\xfb\xff\x1f\x15\x00\x00";
d_len = 16;
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
CHECK((r == 0 && d_len == 16));
r = upx_zlib_decompress(c_data, 5, d_buf, &d_len, M_DEFLATE, nullptr);
CHECK(r == UPX_E_INPUT_OVERRUN);
d_len = 15;
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN);
}
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+229
View File
@@ -0,0 +1,229 @@
/* compress_zstd.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
*/
#include "../conf.h"
void zstd_compress_config_t::reset() { mem_clear(this, sizeof(*this)); }
#if WITH_ZSTD
#include "compress.h"
#include "../util/membuffer.h"
#include <zstd/lib/zstd.h>
#include <zstd/lib/zstd_errors.h>
#include <zstd/lib/compress/hist.h>
static int convert_errno_from_zstd(size_t zr) {
const ZSTD_ErrorCode ze = ZSTD_getErrorCode(zr);
switch (ze) {
case ZSTD_error_memory_allocation:
return UPX_E_OUT_OF_MEMORY;
case ZSTD_error_srcSize_wrong:
return UPX_E_INPUT_OVERRUN;
case ZSTD_error_dstSize_tooSmall:
return UPX_E_OUTPUT_OVERRUN;
default:
break;
}
return UPX_E_ERROR;
}
/*************************************************************************
// TODO later: use advanced compression API for compression finetuning
**************************************************************************/
int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(method == M_ZSTD);
assert(level > 0);
assert(cresult != nullptr);
UNUSED(cb_parm);
int r = UPX_E_ERROR;
size_t zr;
const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr;
zstd_compress_result_t *const res = &cresult->result_zstd;
// TODO later: map level 1..10 to zstd-level 1..22
if (level == 10)
level = 22;
// cconf overrides
if (lcconf) {
UNUSED(lcconf);
}
res->dummy = 0;
zr = ZSTD_compress(dst, *dst_len, src, src_len, level);
if (ZSTD_isError(zr)) {
*dst_len = 0; // TODO ???
r = convert_errno_from_zstd(zr);
assert(r != UPX_E_OK);
} else {
assert(zr <= *dst_len);
*dst_len = (unsigned) zr;
r = UPX_E_OK;
}
return r;
}
/*************************************************************************
//
**************************************************************************/
int upx_zstd_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
int method, const upx_compress_result_t *cresult) {
assert(method == M_ZSTD);
UNUSED(method);
UNUSED(cresult);
int r = UPX_E_ERROR;
size_t zr;
zr = ZSTD_decompress(dst, *dst_len, src, src_len);
if (ZSTD_isError(zr)) {
*dst_len = 0; // TODO ???
r = convert_errno_from_zstd(zr);
assert(r != UPX_E_OK);
} else {
assert(zr <= *dst_len);
*dst_len = (unsigned) zr;
r = UPX_E_OK;
}
return r;
}
/*************************************************************************
// test_overlap - see <ucl/ucl.h> for semantics
**************************************************************************/
int upx_zstd_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
unsigned src_len, unsigned *dst_len, int method,
const upx_compress_result_t *cresult) {
assert(method == M_ZSTD);
MemBuffer b(src_off + src_len);
memcpy(b + src_off, buf + src_off, src_len);
unsigned saved_dst_len = *dst_len;
int r = upx_zstd_decompress(raw_index_bytes(b, src_off, src_len), src_len,
raw_bytes(b, *dst_len), dst_len, method, cresult);
if (r != UPX_E_OK)
return r;
if (*dst_len != saved_dst_len)
return UPX_E_ERROR;
// NOTE: there is a very tiny possibility that decompression has
// succeeded but the data is not restored correctly because of
// in-place buffer overlapping, so we use an extra memcmp().
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
return UPX_E_ERROR;
return UPX_E_OK;
}
/*************************************************************************
// misc
**************************************************************************/
int upx_zstd_init(void) {
if (strcmp(ZSTD_VERSION_STRING, ZSTD_versionString()) != 0)
return -2;
return 0;
}
const char *upx_zstd_version_string(void) { return ZSTD_VERSION_STRING; }
/*************************************************************************
// doctest checks
**************************************************************************/
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
static bool check_zstd(const int method, const int level, const unsigned expected_c_len) {
const unsigned u_len = 16384;
const unsigned c_extra = 4096;
MemBuffer u_buf, c_buf, d_buf;
unsigned c_len, d_len;
upx_compress_result_t cresult;
int r;
u_buf.alloc(u_len);
memset(u_buf, 0, u_len);
c_buf.allocForCompression(u_len, c_extra);
d_buf.allocForDecompression(u_len);
c_len = c_buf.getSize() - c_extra;
r = upx_zstd_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
&c_len, nullptr, method, level, NULL_cconf, &cresult);
if (r != 0 || c_len != expected_c_len)
return false;
d_len = d_buf.getSize();
r = upx_zstd_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
return false;
d_len = u_len - 1;
r = upx_zstd_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r == 0)
return false;
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
// unsigned x_len = d_len;
// r = upx_zstd_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
return true;
}
TEST_CASE("compress_zstd") {
CHECK(check_zstd(M_ZSTD, 1, 19));
CHECK(check_zstd(M_ZSTD, 3, 19));
CHECK(check_zstd(M_ZSTD, 5, 19));
}
#endif // DEBUG
TEST_CASE("upx_zstd_decompress") {
typedef const upx_byte C;
C *c_data;
upx_byte d_buf[32];
unsigned d_len;
int r;
c_data = (C *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
d_len = 32;
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
CHECK((r == 0 && d_len == 32));
r = upx_zstd_decompress(c_data, 15, d_buf, &d_len, M_ZSTD, nullptr);
CHECK(r == UPX_E_INPUT_OVERRUN);
d_len = 31;
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN);
}
#endif // WITH_ZSTD
/* vim:set ts=4 sw=4 et: */
-340
View File
@@ -1,340 +0,0 @@
/* compress_ucl.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
<markus@oberhumer.com> <ezerotven+github@gmail.com>
*/
#include "conf.h"
#include "compress.h"
/*************************************************************************
//
**************************************************************************/
static int convert_errno_from_ucl(int r)
{
switch (r)
{
case UCL_E_OK: return UPX_E_OK;
case UCL_E_ERROR: return UPX_E_ERROR;
case UCL_E_OUT_OF_MEMORY: return UPX_E_OUT_OF_MEMORY;
case UCL_E_NOT_COMPRESSIBLE: return UPX_E_NOT_COMPRESSIBLE;
case UCL_E_INPUT_OVERRUN: return UPX_E_INPUT_OVERRUN;
case UCL_E_OUTPUT_OVERRUN: return UPX_E_OUTPUT_OVERRUN;
case UCL_E_LOOKBEHIND_OVERRUN: return UPX_E_LOOKBEHIND_OVERRUN;
case UCL_E_EOF_NOT_FOUND: return UPX_E_EOF_NOT_FOUND;
case UCL_E_INPUT_NOT_CONSUMED: return UPX_E_INPUT_NOT_CONSUMED;
// case UCL_E_NOT_YET_IMPLEMENTED: return UPX_E_NOT_YET_IMPLEMENTED;
case UCL_E_INVALID_ARGUMENT: return UPX_E_INVALID_ARGUMENT;
// UCL extra:
case UCL_E_OVERLAP_OVERRUN: return UPX_E_ERROR;
}
return UPX_E_ERROR;
}
extern "C" {
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
{
if (state != -1 && state != 3) return;
upx_callback_p cb = (upx_callback_p) user;
if (cb && cb->nprogress)
cb->nprogress(cb, a, b);
}}
/*************************************************************************
//
**************************************************************************/
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb_parm,
int method, int level,
const upx_compress_config_t *cconf_parm,
upx_compress_result_t *cresult )
{
int r;
assert(level > 0); assert(cresult != nullptr);
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
ucl_progress_callback_t cb;
cb.callback = nullptr;
cb.user = nullptr;
if (cb_parm && cb_parm->nprogress) {
cb.callback = wrap_nprogress_ucl;
cb.user = cb_parm;
}
ucl_compress_config_t cconf; cconf.reset();
if (cconf_parm)
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf)); // cconf = cconf_parm->conf_ucl; // struct copy
ucl_uint *res = cresult->result_ucl.result;
// assume no info available - fill in worst case results
//res[0] = 1; // min_offset_found - NOT USED
res[1] = src_len - 1; // max_offset_found
//res[2] = 2; // min_match_found - NOT USED
res[3] = src_len - 1; // max_match_found
//res[4] = 1; // min_run_found - NOT USED
res[5] = src_len; // max_run_found
res[6] = 1; // first_offset_found
//res[7] = 999999; // same_match_offsets_found - NOT USED
// prepare bit-buffer settings
cconf.bb_endian = 0;
cconf.bb_size = 0;
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
{
static const unsigned char sizes[3] = {32, 8, 16};
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
}
else {
throwInternalError("unknown compression method");
return UPX_E_ERROR;
}
// optimize compression parms
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
cconf.max_offset = 8*1024-1;
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
cconf.max_offset = 32*1024-1;
if M_IS_NRV2B(method)
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
&cb, level, &cconf, res);
else if M_IS_NRV2D(method)
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
&cb, level, &cconf, res);
else if M_IS_NRV2E(method)
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
&cb, level, &cconf, res);
else {
throwInternalError("unknown compression method");
return UPX_E_ERROR;
}
// make sure first_offset_found is set
if (res[6] == 0)
res[6] = 1;
return convert_errno_from_ucl(r);
}
/*************************************************************************
//
**************************************************************************/
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult )
{
int r;
switch (method)
{
case M_NRV2B_8:
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
break;
case M_NRV2B_LE16:
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
break;
case M_NRV2B_LE32:
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
break;
case M_NRV2D_8:
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
break;
case M_NRV2D_LE16:
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
break;
case M_NRV2D_LE32:
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
break;
case M_NRV2E_8:
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
break;
case M_NRV2E_LE16:
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
break;
case M_NRV2E_LE32:
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
break;
default:
throwInternalError("unknown decompression method");
return UPX_E_ERROR;
}
UNUSED(cresult);
return convert_errno_from_ucl(r);
}
/*************************************************************************
//
**************************************************************************/
int upx_ucl_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf,
unsigned src_off, unsigned src_len,
unsigned* dst_len,
int method,
const upx_compress_result_t *cresult )
{
int r;
UNUSED(tbuf); // not needed for UCL
switch (method)
{
case M_NRV2B_8:
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
break;
case M_NRV2B_LE16:
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
break;
case M_NRV2B_LE32:
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
break;
case M_NRV2D_8:
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
break;
case M_NRV2D_LE16:
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
break;
case M_NRV2D_LE32:
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
break;
case M_NRV2E_8:
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
break;
case M_NRV2E_LE16:
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
break;
case M_NRV2E_LE32:
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
break;
default:
throwInternalError("unknown decompression method");
return UPX_E_ERROR;
}
UNUSED(cresult);
return convert_errno_from_ucl(r);
}
/*************************************************************************
// misc
**************************************************************************/
extern "C" {
static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return calloc(1, n); }
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
}
int upx_ucl_init(void)
{
if (ucl_init() != UCL_E_OK)
return -1;
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
return -2;
ucl_set_malloc_hooks(my_malloc, my_free);
return 0;
}
const char *upx_ucl_version_string(void)
{
return ucl_version_string();
}
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler)
{
return ucl_adler32(adler, (const ucl_bytep) buf, len);
}
#if 0 /* UNUSED */
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc)
{
return ucl_crc32(crc, (const ucl_bytep) buf, len);
}
#endif
/*************************************************************************
// Debug checks
**************************************************************************/
#if DEBUG && 1
#include "util/membuffer.h"
static bool check_ucl(const int method, const unsigned expected_c_len) {
const unsigned u_len = 16384;
const unsigned c_extra = 4096;
MemBuffer u_buf, c_buf, d_buf;
unsigned c_len, d_len;
upx_compress_result_t cresult;
int r;
const int level = 3; // don't waste time
u_buf.alloc(u_len);
memset(u_buf, 0, u_len);
c_buf.allocForCompression(u_len, c_extra);
d_buf.allocForUncompression(u_len);
c_len = c_buf.getSize() - c_extra;
r = upx_ucl_compress(u_buf, u_len, c_buf + c_extra, &c_len, nullptr, method, level, NULL_cconf, &cresult);
if (r != 0 || c_len != expected_c_len) return false;
d_len = d_buf.getSize();
r = upx_ucl_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
if (r != 0 || d_len != u_len) return false;
if (memcmp(u_buf, d_buf, u_len) != 0) return false;
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
//unsigned x_len = d_len;
//r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
return true;
}
TEST_CASE("compress_ucl") {
CHECK(check_ucl(M_NRV2B_8, 34));
CHECK(check_ucl(M_NRV2B_LE16, 34));
CHECK(check_ucl(M_NRV2B_LE32, 34));
CHECK(check_ucl(M_NRV2D_8, 32));
CHECK(check_ucl(M_NRV2D_LE16, 32));
CHECK(check_ucl(M_NRV2D_LE32, 34));
CHECK(check_ucl(M_NRV2E_8, 32));
CHECK(check_ucl(M_NRV2E_LE16, 32));
CHECK(check_ucl(M_NRV2E_LE32, 34));
}
#endif // DEBUG
/* vim:set ts=4 sw=4 et: */
+200 -128
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -29,12 +29,8 @@
#ifndef UPX_CONF_H__ #ifndef UPX_CONF_H__
#define UPX_CONF_H__ 1 #define UPX_CONF_H__ 1
#if defined(__cplusplus) #if !(__cplusplus+0 >= 201703L)
# if (__cplusplus >= 201402L) # error "C++ 17 is required"
# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L)
# else
# error "C++ 14 is required"
# endif
#endif #endif
#include "version.h" #include "version.h"
@@ -48,11 +44,9 @@
# endif # endif
#endif #endif
#undef NDEBUG
/************************************************************************* /*************************************************************************
// ACC // ACC and system includes
**************************************************************************/ **************************************************************************/
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS #ifndef ACC_CFG_USE_NEW_STYLE_CASTS
@@ -117,8 +111,59 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
#define ACC_WANT_ACC_LIB_H 1 #define ACC_WANT_ACC_LIB_H 1
#define ACC_WANT_ACC_CXX_H 1 #define ACC_WANT_ACC_CXX_H 1
#include "miniacc.h" #include "miniacc.h"
#if (ACC_CC_MSC)
# include <intrin.h>
#endif
/* intergral types */ // C++ system headers
#include <exception>
#include <new>
#include <type_traits>
#include <typeinfo>
#if __STDC_NO_ATOMICS__ || 1
// UPX currently does not use multithreading
#define upx_std_atomic(Type) Type
//#define upx_std_atomic(Type) typename std::add_volatile<Type>::type
#else
#include <atomic>
#define upx_std_atomic(Type) std::atomic<Type>
#endif
// C++ submodule headers
#include <doctest/doctest/parts/doctest_fwd.h>
#if WITH_BOOST_PFR
# include <sstream>
# include <boost/pfr/io.hpp>
#endif
#if WITH_RANGELESS_FN
# include <rangeless/include/fn.hpp>
#endif
#ifndef WITH_VALGRIND
# define WITH_VALGRIND 1
#endif
#if defined(__SANITIZE_ADDRESS__) || defined(_WIN32) || !defined(__GNUC__)
# undef WITH_VALGRIND
#endif
#if (WITH_VALGRIND)
# include <valgrind/include/valgrind/memcheck.h>
#endif
// IMPORTANT: unconditionally enable assertions
#undef NDEBUG
#include <assert.h>
// <type_traits> C++20 std::is_bounded_array
template <class T>
struct std_is_bounded_array : public std::false_type {};
template <class T, size_t N>
struct std_is_bounded_array<T[N]> : public std::true_type {};
/*************************************************************************
// core
**************************************************************************/
// intergral types
typedef acc_int8_t upx_int8_t; typedef acc_int8_t upx_int8_t;
typedef acc_uint8_t upx_uint8_t; typedef acc_uint8_t upx_uint8_t;
typedef acc_int16_t upx_int16_t; typedef acc_int16_t upx_int16_t;
@@ -132,59 +177,6 @@ typedef acc_uintptr_t upx_uintptr_t;
typedef unsigned char upx_byte; typedef unsigned char upx_byte;
#define upx_bytep upx_byte * #define upx_bytep upx_byte *
/*************************************************************************
//
**************************************************************************/
#if defined(__linux__) && !defined(__unix__)
# define __unix__ 1
#endif
// just in case
#undef _
#undef __
#undef ___
#undef dos
#undef linux
#undef small
#undef tos
#undef unix
#if (ACC_OS_DOS32) && defined(__DJGPP__)
# undef sopen
# undef __unix__
# undef __unix
#endif
#define WITH_LZMA 0x443
#define WITH_UCL 1
#define WITH_ZLIB 1
#if (WITH_UCL)
# define ucl_compress_config_t REAL_ucl_compress_config_t
# include <ucl/include/ucl/uclconf.h>
# include <ucl/include/ucl/ucl.h>
# undef ucl_compress_config_t
# undef ucl_compress_config_p
#endif
// malloc debuggers
#if (WITH_VALGRIND)
# include <valgrind/memcheck.h>
#endif
#if !defined(VALGRIND_MAKE_MEM_DEFINED)
# define VALGRIND_MAKE_MEM_DEFINED(addr,len) 0
#endif
#if !defined(VALGRIND_MAKE_MEM_NOACCESS)
# define VALGRIND_MAKE_MEM_NOACCESS(addr,len) 0
#endif
#if !defined(VALGRIND_MAKE_MEM_UNDEFINED)
# define VALGRIND_MAKE_MEM_UNDEFINED(addr,len) 0
#endif
// IMPORTANT: unconditionally enable assertions
#undef NDEBUG
#include <assert.h>
// protect against integer overflows and malicious header fields // protect against integer overflows and malicious header fields
// see C 11 standard, Annex K // see C 11 standard, Annex K
typedef size_t upx_rsize_t; typedef size_t upx_rsize_t;
@@ -202,11 +194,47 @@ typedef upx_int64_t upx_off_t;
#define off_t upx_off_t #define off_t upx_off_t
#endif #endif
// shortcuts
#define forceinline __acc_forceinline
#if _MSC_VER
#define noinline __declspec(noinline)
#undef __acc_noinline
#define __acc_noinline noinline
#else
#define noinline __acc_noinline
#endif
#define likely __acc_likely
#define unlikely __acc_unlikely
#define very_likely __acc_very_likely
#define very_unlikely __acc_very_unlikely
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
#define DELETED_FUNCTION = delete
#define UNUSED(var) ACC_UNUSED(var)
/************************************************************************* /*************************************************************************
// portab // portab
**************************************************************************/ **************************************************************************/
// just in case
#undef _
#undef __
#undef ___
#undef dos
#undef linux
#undef small
#undef tos
#undef unix
#if defined(__linux__) && !defined(__unix__)
# define __unix__ 1
#endif
#if (ACC_OS_DOS32) && defined(__DJGPP__)
# undef sopen
# undef __unix__
# undef __unix
#endif
#ifndef STDIN_FILENO #ifndef STDIN_FILENO
# define STDIN_FILENO (fileno(stdin)) # define STDIN_FILENO (fileno(stdin))
#endif #endif
@@ -264,12 +292,14 @@ typedef upx_int64_t upx_off_t;
#endif #endif
// avoid warnings about shadowing global functions // avoid warnings about shadowing global functions
#undef _base
#undef basename #undef basename
#undef index #undef index
#undef outp #undef outp
#define basename upx_basename #define _base upx_renamed__base
#define index upx_index #define basename upx_renamed_basename
#define outp upx_outp #define index upx_renamed_index
#define outp upx_renamed_outp
#undef PAGE_MASK #undef PAGE_MASK
#undef PAGE_SIZE #undef PAGE_SIZE
@@ -283,21 +313,34 @@ typedef upx_int64_t upx_off_t;
# define O_BINARY 0 # define O_BINARY 0
#endif #endif
#ifndef OPTIONS_VAR
# define OPTIONS_VAR "UPX"
#endif
/************************************************************************* /*************************************************************************
// // util
**************************************************************************/ **************************************************************************/
#define CLANG_FORMAT_DUMMY_STATEMENT /*empty*/ #define CLANG_FORMAT_DUMMY_STATEMENT /*empty*/
// malloc debuggers
#if !defined(VALGRIND_CHECK_MEM_IS_ADDRESSABLE)
# define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr,len) 0
#endif
#if !defined(VALGRIND_CHECK_MEM_IS_DEFINED)
# define VALGRIND_CHECK_MEM_IS_DEFINED(addr,len) 0
#endif
#if !defined(VALGRIND_MAKE_MEM_DEFINED)
# define VALGRIND_MAKE_MEM_DEFINED(addr,len) 0
#endif
#if !defined(VALGRIND_MAKE_MEM_NOACCESS)
# define VALGRIND_MAKE_MEM_NOACCESS(addr,len) 0
#endif
#if !defined(VALGRIND_MAKE_MEM_UNDEFINED)
# define VALGRIND_MAKE_MEM_UNDEFINED(addr,len) 0
#endif
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) #if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b))); # define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b)))
#elif (ACC_CC_CLANG || ACC_CC_GNUC) #elif (ACC_CC_CLANG || ACC_CC_GNUC)
# define attribute_format(a,b) __attribute__((__format__(__printf__,a,b))); # define attribute_format(a,b) __attribute__((__format__(__printf__,a,b)))
#else #else
# define attribute_format(a,b) /*empty*/ # define attribute_format(a,b) /*empty*/
#endif #endif
@@ -321,13 +364,28 @@ inline void NO_fprintf(FILE *, const char *, ...) {}
# define upx_memcpy_inline memcpy # define upx_memcpy_inline memcpy
#endif #endif
#define UNUSED(var) ACC_UNUSED(var) #if __has_builtin(__builtin_return_address)
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e) # define upx_return_address() __builtin_return_address(0)
#elif defined(__GNUC__)
# define upx_return_address() __builtin_return_address(0)
#elif (ACC_CC_MSC)
# define upx_return_address() _ReturnAddress()
#else
# define upx_return_address() nullptr
#endif
// TODO cleanup: we now require C++14, so remove all __packed_struct usage // TODO cleanup: we now require C++14, so remove all __packed_struct usage
#define __packed_struct(s) struct alignas(1) s { #define __packed_struct(s) struct alignas(1) s {
#define __packed_struct_end() }; #define __packed_struct_end() };
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
// horrible hack for broken compiler
#define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__))
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
#define upx_fake_alignas__(a) upx_fake_alignas_ ## a
#define alignas(x) upx_fake_alignas__(x)
#endif
#define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \ #define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \ typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \ struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \
@@ -355,6 +413,15 @@ inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a;
template <class T> template <class T>
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; } inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
template <size_t TypeSize>
struct USizeOfTypeImpl {
static forceinline constexpr unsigned value() {
COMPILE_TIME_ASSERT(TypeSize >= 1 && TypeSize <= 64 * 1024); // arbitrary limit
return ACC_ICONV(unsigned, TypeSize);
}
};
#define usizeof(type) (USizeOfTypeImpl<sizeof(type)>::value())
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == 4)
// An Array allocates memory on the heap, and automatically // An Array allocates memory on the heap, and automatically
// gets destructed when leaving scope or on exceptions. // gets destructed when leaving scope or on exceptions.
@@ -371,12 +438,17 @@ protected:
inline noncopyable() {} inline noncopyable() {}
inline ~noncopyable() {} inline ~noncopyable() {}
private: private:
noncopyable(const noncopyable &); // undefined noncopyable(const noncopyable &) DELETED_FUNCTION; // copy constuctor
const noncopyable& operator=(const noncopyable &); // undefined noncopyable& operator=(const noncopyable &) DELETED_FUNCTION; // copy assignment
noncopyable(noncopyable &&) DELETED_FUNCTION; // move constructor
noncopyable& operator=(noncopyable &&) DELETED_FUNCTION; // move assignment
}; };
namespace compile_time { namespace compile_time {
constexpr size_t string_len(const char *a) {
return *a == '\0' ? 0 : 1 + string_len(a + 1);
}
constexpr bool string_eq(const char *a, const char *b) { constexpr bool string_eq(const char *a, const char *b) {
return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1)); return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1));
} }
@@ -440,14 +512,14 @@ constexpr bool string_ge(const char *a, const char *b) {
#define UPX_F_DOS_EXE 3 #define UPX_F_DOS_EXE 3
#define UPX_F_DJGPP2_COFF 4 #define UPX_F_DJGPP2_COFF 4
#define UPX_F_WATCOM_LE 5 #define UPX_F_WATCOM_LE 5
#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED //#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED
#define UPX_F_DOS_EXEH 7 // OBSOLETE #define UPX_F_DOS_EXEH 7 // OBSOLETE
#define UPX_F_TMT_ADAM 8 #define UPX_F_TMT_ADAM 8
#define UPX_F_WIN32_PE 9 #define UPX_F_WIN32_PE 9
#define UPX_F_LINUX_i386 10 #define UPX_F_LINUX_i386 10
#define UPX_F_WIN16_NE 11 // NOT IMPLEMENTED //#define UPX_F_WIN16_NE 11 // NOT IMPLEMENTED
#define UPX_F_LINUX_ELF_i386 12 #define UPX_F_LINUX_ELF_i386 12
#define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED //#define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED
#define UPX_F_LINUX_SH_i386 14 #define UPX_F_LINUX_SH_i386 14
#define UPX_F_VMLINUZ_i386 15 #define UPX_F_VMLINUZ_i386 15
#define UPX_F_BVMLINUZ_i386 16 #define UPX_F_BVMLINUZ_i386 16
@@ -485,7 +557,7 @@ constexpr bool string_ge(const char *a, const char *b) {
#define UPX_F_LINUX_ELF64_ARM 42 #define UPX_F_LINUX_ELF64_ARM 42
#define UPX_F_ATARI_TOS 129 #define UPX_F_ATARI_TOS 129
#define UPX_F_SOLARIS_SPARC 130 // NOT IMPLEMENTED //#define UPX_F_SOLARIS_SPARC 130 // NOT IMPLEMENTED
#define UPX_F_MACH_PPC32 131 #define UPX_F_MACH_PPC32 131
#define UPX_F_LINUX_ELFPPC32 132 #define UPX_F_LINUX_ELFPPC32 132
#define UPX_F_LINUX_ELF32_ARMEB 133 #define UPX_F_LINUX_ELF32_ARMEB 133
@@ -514,7 +586,8 @@ constexpr bool string_ge(const char *a, const char *b) {
//#define M_CL1B_8 12 //#define M_CL1B_8 12
//#define M_CL1B_LE16 13 //#define M_CL1B_LE16 13
#define M_LZMA 14 #define M_LZMA 14
#define M_DEFLATE 15 /* zlib */ #define M_DEFLATE 15 // zlib
#define M_ZSTD 16
// compression methods internal usage // compression methods internal usage
#define M_ALL (-1) #define M_ALL (-1)
#define M_END (-2) #define M_END (-2)
@@ -528,6 +601,7 @@ constexpr bool string_ge(const char *a, const char *b) {
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16) //#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA) #define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE) #define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
#define M_IS_ZSTD(x) ((x) == M_ZSTD)
// filters // filters
@@ -538,9 +612,20 @@ constexpr bool string_ge(const char *a, const char *b) {
/************************************************************************* /*************************************************************************
// compression - callback_t // compression - setup and callback_t
**************************************************************************/ **************************************************************************/
#define WITH_LZMA 1
#define WITH_UCL 1
#define WITH_ZLIB 1
#if (WITH_UCL)
# define ucl_compress_config_t REAL_ucl_compress_config_t
# include <ucl/include/ucl/uclconf.h>
# include <ucl/include/ucl/ucl.h>
# undef ucl_compress_config_t
# undef ucl_compress_config_p
#endif
struct upx_callback_t; struct upx_callback_t;
typedef upx_callback_t *upx_callback_p; typedef upx_callback_t *upx_callback_p;
typedef void (__acc_cdecl *upx_progress_func_t) typedef void (__acc_cdecl *upx_progress_func_t)
@@ -577,25 +662,26 @@ struct OptVar
assertValue(v); assertValue(v);
} }
OptVar() : v(default_value), is_set(0) { } OptVar() : v(default_value), is_set(false) { }
OptVar& operator= (const T &other) { OptVar& operator= (const T &other) {
v = other; is_set = 1; assertValue(other);
assertValue(); v = other;
is_set = true;
return *this; return *this;
} }
void reset() { v = default_value; is_set = 0; } void reset() { v = default_value; is_set = false; }
operator T () const { return v; } operator T () const { return v; }
T v; T v;
unsigned is_set; bool is_set;
}; };
// optional assignments // optional assignments
template <class T, T a, T b, T c> template <class T, T a, T b, T c>
inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) { inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) {
if (other.is_set) { self.v = other.v; self.is_set = 1; } if (other.is_set) { self.v = other.v; self.is_set = true; }
} }
template <class T, T a, T b, T c> template <class T, T a, T b, T c>
inline void oassign(T &v, const OptVar<T,a,b,c> &other) { inline void oassign(T &v, const OptVar<T,a,b,c> &other) {
@@ -624,13 +710,11 @@ struct lzma_compress_config_t
void reset(); void reset();
}; };
struct ucl_compress_config_t : public REAL_ucl_compress_config_t struct ucl_compress_config_t : public REAL_ucl_compress_config_t
{ {
void reset() { memset(this, 0xff, sizeof(*this)); } void reset() { memset(this, 0xff, sizeof(*this)); }
}; };
struct zlib_compress_config_t struct zlib_compress_config_t
{ {
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
@@ -644,13 +728,20 @@ struct zlib_compress_config_t
void reset(); void reset();
}; };
struct zstd_compress_config_t
{
unsigned dummy;
void reset();
};
struct upx_compress_config_t struct upx_compress_config_t
{ {
lzma_compress_config_t conf_lzma; lzma_compress_config_t conf_lzma;
ucl_compress_config_t conf_ucl; ucl_compress_config_t conf_ucl;
zlib_compress_config_t conf_zlib; zlib_compress_config_t conf_zlib;
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); } zstd_compress_config_t conf_zstd;
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); }
}; };
#define NULL_cconf ((upx_compress_config_t *) nullptr) #define NULL_cconf ((upx_compress_config_t *) nullptr)
@@ -674,7 +765,6 @@ struct lzma_compress_result_t
void reset() { memset(this, 0, sizeof(*this)); } void reset() { memset(this, 0, sizeof(*this)); }
}; };
struct ucl_compress_result_t struct ucl_compress_result_t
{ {
ucl_uint result[16]; ucl_uint result[16];
@@ -682,7 +772,6 @@ struct ucl_compress_result_t
void reset() { memset(this, 0, sizeof(*this)); } void reset() { memset(this, 0, sizeof(*this)); }
}; };
struct zlib_compress_result_t struct zlib_compress_result_t
{ {
unsigned dummy; unsigned dummy;
@@ -690,20 +779,29 @@ struct zlib_compress_result_t
void reset() { memset(this, 0, sizeof(*this)); } void reset() { memset(this, 0, sizeof(*this)); }
}; };
struct zstd_compress_result_t
{
unsigned dummy;
void reset() { memset(this, 0, sizeof(*this)); }
};
struct upx_compress_result_t struct upx_compress_result_t
{ {
// debug // debugging aid
struct {
int method, level; int method, level;
unsigned u_len, c_len; unsigned u_len, c_len;
} debug;
lzma_compress_result_t result_lzma; lzma_compress_result_t result_lzma;
ucl_compress_result_t result_ucl; ucl_compress_result_t result_ucl;
zlib_compress_result_t result_zlib; zlib_compress_result_t result_zlib;
zstd_compress_result_t result_zstd;
void reset() { void reset() {
memset(this, 0, sizeof(*this)); memset(&this->debug, 0, sizeof(this->debug));
result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset();
} }
}; };
@@ -713,16 +811,10 @@ struct upx_compress_result_t
**************************************************************************/ **************************************************************************/
#include "util/snprintf.h" // must get included first! #include "util/snprintf.h" // must get included first!
#include <exception>
#include <new>
#include <type_traits>
#include <typeinfo>
#include "options.h" #include "options.h"
#include "except.h" #include "except.h"
#include "bele.h" #include "bele.h"
#include "console.h" #include "console/console.h"
#include "util/util.h" #include "util/util.h"
// classes // classes
@@ -734,11 +826,9 @@ class MemBuffer;
void *membuffer_get_void_ptr(MemBuffer &mb); void *membuffer_get_void_ptr(MemBuffer &mb);
unsigned membuffer_get_size(MemBuffer &mb); unsigned membuffer_get_size(MemBuffer &mb);
// xspan
#include "util/xspan.h" #include "util/xspan.h"
//#define DOCTEST_CONFIG_DISABLE 1
#include <doctest/doctest/parts/doctest_fwd.h>
// util/dt_check.cpp // util/dt_check.cpp
void upx_compiler_sanity_check(); void upx_compiler_sanity_check();
int upx_doctest_check(); int upx_doctest_check();
@@ -777,7 +867,7 @@ void show_license();
void show_usage(); void show_usage();
void show_version(bool one_line=false); void show_version(bool one_line=false);
// compress.cpp // compress/compress.cpp
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1); unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0); unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
@@ -798,24 +888,6 @@ int upx_test_overlap ( const upx_bytep buf,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
/*************************************************************************
// raw_bytes() - get underlying memory from checked buffers/pointers.
// This is overloaded by various utility classes like BoundedPtr,
// MemBuffer and Span.
//
// Note that the pointer type is retained, the "_bytes" hints size_in_bytes
**************************************************************************/
// default: for any regular pointer, raw_bytes() is just the pointer itself
template <class T>
inline T *raw_bytes(T *ptr, size_t size_in_bytes) {
if (size_in_bytes > 0) {
if __acc_very_unlikely (ptr == nullptr)
throwInternalError("raw_bytes unexpected NULL ptr");
}
return ptr;
}
#if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64) #if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
# if defined(INVALID_HANDLE_VALUE) || defined(MAKEWORD) || defined(RT_CURSOR) # if defined(INVALID_HANDLE_VALUE) || defined(MAKEWORD) || defined(RT_CURSOR)
+11 -29
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "../conf.h"
#include "conf.h"
#if (USE_CONSOLE) #if (USE_CONSOLE)
@@ -34,58 +33,41 @@
// //
**************************************************************************/ **************************************************************************/
static int init(FILE *f, int o, int now) static int init(FILE *f, int o, int now) {
{
UNUSED(f); UNUSED(f);
UNUSED(o); UNUSED(o);
UNUSED(now); UNUSED(now);
return CON_FILE; return CON_FILE;
} }
static int set_fg(FILE *f, int fg) {
static int set_fg(FILE *f, int fg)
{
UNUSED(f); UNUSED(f);
UNUSED(fg); UNUSED(fg);
return -1; return -1;
} }
static void print0(FILE *f, const char *s) {
static void print0(FILE *f, const char *s)
{
#if 1 #if 1
fputs(s, f); fputs(s, f);
#else #else
/* filter out all ANSI sequences */ /* filter out all ANSI sequences */
int c; int c;
while ((c = *s++) != 0) while ((c = *s++) != 0) {
{ if (c == '\033' && *s == ']') {
if (c == '\033' && *s == ']')
{
while (*s && *s != 'm') while (*s && *s != 'm')
s++; s++;
} } else
else
fputc(c, f); fputc(c, f);
} }
#endif #endif
} }
static bool intro(FILE *f) {
static bool intro(FILE *f)
{
UNUSED(f); UNUSED(f);
return 0; return 0;
} }
console_t console_file = {init, set_fg, print0, intro};
console_t console_file =
{
init,
set_fg,
print0,
intro
};
#endif /* USE_CONSOLE */ #endif /* USE_CONSOLE */
+11 -32
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "../conf.h"
#include "conf.h"
FILE *con_term = nullptr; FILE *con_term = nullptr;
@@ -41,9 +40,7 @@ console_t * con = &console_init;
int con_mode = CON_INIT; int con_mode = CON_INIT;
static void try_init(console_t *c, FILE *f) {
static void try_init(console_t *c, FILE *f)
{
int k; int k;
assert(c); assert(c);
@@ -56,8 +53,7 @@ static void try_init(console_t *c, FILE *f)
if (k != opt->console) if (k != opt->console)
return; return;
#endif #endif
if (k > con_mode) if (k > con_mode) {
{
con_mode = k; con_mode = k;
con = c; con = c;
con->init = nullptr; con->init = nullptr;
@@ -70,9 +66,7 @@ static void try_init(console_t *c, FILE *f)
} }
} }
static int do_init(FILE *f) {
static int do_init(FILE *f)
{
assert(con_mode == CON_INIT); assert(con_mode == CON_INIT);
try_init(&console_none, f); try_init(&console_none, f);
@@ -98,13 +92,11 @@ static int do_init(FILE *f)
return con_mode; return con_mode;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
static int init(FILE *f, int o, int now) static int init(FILE *f, int o, int now) {
{
if (con != me) if (con != me)
return con_mode; return con_mode;
assert(o == -1); assert(o == -1);
@@ -114,36 +106,23 @@ static int init(FILE *f, int o, int now)
return do_init(f); return do_init(f);
} }
static int set_fg(FILE *f, int fg) {
static int set_fg(FILE *f, int fg)
{
if (con == me) if (con == me)
init(f, -1, -1); init(f, -1, -1);
assert(con != me); assert(con != me);
return con->set_fg(f, fg); return con->set_fg(f, fg);
} }
static bool intro(FILE *f) {
static bool intro(FILE *f)
{
if (con == me) if (con == me)
init(f, -1, -1); init(f, -1, -1);
assert(con != me); assert(con != me);
return con->intro(f); return con->intro(f);
} }
console_t console_init = {init, set_fg, nullptr, intro};
console_t console_init = void con_fprintf(FILE *f, const char *format, ...) {
{
init,
set_fg,
nullptr,
intro
};
void con_fprintf(FILE *f, const char *format, ...)
{
va_list args; va_list args;
char buf[80 * 25]; char buf[80 * 25];
+8 -23
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "../conf.h"
#include "conf.h"
#if (USE_CONSOLE) #if (USE_CONSOLE)
@@ -34,44 +33,30 @@
// //
**************************************************************************/ **************************************************************************/
static int init(FILE *f, int o, int now) static int init(FILE *f, int o, int now) {
{
UNUSED(f); UNUSED(f);
UNUSED(o); UNUSED(o);
UNUSED(now); UNUSED(now);
return CON_NONE; return CON_NONE;
} }
static int set_fg(FILE *f, int fg) {
static int set_fg(FILE *f, int fg)
{
UNUSED(f); UNUSED(f);
UNUSED(fg); UNUSED(fg);
return -1; return -1;
} }
static void print0(FILE *f, const char *s) {
static void print0(FILE *f, const char *s)
{
UNUSED(f); UNUSED(f);
UNUSED(s); UNUSED(s);
} }
static bool intro(FILE *f) {
static bool intro(FILE *f)
{
UNUSED(f); UNUSED(f);
return 0; return 0;
} }
console_t console_none = {init, set_fg, print0, intro};
console_t console_none =
{
init,
set_fg,
print0,
intro
};
#endif /* USE_CONSOLE */ #endif /* USE_CONSOLE */
+33 -78
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "../conf.h"
#include "conf.h"
#if (USE_SCREEN) #if (USE_SCREEN)
@@ -35,13 +34,11 @@
#define mask_fg 0x0f #define mask_fg 0x0f
#define mask_bg 0xf0 #define mask_bg 0xf0
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
static int do_init(screen_t *s, int fd) static int do_init(screen_t *s, int fd) {
{
int fg, bg; int fg, bg;
if (s->init(s, fd) != 0) if (s->init(s, fd) != 0)
@@ -59,8 +56,7 @@ static int do_init(screen_t *s, int fd)
if (fg == (bg >> 4)) if (fg == (bg >> 4))
return -1; return -1;
if (bg != BG_BLACK) if (bg != BG_BLACK)
if (!s->isMono(s)) if (!s->isMono(s)) {
{
/* return 0; */ /* we could emulate ANSI mono */ /* return 0; */ /* we could emulate ANSI mono */
return -1; return -1;
} }
@@ -68,30 +64,24 @@ static int do_init(screen_t *s, int fd)
return 0; return 0;
} }
static screen_t *do_construct(screen_t *s, int fd) {
static screen_t *do_construct(screen_t *s, int fd)
{
if (!s) if (!s)
return nullptr; return nullptr;
if (do_init(s,fd) != 0) if (do_init(s, fd) != 0) {
{
s->destroy(s); s->destroy(s);
return nullptr; return nullptr;
} }
return s; return s;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
static screen_t *screen = nullptr; static screen_t *screen = nullptr;
static void __acc_cdecl_atexit do_destroy(void) static void __acc_cdecl_atexit do_destroy(void) {
{ if (screen) {
if (screen)
{
if (screen->atExit) if (screen->atExit)
screen->atExit(); screen->atExit();
screen->destroy(screen); screen->destroy(screen);
@@ -99,16 +89,13 @@ static void __acc_cdecl_atexit do_destroy(void)
} }
} }
static int mode = -1; static int mode = -1;
static int init_fg = -1; static int init_fg = -1;
static int init_bg = -1; static int init_bg = -1;
static int cur_fg = -1; static int cur_fg = -1;
static int cur_bg = -1; static int cur_bg = -1;
static int init(FILE *f, int o, int now) {
static int init(FILE *f, int o, int now)
{
int fd = fileno(f); int fd = fileno(f);
int n; int n;
@@ -155,17 +142,14 @@ static int init(FILE *f, int o, int now)
return n; return n;
} }
static int set_fg(FILE *f, int fg) {
static int set_fg(FILE *f, int fg)
{
const int last_fg = cur_fg; const int last_fg = cur_fg;
int f1 = fg & mask_fg; int f1 = fg & mask_fg;
int f2 = init_fg & mask_fg; int f2 = init_fg & mask_fg;
UNUSED(f); UNUSED(f);
cur_fg = fg; cur_fg = fg;
if (screen->isMono(screen)) if (screen->isMono(screen)) {
{
const int b = (init_bg & mask_bg) >> 4; const int b = (init_bg & mask_bg) >> 4;
if (fg == -1) /* restore startup fg */ if (fg == -1) /* restore startup fg */
f1 = f2; f1 = f2;
@@ -175,9 +159,7 @@ static int set_fg(FILE *f, int fg)
f1 = (f2 == 0) ? 15 : 0; f1 = (f2 == 0) ? 15 : 0;
else else
f1 = (f2 == 0) ? 8 : 0; f1 = (f2 == 0) ? 8 : 0;
} } else if (con_mode == CON_ANSI_MONO && f1 != f2) {
else if (con_mode == CON_ANSI_MONO && f1 != f2)
{
f1 = f2 ^ 0x08; f1 = f2 ^ 0x08;
} }
@@ -185,9 +167,7 @@ static int set_fg(FILE *f, int fg)
return last_fg; return last_fg;
} }
static void print0(FILE *f, const char *ss) {
static void print0(FILE *f, const char *ss)
{
int cx, cy; int cx, cy;
int old_cx = 0, old_cy = 0; int old_cx = 0, old_cy = 0;
const int sx = screen->getCols(screen); const int sx = screen->getCols(screen);
@@ -200,54 +180,44 @@ static void print0(FILE *f, const char *ss)
UNUSED(f); UNUSED(f);
screen->getCursor(screen, &old_cx, &old_cy); screen->getCursor(screen, &old_cx, &old_cy);
cx = old_cx; cy = old_cy; cx = old_cx;
cy = old_cy;
for (pass = 0; pass < 2; pass++) for (pass = 0; pass < 2; pass++) {
{
const char *s = ss; const char *s = ss;
// char buffer for pass 2 // char buffer for pass 2
char p[256 + 1]; char p[256 + 1];
int pi = 0, px = 0, py = 0; int pi = 0, px = 0, py = 0;
for (;;) for (;;) {
{
// walk over whitespace // walk over whitespace
for (;;) for (;;) {
{ if (*s == '\n') {
if (*s == '\n')
{
cx = 0; cx = 0;
cy++; cy++;
} } else if (*s == '\r') {
else if (*s == '\r')
{
cx = 0; cx = 0;
if (pass > 0 && cy < sy) if (pass > 0 && cy < sy)
screen->clearLine(screen, cy); screen->clearLine(screen, cy);
} } else
else
break; break;
s++; s++;
} }
// adjust cursor // adjust cursor
if (cx >= sx) if (cx >= sx) {
{
cx = 0; cx = 0;
cy++; cy++;
} }
if (pass > 0) if (pass > 0) {
{
// check if we should print something // check if we should print something
if (pi > 0 && (*s == 0 || py != cy)) if (pi > 0 && (*s == 0 || py != cy)) {
{
p[pi] = 0; p[pi] = 0;
screen->putString(screen, p, px, py); screen->putString(screen, p, px, py);
pi = 0; pi = 0;
} }
// check if we should scroll even more (this can happen // check if we should scroll even more (this can happen
// if the string is longer than sy lines) // if the string is longer than sy lines)
if (cy >= sy) if (cy >= sy) {
{
int scroll_y = cy - sy + 1; int scroll_y = cy - sy + 1;
screen->scrollUp(screen, scroll_y); screen->scrollUp(screen, scroll_y);
cy -= scroll_y; cy -= scroll_y;
@@ -258,11 +228,9 @@ static void print0(FILE *f, const char *ss)
// done ? // done ?
if (*s == 0) if (*s == 0)
break; break;
if (pass > 0) if (pass > 0) {
{
// store current char // store current char
if (pi == 0) if (pi == 0) {
{
px = cx; px = cx;
py = cy; py = cy;
} }
@@ -273,18 +241,15 @@ static void print0(FILE *f, const char *ss)
s++; s++;
} }
if (pass == 0) if (pass == 0) {
{
// end of pass 1 - scroll up, restore cursor // end of pass 1 - scroll up, restore cursor
if (cy >= sy) if (cy >= sy) {
{
int scroll_y = cy - sy + 1; int scroll_y = cy - sy + 1;
screen->scrollUp(screen, scroll_y); screen->scrollUp(screen, scroll_y);
cy = old_cy - scroll_y; cy = old_cy - scroll_y;
if (cy < 0) if (cy < 0)
cy = 0; cy = 0;
} } else
else
cy = old_cy; cy = old_cy;
cx = old_cx; cx = old_cx;
} }
@@ -294,9 +259,7 @@ static void print0(FILE *f, const char *ss)
screen->refresh(screen); screen->refresh(screen);
} }
static bool intro(FILE *f) {
static bool intro(FILE *f)
{
UNUSED(f); UNUSED(f);
#if (USE_FRAMES) #if (USE_FRAMES)
if (screen->intro) if (screen->intro)
@@ -305,15 +268,7 @@ static bool intro(FILE *f)
return 0; return 0;
} }
console_t console_screen = {init, set_fg, print0, intro};
console_t console_screen =
{
init,
set_fg,
print0,
intro
};
#endif /* USE_SCREEN */ #endif /* USE_SCREEN */
+8 -24
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#pragma once
/************************************************************************* /*************************************************************************
// //
@@ -64,9 +64,10 @@
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__)) #elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
#define USE_SCREEN 1 #define USE_SCREEN 1
#define USE_SCREEN_WIN32 1 #define USE_SCREEN_WIN32 1
#elif 1 && (ACC_ARCH_M68K && ACC_OS_TOS)
#define NO_CONSOLE 1
#endif #endif
#if 0 || (NO_ANSI) #if 0 || (NO_ANSI)
#undef USE_ANSI #undef USE_ANSI
#endif #endif
@@ -80,7 +81,6 @@
#undef USE_FRAMES #undef USE_FRAMES
#endif #endif
#if 0 || (USE_ANSI) || (USE_SCREEN) #if 0 || (USE_ANSI) || (USE_SCREEN)
#define USE_CONSOLE 1 #define USE_CONSOLE 1
#endif #endif
@@ -94,37 +94,23 @@
#undef USE_FRAMES #undef USE_FRAMES
#endif #endif
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
enum { enum { CON_INIT, CON_NONE, CON_FILE, CON_ANSI_MONO, CON_ANSI_COLOR, CON_SCREEN, CON_UNUSED };
CON_INIT,
CON_NONE,
CON_FILE,
CON_ANSI_MONO,
CON_ANSI_COLOR,
CON_SCREEN,
CON_UNUSED
};
#if (USE_CONSOLE) #if (USE_CONSOLE)
typedef struct typedef struct {
{
int (*init)(FILE *f, int, int); int (*init)(FILE *f, int, int);
int (*set_fg)(FILE *f, int fg); int (*set_fg)(FILE *f, int fg);
void (*print0)(FILE *f, const char *s); void (*print0)(FILE *f, const char *s);
bool (*intro)(FILE *f); bool (*intro)(FILE *f);
} } console_t;
console_t;
void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3); void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
#define FG_BLACK 0x00 #define FG_BLACK 0x00
#define FG_BLUE 0x01 #define FG_BLUE 0x01
#define FG_GREEN 0x02 #define FG_GREEN 0x02
@@ -153,7 +139,6 @@ void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
#endif /* USE_CONSOLE */ #endif /* USE_CONSOLE */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -172,7 +157,6 @@ extern console_t console_ansi_mono;
extern console_t console_ansi_color; extern console_t console_ansi_color;
extern console_t console_screen; extern console_t console_screen;
#define con_fg(f, x) con->set_fg(f, x) #define con_fg(f, x) con->set_fg(f, x)
#else #else
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "../conf.h"
#if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__) #if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__)
#if (ACC_CC_GNUC >= 0x040300ul) #if (ACC_CC_GNUC >= 0x040300ul)
@@ -81,7 +81,9 @@ struct screen_data_t {
}; };
/* atExit information */ /* atExit information */
static struct { int cursor_shape; } ae = {-1}; static struct {
int cursor_shape;
} ae = {-1};
#if USE_SCROLLBACK #if USE_SCROLLBACK
static __inline__ void sb_add(screen_t *this, int *val, int inc) { static __inline__ void sb_add(screen_t *this, int *val, int inc) {
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "../conf.h"
#if (USE_SCREEN) #if (USE_SCREEN)
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "../conf.h"
#if (USE_SCREEN) && (USE_SCREEN_VCSA) #if (USE_SCREEN) && (USE_SCREEN_VCSA)
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "../conf.h"
#if (USE_SCREEN_WIN32) #if (USE_SCREEN_WIN32)
+5 -4
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,9 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#ifndef __UPX_SCREEN_H #pragma once
#define __UPX_SCREEN_H 1 #ifndef UPX_SCREEN_H__
#define UPX_SCREEN_H__ 1
#if (USE_SCREEN) #if (USE_SCREEN)
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+7 -4
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -117,6 +117,7 @@ void FileBase::closex() {
throwIOException("close failed", errno); throwIOException("close failed", errno);
} }
// Return value of ::seek is the resulting file offset (same as ::tell())
upx_off_t FileBase::seek(upx_off_t off, int whence) { upx_off_t FileBase::seek(upx_off_t off, int whence) {
if (!isOpen()) if (!isOpen())
throwIOException("bad seek 1"); throwIOException("bad seek 1");
@@ -132,9 +133,11 @@ upx_off_t FileBase::seek(upx_off_t off, int whence) {
off += _offset + _length; off += _offset + _length;
whence = SEEK_SET; whence = SEEK_SET;
} }
if (::lseek(_fd, off, whence) < 0) // SEEK_CUR falls through to here
upx_off_t rv = ::lseek(_fd, off, whence);
if (rv < 0)
throwIOException("seek error", errno); throwIOException("seek error", errno);
return off - _offset; return rv - _offset;
} }
upx_off_t FileBase::tell() const { upx_off_t FileBase::tell() const {
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+25 -47
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,42 +25,34 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "conf.h"
#include "filter.h" #include "filter.h"
#include "file.h" #include "file.h"
/************************************************************************* /*************************************************************************
// util // util
**************************************************************************/ **************************************************************************/
static //inline static void initFilter(Filter *f, upx_byte *buf, unsigned buf_len) {
void initFilter(Filter *f, upx_byte *buf, unsigned buf_len)
{
f->buf = buf; f->buf = buf;
f->buf_len = buf_len; f->buf_len = buf_len;
// clear output parameters // clear output parameters
f->calls = f->wrongcalls = f->noncalls = f->firstcall = f->lastcall = 0; f->calls = f->wrongcalls = f->noncalls = f->firstcall = f->lastcall = 0;
} }
/************************************************************************* /*************************************************************************
// get a FilterEntry // get a FilterEntry
**************************************************************************/ **************************************************************************/
const FilterImp::FilterEntry *FilterImp::getFilter(int id) const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) {
{
static bool done = false; static bool done = false;
static unsigned char filter_map[256]; static unsigned char filter_map[256];
if (!done) if (!done) {
{
// init the filter_map[] // init the filter_map[]
assert(n_filters <= 254); // as 0xff means "empty slot" assert(n_filters <= 254); // as 0xff means "empty slot"
memset(filter_map, 0xff, sizeof(filter_map)); memset(filter_map, 0xff, sizeof(filter_map));
for (int i = 0; i < n_filters; i++) for (int i = 0; i < n_filters; i++) {
{
int filter_id = filters[i].id; int filter_id = filters[i].id;
assert(filter_id >= 0 && filter_id <= 255); assert(filter_id >= 0 && filter_id <= 255);
assert(filter_map[filter_id] == 0xff); assert(filter_map[filter_id] == 0xff);
@@ -78,15 +70,12 @@ const FilterImp::FilterEntry *FilterImp::getFilter(int id)
return &filters[index]; return &filters[index];
} }
bool Filter::isValidFilter(int filter_id) {
bool Filter::isValidFilter(int filter_id) const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(filter_id);
{
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(filter_id);
return fe != nullptr; return fe != nullptr;
} }
bool Filter::isValidFilter(int filter_id, const int *allowed_filters) bool Filter::isValidFilter(int filter_id, const int *allowed_filters) {
{
if (!isValidFilter(filter_id)) if (!isValidFilter(filter_id))
return false; return false;
if (filter_id == 0) if (filter_id == 0)
@@ -99,13 +88,11 @@ bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
return false; return false;
} }
/************************************************************************* /*************************************************************************
// high level API // high level API
**************************************************************************/ **************************************************************************/
void Filter::init(int id_, unsigned addvalue_) void Filter::init(int id_, unsigned addvalue_) {
{
this->id = id_; this->id = id_;
initFilter(this, nullptr, 0); initFilter(this, nullptr, 0);
// clear input parameters // clear input parameters
@@ -116,12 +103,10 @@ void Filter::init(int id_, unsigned addvalue_)
this->n_mru = 0; this->n_mru = 0;
} }
bool Filter::filter(upx_byte *buf_, unsigned buf_len_) {
bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
{
initFilter(this, buf_, buf_len_); initFilter(this, buf_, buf_len_);
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id); const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
if (fe == nullptr) if (fe == nullptr)
throwInternalError("filter-1"); throwInternalError("filter-1");
if (fe->id == 0) if (fe->id == 0)
@@ -138,10 +123,10 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
if (clevel != 1) if (clevel != 1)
this->adler = upx_adler32(this->buf, this->buf_len); this->adler = upx_adler32(this->buf, this->buf_len);
//printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len); NO_printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
// OutputFile::dump("filter.dat", buf, buf_len); // OutputFile::dump("filter.dat", buf, buf_len);
int r = (*fe->do_filter)(this); int r = (*fe->do_filter)(this);
//printf("filter: %02x %d\n", fe->id, r); NO_printf("filter: %02x %d\n", fe->id, r);
if (r > 0) if (r > 0)
throwFilterException(); throwFilterException();
if (r == 0) if (r == 0)
@@ -149,12 +134,10 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
return false; return false;
} }
void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum) {
void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum)
{
initFilter(this, buf_, buf_len_); initFilter(this, buf_, buf_len_);
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id); const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
if (fe == nullptr) if (fe == nullptr)
throwInternalError("unfilter-1"); throwInternalError("unfilter-1");
if (fe->id == 0) if (fe->id == 0)
@@ -166,24 +149,21 @@ void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum)
if (!fe->do_unfilter) if (!fe->do_unfilter)
throwInternalError("unfilter-2"); throwInternalError("unfilter-2");
//printf("unfilter: %02x %p %d\n", this->id, this->buf, this->buf_len); NO_printf("unfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
int r = (*fe->do_unfilter)(this); int r = (*fe->do_unfilter)(this);
//printf("unfilter: %02x %d\n", fe->id, r); NO_printf("unfilter: %02x %d\n", fe->id, r);
if (r != 0) if (r != 0)
throwInternalError("unfilter-3"); throwInternalError("unfilter-3");
// OutputFile::dump("unfilter.dat", buf, buf_len); // OutputFile::dump("unfilter.dat", buf, buf_len);
// verify checksum // verify checksum
if (verify_checksum && clevel != 1) if (verify_checksum && clevel != 1) {
{
if (this->adler != upx_adler32(this->buf, this->buf_len)) if (this->adler != upx_adler32(this->buf, this->buf_len))
throwInternalError("unfilter-4"); throwInternalError("unfilter-4");
} }
} }
void Filter::verifyUnfilter() {
void Filter::verifyUnfilter()
{
// Note: // Note:
// This verify is just because of complete paranoia that there // This verify is just because of complete paranoia that there
// could be a hidden bug in the filter implementation, and // could be a hidden bug in the filter implementation, and
@@ -193,20 +173,18 @@ void Filter::verifyUnfilter()
// See also: // See also:
// Packer::verifyOverlappingDecompression() // Packer::verifyOverlappingDecompression()
//printf("verifyUnfilter: %02x %p %d\n", this->id, this->buf, this->buf_len); NO_printf("verifyUnfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
if (clevel != 1) if (clevel != 1)
unfilter(this->buf, this->buf_len, true); unfilter(this->buf, this->buf_len, true);
} }
bool Filter::scan(const upx_byte *buf_, unsigned buf_len_) {
bool Filter::scan(const upx_byte *buf_, unsigned buf_len_)
{
// Note: must use const_cast here. This is fine as the scan // Note: must use const_cast here. This is fine as the scan
// implementations (fe->do_scan) actually don't change the buffer. // implementations (fe->do_scan) actually don't change the buffer.
upx_byte *b = const_cast<upx_byte *>(buf_); upx_byte *b = const_cast<upx_byte *>(buf_);
initFilter(this, b, buf_len_); initFilter(this, b, buf_len_);
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id); const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
if (fe == nullptr) if (fe == nullptr)
throwInternalError("scan-1"); throwInternalError("scan-1");
if (fe->id == 0) if (fe->id == 0)
@@ -218,9 +196,9 @@ bool Filter::scan(const upx_byte *buf_, unsigned buf_len_)
if (!fe->do_scan) if (!fe->do_scan)
throwInternalError("scan-2"); throwInternalError("scan-2");
//printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len); NO_printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
int r = (*fe->do_scan)(this); int r = (*fe->do_scan)(this);
//printf("filter: %02x %d\n", fe->id, r); NO_printf("filter: %02x %d\n", fe->id, r);
if (r > 0) if (r > 0)
throwFilterException(); throwFilterException();
if (r == 0) if (r == 0)
+12 -18
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,13 +25,9 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#pragma once
#ifndef __UPX_FILTER_H #ifndef UPX_FILTER_H__
#define __UPX_FILTER_H 1 #define UPX_FILTER_H__ 1
class Filter;
class FilterImp;
/************************************************************************* /*************************************************************************
// A filter is a reversible operation that modifies a given // A filter is a reversible operation that modifies a given
@@ -50,10 +46,12 @@ class FilterImp;
// to absolute addresses so that the buffer compresses better. // to absolute addresses so that the buffer compresses better.
**************************************************************************/ **************************************************************************/
class Filter class Filter {
{
public: public:
Filter(int level) { clevel = level; init(); } Filter(int level) {
clevel = level;
init();
}
void init(int id = 0, unsigned addvalue = 0); void init(int id = 0, unsigned addvalue = 0);
bool filter(upx_byte *buf, unsigned buf_len); bool filter(upx_byte *buf, unsigned buf_len);
@@ -96,7 +94,6 @@ private:
int clevel; // compression level int clevel; // compression level
}; };
/************************************************************************* /*************************************************************************
// We don't want a full OO interface here because of // We don't want a full OO interface here because of
// certain implementation speed reasons. // certain implementation speed reasons.
@@ -104,13 +101,11 @@ private:
// This class is private to Filter - don't look. // This class is private to Filter - don't look.
**************************************************************************/ **************************************************************************/
class FilterImp class FilterImpl {
{
friend class Filter; friend class Filter;
private: private:
struct FilterEntry struct FilterEntry {
{
int id; // 0 .. 255 int id; // 0 .. 255
unsigned min_buf_len; unsigned min_buf_len;
unsigned max_buf_len; unsigned max_buf_len;
@@ -128,7 +123,6 @@ private:
static const int n_filters; // number of filters[] static const int n_filters; // number of filters[]
}; };
#endif /* already included */ #endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2000-2022 John F. Reiser Copyright (C) 2000-2023 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2000-2022 John F. Reiser Copyright (C) 2000-2023 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2000-2022 John F. Reiser Copyright (C) 2000-2023 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+28 -28
View File
@@ -1,9 +1,9 @@
/* filteri.cpp -- filter implementation (low-level) /* filter_impl.cpp -- filter implementation (low-level)
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -26,8 +26,8 @@
*/ */
#include "conf.h" #include "../conf.h"
#include "filter.h" #include "../filter.h"
static unsigned static unsigned
umin(unsigned const a, unsigned const b) umin(unsigned const a, unsigned const b)
@@ -45,20 +45,20 @@ umin(unsigned const a, unsigned const b)
// util // util
**************************************************************************/ **************************************************************************/
#include "filter/getcto.h" #include "getcto.h"
/************************************************************************* /*************************************************************************
// simple filters: calltrick / swaptrick / delta / ... // simple filters: calltrick / swaptrick / delta / ...
**************************************************************************/ **************************************************************************/
#include "filter/ct.h" #include "ct.h"
#include "filter/sw.h" #include "sw.h"
#include "filter/ctsw.h" #include "ctsw.h"
#include "filter/sub8.h" #include "sub8.h"
#include "filter/sub16.h" #include "sub16.h"
#include "filter/sub32.h" #include "sub32.h"
/************************************************************************* /*************************************************************************
@@ -68,25 +68,25 @@ umin(unsigned const a, unsigned const b)
#define COND(b,x) (b[x] == 0xe8) #define COND(b,x) (b[x] == 0xe8)
#define F f_cto32_e8_bswap_le #define F f_cto32_e8_bswap_le
#define U u_cto32_e8_bswap_le #define U u_cto32_e8_bswap_le
#include "filter/cto.h" #include "cto.h"
#define F s_cto32_e8_bswap_le #define F s_cto32_e8_bswap_le
#include "filter/cto.h" #include "cto.h"
#undef COND #undef COND
#define COND(b,x) (b[x] == 0xe9) #define COND(b,x) (b[x] == 0xe9)
#define F f_cto32_e9_bswap_le #define F f_cto32_e9_bswap_le
#define U u_cto32_e9_bswap_le #define U u_cto32_e9_bswap_le
#include "filter/cto.h" #include "cto.h"
#define F s_cto32_e9_bswap_le #define F s_cto32_e9_bswap_le
#include "filter/cto.h" #include "cto.h"
#undef COND #undef COND
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9) #define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
#define F f_cto32_e8e9_bswap_le #define F f_cto32_e8e9_bswap_le
#define U u_cto32_e8e9_bswap_le #define U u_cto32_e8e9_bswap_le
#include "filter/cto.h" #include "cto.h"
#define F s_cto32_e8e9_bswap_le #define F s_cto32_e8e9_bswap_le
#include "filter/cto.h" #include "cto.h"
#undef COND #undef COND
@@ -97,9 +97,9 @@ umin(unsigned const a, unsigned const b)
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9) #define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
#define F f_ctoj32_e8e9_bswap_le #define F f_ctoj32_e8e9_bswap_le
#define U u_ctoj32_e8e9_bswap_le #define U u_ctoj32_e8e9_bswap_le
#include "filter/ctoj.h" #include "ctoj.h"
#define F s_ctoj32_e8e9_bswap_le #define F s_ctoj32_e8e9_bswap_le
#include "filter/ctoj.h" #include "ctoj.h"
#undef COND #undef COND
@@ -112,9 +112,9 @@ umin(unsigned const a, unsigned const b)
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc))) #define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
#define F f_ctok32_e8e9_bswap_le #define F f_ctok32_e8e9_bswap_le
#define U u_ctok32_e8e9_bswap_le #define U u_ctok32_e8e9_bswap_le
#include "filter/ctok.h" #include "ctok.h"
#define F s_ctok32_e8e9_bswap_le #define F s_ctok32_e8e9_bswap_le
#include "filter/ctok.h" #include "ctok.h"
#undef COND #undef COND
#undef COND2 #undef COND2
#undef COND1 #undef COND1
@@ -138,9 +138,9 @@ umin(unsigned const a, unsigned const b)
#define F f_ctojr32_e8e9_bswap_le #define F f_ctojr32_e8e9_bswap_le
#define U u_ctojr32_e8e9_bswap_le #define U u_ctojr32_e8e9_bswap_le
#include "filter/ctojr.h" #include "ctojr.h"
#define F s_ctojr32_e8e9_bswap_le #define F s_ctojr32_e8e9_bswap_le
#include "filter/ctojr.h" #include "ctojr.h"
#undef CONDU #undef CONDU
#undef CONDF #undef CONDF
@@ -158,9 +158,9 @@ umin(unsigned const a, unsigned const b)
#define COND(b,x) (18==(get_be32(b+x)>>26)) #define COND(b,x) (18==(get_be32(b+x)>>26))
#define F f_ppcbxx #define F f_ppcbxx
#define U u_ppcbxx #define U u_ppcbxx
#include "filter/ppcbxx.h" #include "ppcbxx.h"
#define F s_ppcbxx #define F s_ppcbxx
#include "filter/ppcbxx.h" #include "ppcbxx.h"
#undef COND #undef COND
@@ -168,7 +168,7 @@ umin(unsigned const a, unsigned const b)
// database for use in class Filter // database for use in class Filter
**************************************************************************/ **************************************************************************/
const FilterImp::FilterEntry FilterImp::filters[] = { const FilterImpl::FilterEntry FilterImpl::filters[] = {
// no filter // no filter
{ 0x00, 0, 0, nullptr, nullptr, nullptr }, { 0x00, 0, 0, nullptr, nullptr, nullptr },
@@ -261,6 +261,6 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx }, { 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
}; };
const int FilterImp::n_filters = TABLESIZE(filters); const int FilterImpl::n_filters = TABLESIZE(filters);
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2004-2022 John F. Reiser Copyright (C) 2004-2023 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+23 -11
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -27,9 +27,9 @@
#include "conf.h" #include "conf.h"
#include "compress.h"
#include "packmast.h" #include "packmast.h"
#include "packer.h" #include "packer.h"
#include "compress/compress.h" // upx_ucl_version_string()
/************************************************************************* /*************************************************************************
@@ -38,6 +38,7 @@
static bool head_done = 0; static bool head_done = 0;
// also see UPX_CONFIG_DISABLE_GITREV in CMakeLists.txt
#if defined(UPX_VERSION_GITREV) #if defined(UPX_VERSION_GITREV)
const char gitrev[] = UPX_VERSION_GITREV; const char gitrev[] = UPX_VERSION_GITREV;
#else #else
@@ -381,11 +382,13 @@ void show_version(bool one_line)
FILE *fp = stdout; FILE *fp = stdout;
const char *v; const char *v;
fprintf(fp, "upx %s\n", UPX_VERSION_STRING #if defined(UPX_VERSION_GIT_DESCRIBE)
#if defined(UPX_VERSION_GITREV) fprintf(fp, "upx %s\n", UPX_VERSION_GIT_DESCRIBE);
"-git-" UPX_VERSION_GITREV #elif defined(UPX_VERSION_GITREV)
fprintf(fp, "upx %s\n", UPX_VERSION_STRING "-git-" UPX_VERSION_GITREV);
#else
fprintf(fp, "upx %s\n", UPX_VERSION_STRING);
#endif #endif
);
if (one_line) if (one_line)
return; return;
#if (WITH_NRV) #if (WITH_NRV)
@@ -408,19 +411,28 @@ void show_version(bool one_line)
if (v != nullptr && v[0]) if (v != nullptr && v[0])
fprintf(fp, "LZMA SDK version %s\n", v); fprintf(fp, "LZMA SDK version %s\n", v);
#endif #endif
#if (WITH_ZSTD)
v = upx_zstd_version_string();
if (v != nullptr && v[0])
fprintf(fp, "zstd data compression library %s\n", v);
#endif
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
fprintf(fp, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR); fprintf(fp, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
#endif #endif
fprintf(fp, "Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer\n"); fprintf(fp, "Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer\n");
fprintf(fp, "Copyright (C) 1996-2022 Laszlo Molnar\n"); fprintf(fp, "Copyright (C) 1996-2023 Laszlo Molnar\n");
fprintf(fp, "Copyright (C) 2000-2022 John F. Reiser\n"); fprintf(fp, "Copyright (C) 2000-2023 John F. Reiser\n");
fprintf(fp, "Copyright (C) 2002-2022 Jens Medoch\n"); fprintf(fp, "Copyright (C) 2002-2023 Jens Medoch\n");
#if (WITH_ZLIB) #if (WITH_ZLIB)
fprintf(fp, "Copyright (C) 1995" "-2022 Jean-loup Gailly and Mark Adler\n"); fprintf(fp, "Copyright (C) 1995" "-2022 Jean-loup Gailly and Mark Adler\n");
#endif #endif
#if (WITH_LZMA) #if (WITH_LZMA)
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n"); fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
#endif #endif
#if (WITH_ZSTD)
// see vendor/zstd/LICENSE; main author is Yann Collet
fprintf(fp, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n");
#endif
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
fprintf(fp, "Copyright (C) 2016" "-2021 Viktor Kirilov\n"); fprintf(fp, "Copyright (C) 2016" "-2021 Viktor Kirilov\n");
#endif #endif
+44 -107
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,34 +25,20 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "conf.h"
#include "file.h" #include "file.h"
#include "util/membuffer.h" #include "util/membuffer.h"
#include "lefile.h" #include "lefile.h"
LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) {
LeFile::LeFile(InputFile *f) : COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196)
fif(f), fof(nullptr), COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24)
le_offset(0), exe_offset(0) COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4)
{
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(&ih, 0, sizeof ih);
memset(&oh, 0, sizeof oh); memset(&oh, 0, sizeof oh);
iobject_table = oobject_table = nullptr;
ifpage_table = ofpage_table = nullptr;
ipm_entries = opm_entries = nullptr;
ires_names = ores_names = nullptr;
ifixups = ofixups = nullptr;
inonres_names = ononres_names = nullptr;
ientries = oentries = nullptr;
} }
LeFile::~LeFile() {
LeFile::~LeFile()
{
delete[] iobject_table; delete[] iobject_table;
delete[] oobject_table; delete[] oobject_table;
delete[] ifpage_table; delete[] ifpage_table;
@@ -69,30 +55,23 @@ LeFile::~LeFile()
delete[] oentries; delete[] oentries;
} }
#define objects ih.object_table_entries #define objects ih.object_table_entries
#define pages ih.memory_pages #define pages ih.memory_pages
#define mps ih.memory_page_size #define mps ih.memory_page_size
void LeFile::readObjectTable() {
void LeFile::readObjectTable()
{
soobject_table = objects; soobject_table = objects;
iobject_table = New(le_object_table_entry_t, soobject_table); iobject_table = New(le_object_table_entry_t, soobject_table);
fif->seek(le_offset + ih.object_table_offset, SEEK_SET); fif->seek(le_offset + ih.object_table_offset, SEEK_SET);
fif->readx(iobject_table, sizeof(*iobject_table) * objects); fif->readx(iobject_table, sizeof(*iobject_table) * objects);
} }
void LeFile::writeObjectTable() {
void LeFile::writeObjectTable()
{
if (fof && oobject_table) if (fof && oobject_table)
fof->write(oobject_table, sizeof(*iobject_table) * soobject_table); fof->write(oobject_table, sizeof(*iobject_table) * soobject_table);
} }
void LeFile::readPageMap() {
void LeFile::readPageMap()
{
sopm_entries = pages; sopm_entries = pages;
ipm_entries = New(le_pagemap_entry_t, sopm_entries); ipm_entries = New(le_pagemap_entry_t, sopm_entries);
fif->seek(le_offset + ih.object_pagemap_offset, SEEK_SET); fif->seek(le_offset + ih.object_pagemap_offset, SEEK_SET);
@@ -103,104 +82,80 @@ void LeFile::readPageMap()
throwCantPack("unexpected value in page map table"); throwCantPack("unexpected value in page map table");
} }
void LeFile::writePageMap() {
void LeFile::writePageMap()
{
if (fof && opm_entries) if (fof && opm_entries)
fof->write(opm_entries, sizeof(*ipm_entries) * sopm_entries); fof->write(opm_entries, sizeof(*ipm_entries) * sopm_entries);
} }
void LeFile::readResidentNames() {
void LeFile::readResidentNames()
{
sores_names = ih.entry_table_offset - ih.resident_names_offset; sores_names = ih.entry_table_offset - ih.resident_names_offset;
ires_names = New(upx_byte, sores_names); ires_names = New(upx_byte, sores_names);
fif->seek(le_offset + ih.resident_names_offset, SEEK_SET); fif->seek(le_offset + ih.resident_names_offset, SEEK_SET);
fif->readx(ires_names, sores_names); fif->readx(ires_names, sores_names);
} }
void LeFile::writeResidentNames() {
void LeFile::writeResidentNames()
{
if (fof && ores_names) if (fof && ores_names)
fof->write(ores_names, sores_names); fof->write(ores_names, sores_names);
} }
void LeFile::readEntryTable() {
void LeFile::readEntryTable()
{
soentries = ih.fixup_page_table_offset - ih.entry_table_offset; soentries = ih.fixup_page_table_offset - ih.entry_table_offset;
fif->seek(le_offset + ih.entry_table_offset, SEEK_SET); fif->seek(le_offset + ih.entry_table_offset, SEEK_SET);
ientries = New(upx_byte, soentries); ientries = New(upx_byte, soentries);
fif->readx(ientries, soentries); fif->readx(ientries, soentries);
} }
void LeFile::writeEntryTable() {
void LeFile::writeEntryTable()
{
if (fof && oentries) if (fof && oentries)
fof->write(oentries, soentries); fof->write(oentries, soentries);
} }
void LeFile::readFixupPageTable() {
void LeFile::readFixupPageTable()
{
sofpage_table = 1 + pages; sofpage_table = 1 + pages;
ifpage_table = New(unsigned, sofpage_table); ifpage_table = New(unsigned, sofpage_table);
fif->seek(le_offset + ih.fixup_page_table_offset, SEEK_SET); fif->seek(le_offset + ih.fixup_page_table_offset, SEEK_SET);
fif->readx(ifpage_table, 4 * sofpage_table); fif->readx(ifpage_table, 4 * sofpage_table);
} }
void LeFile::writeFixupPageTable() {
void LeFile::writeFixupPageTable()
{
if (fof && ofpage_table) if (fof && ofpage_table)
fof->write(ofpage_table, 4 * sofpage_table); fof->write(ofpage_table, 4 * sofpage_table);
} }
void LeFile::readFixups() {
void LeFile::readFixups()
{
sofixups = get_le32(ifpage_table + pages) - get_le32(ifpage_table); sofixups = get_le32(ifpage_table + pages) - get_le32(ifpage_table);
ifixups = New(upx_byte, sofixups); ifixups = New(upx_byte, sofixups);
fif->seek(le_offset + ih.fixup_record_table_offset, SEEK_SET); fif->seek(le_offset + ih.fixup_record_table_offset, SEEK_SET);
fif->readx(ifixups, sofixups); fif->readx(ifixups, sofixups);
} }
void LeFile::writeFixups() {
void LeFile::writeFixups()
{
if (fof && ofixups) if (fof && ofixups)
fof->write(ofixups, sofixups); fof->write(ofixups, sofixups);
} }
unsigned LeFile::getImageSize() const {
unsigned LeFile::getImageSize() const
{
unsigned n = 0; unsigned n = 0;
if (ih.memory_pages > 0) if (ih.memory_pages > 0) {
{
n = (ih.memory_pages - 1) * ih.memory_page_size; n = (ih.memory_pages - 1) * ih.memory_page_size;
n += ih.bytes_on_last_page; n += ih.bytes_on_last_page;
} }
return n; return n;
} }
void LeFile::readImage() {
void LeFile::readImage()
{
soimage = pages * mps; soimage = pages * mps;
mb_iimage.alloc(soimage); mb_iimage.alloc(soimage);
mb_iimage.clear(); mb_iimage.clear();
iimage = mb_iimage; iimage = mb_iimage;
unsigned ic, jc; unsigned ic, jc;
for (ic = jc = 0; ic < pages; ic++) for (ic = jc = 0; ic < pages; ic++) {
{ if ((ipm_entries[ic].type & 0xC0) == 0) {
if ((ipm_entries[ic].type & 0xC0) == 0)
{
fif->seek(ih.data_pages_offset + exe_offset + fif->seek(ih.data_pages_offset + exe_offset +
(ipm_entries[ic].m*0x100 + ipm_entries[ic].l-1) * mps,SEEK_SET); (ipm_entries[ic].m * 0x100 + ipm_entries[ic].l - 1) * mps,
SEEK_SET);
auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page; auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page;
fif->readx(raw_bytes(iimage + jc, bytes), bytes); fif->readx(raw_bytes(iimage + jc, bytes), bytes);
} }
@@ -208,18 +163,13 @@ void LeFile::readImage()
} }
} }
void LeFile::writeImage() {
void LeFile::writeImage()
{
if (fof && oimage != nullptr) if (fof && oimage != nullptr)
fof->write(raw_bytes(oimage, soimage), soimage); fof->write(raw_bytes(oimage, soimage), soimage);
} }
void LeFile::readNonResidentNames() {
void LeFile::readNonResidentNames() if (ih.non_resident_name_table_length) {
{
if (ih.non_resident_name_table_length)
{
sononres_names = ih.non_resident_name_table_length; sononres_names = ih.non_resident_name_table_length;
inonres_names = New(upx_byte, sononres_names); inonres_names = New(upx_byte, sononres_names);
fif->seek(exe_offset + ih.non_resident_name_table_offset, SEEK_SET); fif->seek(exe_offset + ih.non_resident_name_table_offset, SEEK_SET);
@@ -227,42 +177,34 @@ void LeFile::readNonResidentNames()
} }
} }
void LeFile::writeNonResidentNames() {
void LeFile::writeNonResidentNames()
{
if (fof && ononres_names) if (fof && ononres_names)
fof->write(ononres_names, sononres_names); fof->write(ononres_names, sononres_names);
} }
bool LeFile::readFileHeader() {
bool LeFile::readFileHeader()
{
#define H(x) get_le16(header + 2 * (x)) #define H(x) get_le16(header + 2 * (x))
upx_byte header[0x40]; upx_byte header[0x40];
le_offset = exe_offset = 0; le_offset = exe_offset = 0;
int ic; int ic;
for (ic = 0; ic < 20; ic++) for (ic = 0; ic < 20; ic++) {
{
fif->seek(le_offset, SEEK_SET); fif->seek(le_offset, SEEK_SET);
fif->readx(header, sizeof(header)); fif->readx(header, sizeof(header));
if (memcmp(header, "MZ", 2) == 0) // normal dos exe if (memcmp(header, "MZ", 2) == 0) // normal dos exe
{ {
exe_offset = le_offset; exe_offset = le_offset;
if (H(0x18/2) >= 0x40 if (H(0x18 / 2) >= 0x40 && memcmp(header + 0x19, "TIPPACH", 7)) // new format exe
&& memcmp(header+0x19,"TIPPACH",7)) // new format exe
le_offset += H(0x3c / 2) + H(0x3e / 2) * 65536; le_offset += H(0x3c / 2) + H(0x3e / 2) * 65536;
else else {
{
le_offset += H(2) * 512 + H(1); le_offset += H(2) * 512 + H(1);
if (H(1)) if (H(1))
le_offset -= 512; le_offset -= 512;
else if (H(2) == 0) else if (H(2) == 0)
return false; return false;
} }
} } else if (memcmp(header, "BW", 2) == 0) // used in dos4gw.exe
else if (memcmp(header,"BW",2) == 0) // used in dos4gw.exe
le_offset += H(2) * 512 + H(1); le_offset += H(2) * 512 + H(1);
else if (memcmp(header, "LE", 2) == 0) else if (memcmp(header, "LE", 2) == 0)
break; break;
@@ -279,11 +221,10 @@ bool LeFile::readFileHeader()
#undef H #undef H
} }
void LeFile::writeFile(OutputFile *f, bool le) {
void LeFile::writeFile(OutputFile *f, bool le)
{
fof = f; fof = f;
memcpy (&oh,&ih,(char*)&oh.memory_pages-(char*)&oh); // copy some members of the orig. header memcpy(&oh, &ih,
(char *) &oh.memory_pages - (char *) &oh); // copy some members of the orig. header
oh.memory_page_size = mps; oh.memory_page_size = mps;
oh.object_table_offset = sizeof(oh); oh.object_table_offset = sizeof(oh);
oh.object_table_entries = soobject_table; oh.object_table_entries = soobject_table;
@@ -294,9 +235,9 @@ void LeFile::writeFile(OutputFile *f, bool le)
oh.fixup_record_table_offset = oh.fixup_page_table_offset + sofpage_table * 4; oh.fixup_record_table_offset = oh.fixup_page_table_offset + sofpage_table * 4;
oh.imported_modules_name_table_offset = oh.fixup_record_table_offset + sofixups - FIXUP_EXTRA; oh.imported_modules_name_table_offset = oh.fixup_record_table_offset + sofixups - FIXUP_EXTRA;
oh.imported_procedures_name_table_offset = oh.imported_modules_name_table_offset; oh.imported_procedures_name_table_offset = oh.imported_modules_name_table_offset;
oh.data_pages_offset = oh.fixup_record_table_offset + sofixups + (le ? 0 : le_offset-exe_offset); oh.data_pages_offset =
if (ih.non_resident_name_table_length) oh.fixup_record_table_offset + sofixups + (le ? 0 : le_offset - exe_offset);
{ if (ih.non_resident_name_table_length) {
oh.non_resident_name_table_offset = oh.data_pages_offset + soimage; oh.non_resident_name_table_offset = oh.data_pages_offset + soimage;
oh.non_resident_name_table_length = sononres_names; oh.non_resident_name_table_length = sononres_names;
} }
@@ -314,9 +255,7 @@ void LeFile::writeFile(OutputFile *f, bool le)
writeNonResidentNames(); writeNonResidentNames();
} }
void LeFile::countFixups(unsigned *counts) const {
void LeFile::countFixups(unsigned *counts) const
{
const unsigned o = objects; const unsigned o = objects;
memset(counts, 0, sizeof(unsigned) * (o + 2)); memset(counts, 0, sizeof(unsigned) * (o + 2));
// counts[0..objects-1] - # of 32-bit offset relocations in for that objects // counts[0..objects-1] - # of 32-bit offset relocations in for that objects
@@ -327,12 +266,10 @@ void LeFile::countFixups(unsigned *counts) const
const unsigned sfixups = get_le32(ifpage_table + pages); const unsigned sfixups = get_le32(ifpage_table + pages);
unsigned ll; unsigned ll;
while ((unsigned)(fix - ifixups) < sfixups) while (ptr_udiff_bytes(fix, ifixups) < sfixups) {
{
if ((fix[1] & ~0x10) != 0) if ((fix[1] & ~0x10) != 0)
throwCantPack("unsupported fixup record"); throwCantPack("unsupported fixup record");
switch (*fix) switch (*fix) {
{
case 2: // selector fixup case 2: // selector fixup
counts[o] += 9; counts[o] += 9;
fix += 5; fix += 5;
+40 -34
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,20 +25,18 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#pragma once
#ifndef __UPX_LEFILE_H #ifndef UPX_LEFILE_H__
#define __UPX_LEFILE_H 1 #define UPX_LEFILE_H__ 1
class InputFile; class InputFile;
class OutputFile; class OutputFile;
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
class LeFile class LeFile {
{
protected: protected:
LeFile(InputFile *); LeFile(InputFile *);
virtual ~LeFile(); virtual ~LeFile();
@@ -49,7 +47,7 @@ protected:
protected: protected:
enum { FIXUP_EXTRA = 3 }; enum { FIXUP_EXTRA = 3 };
__packed_struct(le_header_t) struct alignas(1) le_header_t {
// 0x00 // 0x00
char _[2]; // signature: 'LE' || 'LX' char _[2]; // signature: 'LE' || 'LX'
char byte_order; // 0 little endian char byte_order; // 0 little endian
@@ -117,23 +115,23 @@ protected:
LE16 device_id; LE16 device_id;
LE16 ddk_version; LE16 ddk_version;
#endif #endif
__packed_struct_end() };
__packed_struct(le_object_table_entry_t) struct alignas(1) le_object_table_entry_t {
LE32 virtual_size; LE32 virtual_size;
LE32 base_address; LE32 base_address;
LE32 flags; LE32 flags;
LE32 pagemap_index; LE32 pagemap_index;
LE32 npages; LE32 npages;
LE32 reserved; LE32 reserved;
__packed_struct_end() };
__packed_struct(le_pagemap_entry_t) struct alignas(1) le_pagemap_entry_t {
unsigned char h; unsigned char h;
unsigned char m; unsigned char m;
unsigned char l; unsigned char l;
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
__packed_struct_end() };
virtual void readObjectTable(); virtual void readObjectTable();
virtual void writeObjectTable(); virtual void writeObjectTable();
@@ -147,17 +145,26 @@ protected:
virtual void readPageMap(); virtual void readPageMap();
virtual void writePageMap(); virtual void writePageMap();
virtual void encodePageMap(){opm_entries = ipm_entries; ipm_entries = nullptr;} virtual void encodePageMap() {
opm_entries = ipm_entries;
ipm_entries = nullptr;
}
virtual void decodePageMap() { encodePageMap(); } virtual void decodePageMap() { encodePageMap(); }
virtual void readResidentNames(); virtual void readResidentNames();
virtual void writeResidentNames(); virtual void writeResidentNames();
virtual void encodeResidentNames(){ores_names = ires_names; ires_names = nullptr;} virtual void encodeResidentNames() {
ores_names = ires_names;
ires_names = nullptr;
}
virtual void decodeResidentNames() { encodeResidentNames(); } virtual void decodeResidentNames() { encodeResidentNames(); }
virtual void readNonResidentNames(); virtual void readNonResidentNames();
virtual void writeNonResidentNames(); virtual void writeNonResidentNames();
virtual void encodeNonResidentNames(){ononres_names = inonres_names; inonres_names = nullptr;} virtual void encodeNonResidentNames() {
ononres_names = inonres_names;
inonres_names = nullptr;
}
virtual void decodeNonResidentNames() { encodeNonResidentNames(); } virtual void decodeNonResidentNames() { encodeNonResidentNames(); }
virtual void readEntryTable(); virtual void readEntryTable();
@@ -178,32 +185,32 @@ protected:
void countFixups(unsigned *) const; void countFixups(unsigned *) const;
unsigned getImageSize() const; unsigned getImageSize() const;
InputFile *fif; InputFile *fif = nullptr;
OutputFile *fof; OutputFile *fof = nullptr;
unsigned le_offset; unsigned le_offset;
unsigned exe_offset; unsigned exe_offset;
le_header_t ih; le_header_t ih;
le_header_t oh; le_header_t oh;
le_object_table_entry_t *iobject_table; le_object_table_entry_t *iobject_table = nullptr;
le_object_table_entry_t *oobject_table; le_object_table_entry_t *oobject_table = nullptr;
unsigned *ifpage_table; unsigned *ifpage_table = nullptr;
unsigned *ofpage_table; unsigned *ofpage_table = nullptr;
le_pagemap_entry_t *ipm_entries; le_pagemap_entry_t *ipm_entries = nullptr;
le_pagemap_entry_t *opm_entries; le_pagemap_entry_t *opm_entries = nullptr;
upx_byte *ires_names; upx_byte *ires_names = nullptr;
upx_byte *ores_names; upx_byte *ores_names = nullptr;
upx_byte *ifixups; upx_byte *ifixups = nullptr;
upx_byte *ofixups; upx_byte *ofixups = nullptr;
upx_byte *inonres_names; upx_byte *inonres_names = nullptr;
upx_byte *ononres_names; upx_byte *ononres_names = nullptr;
MemBuffer mb_iimage; MemBuffer mb_iimage;
SPAN_0(upx_byte) iimage = nullptr; SPAN_0(upx_byte) iimage = nullptr;
MemBuffer mb_oimage; MemBuffer mb_oimage;
SPAN_0(upx_byte) oimage = nullptr; SPAN_0(upx_byte) oimage = nullptr;
upx_byte *ientries; upx_byte *ientries = nullptr;
upx_byte *oentries; upx_byte *oentries = nullptr;
unsigned soobject_table; unsigned soobject_table;
unsigned sofpage_table; unsigned sofpage_table;
@@ -220,7 +227,6 @@ private:
LeFile &operator=(const LeFile &) = delete; LeFile &operator=(const LeFile &) = delete;
}; };
#endif /* already included */ #endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+30 -21
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -157,8 +157,11 @@ void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra) {
} }
input[inputlen] = 0; // NUL terminate input[inputlen] = 0; // NUL terminate
output = new upx_byte[inputlen ? (inputlen + pxtra) : 0x4000]; output_capacity = (inputlen ? (inputlen + pxtra) : 0x4000);
assert(output_capacity <= (1 << 16)); // LE16 l_info.l_size
output = new upx_byte[output_capacity];
outputlen = 0; outputlen = 0;
NO_printf("\nElfLinker::init %d @%p\n", output_capacity, output);
// FIXME: bad compare when either symbols or relocs are absent // FIXME: bad compare when either symbols or relocs are absent
if ((int) strlen("Sections:\n" if ((int) strlen("Sections:\n"
@@ -198,8 +201,7 @@ void ElfLinker::preprocessSections(char *start, char const *end) {
char *n = strstr(start, name); char *n = strstr(start, name);
n[strlen(name)] = 0; n[strlen(name)] = 0;
addSection(n, input + offset, size, align); addSection(n, input + offset, size, align);
NO_printf("section %s preprocessed\n", n);
// printf("section %s preprocessed\n", n);
} }
} }
addSection("*ABS*", nullptr, 0, 0); addSection("*ABS*", nullptr, 0, 0);
@@ -224,13 +226,13 @@ void ElfLinker::preprocessSymbols(char *start, char const *end) {
assert(offset == 0); assert(offset == 0);
} }
#if 0 #if 0
else if (sscanf(start, "%x%*8c %1023s %*x %1023s", else if (sscanf(start, "%x%*8c %1023s %*x %1023s", &offset, section, symbol) == 3)
#else #else
// work around broken scanf() implementations // work around broken scanf() implementations
// http://bugs.winehq.org/show_bug.cgi?id=10401 (fixed in Wine 0.9.58) // http://bugs.winehq.org/show_bug.cgi?id=10401 (fixed in Wine 0.9.58)
else if (sscanf(start, "%x%*c%*c%*c%*c%*c%*c%*c%*c %1023s %*x %1023s", else if (sscanf(start, "%x%*c%*c%*c%*c%*c%*c%*c%*c %1023s %*x %1023s", &offset, section,
symbol) == 3)
#endif #endif
&offset, section, symbol) == 3)
{ {
char *s = strstr(start, symbol); char *s = strstr(start, symbol);
s[strlen(symbol)] = 0; s[strlen(symbol)] = 0;
@@ -290,8 +292,8 @@ void ElfLinker::preprocessRelocations(char *start, char const *end) {
if (section) { if (section) {
addRelocation(section->name, offset, t, symbol, add); addRelocation(section->name, offset, t, symbol, add);
// printf("relocation %s %s %x %llu preprocessed\n", section->name, symbol, offset, NO_printf("relocation %s %s %x %llu preprocessed\n", section->name, symbol, offset,
// (unsigned long long) add); (unsigned long long) add);
} }
} }
} }
@@ -317,7 +319,7 @@ ElfLinker::Symbol *ElfLinker::findSymbol(const char *name, bool fatal) const {
ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen, ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen,
unsigned p2align) { unsigned p2align) {
// printf("addSection: %s len=%d align=%d\n", sname, slen, p2align); NO_printf("addSection: %s len=%d align=%d\n", sname, slen, p2align);
if (!sdata && (!strcmp("ABS*", sname) || !strcmp("UND*", sname))) if (!sdata && (!strcmp("ABS*", sname) || !strcmp("UND*", sname)))
return nullptr; return nullptr;
if (update_capacity(nsections, &nsections_capacity)) if (update_capacity(nsections, &nsections_capacity))
@@ -335,7 +337,7 @@ ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata,
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section, ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
upx_uint64_t offset) { upx_uint64_t offset) {
// printf("addSymbol: %s %s 0x%x\n", name, section, offset); NO_printf("addSymbol: %s %s 0x%llx\n", name, section, offset);
if (update_capacity(nsymbols, &nsymbols_capacity)) if (update_capacity(nsymbols, &nsymbols_capacity))
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *))); symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
assert(symbols != nullptr); assert(symbols != nullptr);
@@ -363,7 +365,7 @@ ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned of
void ElfLinker::setLoaderAlignOffset(int phase) void ElfLinker::setLoaderAlignOffset(int phase)
{ {
//assert(phase & 0); //assert(phase & 0);
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase); NO_printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
} }
#endif #endif
@@ -408,9 +410,11 @@ int ElfLinker::addLoader(const char *sname) {
tail->size += l; tail->size += l;
} }
} }
// Section->output is not relocatable, and C++ has no realloc() anyway.
assert((section->size + outputlen) <= output_capacity);
memcpy(output + outputlen, section->input, section->size); memcpy(output + outputlen, section->input, section->size);
section->output = output + outputlen; section->output = output + outputlen; // FIXME: INVALIDATED by realloc()
// printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name); NO_printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name);
outputlen += section->size; outputlen += section->size;
if (head) { if (head) {
@@ -479,11 +483,12 @@ void ElfLinker::relocate() {
value = rel->value->section->offset + rel->value->offset + rel->add; value = rel->value->section->offset + rel->value->offset + rel->add;
} }
upx_byte *location = rel->section->output + rel->offset; upx_byte *location = rel->section->output + rel->offset;
// printf("%-28s %-28s %-10s %#16llx %#16llx\n", rel->section->name, rel->value->name, NO_printf("%-28s %-28s %-10s %#16llx %#16llx\n", rel->section->name, rel->value->name,
// rel->type, (long long) value, (long long) value - rel->section->offset - rel->offset); rel->type, (long long) value,
// printf(" %llx %d %llx %d %llx : %d\n", (long long) value, (long long) value - rel->section->offset - rel->offset);
// (int)rel->value->section->offset, NO_printf(" %llx %d %llx %d %llx :%d\n", (long long) value,
// rel->value->offset, rel->offset, (long long) rel->add, *location); (int) rel->value->section->offset, rel->value->offset, rel->offset,
(long long) rel->add, *location);
relocate1(rel, location, value, rel->type); relocate1(rel, location, value, rel->type);
} }
} }
@@ -578,8 +583,12 @@ void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location, upx_ui
bool range_check = false; bool range_check = false;
if (strncmp(type, "PC", 2) == 0) { if (strncmp(type, "PC", 2) == 0) {
value -= rel->section->offset + rel->offset;
type += 2; type += 2;
value -= rel->section->offset + rel->offset;
range_check = true;
} else if (strncmp(type, "PLT", 3) == 0) {
type += 3;
value -= rel->section->offset + rel->offset;
range_check = true; range_check = true;
} }
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -46,6 +46,7 @@ protected:
int inputlen = 0; int inputlen = 0;
upx_byte *output = nullptr; upx_byte *output = nullptr;
int outputlen = 0; int outputlen = 0;
unsigned output_capacity = 0;
Section *head = nullptr; Section *head = nullptr;
Section *tail = nullptr; Section *tail = nullptr;
+29 -12
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,16 +25,22 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
// main entry, mostly boring stuff; see work.cpp for actual action
#include "conf.h" #include "conf.h"
#include "compress.h"
#include "file.h" #include "file.h"
#include "packer.h" #include "packer.h"
#include "p_elf.h" #include "p_elf.h"
#include "compress/compress.h" // upx_ucl_init()
/************************************************************************* /*************************************************************************
// options // options
**************************************************************************/ **************************************************************************/
#ifndef OPTIONS_VAR
#define OPTIONS_VAR "UPX"
#endif
static const char *argv0 = ""; static const char *argv0 = "";
const char *progname = ""; const char *progname = "";
@@ -375,6 +381,9 @@ static int do_option(int optc, const char *arg) {
case 'f': case 'f':
opt->force++; opt->force++;
break; break;
case 529:
opt->force_overwrite = true;
break;
case 909: case 909:
set_cmd(CMD_FILEINFO); set_cmd(CMD_FILEINFO);
break; break;
@@ -566,7 +575,7 @@ static int do_option(int optc, const char *arg) {
case 525: // --exact case 525: // --exact
opt->exact = true; opt->exact = true;
break; break;
// compression runtime parameters // CRP - Compression Runtime Parameters (undocumented and subject to change)
case 801: case 801:
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg); getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
break; break;
@@ -801,6 +810,7 @@ int main_get_options(int argc, char **argv) {
// options // options
{"force", 0, N, 'f'}, // force overwrite of output files {"force", 0, N, 'f'}, // force overwrite of output files
{"force-compress", 0, N, 'f'}, // and compression of suspicious files {"force-compress", 0, N, 'f'}, // and compression of suspicious files
{"force-overwrite", 0x90, N, 529}, // force overwrite of output files
{"info", 0, N, 'i'}, // info mode {"info", 0, N, 'i'}, // info mode
{"no-env", 0x10, N, 519}, // no environment var {"no-env", 0x10, N, 519}, // no environment var
{"no-mode", 0x10, N, 526}, // do not preserve mode (permissions) {"no-mode", 0x10, N, 526}, // do not preserve mode (permissions)
@@ -862,7 +872,7 @@ int main_get_options(int argc, char **argv) {
{"filter", 0x31, N, 521}, // --filter= {"filter", 0x31, N, 521}, // --filter=
{"no-filter", 0x10, N, 522}, {"no-filter", 0x10, N, 522},
{"small", 0x10, N, 520}, {"small", 0x10, N, 520},
// compression runtime parameters // CRP - Compression Runtime Parameters (undocumented and subject to change)
{"crp-nrv-cf", 0x31, N, 801}, {"crp-nrv-cf", 0x31, N, 801},
{"crp-nrv-sl", 0x31, N, 802}, {"crp-nrv-sl", 0x31, N, 802},
{"crp-nrv-hl", 0x31, N, 803}, {"crp-nrv-hl", 0x31, N, 803},
@@ -897,7 +907,7 @@ int main_get_options(int argc, char **argv) {
// dos/sys // dos/sys
// unix // unix
{"blocksize", 0x31, N, 660}, // --blocksize= {"blocksize", 0x31, N, 660}, // --blocksize=
{"force-execve", 0x10, N, 661}, // force linux/386 execve format {"force-execve", 0x90, N, 661}, // force linux/386 execve format
{"is_ptinterp", 0x10, N, 663}, // linux/elf386 PT_INTERP program {"is_ptinterp", 0x10, N, 663}, // linux/elf386 PT_INTERP program
{"use_ptinterp", 0x10, N, 664}, // linux/elf386 PT_INTERP program {"use_ptinterp", 0x10, N, 664}, // linux/elf386 PT_INTERP program
{"make_ptinterp", 0x10, N, 665}, // linux/elf386 PT_INTERP program {"make_ptinterp", 0x10, N, 665}, // linux/elf386 PT_INTERP program
@@ -912,7 +922,7 @@ int main_get_options(int argc, char **argv) {
{"unmap-all-pages", 0x10, N, 674}, // linux /proc/self/exe vanishes {"unmap-all-pages", 0x10, N, 674}, // linux /proc/self/exe vanishes
{"preserve-build-id", 0, N, 675}, {"preserve-build-id", 0, N, 675},
{"android-shlib", 0, N, 676}, {"android-shlib", 0, N, 676},
{"force-pie", 0, N, 677}, {"force-pie", 0x90, N, 677},
// watcom/le // watcom/le
{"le", 0x10, N, 620}, // produce LE output {"le", 0x10, N, 620}, // produce LE output
// win32/pe // win32/pe
@@ -1197,12 +1207,18 @@ int upx_main(int argc, char *argv[]) {
set_term(stderr); set_term(stderr);
#if (WITH_BZIP2)
assert(upx_bzip2_init() == 0);
#endif
assert(upx_lzma_init() == 0); assert(upx_lzma_init() == 0);
assert(upx_ucl_init() == 0);
assert(upx_zlib_init() == 0);
#if (WITH_NRV) #if (WITH_NRV)
assert(upx_nrv_init() == 0); assert(upx_nrv_init() == 0);
#endif #endif
assert(upx_ucl_init() == 0);
assert(upx_zlib_init() == 0);
#if (WITH_ZSTD)
assert(upx_zstd_init() == 0);
#endif
/* get options */ /* get options */
first_options(argc, argv); first_options(argc, argv);
@@ -1263,11 +1279,12 @@ int upx_main(int argc, char *argv[]) {
return exit_code; return exit_code;
if (gitrev[0]) { if (gitrev[0]) {
bool warn = true; // also see UPX_CONFIG_DISABLE_GITREV in CMakeLists.txt
bool warn_gitrev = true;
const char *ee = getenv("UPX_DEBUG_DISABLE_GITREV_WARNING"); const char *ee = getenv("UPX_DEBUG_DISABLE_GITREV_WARNING");
if (ee && ee[0] && strcmp(ee, "1") == 0) if (ee && ee[0] && strcmp(ee, "1") == 0)
warn = false; warn_gitrev = false;
if (warn) { if (warn_gitrev) {
FILE *f = stdout; FILE *f = stdout;
int fg = con_fg(f, FG_RED); int fg = con_fg(f, FG_RED);
con_fprintf( con_fprintf(
+35 -61
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -27,7 +27,7 @@
#ifndef __ACC_H_INCLUDED #ifndef __ACC_H_INCLUDED
#define __ACC_H_INCLUDED 1 #define __ACC_H_INCLUDED 1
#define ACC_VERSION 20220904L #define ACC_VERSION 20230104L
#if defined(__CYGWIN32__) && !defined(__CYGWIN__) #if defined(__CYGWIN32__) && !defined(__CYGWIN__)
# define __CYGWIN__ __CYGWIN32__ # define __CYGWIN__ __CYGWIN32__
#endif #endif
@@ -1561,7 +1561,7 @@ extern "C" {
#endif #endif
#if !defined(ACC_BLOCK_BEGIN) #if !defined(ACC_BLOCK_BEGIN)
# define ACC_BLOCK_BEGIN do { # define ACC_BLOCK_BEGIN do {
# define ACC_BLOCK_END } while __acc_cte(0) # define ACC_BLOCK_END } while (__acc_cte(0))
#endif #endif
#if !defined(ACC_UNUSED) #if !defined(ACC_UNUSED)
# if (ACC_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) # if (ACC_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
@@ -1608,7 +1608,7 @@ extern "C" {
# if (ACC_CC_CLANG >= 0x020800ul) # if (ACC_CC_CLANG >= 0x020800ul)
# define ACC_UNUSED_LABEL(l) (__acc_gnuc_extension__ ((void) ACC_STATIC_CAST(const void *, &&l))) # define ACC_UNUSED_LABEL(l) (__acc_gnuc_extension__ ((void) ACC_STATIC_CAST(const void *, &&l)))
# elif (ACC_CC_ARMCC || ACC_CC_CLANG || ACC_CC_INTELC || ACC_CC_WATCOMC) # elif (ACC_CC_ARMCC || ACC_CC_CLANG || ACC_CC_INTELC || ACC_CC_WATCOMC)
# define ACC_UNUSED_LABEL(l) if __acc_cte(0) goto l # define ACC_UNUSED_LABEL(l) if (__acc_cte(0)) goto l
# else # else
# define ACC_UNUSED_LABEL(l) switch (0) case 1:goto l # define ACC_UNUSED_LABEL(l) switch (0) case 1:goto l
# endif # endif
@@ -2047,7 +2047,7 @@ extern "C" {
# if (ACC_CC_IBMC) # if (ACC_CC_IBMC)
# define __acc_loop_forever() ACC_BLOCK_BEGIN for (;;) { ; } ACC_BLOCK_END # define __acc_loop_forever() ACC_BLOCK_BEGIN for (;;) { ; } ACC_BLOCK_END
# else # else
# define __acc_loop_forever() do { ; } while __acc_cte(1) # define __acc_loop_forever() do { ; } while (__acc_cte(1))
# endif # endif
#endif #endif
#if !defined(__acc_unreachable) #if !defined(__acc_unreachable)
@@ -2079,11 +2079,11 @@ extern "C" {
# define acc_unused_funcs_impl(r,f) __acc_static_forceinline r f # define acc_unused_funcs_impl(r,f) __acc_static_forceinline r f
# endif # endif
#endif #endif
#ifndef __ACC_CTA_NAME #ifndef ACC_CTA_INTERNAL_NAME__
#if (ACC_CFG_USE_COUNTER) #if (ACC_CFG_USE_COUNTER)
# define __ACC_CTA_NAME(a) ACC_PP_ECONCAT2(a,__COUNTER__) # define ACC_CTA_INTERNAL_NAME__(a) ACC_PP_ECONCAT2(a,__COUNTER__)
#else #else
# define __ACC_CTA_NAME(a) ACC_PP_ECONCAT2(a,__LINE__) # define ACC_CTA_INTERNAL_NAME__(a) ACC_PP_ECONCAT2(a,__LINE__)
#endif #endif
#endif #endif
#if !defined(ACC_COMPILE_TIME_ASSERT_HEADER) #if !defined(ACC_COMPILE_TIME_ASSERT_HEADER)
@@ -2092,17 +2092,17 @@ extern "C" {
# elif (ACC_LANG_C >= 201112L) # elif (ACC_LANG_C >= 201112L)
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) _Static_assert(e, #e); # define ACC_COMPILE_TIME_ASSERT_HEADER(e) _Static_assert(e, #e);
# elif (ACC_CC_AZTECC || ACC_CC_ZORTECHC) # elif (ACC_CC_AZTECC || ACC_CC_ZORTECHC)
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int __ACC_CTA_NAME(acc_cta__)[1-!(e)]; ACC_EXTERN_C_END # define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int ACC_CTA_INTERNAL_NAME__(acc_cta__)[1-!(e)]; ACC_EXTERN_C_END
# elif (ACC_CC_DMC || ACC_CC_SYMANTECC) # elif (ACC_CC_DMC || ACC_CC_SYMANTECC)
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int __ACC_CTA_NAME(acc_cta__)[1u-2*!(e)]; ACC_EXTERN_C_END # define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int ACC_CTA_INTERNAL_NAME__(acc_cta__)[1u-2*!(e)]; ACC_EXTERN_C_END
# elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295)) # elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295))
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int __ACC_CTA_NAME(acc_cta__)[1-!(e)]; ACC_EXTERN_C_END # define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int ACC_CTA_INTERNAL_NAME__(acc_cta__)[1-!(e)]; ACC_EXTERN_C_END
# elif (ACC_CC_CLANG && (ACC_CC_CLANG < 0x020900ul)) && defined(__cplusplus) # elif (ACC_CC_CLANG && (ACC_CC_CLANG < 0x020900ul)) && defined(__cplusplus)
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN int __ACC_CTA_NAME(acc_cta_f__)(int [1-2*!(e)]); ACC_EXTERN_C_END # define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN int ACC_CTA_INTERNAL_NAME__(acc_cta_f__)(int [1-2*!(e)]); ACC_EXTERN_C_END
# elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) # elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN enum {__ACC_CTA_NAME(acc_cta_e__)=1/!!(e)} __attribute__((__unused__)); ACC_EXTERN_C_END # define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN enum {ACC_CTA_INTERNAL_NAME__(acc_cta_e__)=1/!!(e)} __attribute__((__unused__)); ACC_EXTERN_C_END
# else # else
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int __ACC_CTA_NAME(acc_cta__)[1-2*!(e)]; ACC_EXTERN_C_END # define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int ACC_CTA_INTERNAL_NAME__(acc_cta__)[1-2*!(e)]; ACC_EXTERN_C_END
# endif # endif
#endif #endif
#if !defined(ACC_COMPILE_TIME_ASSERT) #if !defined(ACC_COMPILE_TIME_ASSERT)
@@ -2111,23 +2111,23 @@ extern "C" {
# elif (ACC_LANG_C >= 201112L) # elif (ACC_LANG_C >= 201112L)
# define ACC_COMPILE_TIME_ASSERT(e) {_Static_assert(e, #e);} # define ACC_COMPILE_TIME_ASSERT(e) {_Static_assert(e, #e);}
# elif (ACC_CC_AZTECC) # elif (ACC_CC_AZTECC)
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int __ACC_CTA_NAME(acc_cta_t__)[1-!(e)];} # define ACC_COMPILE_TIME_ASSERT(e) {typedef int ACC_CTA_INTERNAL_NAME__(acc_cta_t__)[1-!(e)];}
# elif (ACC_CC_CLANG && (ACC_CC_CLANG >= 0x030000ul)) # elif (ACC_CC_CLANG && (ACC_CC_CLANG >= 0x030000ul))
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int __ACC_CTA_NAME(acc_cta_t__)[1-2*!(e)] __attribute__((__unused__));} # define ACC_COMPILE_TIME_ASSERT(e) {typedef int ACC_CTA_INTERNAL_NAME__(acc_cta_t__)[1-2*!(e)] __attribute__((__unused__));}
# elif (ACC_CC_DMC || ACC_CC_PACIFICC || ACC_CC_SYMANTECC || ACC_CC_ZORTECHC) # elif (ACC_CC_DMC || ACC_CC_PACIFICC || ACC_CC_SYMANTECC || ACC_CC_ZORTECHC)
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; # define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
# elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) # elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
# define ACC_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} # define ACC_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));}
# elif (ACC_CC_GNUC >= 0x040700ul) && (ACC_CFG_USE_COUNTER) && defined(__cplusplus) # elif (ACC_CC_GNUC >= 0x040700ul) && (ACC_CFG_USE_COUNTER) && defined(__cplusplus)
# define ACC_COMPILE_TIME_ASSERT(e) {enum {__ACC_CTA_NAME(acc_cta_e__)=1/!!(e)} __attribute__((__unused__));} # define ACC_COMPILE_TIME_ASSERT(e) {enum {ACC_CTA_INTERNAL_NAME__(acc_cta_e__)=1/!!(e)} __attribute__((__unused__));}
# elif (ACC_CC_GNUC >= 0x040700ul) # elif (ACC_CC_GNUC >= 0x040700ul)
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int __ACC_CTA_NAME(acc_cta_t__)[1-2*!(e)] __attribute__((__unused__));} # define ACC_COMPILE_TIME_ASSERT(e) {typedef int ACC_CTA_INTERNAL_NAME__(acc_cta_t__)[1-2*!(e)] __attribute__((__unused__));}
# elif (ACC_CC_MSC && (_MSC_VER < 900)) # elif (ACC_CC_MSC && (_MSC_VER < 900))
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; # define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
# elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295)) # elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295))
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; # define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
# else # else
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int __ACC_CTA_NAME(acc_cta_t__)[1-2*!(e)];} # define ACC_COMPILE_TIME_ASSERT(e) {typedef int ACC_CTA_INTERNAL_NAME__(acc_cta_t__)[1-2*!(e)];}
# endif # endif
#endif #endif
#if (ACC_LANG_ASSEMBLER) #if (ACC_LANG_ASSEMBLER)
@@ -2557,7 +2557,11 @@ ACC_COMPILE_TIME_ASSERT_HEADER(ACC_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
# undef ACC_ABI_BIG_ENDIAN # undef ACC_ABI_BIG_ENDIAN
# undef ACC_ABI_LITTLE_ENDIAN # undef ACC_ABI_LITTLE_ENDIAN
#elif !(ACC_ABI_BIG_ENDIAN) && !(ACC_ABI_LITTLE_ENDIAN) #elif !(ACC_ABI_BIG_ENDIAN) && !(ACC_ABI_LITTLE_ENDIAN)
#if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP) #if defined(__ORDER_BIG_ENDIAN__) && defined(__ORDER_LITTLE_ENDIAN__) && (__ORDER_BIG_ENDIAN__+0 != 0) && (__ORDER_LITTLE_ENDIAN__+0 != 0) && (__ORDER_BIG_ENDIAN__ != __ORDER_LITTLE_ENDIAN__) && defined(__BYTE_ORDER__) && (__BYTE_ORDER__+0 == __ORDER_BIG_ENDIAN__)
# define ACC_ABI_BIG_ENDIAN 1
#elif defined(__ORDER_BIG_ENDIAN__) && defined(__ORDER_LITTLE_ENDIAN__) && (__ORDER_BIG_ENDIAN__+0 != 0) && (__ORDER_LITTLE_ENDIAN__+0 != 0) && (__ORDER_BIG_ENDIAN__ != __ORDER_LITTLE_ENDIAN__) && defined(__BYTE_ORDER__) && (__BYTE_ORDER__+0 == __ORDER_LITTLE_ENDIAN__)
# define ACC_ABI_LITTLE_ENDIAN 1
#elif (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
# define ACC_ABI_BIG_ENDIAN 1 # define ACC_ABI_BIG_ENDIAN 1
#elif (ACC_ARCH_IA64) && (ACC_OS_POSIX_LINUX || ACC_OS_WIN64) #elif (ACC_ARCH_IA64) && (ACC_OS_POSIX_LINUX || ACC_OS_WIN64)
# define ACC_ABI_LITTLE_ENDIAN 1 # define ACC_ABI_LITTLE_ENDIAN 1
@@ -2733,37 +2737,14 @@ ACC_COMPILE_TIME_ASSERT_HEADER(ACC_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
# define ACC_OPT_UNALIGNED64 1 # define ACC_OPT_UNALIGNED64 1
# endif # endif
#elif (ACC_ARCH_ARM) #elif (ACC_ARCH_ARM)
# if defined(__ARM_FEATURE_UNALIGNED) # if defined(__ARM_FEATURE_UNALIGNED) && (__ARM_FEATURE_UNALIGNED+0)
# if ((__ARM_FEATURE_UNALIGNED)+0)
# ifndef ACC_OPT_UNALIGNED16 # ifndef ACC_OPT_UNALIGNED16
# define ACC_OPT_UNALIGNED16 1 # define ACC_OPT_UNALIGNED16 1
# endif # endif
# ifndef ACC_OPT_UNALIGNED32 # ifndef ACC_OPT_UNALIGNED32
# define ACC_OPT_UNALIGNED32 1 # define ACC_OPT_UNALIGNED32 1
# endif # endif
# endif # elif defined(__TARGET_FEATURE_UNALIGNED) && (__TARGET_FEATURE_UNALIGNED+0)
# elif 1 && (ACC_ARCH_ARM_THUMB2)
# ifndef ACC_OPT_UNALIGNED16
# define ACC_OPT_UNALIGNED16 1
# endif
# ifndef ACC_OPT_UNALIGNED32
# define ACC_OPT_UNALIGNED32 1
# endif
# elif 1 && defined(__ARM_ARCH) && ((__ARM_ARCH)+0 >= 7)
# ifndef ACC_OPT_UNALIGNED16
# define ACC_OPT_UNALIGNED16 1
# endif
# ifndef ACC_OPT_UNALIGNED32
# define ACC_OPT_UNALIGNED32 1
# endif
# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 7)
# ifndef ACC_OPT_UNALIGNED16
# define ACC_OPT_UNALIGNED16 1
# endif
# ifndef ACC_OPT_UNALIGNED32
# define ACC_OPT_UNALIGNED32 1
# endif
# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 6) && (defined(__TARGET_PROFILE_A) || defined(__TARGET_PROFILE_R))
# ifndef ACC_OPT_UNALIGNED16 # ifndef ACC_OPT_UNALIGNED16
# define ACC_OPT_UNALIGNED16 1 # define ACC_OPT_UNALIGNED16 1
# endif # endif
@@ -2822,34 +2803,21 @@ ACC_COMPILE_TIME_ASSERT_HEADER(ACC_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
#elif (ACC_ARCH_POWERPC) #elif (ACC_ARCH_POWERPC)
# define ACC_OPT_PREFER_PREINC 1 # define ACC_OPT_PREFER_PREINC 1
# define ACC_OPT_PREFER_PREDEC 1 # define ACC_OPT_PREFER_PREDEC 1
# if (ACC_ABI_BIG_ENDIAN) || (ACC_WORDSIZE == 8) # if (ACC_WORDSIZE == 8) || (ACC_ABI_BIG_ENDIAN)
# ifndef ACC_OPT_UNALIGNED16 # ifndef ACC_OPT_UNALIGNED16
# define ACC_OPT_UNALIGNED16 1 # define ACC_OPT_UNALIGNED16 1
# endif # endif
# ifndef ACC_OPT_UNALIGNED32 # ifndef ACC_OPT_UNALIGNED32
# define ACC_OPT_UNALIGNED32 1 # define ACC_OPT_UNALIGNED32 1
# endif # endif
# endif
# if (ACC_WORDSIZE == 8) # if (ACC_WORDSIZE == 8)
# ifndef ACC_OPT_UNALIGNED64 # ifndef ACC_OPT_UNALIGNED64
# define ACC_OPT_UNALIGNED64 1 # define ACC_OPT_UNALIGNED64 1
# endif # endif
# endif # endif
# endif
#elif (ACC_ARCH_RISCV) #elif (ACC_ARCH_RISCV)
# define ACC_OPT_AVOID_UINT_INDEX 1 # define ACC_OPT_AVOID_UINT_INDEX 1
# if 0
# ifndef ACC_OPT_UNALIGNED16
# define ACC_OPT_UNALIGNED16 1
# endif
# ifndef ACC_OPT_UNALIGNED32
# define ACC_OPT_UNALIGNED32 1
# endif
# if (ACC_WORDSIZE == 8)
# ifndef ACC_OPT_UNALIGNED64
# define ACC_OPT_UNALIGNED64 1
# endif
# endif
# endif
#elif (ACC_ARCH_S390) #elif (ACC_ARCH_S390)
# ifndef ACC_OPT_UNALIGNED16 # ifndef ACC_OPT_UNALIGNED16
# define ACC_OPT_UNALIGNED16 1 # define ACC_OPT_UNALIGNED16 1
@@ -3404,7 +3372,9 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6
# define HAVE_STDDEF_H 1 # define HAVE_STDDEF_H 1
#elif (ACC_LIBC_MOSTLY_FREESTANDING) #elif (ACC_LIBC_MOSTLY_FREESTANDING)
# define HAVE_LIMITS_H 1 # define HAVE_LIMITS_H 1
# ifndef HAVE_SETJMP_H
# define HAVE_SETJMP_H 1 # define HAVE_SETJMP_H 1
# endif
# define HAVE_STDARG_H 1 # define HAVE_STDARG_H 1
# define HAVE_STDDEF_H 1 # define HAVE_STDDEF_H 1
# define HAVE_STDIO_H 1 # define HAVE_STDIO_H 1
@@ -3420,8 +3390,12 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6
#define HAVE_LIMITS_H 1 #define HAVE_LIMITS_H 1
#define HAVE_MALLOC_H 1 #define HAVE_MALLOC_H 1
#define HAVE_MEMORY_H 1 #define HAVE_MEMORY_H 1
#ifndef HAVE_SETJMP_H
#define HAVE_SETJMP_H 1 #define HAVE_SETJMP_H 1
#endif
#ifndef HAVE_SIGNAL_H
#define HAVE_SIGNAL_H 1 #define HAVE_SIGNAL_H 1
#endif
#define HAVE_STDARG_H 1 #define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1 #define HAVE_STDDEF_H 1
#define HAVE_STDIO_H 1 #define HAVE_STDIO_H 1
@@ -4804,7 +4778,7 @@ typedef long acc_fallback_ptrdiff_t;
#if defined(__SIZE_TYPE__) #if defined(__SIZE_TYPE__)
typedef __SIZE_TYPE__ acc_fallback_size_t; typedef __SIZE_TYPE__ acc_fallback_size_t;
#elif defined(_WIN64) #elif defined(_WIN64)
typedef unsigned long long acc_fallback_ptrdiff_t; typedef unsigned long long acc_fallback_size_t;
#elif defined(__MIPS_PSX2__) #elif defined(__MIPS_PSX2__)
typedef unsigned acc_fallback_size_t; typedef unsigned acc_fallback_size_t;
#else #else
+28 -63
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,10 +25,8 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "conf.h"
/************************************************************************* /*************************************************************************
// FIXME: if stdout is redirected to a file and stderr is not, should // FIXME: if stdout is redirected to a file and stderr is not, should
// we write all error messages to both stderr and stdout ? // we write all error messages to both stderr and stdout ?
@@ -36,17 +34,11 @@
static int pr_need_nl = 0; static int pr_need_nl = 0;
void printSetNl(int need_nl) { pr_need_nl = need_nl; }
void printSetNl(int need_nl) void printClearLine(FILE *f) {
{
pr_need_nl = need_nl;
}
void printClearLine(FILE *f)
{
static char clear_line_msg[1 + 79 + 1 + 1]; static char clear_line_msg[1 + 79 + 1 + 1];
if (!clear_line_msg[0]) if (!clear_line_msg[0]) {
{
char *msg = clear_line_msg; char *msg = clear_line_msg;
msg[0] = '\r'; msg[0] = '\r';
memset(msg + 1, ' ', 79); memset(msg + 1, ' ', 79);
@@ -54,7 +46,8 @@ void printClearLine(FILE *f)
msg[81] = 0; msg[81] = 0;
} }
fflush(stdout); fflush(stderr); fflush(stdout);
fflush(stderr);
if (f == nullptr) if (f == nullptr)
f = stdout; f = stdout;
con_fprintf(f, "%s", clear_line_msg); con_fprintf(f, "%s", clear_line_msg);
@@ -62,24 +55,21 @@ void printClearLine(FILE *f)
printSetNl(0); printSetNl(0);
} }
static void pr_print(bool c, const char *msg) {
static void pr_print(bool c, const char *msg)
{
if (c && !opt->to_stdout) if (c && !opt->to_stdout)
con_fprintf(stderr, "%s", msg); con_fprintf(stderr, "%s", msg);
else else
fprintf(stderr, "%s", msg); fprintf(stderr, "%s", msg);
} }
static void pr_error(const char *iname, const char *msg, bool is_warning) static void pr_error(const char *iname, const char *msg, bool is_warning) {
{ fflush(stdout);
fflush(stdout); fflush(stderr); fflush(stderr);
char buf[1024]; char buf[1024];
buf[0] = 0; buf[0] = 0;
if (pr_need_nl == 2) if (pr_need_nl == 2)
printClearLine(stdout); printClearLine(stdout);
else if (pr_need_nl) else if (pr_need_nl) {
{
buf[0] = '\n'; buf[0] = '\n';
buf[1] = 0; buf[1] = 0;
printSetNl(0); printSetNl(0);
@@ -99,16 +89,15 @@ static void pr_error(const char *iname, const char *msg, bool is_warning)
//(void)con_fg(stderr,FG_BRTRED); //(void)con_fg(stderr,FG_BRTRED);
pr_print(c, msg); pr_print(c, msg);
pr_print(c, "\n"); pr_print(c, "\n");
fflush(stdout); fflush(stderr); fflush(stdout);
fflush(stderr);
fg = con_fg(stderr, fg); fg = con_fg(stderr, fg);
UNUSED(is_warning); UNUSED(is_warning);
UNUSED(fg); UNUSED(fg);
} }
void printErr(const char *iname, const Throwable *e) {
void printErr(const char *iname, const Throwable *e)
{
char buf[1024]; char buf[1024];
size_t l; size_t l;
@@ -130,9 +119,7 @@ void printErr(const char *iname, const Throwable *e)
pr_error(iname, buf, e->isWarning()); pr_error(iname, buf, e->isWarning());
} }
void printErr(const char *iname, const char *format, ...) {
void printErr(const char *iname, const char *format, ...)
{
va_list args; va_list args;
char buf[1024]; char buf[1024];
@@ -143,9 +130,7 @@ void printErr(const char *iname, const char *format, ...)
pr_error(iname, buf, false); pr_error(iname, buf, false);
} }
void printWarn(const char *iname, const char *format, ...) {
void printWarn(const char *iname, const char *format, ...)
{
va_list args; va_list args;
char buf[1024]; char buf[1024];
@@ -156,38 +141,30 @@ void printWarn(const char *iname, const char *format, ...)
pr_error(iname, buf, true); pr_error(iname, buf, true);
} }
void printUnhandledException(const char *iname, const std::exception *e) {
void printUnhandledException(const char *iname, const std::exception *e)
{
if (e) if (e)
printErr(iname, "unhandled exception: %s\n", prettyName(e->what())); printErr(iname, "unhandled exception: %s\n", prettyName(e->what()));
else else
printErr(iname, "internal error: unhandled exception!\n"); printErr(iname, "internal error: unhandled exception!\n");
if (opt->cmd != CMD_COMPRESS) if (opt->cmd != CMD_COMPRESS) {
{
printErr(iname, " this file has possibly been modified/hacked; take care!\n"); printErr(iname, " this file has possibly been modified/hacked; take care!\n");
} }
} }
/************************************************************************* /*************************************************************************
// FIXME: should use colors and a consistent layout here // FIXME: should use colors and a consistent layout here
**************************************************************************/ **************************************************************************/
static int info_header = 0; static int info_header = 0;
static void info_print(const char *msg) {
static void info_print(const char *msg)
{
if (opt->info_mode <= 0) if (opt->info_mode <= 0)
return; return;
FILE *f = opt->to_stdout ? stderr : stdout; FILE *f = opt->to_stdout ? stderr : stdout;
if (pr_need_nl) if (pr_need_nl) {
{
printClearLine(f); printClearLine(f);
con_fprintf(f, "%s\n", msg); con_fprintf(f, "%s\n", msg);
} } else if (pr_need_nl)
else if (pr_need_nl)
con_fprintf(f, "\n%s\n", msg); con_fprintf(f, "\n%s\n", msg);
else else
con_fprintf(f, "%s\n", msg); con_fprintf(f, "%s\n", msg);
@@ -195,14 +172,9 @@ static void info_print(const char *msg)
printSetNl(0); printSetNl(0);
} }
void infoHeader() { info_header = 0; }
void infoHeader() void infoHeader(const char *format, ...) {
{
info_header = 0;
}
void infoHeader(const char *format, ...)
{
if (opt->info_mode <= 0) if (opt->info_mode <= 0)
return; return;
va_list args; va_list args;
@@ -214,9 +186,7 @@ void infoHeader(const char *format, ...)
info_header = 1; info_header = 1;
} }
void info(const char *format, ...) {
void info(const char *format, ...)
{
if (opt->info_mode <= 0) if (opt->info_mode <= 0)
return; return;
va_list args; va_list args;
@@ -229,11 +199,8 @@ void info(const char *format, ...)
info_print(buf); info_print(buf);
} }
void infoWarning(const char *format, ...) {
void infoWarning(const char *format, ...) if (opt->info_mode <= 0) {
{
if (opt->info_mode <= 0)
{
// FIXME - should still print something here // FIXME - should still print something here
return; return;
} }
@@ -245,9 +212,7 @@ void infoWarning(const char *format, ...)
info("[WARNING] %s\n", buf); info("[WARNING] %s\n", buf);
} }
void infoWriting(const char *what, long size) {
void infoWriting(const char *what, long size)
{
if (opt->info_mode <= 0) if (opt->info_mode <= 0)
return; return;
info("Writing %s: %ld bytes", what, size); info("Writing %s: %ld bytes", what, size);
+16 -9
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -27,8 +27,11 @@
#include "conf.h" #include "conf.h"
static options_t global_options;
options_t *opt = &global_options; // also see class PackMaster
/************************************************************************* /*************************************************************************
// options // reset
**************************************************************************/ **************************************************************************/
void options_t::reset() { void options_t::reset() {
@@ -57,7 +60,7 @@ void options_t::reset() {
#endif #endif
o->verbose = 2; o->verbose = 2;
opt->o_unix.osabi0 = 3; // 3 == ELFOSABI_LINUX o->o_unix.osabi0 = 3; // 3 == ELFOSABI_LINUX
o->win32_pe.compress_exports = 1; o->win32_pe.compress_exports = 1;
o->win32_pe.compress_icons = 2; o->win32_pe.compress_icons = 2;
@@ -69,20 +72,24 @@ void options_t::reset() {
o->win32_pe.keep_resource = ""; o->win32_pe.keep_resource = "";
} }
static options_t global_options;
options_t *opt = &global_options;
/************************************************************************* /*************************************************************************
// // doctest checks
**************************************************************************/ **************************************************************************/
TEST_CASE("options_t::reset") {
options_t local_options;
options_t *o = &local_options;
o->reset();
CHECK(o->o_unix.osabi0 == 3);
}
template <size_t N> template <size_t N>
static inline void test_options(const char *(&a)[N]) { static inline void test_options(const char *(&a)[N]) {
(void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a)); (void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a));
} }
TEST_CASE("getopt") { TEST_CASE("getopt") {
options_t *saved_opt = opt; options_t *const saved_opt = opt;
options_t local_options; options_t local_options;
opt = &local_options; opt = &local_options;
opt->reset(); opt->reset();
+13 -13
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -43,10 +43,10 @@ enum {
CMD_FILEINFO, CMD_FILEINFO,
CMD_HELP, CMD_HELP,
CMD_LICENSE, CMD_LICENSE,
CMD_VERSION CMD_VERSION,
}; };
struct options_t { struct options_t final {
int cmd; int cmd;
// compression options // compression options
@@ -69,6 +69,7 @@ struct options_t {
int backup; int backup;
int console; int console;
int force; int force;
bool force_overwrite;
int info_mode; int info_mode;
bool ignorewarn; bool ignorewarn;
bool no_env; bool no_env;
@@ -95,7 +96,8 @@ struct options_t {
enum { SKIP_OVERLAY = 0, COPY_OVERLAY = 1, STRIP_OVERLAY = 2 }; enum { SKIP_OVERLAY = 0, COPY_OVERLAY = 1, STRIP_OVERLAY = 2 };
int overlay; int overlay;
// compression runtime parameters - see struct XXX_compress_config_t // CRP - Compression Runtime Parameters (undocumented and subject to change)
// see struct XXX_compress_config_t
struct crp_t { struct crp_t {
lzma_compress_config_t crp_lzma; lzma_compress_config_t crp_lzma;
ucl_compress_config_t crp_ucl; ucl_compress_config_t crp_ucl;
@@ -115,8 +117,6 @@ struct options_t {
CPU_286 = 2, CPU_286 = 2,
CPU_386 = 3, CPU_386 = 3,
CPU_486 = 4, CPU_486 = 4,
CPU_586 = 5,
CPU_686 = 6
}; };
int cpu; int cpu;
@@ -131,12 +131,6 @@ struct options_t {
bool force_stub; bool force_stub;
bool no_reloc; bool no_reloc;
} dos_exe; } dos_exe;
struct {
bool boot_only;
bool no_align;
bool do_8bit;
bool do_8mib;
} ps1_exe;
struct { struct {
unsigned blocksize; unsigned blocksize;
bool force_execve; // force the linux/386 execve format bool force_execve; // force the linux/386 execve format
@@ -149,6 +143,12 @@ struct options_t {
bool android_shlib; // keep some ElfXX_Shdr for dlopen() bool android_shlib; // keep some ElfXX_Shdr for dlopen()
bool force_pie; // choose DF_1_PIE instead of is_shlib bool force_pie; // choose DF_1_PIE instead of is_shlib
} o_unix; } o_unix;
struct {
bool boot_only;
bool no_align;
bool do_8bit;
bool do_8mib;
} ps1_exe;
struct { struct {
bool le; bool le;
} watcom_le; } watcom_le;
+40 -74
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "conf.h"
#include "file.h" #include "file.h"
#include "filter.h" #include "filter.h"
@@ -34,27 +33,20 @@
#include "p_armpe.h" #include "p_armpe.h"
#include "linker.h" #include "linker.h"
static const static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/arm.v4a-wince.pe.h" #include "stub/arm.v4a-wince.pe.h"
static const static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/arm.v4t-wince.pe.h" #include "stub/arm.v4t-wince.pe.h"
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
PackArmPe::PackArmPe(InputFile *f) : super(f) PackArmPe::PackArmPe(InputFile *f) : super(f) {}
{
use_thumb_stub = false;
}
PackArmPe::~PackArmPe() {}
PackArmPe::~PackArmPe() const int *PackArmPe::getCompressionMethods(int method, int level) const {
{}
const int *PackArmPe::getCompressionMethods(int method, int level) const
{
static const int m_all[] = {M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END}; static const int m_all[] = {M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END};
static const int m_lzma[] = {M_LZMA, M_END}; static const int m_lzma[] = {M_LZMA, M_END};
static const int m_nrv2b[] = {M_NRV2B_8, M_END}; static const int m_nrv2b[] = {M_NRV2B_8, M_END};
@@ -63,26 +55,23 @@ const int *PackArmPe::getCompressionMethods(int method, int level) const
if (!use_thumb_stub) if (!use_thumb_stub)
return getDefaultCompressionMethods_8(method, level); return getDefaultCompressionMethods_8(method, level);
if (method == M_ALL) return m_all; if (method == M_ALL)
if (M_IS_LZMA(method)) return m_lzma; return m_all;
if (M_IS_NRV2B(method)) return m_nrv2b; if (M_IS_LZMA(method))
if (M_IS_NRV2E(method)) return m_nrv2e; return m_lzma;
if (M_IS_NRV2B(method))
return m_nrv2b;
if (M_IS_NRV2E(method))
return m_nrv2e;
return m_nrv2e; return m_nrv2e;
} }
const int *PackArmPe::getFilters() const {
const int *PackArmPe::getFilters() const
{
static const int filters[] = {0x50, FT_END}; static const int filters[] = {0x50, FT_END};
return filters; return filters;
} }
Linker *PackArmPe::newLinker() const { return new ElfLinkerArmLE; }
Linker* PackArmPe::newLinker() const
{
return new ElfLinkerArmLE;
}
/************************************************************************* /*************************************************************************
// import handling // import handling
@@ -93,17 +82,14 @@ void PackArmPe::processImports2(unsigned myimport, unsigned iat_off) // pass 2
PeFile::processImports2(myimport, iat_off); PeFile::processImports2(myimport, iat_off);
// adjust import data // adjust import data
for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++) for (import_desc *im = (import_desc *) oimpdlls; im->dllname; im++) {
{
im->oft = im->iat; im->oft = im->iat;
bool is_coredll = strcasecmp(kernelDll(), (char*) oimpdlls + bool is_coredll = strcasecmp(kernelDll(), oimpdlls + (im->dllname - myimport)) == 0;
im->dllname - myimport) == 0;
im->iat = is_coredll ? iat_off : iat_off + 12; im->iat = is_coredll ? iat_off : iat_off + 12;
} }
} }
void PackArmPe::addStubImports() void PackArmPe::addStubImports() {
{
// the order of procedure names below should match the // the order of procedure names below should match the
// assumptions of the assembly stubs // assumptions of the assembly stubs
// WARNING! these names are sorted alphanumerically by the ImportLinker // WARNING! these names are sorted alphanumerically by the ImportLinker
@@ -121,13 +107,11 @@ void PackArmPe::processTls(Interval *) // pass 1
throwCantPack("Static TLS entries found. Send a report please."); throwCantPack("Static TLS entries found. Send a report please.");
} }
/************************************************************************* /*************************************************************************
// pack // pack
**************************************************************************/ **************************************************************************/
bool PackArmPe::canPack() bool PackArmPe::canPack() {
{
if (!readFileHeader() || (ih.cpu != 0x1c0 && ih.cpu != 0x1c2)) if (!readFileHeader() || (ih.cpu != 0x1c0 && ih.cpu != 0x1c2))
return false; return false;
use_thumb_stub |= ih.cpu == 0x1c2 || (ih.entry & 1) == 1; use_thumb_stub |= ih.cpu == 0x1c2 || (ih.entry & 1) == 1;
@@ -135,9 +119,7 @@ bool PackArmPe::canPack()
return true; return true;
} }
void PackArmPe::buildLoader(const Filter *ft) {
void PackArmPe::buildLoader(const Filter *ft)
{
const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe; const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe;
unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe); unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe);
@@ -157,7 +139,6 @@ void PackArmPe::buildLoader(const Filter *ft)
else if (M_IS_LZMA(ph.method)) else if (M_IS_LZMA(ph.method))
addLoader("+40C,CallLZMA", nullptr); addLoader("+40C,CallLZMA", nullptr);
if (ft->id == 0x50) if (ft->id == 0x50)
addLoader("+40C,Unfilter_0x50", nullptr); addLoader("+40C,Unfilter_0x50", nullptr);
@@ -179,48 +160,38 @@ void PackArmPe::buildLoader(const Filter *ft)
addLoader("IDENTSTR,UPX1HEAD", nullptr); addLoader("IDENTSTR,UPX1HEAD", nullptr);
} }
bool PackArmPe::handleForceOption() bool PackArmPe::handleForceOption() {
{ return (ih.cpu != 0x1c0 && ih.cpu != 0x1c2) || (ih.opthdrsize != 0xe0) ||
return (ih.cpu != 0x1c0 && ih.cpu != 0x1c2) ((ih.flags & EXECUTABLE) == 0) || (ih.entry == 0 /*&& !isdll*/) ||
|| (ih.opthdrsize != 0xe0) (ih.ddirsentries != 16);
|| ((ih.flags & EXECUTABLE) == 0)
|| (ih.entry == 0 /*&& !isdll*/)
|| (ih.ddirsentries != 16)
// || IDSIZE(PEDIR_EXCEPTION) // is this used on arm? // || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?
// || IDSIZE(PEDIR_COPYRIGHT) // || IDSIZE(PEDIR_COPYRIGHT)
;
} }
void PackArmPe::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned ih_codebase) void PackArmPe::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned ih_codebase) {
{
// limit stack size needed for runtime decompression // limit stack size needed for runtime decompression
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf;
cconf.reset();
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
compressWithFilters(&ft, 2048, &cconf, filter_strategy, compressWithFilters(&ft, 2048, &cconf, filter_strategy, ih_codebase, rvamin, 0, nullptr, 0);
ih_codebase, rvamin, 0, nullptr, 0);
} }
void PackArmPe::addNewRelocations(Reloc &rel, unsigned upxsection) void PackArmPe::addNewRelocations(Reloc &rel, unsigned upxsection) {
{ static const char *const symbols_to_relocate[] = {"ONAM", "BIMP", "BREL", "FIBE",
static const char* symbols_to_relocate[] = { "FIBS", "ENTR", "DST0", "SRC0"};
"ONAM", "BIMP", "BREL", "FIBE", "FIBS", "ENTR", "DST0", "SRC0" for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++) {
};
for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++)
{
unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]); unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]);
if (off != 0xdeaddead) if (off != 0xdeaddead)
rel.add(off + upxsection, 3); rel.add(off + upxsection, 3);
} }
} }
unsigned PackArmPe::getProcessImportParam(unsigned upxsection) unsigned PackArmPe::getProcessImportParam(unsigned upxsection) {
{
return linker->getSymbolOffset("IATT") + upxsection; return linker->getSymbolOffset("IATT") + upxsection;
} }
void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned, void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned, unsigned ic,
unsigned ic, unsigned s1addr) unsigned s1addr) {
{
const unsigned onam = ncsection + soxrelocs + ih.imagebase; const unsigned onam = ncsection + soxrelocs + ih.imagebase;
linker->defineSymbol("start_of_dll_names", onam); linker->defineSymbol("start_of_dll_names", onam);
linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports); linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
@@ -235,18 +206,13 @@ void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned,
defineDecompressorSymbols(); defineDecompressorSymbols();
} }
void PackArmPe::setOhDataBase(const pe_section_t *osection) void PackArmPe::setOhDataBase(const pe_section_t *osection) { oh.database = osection[2].vaddr; }
{
oh.database = osection[2].vaddr;
}
void PackArmPe::setOhHeaderSize(const pe_section_t *osection) void PackArmPe::setOhHeaderSize(const pe_section_t *osection) {
{
oh.headersize = osection[1].rawdataptr; oh.headersize = osection[1].rawdataptr;
} }
void PackArmPe::pack(OutputFile *fo) void PackArmPe::pack(OutputFile *fo) {
{
super::pack0(fo, (1u << IMAGE_SUBSYSTEM_WINDOWS_CE_GUI), 0x10000, true); super::pack0(fo, (1u << IMAGE_SUBSYSTEM_WINDOWS_CE_GUI), 0x10000, true);
} }
+9 -13
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,17 +25,15 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#pragma once
#ifndef __UPX_P_ARMPE_H #ifndef UPX_P_ARMPE_H__
#define __UPX_P_ARMPE_H 1 #define UPX_P_ARMPE_H__ 1
/************************************************************************* /*************************************************************************
// arm/pe // arm/pe
**************************************************************************/ **************************************************************************/
class PackArmPe : public PeFile32 class PackArmPe final : public PeFile32 {
{
typedef PeFile32 super; typedef PeFile32 super;
public: public:
@@ -51,9 +49,8 @@ public:
virtual bool handleForceOption() override; virtual bool handleForceOption() override;
virtual void callCompressWithFilters(Filter &, int filter_strategy, virtual void callCompressWithFilters(Filter &, int filter_strategy,
unsigned ih_codebase) override; unsigned ih_codebase) override;
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
unsigned sizeof_oh, unsigned isize_isplit, unsigned isize_isplit, unsigned s1addr) override;
unsigned s1addr) override;
virtual void addNewRelocations(Reloc &, unsigned upxsection) override; virtual void addNewRelocations(Reloc &, unsigned upxsection) override;
virtual unsigned getProcessImportParam(unsigned upxsection) override; virtual unsigned getProcessImportParam(unsigned upxsection) override;
virtual void setOhDataBase(const pe_section_t *osection) override; virtual void setOhDataBase(const pe_section_t *osection) override;
@@ -72,10 +69,9 @@ protected:
virtual void processTls(Interval *) override; virtual void processTls(Interval *) override;
bool use_thumb_stub; bool use_thumb_stub = false;
}; };
#endif /* already included */ #endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+30 -70
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "conf.h"
#include "file.h" #include "file.h"
#include "filter.h" #include "filter.h"
@@ -33,42 +32,35 @@
#include "p_com.h" #include "p_com.h"
#include "linker.h" #include "linker.h"
static const static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i086-dos16.com.h" #include "stub/i086-dos16.com.h"
// #define TESTING 1 // #define TESTING 1
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
const int *PackCom::getCompressionMethods(int method, int level) const const int *PackCom::getCompressionMethods(int method, int level) const {
{
static const int m_nrv2b[] = {M_NRV2B_LE16, M_END}; static const int m_nrv2b[] = {M_NRV2B_LE16, M_END};
#if 0 #if 0
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END }; static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
#endif #endif
UNUSED(method); UNUSED(level); UNUSED(method);
UNUSED(level);
return m_nrv2b; return m_nrv2b;
} }
const int *PackCom::getFilters() const {
const int *PackCom::getFilters() const static const int filters[] = {0x06, 0x03, 0x04, 0x01, 0x05, 0x02, FT_END};
{
static const int filters[] = {
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
FT_END };
return filters; return filters;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
bool PackCom::canPack() bool PackCom::canPack() {
{
unsigned char buf[128]; unsigned char buf[128];
fi->readx(buf, sizeof(buf)); fi->readx(buf, sizeof(buf));
@@ -85,15 +77,11 @@ bool PackCom::canPack()
return true; return true;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
void PackCom::patchLoader(OutputFile *fo, void PackCom::patchLoader(OutputFile *fo, upx_byte *loader, int lsize, unsigned calls) {
upx_byte *loader, int lsize,
unsigned calls)
{
const int e_len = getLoaderSectionStart("COMCUTPO"); const int e_len = getLoaderSectionStart("COMCUTPO");
const int d_len = lsize - e_len; const int d_len = lsize - e_len;
assert(e_len > 0 && e_len < 128); assert(e_len > 0 && e_len < 128);
@@ -130,60 +118,40 @@ void PackCom::patchLoader(OutputFile *fo,
#endif #endif
} }
void PackCom::buildLoader(const Filter *ft) {
void PackCom::buildLoader(const Filter *ft)
{
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com)); initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
addLoader("COMMAIN1", addLoader("COMMAIN1", ph.first_offset_found == 1 ? "COMSBBBP" : "", "COMPSHDI",
ph.first_offset_found == 1 ? "COMSBBBP" : "", ft->id ? "COMCALLT" : "", "COMMAIN2,UPX1HEAD,COMCUTPO,NRV2B160",
"COMPSHDI", ft->id ? "NRVDDONE" : "NRVDRETU", "NRVDECO1",
ft->id ? "COMCALLT" : "", ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00", "NRVDECO2", nullptr);
"COMMAIN2,UPX1HEAD,COMCUTPO,NRV2B160", if (ft->id) {
ft->id ? "NRVDDONE" : "NRVDRETU",
"NRVDECO1",
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
"NRVDECO2",
nullptr
);
if (ft->id)
{
assert(ft->calls > 0); assert(ft->calls > 0);
addFilter16(ft->id); addFilter16(ft->id);
} }
} }
void PackCom::addFilter16(int filter_id) {
void PackCom::addFilter16(int filter_id)
{
assert(filter_id > 0); assert(filter_id > 0);
assert(isValidFilter(filter_id)); assert(isValidFilter(filter_id));
if (filter_id % 3 == 0) if (filter_id % 3 == 0)
addLoader("CALLTR16", addLoader("CALLTR16", filter_id < 4 ? "CT16SUB0" : "",
filter_id < 4 ? "CT16SUB0" : "", filter_id < 4 ? ""
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"), : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"),
"CALLTRI2", "CALLTRI2", getFormat() == UPX_F_DOS_COM ? "CORETURN" : "", nullptr);
getFormat() == UPX_F_DOS_COM ? "CORETURN" : "",
nullptr
);
else else
addLoader(filter_id%3 == 1 ? "CT16E800" : "CT16E900", addLoader(
"CALLTRI5", filter_id % 3 == 1 ? "CT16E800" : "CT16E900", "CALLTRI5",
getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2", getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2", filter_id < 4 ? "CT16SUB1" : "",
filter_id < 4 ? "CT16SUB1" : "",
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"), filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"),
"CALLTRI6", "CALLTRI6", nullptr);
nullptr
);
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
void PackCom::pack(OutputFile *fo) void PackCom::pack(OutputFile *fo) {
{
// read file // read file
ibuf.alloc(file_size); ibuf.alloc(file_size);
obuf.allocForCompression(file_size); obuf.allocForCompression(file_size);
@@ -214,13 +182,11 @@ void PackCom::pack(OutputFile *fo)
throwNotCompressible(); throwNotCompressible();
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int PackCom::canUnpack() int PackCom::canUnpack() {
{
if (!readPackHeader(128)) if (!readPackHeader(128))
return false; return false;
if (file_size_u <= ph.c_len) if (file_size_u <= ph.c_len)
@@ -228,15 +194,13 @@ int PackCom::canUnpack()
return true; return true;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
void PackCom::unpack(OutputFile *fo) void PackCom::unpack(OutputFile *fo) {
{
ibuf.alloc(file_size); ibuf.alloc(file_size);
obuf.allocForUncompression(ph.u_len); obuf.allocForDecompression(ph.u_len);
// read whole file // read whole file
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
@@ -260,10 +224,6 @@ void PackCom::unpack(OutputFile *fo)
fo->write(obuf, ph.u_len); fo->write(obuf, ph.u_len);
} }
Linker *PackCom::newLinker() const { return new ElfLinkerX86(); }
Linker* PackCom::newLinker() const
{
return new ElfLinkerX86();
}
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+7 -10
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,24 +25,22 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#pragma once
#ifndef __UPX_P_COM_H #ifndef UPX_P_COM_H__
#define __UPX_P_COM_H 1 #define UPX_P_COM_H__ 1
/************************************************************************* /*************************************************************************
// dos/com // dos/com
**************************************************************************/ **************************************************************************/
class PackCom : public Packer class PackCom : public Packer {
{
typedef Packer super; typedef Packer super;
public: public:
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; } PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
virtual int getVersion() const override { return 13; } virtual int getVersion() const override { return 13; }
virtual int getFormat() const override { return UPX_F_DOS_COM; } virtual int getFormat() const override { return UPX_F_DOS_COM; }
virtual const char *getName() const override { return "dos/com"; } virtual const char *getName() const override { return "dos/com"; }
//virtual const char *getFullName(const options_t *o) const override { return o && o->cpu == o->CPU_8086 ? "i086-dos16.com" : "i286-dos16.com"; }
virtual const char *getFullName(const options_t *) const override { return "i086-dos16.com"; } virtual const char *getFullName(const options_t *) const override { return "i086-dos16.com"; }
virtual const int *getCompressionMethods(int method, int level) const override; virtual const int *getCompressionMethods(int method, int level) const override;
virtual const int *getFilters() const override; virtual const int *getFilters() const override;
@@ -63,7 +61,6 @@ protected:
virtual void addFilter16(int filter_id); virtual void addFilter16(int filter_id);
}; };
#endif /* already included */ #endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+45 -105
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "conf.h"
#include "file.h" #include "file.h"
#include "filter.h" #include "filter.h"
@@ -33,19 +32,16 @@
#include "p_djgpp2.h" #include "p_djgpp2.h"
#include "linker.h" #include "linker.h"
static const static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i386-dos32.djgpp2.h" #include "stub/i386-dos32.djgpp2.h"
static const static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i386-dos32.djgpp2-stubify.h" #include "stub/i386-dos32.djgpp2-stubify.h"
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
PackDjgpp2::PackDjgpp2(InputFile *f) : PackDjgpp2::PackDjgpp2(InputFile *f) : super(f), coff_offset(0) {
super(f), coff_offset(0)
{
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40) COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8) COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
@@ -58,55 +54,33 @@ PackDjgpp2::PackDjgpp2(InputFile *f) :
// assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32); // assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
} }
const int *PackDjgpp2::getCompressionMethods(int method, int level) const {
const int *PackDjgpp2::getCompressionMethods(int method, int level) const
{
return Packer::getDefaultCompressionMethods_le32(method, level); return Packer::getDefaultCompressionMethods_le32(method, level);
} }
const int *PackDjgpp2::getFilters() const {
const int *PackDjgpp2::getFilters() const static const int filters[] = {0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14,
{ 0x11, FT_ULTRA_BRUTE, 0x25, 0x15, 0x12, FT_END};
static const int filters[] = {
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters; return filters;
} }
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf, unsigned range,
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf, unsigned upper_limit) const {
const upx_bytep tbuf,
unsigned range,
unsigned upper_limit) const
{
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit); unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
o = (o + 0x3ff) & ~0x1ff; o = (o + 0x3ff) & ~0x1ff;
return o; return o;
} }
Linker *PackDjgpp2::newLinker() const { return new ElfLinkerX86; }
Linker* PackDjgpp2::newLinker() const void PackDjgpp2::buildLoader(const Filter *ft) {
{
return new ElfLinkerX86;
}
void PackDjgpp2::buildLoader(const Filter *ft)
{
// prepare loader // prepare loader
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2)); initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
addLoader("IDENTSTR,DJ2MAIN1", addLoader("IDENTSTR,DJ2MAIN1", ft->id ? "DJCALLT1" : "",
ft->id ? "DJCALLT1" : "",
ph.first_offset_found == 1 ? "DJ2MAIN2" : "", ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "", M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "", getDecompressorSections(),
getDecompressorSections(), M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "", "DJ2BSS00", nullptr);
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "", if (ft->id) {
"DJ2BSS00",
nullptr
);
if (ft->id)
{
assert(ft->calls > 0); assert(ft->calls > 0);
addLoader("DJCALLT2", nullptr); addLoader("DJCALLT2", nullptr);
addFilter32(ft->id); addFilter32(ft->id);
@@ -114,22 +88,16 @@ void PackDjgpp2::buildLoader(const Filter *ft)
addLoader("DJRETURN,+40C,UPX1HEAD", nullptr); addLoader("DJRETURN,+40C,UPX1HEAD", nullptr);
} }
/************************************************************************* /*************************************************************************
// util // util
**************************************************************************/ **************************************************************************/
void PackDjgpp2::handleStub(OutputFile *fo) void PackDjgpp2::handleStub(OutputFile *fo) {
{ if (fo && !opt->djgpp2_coff.coff) {
if (fo && !opt->djgpp2_coff.coff) if (coff_offset > 0) {
{
if (coff_offset > 0)
{
// copy stub from exe // copy stub from exe
Packer::handleStub(fi, fo, coff_offset); Packer::handleStub(fi, fo, coff_offset);
} } else {
else
{
// "stubify" stub // "stubify" stub
info("Adding stub: %ld bytes", (long) sizeof(stub_i386_dos32_djgpp2_stubify)); info("Adding stub: %ld bytes", (long) sizeof(stub_i386_dos32_djgpp2_stubify));
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify)); fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
@@ -137,9 +105,7 @@ void PackDjgpp2::handleStub(OutputFile *fo)
} }
} }
static bool is_dlm(InputFile *fi, unsigned coff_offset) {
static bool is_dlm(InputFile *fi, unsigned coff_offset)
{
unsigned char buf[4]; unsigned char buf[4];
unsigned off; unsigned off;
@@ -158,9 +124,7 @@ static bool is_dlm(InputFile *fi, unsigned coff_offset)
return false; return false;
} }
static void handle_allegropak(InputFile *fi, OutputFile *fo) {
static void handle_allegropak(InputFile *fi, OutputFile *fo)
{
unsigned char b[8]; unsigned char b[8];
int pfsize = 0; int pfsize = 0;
@@ -177,8 +141,7 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
return; return;
} }
MemBuffer buf(0x4000); MemBuffer buf(0x4000);
while (pfsize > 0) while (pfsize > 0) {
{
const int len = UPX_MIN(pfsize, (int) buf.getSize()); const int len = UPX_MIN(pfsize, (int) buf.getSize());
fi->readx(buf, len); fi->readx(buf, len);
fo->write(buf, len); fo->write(buf, len);
@@ -186,9 +149,7 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
} }
} }
int PackDjgpp2::readFileHeader() {
int PackDjgpp2::readFileHeader()
{
unsigned char hdr[0x1c]; unsigned char hdr[0x1c];
unsigned char magic[8]; unsigned char magic[8];
@@ -206,9 +167,7 @@ int PackDjgpp2::readFileHeader()
fi->seek(coff_offset, SEEK_SET); fi->seek(coff_offset, SEEK_SET);
if (fi->read(&coff_hdr, sizeof(coff_hdr)) != sizeof(coff_hdr)) if (fi->read(&coff_hdr, sizeof(coff_hdr)) != sizeof(coff_hdr))
throwCantPack("skipping djgpp symlink"); throwCantPack("skipping djgpp symlink");
} } else {
else
{
fi->seek(coff_offset, SEEK_SET); fi->seek(coff_offset, SEEK_SET);
fi->readx(&coff_hdr, 0xa8); fi->readx(&coff_hdr, 0xa8);
} }
@@ -226,23 +185,19 @@ int PackDjgpp2::readFileHeader()
return UPX_F_DJGPP2_COFF; return UPX_F_DJGPP2_COFF;
} }
// "strip" debug info // "strip" debug info
void PackDjgpp2::stripDebug() void PackDjgpp2::stripDebug() {
{
coff_hdr.f_symptr = 0; coff_hdr.f_symptr = 0;
coff_hdr.f_nsyms = 0; coff_hdr.f_nsyms = 0;
coff_hdr.f_flags = 0x10f; // 0x100: "32 bit machine: LSB first" coff_hdr.f_flags = 0x10f; // 0x100: "32 bit machine: LSB first"
memset(text->misc, 0, 12); memset(text->misc, 0, 12);
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
bool PackDjgpp2::canPack() bool PackDjgpp2::canPack() {
{
if (!readFileHeader()) if (!readFileHeader())
return false; return false;
if (is_dlm(fi, coff_offset)) if (is_dlm(fi, coff_offset))
@@ -253,38 +208,32 @@ bool PackDjgpp2::canPack()
throwAlreadyPacked(); throwAlreadyPacked();
// Check for gap in vaddr between text and data, or between data and bss. // Check for gap in vaddr between text and data, or between data and bss.
if (text->vaddr + text->size != data->vaddr if (text->vaddr + text->size != data->vaddr || data->vaddr + data->size != bss->vaddr) {
|| data->vaddr + data->size != bss->vaddr)
{
// "Non-standard" layout of text,data,bss: not contiguous in vaddr. // "Non-standard" layout of text,data,bss: not contiguous in vaddr.
// But should be OK if no overlap. // But should be OK if no overlap.
// Check for no overlap of text and data: // Check for no overlap of text and data:
// neither by vaddr, nor by image data // neither by vaddr, nor by image data
if (text->vaddr + text->size <= data->vaddr && if (text->vaddr + text->size <= data->vaddr &&
data->scnptr - text->scnptr <= data->vaddr - text->vaddr) data->scnptr - text->scnptr <= data->vaddr - text->vaddr) {
{
// Examples: Quake1; FreePascal(DOS) install.exe (github-issue45) // Examples: Quake1; FreePascal(DOS) install.exe (github-issue45)
// Hack: enlarge text image data to eliminate the gap. // Hack: enlarge text image data to eliminate the gap.
text->size = coff_hdr.a_tsize = data->scnptr - text->scnptr; text->size = coff_hdr.a_tsize = data->scnptr - text->scnptr;
// But complain if this causes overlap in vaddr // But complain if this causes overlap in vaddr
if (text->vaddr + text->size > data->vaddr) if (text->vaddr + text->size > data->vaddr)
throwAlreadyPacked(); throwAlreadyPacked();
} } else
else
throwAlreadyPacked(); throwAlreadyPacked();
} }
// FIXME: check for Linux etc. // FIXME: check for Linux etc.
return true; return true;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
void PackDjgpp2::pack(OutputFile *fo) void PackDjgpp2::pack(OutputFile *fo) {
{
handleStub(fo); handleStub(fo);
// patch coff header #1: "strip" debug info // patch coff header #1: "strip" debug info
@@ -313,7 +262,8 @@ void PackDjgpp2::pack(OutputFile *fo)
ft.buf_len = usize - data->size; ft.buf_len = usize - data->size;
ft.addvalue = text->vaddr - hdrsize; ft.addvalue = text->vaddr - hdrsize;
// compress // compress
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf;
cconf.reset();
// limit stack size needed for runtime decompression // limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
compressWithFilters(&ft, 512, &cconf); compressWithFilters(&ft, 512, &cconf);
@@ -331,7 +281,8 @@ void PackDjgpp2::pack(OutputFile *fo)
text->scnptr = sizeof(coff_hdr); text->scnptr = sizeof(coff_hdr);
data->scnptr = text->scnptr + text->size; data->scnptr = text->scnptr + text->size;
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200; data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size +
ph.overlap_overhead - 0x200;
coff_hdr.f_nscns = 3; coff_hdr.f_nscns = 3;
linker->defineSymbol("original_entry", coff_hdr.a_entry); linker->defineSymbol("original_entry", coff_hdr.a_entry);
@@ -391,13 +342,11 @@ void PackDjgpp2::pack(OutputFile *fo)
throwNotCompressible(); throwNotCompressible();
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int PackDjgpp2::canUnpack() int PackDjgpp2::canUnpack() {
{
if (!readFileHeader()) if (!readFileHeader())
return false; return false;
if (is_dlm(fi, coff_offset)) if (is_dlm(fi, coff_offset))
@@ -406,17 +355,15 @@ int PackDjgpp2::canUnpack()
return readPackHeader(4096) ? 1 : -1; return readPackHeader(4096) ? 1 : -1;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
void PackDjgpp2::unpack(OutputFile *fo) void PackDjgpp2::unpack(OutputFile *fo) {
{
handleStub(fo); handleStub(fo);
ibuf.alloc(ph.c_len); ibuf.alloc(ph.c_len);
obuf.allocForUncompression(ph.u_len); obuf.allocForDecompression(ph.u_len);
fi->seek(coff_offset + ph.buf_offset + ph.getPackHeaderSize(), SEEK_SET); fi->seek(coff_offset + ph.buf_offset + ph.getPackHeaderSize(), SEEK_SET);
fi->readx(ibuf, ph.c_len); fi->readx(ibuf, ph.c_len);
@@ -428,8 +375,7 @@ void PackDjgpp2::unpack(OutputFile *fo)
text = chdr->sh; text = chdr->sh;
data = text + 1; data = text + 1;
const unsigned hdrsize = 20 + 28 const unsigned hdrsize = 20 + 28 + sizeof(external_scnhdr_t) * chdr->f_nscns;
+ sizeof(external_scnhdr_t) * chdr->f_nscns;
unsigned addvalue; unsigned addvalue;
if (ph.version >= 14) if (ph.version >= 14)
@@ -438,13 +384,11 @@ void PackDjgpp2::unpack(OutputFile *fo)
addvalue = text->vaddr & ~0x1ff; // for old versions addvalue = text->vaddr & ~0x1ff; // for old versions
// unfilter // unfilter
if (ph.filter) if (ph.filter) {
{
Filter ft(ph.level); Filter ft(ph.level);
ft.init(ph.filter, addvalue); ft.init(ph.filter, addvalue);
ft.cto = (unsigned char) ph.filter_cto; ft.cto = (unsigned char) ph.filter_cto;
if (ph.version < 11) if (ph.version < 11) {
{
unsigned char ctobuf[4]; unsigned char ctobuf[4];
fi->readx(ctobuf, 4); fi->readx(ctobuf, 4);
ft.cto = (unsigned char) (get_le32(ctobuf) >> 24); ft.cto = (unsigned char) (get_le32(ctobuf) >> 24);
@@ -452,17 +396,14 @@ void PackDjgpp2::unpack(OutputFile *fo)
ft.unfilter(obuf, ph.u_len - data->size); ft.unfilter(obuf, ph.u_len - data->size);
} }
if (ph.version < 14) if (ph.version < 14) {
{
// fixup for the aligning bug in strip 2.8+ // fixup for the aligning bug in strip 2.8+
text->scnptr &= 0x1ff; text->scnptr &= 0x1ff;
data->scnptr = text->scnptr + text->size; data->scnptr = text->scnptr + text->size;
// write decompressed file // write decompressed file
if (fo) if (fo)
fo->write(obuf, ph.u_len); fo->write(obuf, ph.u_len);
} } else {
else
{
// write the header // write the header
// some padding might be required between the end // some padding might be required between the end
// of the header and the start of the .text section // of the header and the start of the .text section
@@ -470,8 +411,7 @@ void PackDjgpp2::unpack(OutputFile *fo)
const unsigned padding = text->scnptr - hdrsize; const unsigned padding = text->scnptr - hdrsize;
ibuf.clear(0, padding); ibuf.clear(0, padding);
if (fo) if (fo) {
{
fo->write(obuf, hdrsize); fo->write(obuf, hdrsize);
fo->write(ibuf, padding); fo->write(ibuf, padding);
fo->write(obuf + hdrsize, ph.u_len - hdrsize); fo->write(obuf + hdrsize, ph.u_len - hdrsize);
+14 -16
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,17 +25,15 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#pragma once
#ifndef __UPX_P_DJGPP2_H #ifndef UPX_P_DJGPP2_H__
#define __UPX_P_DJGPP2_H 1 #define UPX_P_DJGPP2_H__ 1
/************************************************************************* /*************************************************************************
// djgpp2/coff // djgpp2/coff
**************************************************************************/ **************************************************************************/
class PackDjgpp2 final : public Packer class PackDjgpp2 final : public Packer {
{
typedef Packer super; typedef Packer super;
public: public:
@@ -43,7 +41,9 @@ public:
virtual int getVersion() const override { return 14; } virtual int getVersion() const override { return 14; }
virtual int getFormat() const override { return UPX_F_DJGPP2_COFF; } virtual int getFormat() const override { return UPX_F_DJGPP2_COFF; }
virtual const char *getName() const override { return "djgpp2/coff"; } virtual const char *getName() const override { return "djgpp2/coff"; }
virtual const char *getFullName(const options_t *) const override { return "i386-dos32.djgpp2.coff"; } virtual const char *getFullName(const options_t *) const override {
return "i386-dos32.djgpp2.coff";
}
virtual const int *getCompressionMethods(int method, int level) const override; virtual const int *getCompressionMethods(int method, int level) const override;
virtual const int *getFilters() const override; virtual const int *getFilters() const override;
@@ -57,8 +57,7 @@ protected:
void handleStub(OutputFile *fo); void handleStub(OutputFile *fo);
int readFileHeader(); int readFileHeader();
virtual unsigned findOverlapOverhead(const upx_bytep buf, virtual unsigned findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf,
const upx_bytep tbuf,
unsigned range = 0, unsigned range = 0,
unsigned upper_limit = ~0u) const override; unsigned upper_limit = ~0u) const override;
virtual void buildLoader(const Filter *ft) override; virtual void buildLoader(const Filter *ft) override;
@@ -66,16 +65,16 @@ protected:
unsigned coff_offset; unsigned coff_offset;
__packed_struct(external_scnhdr_t) struct alignas(1) external_scnhdr_t {
char _[12]; // name, paddr char _[12]; // name, paddr
LE32 vaddr; LE32 vaddr;
LE32 size; LE32 size;
LE32 scnptr; LE32 scnptr;
char misc[12]; // relptr, lnnoptr, nreloc, nlnno char misc[12]; // relptr, lnnoptr, nreloc, nlnno
char __[4]; // flags char __[4]; // flags
__packed_struct_end() };
__packed_struct(coff_header_t) struct alignas(1) coff_header_t {
// ext_file_hdr // ext_file_hdr
LE16 f_magic; LE16 f_magic;
LE16 f_nscns; LE16 f_nscns;
@@ -96,7 +95,7 @@ protected:
// section headers // section headers
external_scnhdr_t sh[3]; external_scnhdr_t sh[3];
__packed_struct_end() };
coff_header_t coff_hdr; coff_header_t coff_hdr;
external_scnhdr_t *text, *data, *bss; external_scnhdr_t *text, *data, *bss;
@@ -104,7 +103,6 @@ protected:
void stripDebug(); void stripDebug();
}; };
#endif /* already included */ #endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+36 -35
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -41,15 +41,15 @@
EI_DATA = 5, /* Data encoding */ EI_DATA = 5, /* Data encoding */
EI_VERSION = 6, EI_VERSION = 6,
EI_OSABI = 7, EI_OSABI = 7,
EI_ABIVERSION = 8 EI_ABIVERSION = 8,
}; };
enum { // e_ident[EI_CLASS] enum { // e_ident[EI_CLASS]
ELFCLASS32 = 1, /* 32-bit objects */ ELFCLASS32 = 1, /* 32-bit objects */
ELFCLASS64 = 2 /* 64-bit objects */ ELFCLASS64 = 2, /* 64-bit objects */
}; };
enum { // e_ident[EI_DATA] enum { // e_ident[EI_DATA]
ELFDATA2LSB = 1, /* 2's complement, little endian */ ELFDATA2LSB = 1, /* 2's complement, little endian */
ELFDATA2MSB = 2 /* 2's complement, big endian */ ELFDATA2MSB = 2, /* 2's complement, big endian */
}; };
enum { // e_ident[EI_OSABI] enum { // e_ident[EI_OSABI]
ELFOSABI_NONE = 0, // == ELFOSABI_SYSV ELFOSABI_NONE = 0, // == ELFOSABI_SYSV
@@ -57,14 +57,14 @@
ELFOSABI_LINUX = 3, ELFOSABI_LINUX = 3,
ELFOSABI_FREEBSD = 9, ELFOSABI_FREEBSD = 9,
ELFOSABI_OPENBSD = 12, ELFOSABI_OPENBSD = 12,
ELFOSABI_ARM = 97 ELFOSABI_ARM = 97,
}; };
enum { // e_type enum { // e_type
ET_NONE = 0, /* No file type */ ET_NONE = 0, /* No file type */
ET_REL = 1, /* Relocatable file */ ET_REL = 1, /* Relocatable file */
ET_EXEC = 2, /* Executable file */ ET_EXEC = 2, /* Executable file */
ET_DYN = 3, /* Shared object file */ ET_DYN = 3, /* Shared object file */
ET_CORE = 4 /* Core file */ ET_CORE = 4, /* Core file */
}; };
enum { // e_machine enum { // e_machine
EM_386 = 3, EM_386 = 3,
@@ -74,11 +74,11 @@
EM_PPC64 = 21, EM_PPC64 = 21,
EM_ARM = 40, EM_ARM = 40,
EM_X86_64 = 62, EM_X86_64 = 62,
EM_AARCH64 = 183 EM_AARCH64 = 183,
}; };
enum { // e_version enum { // e_version
EV_CURRENT = 1 EV_CURRENT = 1,
}; };
#endif #endif
@@ -91,15 +91,16 @@
PT_DYNAMIC = 2, /* Dynamic linking information */ PT_DYNAMIC = 2, /* Dynamic linking information */
PT_INTERP = 3, /* Name of program interpreter */ PT_INTERP = 3, /* Name of program interpreter */
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */ PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
PT_PHDR = 6 /* Entry for header table itself */ PT_PHDR = 6, /* Entry for header table itself */
, PT_NUM = 8 /* Number of defined types in low range */ PT_NUM = 8, /* Number of defined types in low range */
, PT_GNU_STACK = 0x6474e551 /* Indicates stack executability */ PT_GNU_STACK = 0x6474e551, /* Indicates stack executability */
PT_GNU_RELRO = 0x6474e552, /* Read-only after relocation */
}; };
enum { // p_flags enum { // p_flags
PF_X = 1, /* Segment is executable */ PF_X = 1, /* Segment is executable */
PF_W = 2, /* Segment is writable */ PF_W = 2, /* Segment is writable */
PF_R = 4 /* Segment is readable */ PF_R = 4, /* Segment is readable */
}; };
#endif #endif
@@ -125,12 +126,12 @@
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */ SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
SHT_GROUP = 17, /* Section group */ SHT_GROUP = 17, /* Section group */
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */ SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
SHT_GNU_LIBLIST = 0x6ffffff7 /* Prelink library list */ SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
, SHT_GNU_HASH = 0x6ffffff6 /* GNU-style hash table. */ SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */
, SHT_LOOS = 0x60000000 /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */ SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
, SHT_LOPROC = 0x70000000/* Start of processor-specific */ SHT_LOPROC = 0x70000000, /* Start of processor-specific */
, SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3) /* ARM attributes section. */ SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3), /* ARM attributes section. */
}; };
enum { // sh_flags enum { // sh_flags
@@ -140,7 +141,7 @@
SHF_MERGE = (1 << 4), /* Might be merged */ SHF_MERGE = (1 << 4), /* Might be merged */
SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */ SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */
SHF_INFO_LINK = (1 << 6), /* 'sh_info' contains SHT index */ SHF_INFO_LINK = (1 << 6), /* 'sh_info' contains SHT index */
SHF_LINK_ORDER = (1 << 7) /* Preserve order after combining */ SHF_LINK_ORDER = (1 << 7), /* Preserve order after combining */
}; };
#endif #endif
@@ -182,11 +183,11 @@
DT_VERSYM = 0x6ffffff0, /* version[] for each symbol */ DT_VERSYM = 0x6ffffff0, /* version[] for each symbol */
DT_FLAGS_1 = 0x6ffffffb, /* DF_1_* */ DT_FLAGS_1 = 0x6ffffffb, /* DF_1_* */
DT_VERDEF = 0x6ffffffc, /* version definitions[] */ DT_VERDEF = 0x6ffffffc, /* version definitions[] */
DT_VERNEED = 0x6ffffffe /* version[] needed */ DT_VERNEED = 0x6ffffffe, /* version[] needed */
}; };
enum { // DT_FLAGS_1 enum { // DT_FLAGS_1
DF_1_NOW = 0x00000001, /* Set RTLD_NOW for this object. */ DF_1_NOW = 0x00000001, /* Set RTLD_NOW for this object. */
DF_1_PIE = 0x08000000 // Position-Independent Executable (main program) DF_1_PIE = 0x08000000, // Position-Independent Executable (main program)
}; };
#endif #endif
@@ -196,7 +197,7 @@
enum { // st_bind (high 4 bits of st_info) enum { // st_bind (high 4 bits of st_info)
STB_LOCAL = 0, /* Local symbol */ STB_LOCAL = 0, /* Local symbol */
STB_GLOBAL = 1, /* Global symbol */ STB_GLOBAL = 1, /* Global symbol */
STB_WEAK = 2 /* Weak symbol */ STB_WEAK = 2, /* Weak symbol */
}; };
enum { // st_type (low 4 bits of st_info) enum { // st_type (low 4 bits of st_info)
@@ -206,20 +207,20 @@
STT_SECTION = 3, /* Symbol associated with a section */ STT_SECTION = 3, /* Symbol associated with a section */
STT_FILE = 4, /* Symbol's name is file name */ STT_FILE = 4, /* Symbol's name is file name */
STT_COMMON = 5, /* Symbol is a common data object */ STT_COMMON = 5, /* Symbol is a common data object */
STT_TLS = 6 /* Symbol is thread-local data object*/ STT_TLS = 6, /* Symbol is thread-local data object*/
}; };
enum { // st_other (visibility) enum { // st_other (visibility)
STV_DEFAULT = 0, /* Default symbol visibility rules */ STV_DEFAULT = 0, /* Default symbol visibility rules */
STV_INTERNAL = 1, /* Processor specific hidden class */ STV_INTERNAL = 1, /* Processor specific hidden class */
STV_HIDDEN = 2, /* Sym unavailable in other modules */ STV_HIDDEN = 2, /* Sym unavailable in other modules */
STV_PROTECTED= 3 /* Not preemptible, not exported */ STV_PROTECTED= 3, /* Not preemptible, not exported */
}; };
enum { // st_shndx enum { // st_shndx
SHN_UNDEF = 0, /* Undefined section */ SHN_UNDEF = 0, /* Undefined section */
SHN_ABS = 0xfff1, /* Associated symbol is absolute */ SHN_ABS = 0xfff1, /* Associated symbol is absolute */
SHN_COMMON = 0xfff2 /* Associated symbol is common */ SHN_COMMON = 0xfff2, /* Associated symbol is common */
}; };
#endif #endif
@@ -246,13 +247,13 @@
R_ARM_JUMP_SLOT = 22, R_ARM_JUMP_SLOT = 22,
R_PPC_JMP_SLOT = 21, R_PPC_JMP_SLOT = 21,
R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT, R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT,
R_X86_64_JUMP_SLOT = 7 R_X86_64_JUMP_SLOT = 7,
, R_ARM_ABS32 = 2 R_ARM_ABS32 = 2,
, R_ARM_GLOB_DAT = 21 R_ARM_GLOB_DAT = 21,
, R_AARCH64_ABS64 = 257 R_AARCH64_ABS64 = 257,
, R_AARCH64_GLOB_DAT = 1025 R_AARCH64_GLOB_DAT = 1025,
}; };
#endif //} #endif //}
@@ -271,7 +272,7 @@
#define ELF_NOTE_NETBSD_NAME "NetBSD\0" #define ELF_NOTE_NETBSD_NAME "NetBSD\0"
NHDR_NETBSD_TAG = 1, NHDR_NETBSD_TAG = 1,
NHDR_CHECKSUM_TAG = 2, NHDR_CHECKSUM_TAG = 2,
NHDR_PAX_TAG = 3 NHDR_PAX_TAG = 3,
}; };
enum { // descsz descriptor sizes enum { // descsz descriptor sizes
@@ -279,20 +280,20 @@
NETBSD_DESCSZ = 4, // major_ver * (10**8) + minor NETBSD_DESCSZ = 4, // major_ver * (10**8) + minor
OPENBSD_DESCSZ = 4, // 32-bit zero OPENBSD_DESCSZ = 4, // 32-bit zero
// CHECKSUM_DESCSZ is 2*sizeof(short) + sizeof(checksum) // CHECKSUM_DESCSZ is 2*sizeof(short) + sizeof(checksum)
PAX_DESCSZ = 4 // 32-bit mask PAX_DESCSZ = 4, // 32-bit mask
}; };
enum { // GNU OS/version enum { // GNU OS/version
GNU_OS_LINUX = 0, GNU_OS_LINUX = 0,
GNU_OS_HURD = 1, GNU_OS_HURD = 1,
GNU_OS_SOLARIS = 2 GNU_OS_SOLARIS = 2,
}; };
enum { // NetBSD checksum methods enum { // NetBSD checksum methods
CHECKSUM_CRC32 = 1, CHECKSUM_CRC32 = 1,
CHECKSUM_MD5 = 2, CHECKSUM_MD5 = 2,
CHECKSUM_SHA1 = 3, CHECKSUM_SHA1 = 3,
CHECKSUM_SHA256 = 4 CHECKSUM_SHA256 = 4,
}; };
#define ELF_NOTE_PAX_NAME "PaX\0" #define ELF_NOTE_PAX_NAME "PaX\0"
@@ -302,7 +303,7 @@
PAX_GUARD = (1<<2), /* force enable SEGVguard */ PAX_GUARD = (1<<2), /* force enable SEGVguard */
PAX_NOGUARD = (1<<3), /* force disable SEGVguard */ PAX_NOGUARD = (1<<3), /* force disable SEGVguard */
PAX_ASLR = (1<<4), /* force enable ASLR */ PAX_ASLR = (1<<4), /* force enable ASLR */
PAX_NOASLR = (1<<5) /* force disable ASLR */ PAX_NOASLR = (1<<5), /* force disable ASLR */
}; };
#endif #endif
+119 -219
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,7 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "conf.h"
#include "file.h" #include "file.h"
#include "filter.h" #include "filter.h"
@@ -33,7 +32,7 @@
#include "p_exe.h" #include "p_exe.h"
#include "linker.h" #include "linker.h"
static const static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i086-dos16.exe.h" #include "stub/i086-dos16.exe.h"
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info #define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
@@ -42,14 +41,11 @@ static const
#define DI_LIMIT 0xff00 // see the assembly why #define DI_LIMIT 0xff00 // see the assembly why
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
PackExe::PackExe(InputFile *f) : PackExe::PackExe(InputFile *f) : super(f) {
super(f)
{
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32) COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32)
COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t) COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t)
@@ -58,9 +54,7 @@ PackExe::PackExe(InputFile *f) :
use_clear_dirty_stack = false; use_clear_dirty_stack = false;
} }
const int *PackExe::getCompressionMethods(int method, int level) const {
const int *PackExe::getCompressionMethods(int method, int level) const
{
bool small = ih_imagesize <= 256 * 1024; bool small = ih_imagesize <= 256 * 1024;
// disable lzma for "--brute" unless explicitly given "--lzma" // disable lzma for "--brute" unless explicitly given "--lzma"
// WARNING: this side effect may persists for later files; // WARNING: this side effect may persists for later files;
@@ -70,15 +64,9 @@ const int *PackExe::getCompressionMethods(int method, int level) const
return Packer::getDefaultCompressionMethods_8(method, level, small); return Packer::getDefaultCompressionMethods_8(method, level, small);
} }
const int *PackExe::getFilters() const { return nullptr; }
const int *PackExe::getFilters() const int PackExe::fillExeHeader(struct exe_header_t *eh) const {
{
return nullptr;
}
int PackExe::fillExeHeader(struct exe_header_t *eh) const
{
#define oh (*eh) #define oh (*eh)
// fill new exe header // fill new exe header
int flag = 0; int flag = 0;
@@ -106,8 +94,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
oh.ss = ph.c_len / 16 + destpara; oh.ss = ph.c_len / 16 + destpara;
if (ih.ss * 16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200) if (ih.ss * 16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200)
oh.ss = ih.ss; oh.ss = ih.ss;
if (oh.ss*16 + 0x50 < ih.ss*16 + ih.sp if (oh.ss * 16 + 0x50 < ih.ss * 16 + ih.sp && oh.ss * 16 + 0x200 > ih.ss * 16 + ih.sp)
&& oh.ss*16 + 0x200 > ih.ss*16 + ih.sp)
oh.ss += 0x20; oh.ss += 0x20;
if (oh.ss != ih.ss) if (oh.ss != ih.ss)
@@ -118,58 +105,38 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
#undef oh #undef oh
} }
void PackExe::addLoaderEpilogue(int flag) void PackExe::addLoaderEpilogue(int flag) {
{
addLoader("EXEMAIN5", nullptr); addLoader("EXEMAIN5", nullptr);
if (relocsize) if (relocsize)
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS", addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ"
"EXERELO1", : "EXEADJUS",
has_9a ? "EXEREL9A" : "", "EXERELO1", has_9a ? "EXEREL9A" : "", "EXERELO2",
"EXERELO2", ih_exesize > 0xFE00 ? "EXEREBIG" : "", "EXERELO3", nullptr);
ih_exesize > 0xFE00 ? "EXEREBIG" : "", addLoader("EXEMAIN8", device_driver ? "DEVICEEND" : "", (flag & SS) ? "EXESTACK" : "",
"EXERELO3", (flag & SP) ? "EXESTASP" : "", (flag & USEJUMP) ? "EXEJUMPF" : "", nullptr);
nullptr
);
addLoader("EXEMAIN8",
device_driver ? "DEVICEEND" : "",
(flag & SS) ? "EXESTACK" : "",
(flag & SP) ? "EXESTASP" : "",
(flag & USEJUMP) ? "EXEJUMPF" : "",
nullptr
);
if (!(flag & USEJUMP)) if (!(flag & USEJUMP))
addLoader(ih.cs ? "EXERCSPO" : "", addLoader(ih.cs ? "EXERCSPO" : "", "EXERETIP", nullptr);
"EXERETIP",
nullptr
);
linker->defineSymbol("original_cs", ih.cs); linker->defineSymbol("original_cs", ih.cs);
linker->defineSymbol("original_ip", ih.ip); linker->defineSymbol("original_ip", ih.ip);
linker->defineSymbol("original_sp", ih.sp); linker->defineSymbol("original_sp", ih.sp);
linker->defineSymbol("original_ss", ih.ss); linker->defineSymbol("original_ss", ih.ss);
linker->defineSymbol("reloc_size", linker->defineSymbol(
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) "reloc_size",
>= relocsize ? 0 : MAXRELOCS) - relocsize); (ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
} }
void PackExe::buildLoader(const Filter *) void PackExe::buildLoader(const Filter *) {
{
// get flag // get flag
exe_header_t dummy_oh; exe_header_t dummy_oh;
int flag = fillExeHeader(&dummy_oh); int flag = fillExeHeader(&dummy_oh);
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe)); initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
if (M_IS_LZMA(ph.method)) if (M_IS_LZMA(ph.method)) {
{ addLoader("LZMA_DEC00", opt->small ? "LZMA_DEC10" : "LZMA_DEC20", "LZMA_DEC30",
addLoader("LZMA_DEC00", use_clear_dirty_stack ? "LZMA_DEC31" : "", "LZMA_DEC32",
opt->small ? "LZMA_DEC10" : "LZMA_DEC20", ph.u_len > 0xffff ? "LZMA_DEC33" : "", nullptr);
"LZMA_DEC30",
use_clear_dirty_stack ? "LZMA_DEC31" : "",
"LZMA_DEC32",
ph.u_len > 0xffff ? "LZMA_DEC33" : "",
nullptr
);
addLoaderEpilogue(flag); addLoaderEpilogue(flag);
defineDecompressorSymbols(); defineDecompressorSymbols();
@@ -196,9 +163,10 @@ void PackExe::buildLoader(const Filter *)
MemBuffer compressed_lzma; MemBuffer compressed_lzma;
compressed_lzma.allocForCompression(lsize); compressed_lzma.allocForCompression(lsize);
unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize); unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize);
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma, int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma, nullptr, M_NRV2B_LE16, 9,
nullptr, M_NRV2B_LE16, 9, nullptr, nullptr); nullptr, nullptr);
assert(r == UPX_E_OK); assert(c_len_lzma < lsize); assert(r == UPX_E_OK);
assert(c_len_lzma < lsize);
info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma); info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma);
// reinit the loader // reinit the loader
@@ -208,60 +176,32 @@ void PackExe::buildLoader(const Filter *)
addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", nullptr); addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", nullptr);
linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0); linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0);
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2", addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2", nullptr);
nullptr);
} } else if (device_driver)
else if (device_driver)
addLoader("DEVICEENTRY,DEVICEENTRY2", nullptr); addLoader("DEVICEENTRY,DEVICEENTRY2", nullptr);
addLoader("EXEENTRY", addLoader("EXEENTRY", M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB", "JNCDOCOPY", relocsize ? "EXERELPU" : "", "EXEMAIN4",
"JNCDOCOPY", M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B", "EXEMAIN4C",
relocsize ? "EXERELPU" : "",
"EXEMAIN4",
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B",
"EXEMAIN4C",
M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "", M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "",
"+G5DXXXX,UPX1HEAD,EXECUTPO", "+G5DXXXX,UPX1HEAD,EXECUTPO", nullptr);
nullptr
);
if (ph.method == M_NRV2B_8) if (ph.method == M_NRV2B_8)
addLoader("NRV2B16S", // decompressor addLoader("NRV2B16S", // decompressor
ph.u_len > DI_LIMIT ? "N2B64K01" : "", ph.u_len > DI_LIMIT ? "N2B64K01" : "", "NRV2BEX1",
"NRV2BEX1", opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601", "NRV2BEX2",
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601", opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602", "NRV2BEX3",
"NRV2BEX2", ph.c_len > 0xffff ? "N2B64K02" : "", "NRV2BEX9", nullptr);
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
"NRV2BEX3",
ph.c_len > 0xffff ? "N2B64K02" : "",
"NRV2BEX9",
nullptr
);
else if (ph.method == M_NRV2D_8) else if (ph.method == M_NRV2D_8)
addLoader("NRV2D16S", addLoader("NRV2D16S", ph.u_len > DI_LIMIT ? "N2D64K01" : "", "NRV2DEX1",
ph.u_len > DI_LIMIT ? "N2D64K01" : "", opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601", "NRV2DEX2",
"NRV2DEX1", opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602", "NRV2DEX3",
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601", ph.c_len > 0xffff ? "N2D64K02" : "", "NRV2DEX9", nullptr);
"NRV2DEX2",
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
"NRV2DEX3",
ph.c_len > 0xffff ? "N2D64K02" : "",
"NRV2DEX9",
nullptr
);
else if (ph.method == M_NRV2E_8) else if (ph.method == M_NRV2E_8)
addLoader("NRV2E16S", addLoader("NRV2E16S", ph.u_len > DI_LIMIT ? "N2E64K01" : "", "NRV2EEX1",
ph.u_len > DI_LIMIT ? "N2E64K01" : "", opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601", "NRV2EEX2",
"NRV2EEX1", opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602", "NRV2EEX3",
opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601", ph.c_len > 0xffff ? "N2E64K02" : "", "NRV2EEX9", nullptr);
"NRV2EEX2",
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
"NRV2EEX3",
ph.c_len > 0xffff ? "N2E64K02" : "",
"NRV2EEX9",
nullptr
);
else if M_IS_LZMA (ph.method) else if M_IS_LZMA (ph.method)
return; return;
else else
@@ -270,13 +210,11 @@ void PackExe::buildLoader(const Filter *)
addLoaderEpilogue(flag); addLoaderEpilogue(flag);
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int PackExe::readFileHeader() int PackExe::readFileHeader() {
{
ih_exesize = ih_imagesize = ih_overlay = 0; ih_exesize = ih_imagesize = ih_overlay = 0;
fi->readx(&ih, sizeof(ih)); fi->readx(&ih, sizeof(ih));
if (ih.ident != 'M' + 'Z' * 256 && ih.ident != 'Z' + 'M' * 256) if (ih.ident != 'M' + 'Z' * 256 && ih.ident != 'Z' + 'M' * 256)
@@ -287,8 +225,7 @@ int PackExe::readFileHeader()
} }
ih_imagesize = ih_exesize - ih.headsize16 * 16; ih_imagesize = ih_exesize - ih.headsize16 * 16;
ih_overlay = file_size - ih_exesize; ih_overlay = file_size - ih_exesize;
if (file_size_u < sizeof(ih) if (file_size_u < sizeof(ih) || ((ih.m512 | ih.p512) && ih.m512 + ih.p512 * 512u < sizeof(ih)))
|| ((ih.m512 | ih.p512) && ih.m512+ih.p512*512u < sizeof (ih)))
throwCantPack("illegal exe header"); throwCantPack("illegal exe header");
if (file_size_u < ih_exesize || ih_imagesize <= 0 || ih_imagesize > ih_exesize) if (file_size_u < ih_exesize || ih_imagesize <= 0 || ih_imagesize > ih_exesize)
throwCantPack("exe header corrupted"); throwCantPack("exe header corrupted");
@@ -298,9 +235,7 @@ int PackExe::readFileHeader()
return UPX_F_DOS_EXE; return UPX_F_DOS_EXE;
} }
bool PackExe::canPack() {
bool PackExe::canPack()
{
if (fn_has_ext(fi->getName(), "sys")) if (fn_has_ext(fi->getName(), "sys"))
return false; return false;
if (!readFileHeader()) if (!readFileHeader())
@@ -310,8 +245,7 @@ bool PackExe::canPack()
fi->seek(0x3c, SEEK_SET); fi->seek(0x3c, SEEK_SET);
LE32 offs; LE32 offs;
fi->readx(&offs, sizeof(offs)); fi->readx(&offs, sizeof(offs));
if (ih.relocoffs >= 0x40 && offs) if (ih.relocoffs >= 0x40 && offs) {
{
if (opt->dos_exe.force_stub) if (opt->dos_exe.force_stub)
opt->overlay = opt->COPY_OVERLAY; opt->overlay = opt->COPY_OVERLAY;
else else
@@ -320,16 +254,12 @@ bool PackExe::canPack()
return true; return true;
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
static static unsigned optimize_relocs(upx_byte *b, const unsigned size, const upx_byte *relocs,
unsigned optimize_relocs(upx_byte *b, const unsigned size, const unsigned nrelocs, upx_byte *crel, bool *has_9a) {
const upx_byte *relocs, const unsigned nrelocs,
upx_byte *crel, bool *has_9a)
{
if (opt->exact) if (opt->exact)
throwCantPackExact(); throwCantPackExact();
@@ -345,13 +275,11 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
#endif #endif
// pass 1 - find 0x9a bounds // pass 1 - find 0x9a bounds
for (i = 0; i < nrelocs; i++) for (i = 0; i < nrelocs; i++) {
{
unsigned addr = get_le32(relocs + 4 * i); unsigned addr = get_le32(relocs + 4 * i);
if (addr >= size - 1) if (addr >= size - 1)
throwCantPack("unexpected relocation 1"); throwCantPack("unexpected relocation 1");
if (addr >= 3 && b[addr-3] == 0x9a) if (addr >= 3 && b[addr - 3] == 0x9a) {
{
unsigned seg = get_le16(b + addr); unsigned seg = get_le16(b + addr);
if (seg > seg_high) if (seg > seg_high)
seg_high = seg; seg_high = seg;
@@ -375,7 +303,6 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
// printf("%d %d\n", off_low, off_high); // printf("%d %d\n", off_low, off_high);
// printf("%d %d\n", linear_low, linear_high); // printf("%d %d\n", linear_low, linear_high);
// pass 2 - reloc // pass 2 - reloc
crel += 4; // to be filled in later crel += 4; // to be filled in later
@@ -383,22 +310,17 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
unsigned ones = 0; unsigned ones = 0;
unsigned es = 0, di, t; unsigned es = 0, di, t;
i = 0; i = 0;
do do {
{
unsigned addr = get_le32(relocs + 4 * i); unsigned addr = get_le32(relocs + 4 * i);
set_le16(crel, di = addr & 0x0f); set_le16(crel, di = addr & 0x0f);
set_le16(crel + 2, (addr >> 4) - es); set_le16(crel + 2, (addr >> 4) - es);
es = addr >> 4; es = addr >> 4;
crel += 4; crel += 4;
for (++i; i < nrelocs; i++) for (++i; i < nrelocs; i++) {
{
addr = get_le32(relocs + 4 * i); addr = get_le32(relocs + 4 * i);
// printf ("%x\n",es*16+di); // printf ("%x\n",es*16+di);
if ((addr - es*16 > 0xfffe) if ((addr - es * 16 > 0xfffe) || (i == nrelocs - 1 && addr - es * 16 > 0xff00)) {
|| (i == nrelocs - 1 && addr - es * 16 > 0xff00)
)
{
// segment change // segment change
t = 1 + (0xffff - di) / 254; t = 1 + (0xffff - di) / 254;
memset(crel, 1, t); memset(crel, 1, t);
@@ -407,13 +329,11 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
break; break;
} }
unsigned offs = addr - es * 16; unsigned offs = addr - es * 16;
if (offs >= 3 && b[es*16 + offs-3] == 0x9a && offs > di + 3) if (offs >= 3 && b[es * 16 + offs - 3] == 0x9a && offs > di + 3) {
{
for (t = di; t < offs - 3; t++) for (t = di; t < offs - 3; t++)
if (b[es * 16 + t] == 0x9a && get_le16(b + es * 16 + t + 3) <= seg_high) if (b[es * 16 + t] == 0x9a && get_le16(b + es * 16 + t + 3) <= seg_high)
break; break;
if (t == offs-3) if (t == offs - 3) {
{
// code 0: search for 0x9a // code 0: search for 0x9a
*crel++ = 0; *crel++ = 0;
di = offs; di = offs;
@@ -425,8 +345,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
if (t < 2) if (t < 2)
throwCantPack("unexpected relocation 2"); throwCantPack("unexpected relocation 2");
while (t >= 256) while (t >= 256) {
{
// code 1: add 254, don't reloc // code 1: add 254, don't reloc
*crel++ = 1; *crel++ = 1;
t -= 254; t -= 254;
@@ -445,13 +364,11 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
return (unsigned) (crel - crel_save); return (unsigned) (crel - crel_save);
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
void PackExe::pack(OutputFile *fo) void PackExe::pack(OutputFile *fo) {
{
unsigned ic; unsigned ic;
if (ih.relocs > MAXRELOCS) if (ih.relocs > MAXRELOCS)
@@ -474,15 +391,13 @@ void PackExe::pack(OutputFile *fo)
// relocations // relocations
has_9a = false; has_9a = false;
upx_byte *w = ibuf + ih_imagesize; upx_byte *w = ibuf + ih_imagesize;
if (ih.relocs) if (ih.relocs) {
{
upx_byte *wr = w + RSFCRI; upx_byte *wr = w + RSFCRI;
fi->seek(ih.relocoffs, SEEK_SET); fi->seek(ih.relocoffs, SEEK_SET);
fi->readx(wr, 4 * ih.relocs); fi->readx(wr, 4 * ih.relocs);
for (ic = 0; ic < ih.relocs; ic++) for (ic = 0; ic < ih.relocs; ic++) {
{
unsigned jc = get_le32(wr + 4 * ic); unsigned jc = get_le32(wr + 4 * ic);
set_le32(wr + 4 * ic, ((jc >> 16) * 16 + (jc & 0xffff)) & 0xfffff); set_le32(wr + 4 * ic, ((jc >> 16) * 16 + (jc & 0xffff)) & 0xfffff);
} }
@@ -499,9 +414,7 @@ void PackExe::pack(OutputFile *fo)
ucl_nrv2b_99_compress(w, in_len, out, &out_len, nullptr, 9, nullptr, nullptr); ucl_nrv2b_99_compress(w, in_len, out, &out_len, nullptr, 9, nullptr, nullptr);
printf("reloc compress: %d -> %d\n", in_len, out_len); printf("reloc compress: %d -> %d\n", in_len, out_len);
#endif #endif
} } else {
else
{
relocsize = 0; relocsize = 0;
} }
@@ -510,7 +423,8 @@ void PackExe::pack(OutputFile *fo)
// prepare filter // prepare filter
Filter ft(ph.level); Filter ft(ph.level);
// compress (max_match = 8192) // compress (max_match = 8192)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf;
cconf.reset();
cconf.conf_ucl.max_match = MAXMATCH; cconf.conf_ucl.max_match = MAXMATCH;
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
compressWithFilters(&ft, 32, &cconf); compressWithFilters(&ft, 32, &cconf);
@@ -520,12 +434,10 @@ void PackExe::pack(OutputFile *fo)
throwCantPack("decompressor limit exceeded, send a bugreport"); throwCantPack("decompressor limit exceeded, send a bugreport");
#if TESTING #if TESTING
if (opt->debug.debug_level) if (opt->debug.debug_level) {
{
printf("image+relocs %d -> %d\n", ih_imagesize + relocsize, ph.c_len); printf("image+relocs %d -> %d\n", ih_imagesize + relocsize, ph.c_len);
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n", printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n", 0 /*ph.min_offset_found*/,
0/*ph.min_offset_found*/,ph.max_offset_found, ph.max_offset_found, 0 /*ph.min_match_found*/, ph.max_match_found,
0/*ph.min_match_found*/,ph.max_match_found,
0 /*ph.min_run_found*/, ph.max_run_found); 0 /*ph.min_run_found*/, ph.max_run_found);
} }
#endif #endif
@@ -557,26 +469,22 @@ void PackExe::pack(OutputFile *fo)
// set extra info // set extra info
unsigned char extra_info[9]; unsigned char extra_info[9];
unsigned eisize = 0; unsigned eisize = 0;
if (oh.ss != ih.ss) if (oh.ss != ih.ss) {
{
set_le16(extra_info + eisize, ih.ss); set_le16(extra_info + eisize, ih.ss);
eisize += 2; eisize += 2;
assert((flag & SS) != 0); // set in fillExeHeader() assert((flag & SS) != 0); // set in fillExeHeader()
} }
if (oh.sp != ih.sp) if (oh.sp != ih.sp) {
{
set_le16(extra_info + eisize, ih.sp); set_le16(extra_info + eisize, ih.sp);
eisize += 2; eisize += 2;
assert((flag & SP) != 0); // set in fillExeHeader() assert((flag & SP) != 0); // set in fillExeHeader()
} }
if (ih.min != oh.min) if (ih.min != oh.min) {
{
set_le16(extra_info + eisize, ih.min); set_le16(extra_info + eisize, ih.min);
eisize += 2; eisize += 2;
flag |= MINMEM; flag |= MINMEM;
} }
if (ih.max != oh.max) if (ih.max != oh.max) {
{
set_le16(extra_info + eisize, ih.max); set_le16(extra_info + eisize, ih.max);
eisize += 2; eisize += 2;
flag |= MAXMEM; flag |= MAXMEM;
@@ -592,16 +500,13 @@ void PackExe::pack(OutputFile *fo)
linker->defineSymbol("decompressor_entry", decompressor_entry); linker->defineSymbol("decompressor_entry", decompressor_entry);
// patch loader // patch loader
if (flag & USEJUMP) if (flag & USEJUMP) {
{
// I use a relocation entry to set the original cs // I use a relocation entry to set the original cs
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1; unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
n += packedsize + 2; n += packedsize + 2;
oh.relocs = 1; oh.relocs = 1;
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16); oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
} } else {
else
{
oh.relocs = 0; oh.relocs = 0;
oh.firstreloc = ih.cs * 0x10000 + ih.ip; oh.firstreloc = ih.cs * 0x10000 + ih.ip;
} }
@@ -633,7 +538,9 @@ void PackExe::pack(OutputFile *fo)
memcpy(loader, getLoader(), lsize); memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, e_len); patchPackHeader(loader, e_len);
//fprintf(stderr,"\ne_len=%x d_len=%x c_len=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,ph.overlap_overhead,ph.u_len,destpara,copysize,ih_imagesize); NO_fprintf(stderr, "\ne_len=%x d_len=%x c_len=%x oo=%x ulen=%x destp=%x copys=%x images=%x",
e_len, d_len, packedsize, ph.overlap_overhead, ph.u_len, /*destpara*/ 0, copysize,
ih_imagesize);
// write header + write loader + compressed file // write header + write loader + compressed file
#if TESTING #if TESTING
@@ -666,13 +573,11 @@ void PackExe::pack(OutputFile *fo)
throwNotCompressible(); throwNotCompressible();
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
int PackExe::canUnpack() int PackExe::canUnpack() {
{
if (!readFileHeader()) if (!readFileHeader())
return false; return false;
const unsigned off = ih.headsize16 * 16; const unsigned off = ih.headsize16 * 16;
@@ -681,15 +586,13 @@ int PackExe::canUnpack()
return b && (off + ph.c_len <= file_size_u); return b && (off + ph.c_len <= file_size_u);
} }
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
void PackExe::unpack(OutputFile *fo) void PackExe::unpack(OutputFile *fo) {
{
ibuf.alloc(file_size); ibuf.alloc(file_size);
obuf.allocForUncompression(ph.u_len); obuf.allocForDecompression(ph.u_len);
// read the file // read the file
fi->seek(ih.headsize16 * 16, SEEK_SET); fi->seek(ih.headsize16 * 16, SEEK_SET);
@@ -712,47 +615,41 @@ void PackExe::unpack(OutputFile *fo)
unsigned relocn = 0; unsigned relocn = 0;
SPAN_S_VAR(upx_byte, relocs, obuf + ph.u_len, obuf); SPAN_S_VAR(upx_byte, relocs, obuf + ph.u_len, obuf);
MemBuffer wrkmem; MemBuffer mb_wrkmem;
if (!(flag & NORELOC)) SPAN_0_VAR(upx_byte, wrkmem, nullptr);
{ if (!(flag & NORELOC)) {
relocs -= get_le16(obuf+ph.u_len-2); relocs -= get_le16(obuf + (ph.u_len - 2));
ph.u_len -= 2; ph.u_len -= 2;
wrkmem.alloc(4*MAXRELOCS); mb_wrkmem.alloc(4 * MAXRELOCS);
wrkmem = mb_wrkmem; // => now a SPAN_S
unsigned es = 0, ones = get_le16(relocs); unsigned es = 0, ones = get_le16(relocs);
const unsigned seghi = get_le16(relocs + 2); const unsigned seghi = get_le16(relocs + 2);
SPAN_S_VAR(const upx_byte, p, relocs + 4); SPAN_S_VAR(const upx_byte, p, relocs + 4);
while (ones) while (ones) {
{
unsigned di = get_le16(p); unsigned di = get_le16(p);
es += get_le16(p + 2); es += get_le16(p + 2);
bool dorel = true; bool dorel = true;
for (p += 4; ones && di < 0x10000; p++) for (p += 4; ones && di < 0x10000; p++) {
{ if (dorel) {
if (dorel) set_le16(wrkmem + (4 * relocn), di);
{ set_le16(wrkmem + (2 + 4 * relocn++), es);
set_le16(wrkmem+4*relocn,di); NO_printf("%x\n", es * 16 + di);
set_le16(wrkmem+2+4*relocn++,es);
//printf ("%x\n",es*16+di);
} }
dorel = true; dorel = true;
if (*p == 0) if (*p == 0) {
{
SPAN_S_VAR(const upx_byte, q, obuf); SPAN_S_VAR(const upx_byte, q, obuf);
for (q = obuf + (es * 16 + di); !(*q == 0x9a && get_le16(q + 3) <= seghi);
for (q = obuf+es*16+di; !(*q == 0x9a && get_le16(q+3) <= seghi); q++) q++) {
;
di = ptr_diff_bytes(q, obuf+es*16) + 3;
} }
else if (*p == 1) di = ptr_diff_bytes(q, obuf + (es * 16)) + 3;
{ } else if (*p == 1) {
di += 254; di += 254;
if (di < 0x10000) if (di < 0x10000)
ones--; ones--;
dorel = false; dorel = false;
} } else
else
di += *p; di += *p;
} }
} }
@@ -762,11 +659,10 @@ void PackExe::unpack(OutputFile *fo)
memset(&oh, 0, sizeof(oh)); memset(&oh, 0, sizeof(oh));
oh.ident = 'M' + 'Z' * 256; oh.ident = 'M' + 'Z' * 256;
if (relocn) if (relocn) {
{
oh.relocs = relocn; oh.relocs = relocn;
while (relocn & 3) while (relocn & 3)
set_le32(wrkmem+4*relocn++,0); set_le32(wrkmem + (4 * relocn++), 0);
} }
unsigned outputlen = ptr_udiff_bytes(relocs, obuf) + sizeof(oh) + relocn * 4; unsigned outputlen = ptr_udiff_bytes(relocs, obuf) + sizeof(oh) + relocn * 4;
@@ -779,14 +675,22 @@ void PackExe::unpack(OutputFile *fo)
oh.sp = ih.sp; oh.sp = ih.sp;
oh.ss = ih.ss; oh.ss = ih.ss;
if (flag & MAXMEM) if (flag & MAXMEM) {
{ imagesize -= 2; oh.max = get_le16(ibuf+imagesize); } imagesize -= 2;
if (flag & MINMEM) oh.max = get_le16(ibuf + imagesize);
{ imagesize -= 2; oh.min = get_le16(ibuf+imagesize); } }
if (flag & SP) if (flag & MINMEM) {
{ imagesize -= 2; oh.sp = get_le16(ibuf+imagesize); } imagesize -= 2;
if (flag & SS) oh.min = get_le16(ibuf + imagesize);
{ imagesize -= 2; oh.ss = get_le16(ibuf+imagesize); } }
if (flag & SP) {
imagesize -= 2;
oh.sp = get_le16(ibuf + imagesize);
}
if (flag & SS) {
imagesize -= 2;
oh.ss = get_le16(ibuf + imagesize);
}
unsigned ip = (flag & USEJUMP) ? get_le32(ibuf + imagesize - 4) : (unsigned) ih.firstreloc; unsigned ip = (flag & USEJUMP) ? get_le32(ibuf + imagesize - 4) : (unsigned) ih.firstreloc;
oh.ip = ip & 0xffff; oh.ip = ip & 0xffff;
@@ -801,17 +705,13 @@ void PackExe::unpack(OutputFile *fo)
fo->write(&oh, sizeof(oh)); fo->write(&oh, sizeof(oh));
if (relocn) if (relocn)
fo->write(wrkmem, relocn * 4); fo->write(wrkmem, relocn * 4);
fo->write(obuf, ptr_diff_bytes(relocs, obuf)); fo->write(obuf, ptr_udiff_bytes(relocs, obuf));
// copy the overlay // copy the overlay
copyOverlay(fo, ih_overlay, obuf); copyOverlay(fo, ih_overlay, obuf);
} }
Linker *PackExe::newLinker() const { return new ElfLinkerX86(); }
Linker* PackExe::newLinker() const
{
return new ElfLinkerX86();
}
/* /*
+12 -24
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2022 Laszlo Molnar Copyright (C) 1996-2023 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,24 +25,22 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#pragma once
#ifndef __UPX_P_EXE_H #ifndef UPX_P_EXE_H__
#define __UPX_P_EXE_H 1 #define UPX_P_EXE_H__ 1
/************************************************************************* /*************************************************************************
// dos/exe // dos/exe
**************************************************************************/ **************************************************************************/
class PackExe final : public Packer class PackExe final : public Packer {
{
typedef Packer super; typedef Packer super;
public: public:
PackExe(InputFile *f); PackExe(InputFile *f);
virtual int getVersion() const override { return 13; } virtual int getVersion() const override { return 13; }
virtual int getFormat() const override { return UPX_F_DOS_EXE; } virtual int getFormat() const override { return UPX_F_DOS_EXE; }
virtual const char *getName() const override { return "dos/exe"; } virtual const char *getName() const override { return "dos/exe"; }
//virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.exe" : "i286-dos16.exe"; }
virtual const char *getFullName(const options_t *) const override { return "i086-dos16.exe"; } virtual const char *getFullName(const options_t *) const override { return "i086-dos16.exe"; }
virtual const int *getCompressionMethods(int method, int level) const override; virtual const int *getCompressionMethods(int method, int level) const override;
virtual const int *getFilters() const override; virtual const int *getFilters() const override;
@@ -54,13 +52,11 @@ public:
virtual int canUnpack() override; virtual int canUnpack() override;
// unpacker capabilities // unpacker capabilities
virtual bool canUnpackVersion(int version) const override virtual bool canUnpackVersion(int version) const override {
{
// NOTE: could adapt p_exe.cpp to support (version >= 8) // NOTE: could adapt p_exe.cpp to support (version >= 8)
return (version >= 10); return (version >= 10);
} }
virtual bool canUnpackFormat(int format) const override virtual bool canUnpackFormat(int format) const override {
{
return (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH); return (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH);
} }
@@ -74,7 +70,7 @@ protected:
virtual Linker *newLinker() const override; virtual Linker *newLinker() const override;
void addLoaderEpilogue(int flag); void addLoaderEpilogue(int flag);
__packed_struct(exe_header_t) struct alignas(1) exe_header_t {
LE16 ident; LE16 ident;
LE16 m512; LE16 m512;
LE16 p512; LE16 p512;
@@ -90,7 +86,7 @@ protected:
LE16 relocoffs; LE16 relocoffs;
char __[2]; // overlnum char __[2]; // overlnum
LE32 firstreloc; LE32 firstreloc;
__packed_struct_end() };
exe_header_t ih, oh; exe_header_t ih, oh;
@@ -102,20 +98,12 @@ protected:
bool has_9a; bool has_9a;
bool device_driver; bool device_driver;
enum { enum { NORELOC = 1, USEJUMP = 2, SS = 4, SP = 8, MINMEM = 16, MAXMEM = 32 };
NORELOC = 1,
USEJUMP = 2,
SS = 4,
SP = 8,
MINMEM = 16,
MAXMEM = 32
};
unsigned stack_for_lzma; // stack size required for lzma unsigned stack_for_lzma; // stack size required for lzma
bool use_clear_dirty_stack; bool use_clear_dirty_stack;
}; };
#endif /* already included */ #endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+502 -237
View File
File diff suppressed because it is too large Load Diff

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